All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stanley Chu <stanley.chu@mediatek.com>
To: Bart Van Assche <bvanassche@acm.org>
Cc: Jens Axboe <axboe@kernel.dk>, <linux-block@vger.kernel.org>,
	"Christoph Hellwig" <hch@lst.de>,
	Alan Stern <stern@rowland.harvard.edu>,
	Ming Lei <ming.lei@redhat.com>, stable <stable@vger.kernel.org>,
	Can Guo <cang@codeaurora.org>
Subject: Re: [PATCH] block: Fix a race in the runtime power management code
Date: Tue, 25 Aug 2020 17:11:21 +0800	[thread overview]
Message-ID: <1598346681.10649.8.camel@mtkswgap22> (raw)
In-Reply-To: <20200824030607.19357-1-bvanassche@acm.org>

Sorry, resend to fix typo.

Hi Bart,

On Sun, 2020-08-23 at 20:06 -0700, Bart Van Assche wrote:
> With the current implementation the following race can happen:
> * blk_pre_runtime_suspend() calls blk_freeze_queue_start() and
>   blk_mq_unfreeze_queue().
> * blk_queue_enter() calls blk_queue_pm_only() and that function returns
>   true.
> * blk_queue_enter() calls blk_pm_request_resume() and that function does
>   not call pm_request_resume() because the queue runtime status is
>   RPM_ACTIVE.
> * blk_pre_runtime_suspend() changes the queue status into RPM_SUSPENDING.
> 
> Fix this race by changing the queue runtime status into RPM_SUSPENDING
> before switching q_usage_counter to atomic mode.
> 
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: Stanley Chu <stanley.chu@mediatek.com>
> Cc: Ming Lei <ming.lei@redhat.com>
> Cc: stable <stable@vger.kernel.org>
> Fixes: 986d413b7c15 ("blk-mq: Enable support for runtime power management")
> Signed-off-by: Can Guo <cang@codeaurora.org>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
> ---
>  block/blk-pm.c | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/block/blk-pm.c b/block/blk-pm.c
> index b85234d758f7..17bd020268d4 100644
> --- a/block/blk-pm.c
> +++ b/block/blk-pm.c
> @@ -67,6 +67,10 @@ int blk_pre_runtime_suspend(struct request_queue *q)
>  
>  	WARN_ON_ONCE(q->rpm_status != RPM_ACTIVE);
>  
> +	spin_lock_irq(&q->queue_lock);
> +	q->rpm_status = RPM_SUSPENDING;
> +	spin_unlock_irq(&q->queue_lock);
> +

Has below alternative way been considered that RPM_SUSPENDING is set
after blk_freeze_queue_start()?

	blk_freeze_queue_start(q);

+	spin_lock_irq(&q->queue_lock);
+	q->rpm_status = RPM_SUSPENDING;
+	spin_unlock_irq(&q->queue_lock);


Otherwise requests can enter queue while rpm_status is RPM_SUSPENDING
during a small window, i.e., before blk_set_pm_only() is invoked. This
would make the definition of rpm_status ambiguous.

In this way, the racing could be also solved:

- Before blk_freeze_queue_start(), any requests shall be allowed to
enter queue
- blk_freeze_queue_start() freezes the queue and blocks all upcoming
requests (make them wait_event(q->mq_freeze_wq))
- rpm_status is set as RPM_SUSPENDING
- blk_mq_unfreeze_queue() wakes up q->mq_freeze_wq and then
blk_pm_request_resume() can be executed

Thanks,

Stanley Chu


>  	/*
>  	 * Increase the pm_only counter before checking whether any
>  	 * non-PM blk_queue_enter() calls are in progress to avoid that any
> @@ -89,15 +93,14 @@ int blk_pre_runtime_suspend(struct request_queue *q)
>  	/* Switch q_usage_counter back to per-cpu mode. */
>  	blk_mq_unfreeze_queue(q);
>  
> -	spin_lock_irq(&q->queue_lock);
> -	if (ret < 0)
> +	if (ret < 0) {
> +		spin_lock_irq(&q->queue_lock);
> +		q->rpm_status = RPM_ACTIVE;
>  		pm_runtime_mark_last_busy(q->dev);
> -	else
> -		q->rpm_status = RPM_SUSPENDING;
> -	spin_unlock_irq(&q->queue_lock);
> +		spin_unlock_irq(&q->queue_lock);
>  
> -	if (ret)
>  		blk_clear_pm_only(q);
> +	}
>  
>  	return ret;
>  }






  parent reply	other threads:[~2020-08-25  9:11 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-24  3:06 [PATCH] block: Fix a race in the runtime power management code Bart Van Assche
2020-08-24 14:47 ` Alan Stern
2020-08-25  9:01 ` Stanley Chu
2020-08-25  9:11 ` Stanley Chu [this message]
2020-08-25 18:24   ` Alan Stern
2020-08-25 22:22     ` Bart Van Assche
2020-08-26  1:51       ` Alan Stern
2020-08-27  3:35         ` Bart Van Assche
2020-08-27 20:33           ` Alan Stern
2020-08-28  3:27             ` Bart Van Assche
2020-08-28 15:37               ` Alan Stern
2020-08-29  0:51                 ` Bart Van Assche
2020-08-29  1:12                   ` Alan Stern
2020-08-29  2:57                     ` Bart Van Assche
2020-08-26  2:58   ` Bart Van Assche
2020-08-26  4:00     ` Stanley Chu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1598346681.10649.8.camel@mtkswgap22 \
    --to=stanley.chu@mediatek.com \
    --cc=axboe@kernel.dk \
    --cc=bvanassche@acm.org \
    --cc=cang@codeaurora.org \
    --cc=hch@lst.de \
    --cc=linux-block@vger.kernel.org \
    --cc=ming.lei@redhat.com \
    --cc=stable@vger.kernel.org \
    --cc=stern@rowland.harvard.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.