From: Alan Stern <stern@rowland.harvard.edu> To: Bart Van Assche <bvanassche@acm.org> Cc: Martin Kepplinger <martin.kepplinger@puri.sm>, jejb@linux.ibm.com, Can Guo <cang@codeaurora.org>, martin.petersen@oracle.com, linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, kernel@puri.sm Subject: Re: [PATCH] scsi: sd: add runtime pm to open / release Date: Mon, 29 Jun 2020 13:40:55 -0400 [thread overview] Message-ID: <20200629174055.GA408860@rowland.harvard.edu> (raw) In-Reply-To: <df54c02f-dbe9-08d5-fec8-835788caf164@acm.org> On Mon, Jun 29, 2020 at 09:56:49AM -0700, Bart Van Assche wrote: > On 2020-06-29 09:15, Alan Stern wrote: > > Aha. Looking at this more closely, it's apparent that the code in > > blk-core.c contains a logic bug: It assumes that if the BLK_MQ_REQ_PREEMPT > > flag is set then the request can be issued regardless of the queue's > > runtime status. That is not correct when the queue is suspended. > > Please clarify why this is not correct. As I understand it, BLK_MQ_REQ_PREEMPT is supposed to mean (among other things) that this request may be issued as part of the procedure for putting a device into a low-power state or returning it to a high-power state. Consequently, requests with that flag set must be allowed while the queue is in the RPM_SUSPENDING or RPM_RESUMING runtime states -- as opposed to ordinary requests, which are allowed only in the RPM_ACTIVE state. In the RPM_SUSPENDED state, however, the queue is entirely inactive. Even if a request were to be issued somehow, it would fail because the system would not be able to transmit it to the device. In other words, when the queue is in the RPM_SUSPENDED state, a resume must be requested before _any_ request can be issued. > > Index: usb-devel/block/blk-core.c > > =================================================================== > > --- usb-devel.orig/block/blk-core.c > > +++ usb-devel/block/blk-core.c > > @@ -423,7 +423,8 @@ int blk_queue_enter(struct request_queue > > * responsible for ensuring that that counter is > > * globally visible before the queue is unfrozen. > > */ > > - if (pm || !blk_queue_pm_only(q)) { > > + if ((pm && q->rpm_status != RPM_SUSPENDED) || > > + !blk_queue_pm_only(q)) { > > success = true; > > } else { > > percpu_ref_put(&q->q_usage_counter); > > Does the above change make it impossible to bring a suspended device > back to the RPM_ACTIVE state if the BLK_MQ_REQ_NOWAIT flag is set? The only case affected by this change is when BLK_MQ_REQ_PREEMPT is set and the queue is in the RPM_SUSPENDED state. If BLK_MQ_REQ_NOWAIT was also set, the original code would set "success" to true, allowing the request to proceed even though it could not be carried out immediately -- a bug. With the patch, such a request will fail without resuming the device. I don't know whether that is the desired behavior or not, but at least it's not obviously a bug. It does seem odd that blk_queue_enter() tests the queue's pm_only status and the request flag in two different spots (here and below). Why does it do this? It seems like an invitation for bugs. > > @@ -448,8 +449,7 @@ int blk_queue_enter(struct request_queue > > > > wait_event(q->mq_freeze_wq, > > (!q->mq_freeze_depth && > > - (pm || (blk_pm_request_resume(q), > > - !blk_queue_pm_only(q)))) || > > + blk_pm_resume_queue(pm, q)) || > > blk_queue_dying(q)); > > if (blk_queue_dying(q)) > > return -ENODEV; > > Index: usb-devel/block/blk-pm.h > > =================================================================== > > --- usb-devel.orig/block/blk-pm.h > > +++ usb-devel/block/blk-pm.h > > @@ -6,11 +6,14 @@ > > #include <linux/pm_runtime.h> > > > > #ifdef CONFIG_PM > > -static inline void blk_pm_request_resume(struct request_queue *q) > > +static inline int blk_pm_resume_queue(const bool pm, struct request_queue *q) > > { > > - if (q->dev && (q->rpm_status == RPM_SUSPENDED || > > - q->rpm_status == RPM_SUSPENDING)) > > - pm_request_resume(q->dev); > > + if (!q->dev || !blk_queue_pm_only(q)) > > + return 1; /* Nothing to do */ > > + if (pm && q->rpm_status != RPM_SUSPENDED) > > + return 1; /* Request allowed */ > > + pm_request_resume(q->dev); > > + return 0; > > } > > Does the above change, especially the " && q->rpm_status != > RPM_SUSPENDED" part, make it impossible to bring a suspended device back > to the RPM_ACTIVE state? Just the opposite -- the change makes it _possible_ for a BLK_MQ_REQ_PREEMPT request to bring a suspended device back to the RPM_ACTIVE state. Look at the existing code: If pm is true then blk_pm_request_resume() will be skipped, so the device won't be resumed. With this patch -- in particular with the "&& q->rpm_status != RPM_SUSPENDED" part added -- the call won't be skipped and so the resume will take place. The rather complicated syntax of the wait_event() call in the existing code contributes to this confusion. One of the things my patch tries to do is make the code more straightforward and easier to grasp. I admit that there are parts to this thing I don't understand. The wait_event() call in blk_queue_enter(), for example: If we are waiting for the device to leave the RPM_SUSPENDED state (or enter the RPM_ACTIVE state), where does q->mq_freeze_wq get woken up? There's no obvious spot in blk_{pre|post}_runtime_resume(). Alan Stern
next prev parent reply other threads:[~2020-06-29 21:34 UTC|newest] Thread overview: 68+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-06-23 11:10 Martin Kepplinger 2020-06-24 13:33 ` Bart Van Assche 2020-06-25 8:16 ` Martin Kepplinger 2020-06-25 14:52 ` Alan Stern 2020-06-26 3:53 ` Bart Van Assche 2020-06-26 15:07 ` Bart Van Assche 2020-06-26 15:44 ` Alan Stern 2020-06-28 2:37 ` Bart Van Assche 2020-06-28 13:10 ` Alan Stern 2020-06-29 9:42 ` Martin Kepplinger 2020-06-29 16:15 ` Alan Stern 2020-06-29 16:56 ` Bart Van Assche 2020-06-29 17:40 ` Alan Stern [this message] 2020-06-30 3:33 ` Martin Kepplinger 2020-06-30 13:38 ` Alan Stern 2020-06-30 15:59 ` Bart Van Assche 2020-06-30 18:02 ` Alan Stern 2020-06-30 19:23 ` Bart Van Assche 2020-06-30 19:38 ` Alan Stern 2020-06-30 23:31 ` Bart Van Assche 2020-07-01 0:49 ` Alan Stern 2020-07-06 16:41 ` Alan Stern 2020-07-28 7:02 ` Martin Kepplinger 2020-07-28 20:02 ` Alan Stern 2020-07-29 14:12 ` Martin Kepplinger 2020-07-29 14:32 ` Alan Stern 2020-07-29 14:44 ` Martin K. Petersen 2020-07-29 14:56 ` Alan Stern 2020-07-29 14:46 ` James Bottomley 2020-07-29 14:53 ` James Bottomley 2020-07-29 15:40 ` Martin Kepplinger 2020-07-29 15:44 ` James Bottomley 2020-07-29 16:43 ` Martin Kepplinger 2020-07-29 18:25 ` Alan Stern 2020-07-29 18:29 ` James Bottomley 2020-07-30 8:52 ` Martin Kepplinger 2020-07-30 8:54 ` Martin Kepplinger 2020-07-30 15:10 ` Alan Stern 2020-08-04 9:39 ` Martin Kepplinger 2020-08-07 9:51 ` Martin Kepplinger 2020-08-07 14:30 ` Alan Stern 2020-08-08 6:59 ` Martin Kepplinger 2020-08-08 15:05 ` Alan Stern 2020-08-09 9:20 ` Martin Kepplinger 2020-08-09 15:26 ` Alan Stern 2020-08-10 12:03 ` Martin Kepplinger 2020-08-10 14:13 ` Alan Stern 2020-08-11 7:55 ` Martin Kepplinger 2020-08-11 13:48 ` Alan Stern 2020-08-23 14:57 ` [PATCH] block: Fix bug in runtime-resume handling Alan Stern 2020-08-24 17:48 ` Bart Van Assche 2020-08-24 20:13 ` Alan Stern 2020-08-26 7:48 ` Martin Kepplinger 2020-08-27 17:42 ` Martin Kepplinger 2020-08-27 20:29 ` Alan Stern 2020-08-29 7:24 ` Martin Kepplinger 2020-08-29 15:26 ` Alan Stern 2020-08-29 16:33 ` Martin Kepplinger 2020-08-29 18:56 ` Alan Stern 2020-08-30 0:38 ` Bart Van Assche 2020-08-30 1:06 ` Alan Stern 2020-07-29 15:40 ` [PATCH] scsi: sd: add runtime pm to open / release Alan Stern 2020-07-29 15:49 ` James Bottomley 2020-07-29 16:17 ` Alan Stern 2020-07-29 15:52 ` Martin Kepplinger 2020-07-29 18:10 ` Douglas Gilbert 2020-07-30 8:05 ` Martin Kepplinger 2020-07-30 15:14 ` Alan Stern
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=20200629174055.GA408860@rowland.harvard.edu \ --to=stern@rowland.harvard.edu \ --cc=bvanassche@acm.org \ --cc=cang@codeaurora.org \ --cc=jejb@linux.ibm.com \ --cc=kernel@puri.sm \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-scsi@vger.kernel.org \ --cc=martin.kepplinger@puri.sm \ --cc=martin.petersen@oracle.com \ --subject='Re: [PATCH] scsi: sd: add runtime pm to open / release' \ /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
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.