Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 30592e78 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mmc: card: fix race with shutdown handler"

parents 3833f887 3eb69524
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -3115,8 +3115,6 @@ out:
	if (!ctx_info->active_reqs)
		wake_up_interruptible(&host->cmdq_ctx.queue_empty_wq);

	if (blk_queue_stopped(mq->queue) && !ctx_info->active_reqs)
		complete(&mq->cmdq_shutdown_complete);
	return;
}

+6 −31
Original line number Diff line number Diff line
@@ -649,7 +649,6 @@ int mmc_cmdq_init(struct mmc_queue *mq, struct mmc_card *card)

	blk_queue_softirq_done(mq->queue, mmc_cmdq_softirq_done);
	INIT_WORK(&mq->cmdq_err_work, mmc_cmdq_error_work);
	init_completion(&mq->cmdq_shutdown_complete);
	init_completion(&mq->cmdq_pending_req_done);

	blk_queue_rq_timed_out(mq->queue, mmc_cmdq_rq_timed_out);
@@ -698,7 +697,6 @@ int mmc_queue_suspend(struct mmc_queue *mq, int wait)
	int rc = 0;
	struct mmc_card *card = mq->card;
	struct request *req;
	#define SLEEP_TIME_BETWEEN_BLK_REQ_CHECK	100 /* microseconds */

	if (card->cmdq_init && blk_queue_tagged(q)) {
		struct mmc_host *host = card->host;
@@ -706,44 +704,21 @@ int mmc_queue_suspend(struct mmc_queue *mq, int wait)
		if (test_and_set_bit(MMC_QUEUE_SUSPENDED, &mq->flags))
			goto out;

		spin_lock_irqsave(q->queue_lock, flags);
		blk_stop_queue(q);
		spin_unlock_irqrestore(q->queue_lock, flags);

		wake_up(&host->cmdq_ctx.wait);

		if (wait) {
			while (1) {
				spin_lock_irqsave(q->queue_lock, flags);
				req = blk_peek_request(q);
				spin_unlock_irqrestore(q->queue_lock, flags);

				if (!req)
					break;

				/* sleep for some time before rechecking */
				usleep_range(SLEEP_TIME_BETWEEN_BLK_REQ_CHECK,
					SLEEP_TIME_BETWEEN_BLK_REQ_CHECK + 10);
			}

			/* Wait for already issued requests to complete */
			if (host->cmdq_ctx.active_reqs)
				wait_for_completion(
						&mq->cmdq_shutdown_complete);

			blk_cleanup_queue(q);
			mq->cmdq_shutdown(mq);
		} else {
			spin_lock_irqsave(q->queue_lock, flags);
			blk_stop_queue(q);
			wake_up(&host->cmdq_ctx.wait);
			req = blk_peek_request(q);
			spin_unlock_irqrestore(q->queue_lock, flags);

			if (req || host->cmdq_ctx.active_reqs) {
			if (req || mq->cmdq_req_peeked ||
			    host->cmdq_ctx.active_reqs) {
				clear_bit(MMC_QUEUE_SUSPENDED, &mq->flags);
				spin_lock_irqsave(q->queue_lock, flags);
				blk_start_queue(q);
				spin_unlock_irqrestore(q->queue_lock, flags);
				rc = -EBUSY;
			}
			spin_unlock_irqrestore(q->queue_lock, flags);
		}

		goto out;
+0 −1
Original line number Diff line number Diff line
@@ -69,7 +69,6 @@ struct mmc_queue {
	int			num_wr_reqs_to_start_packing;
	bool			no_pack_for_random;
	struct work_struct	cmdq_err_work;
	struct completion	cmdq_shutdown_complete;

	struct completion	cmdq_pending_req_done;
	struct request		*cmdq_req_peeked;