On Thu, 2018-07-26 at 10:45 +0800, jianchao.wang wrote:
> On 07/26/2018 06:26 AM, Bart Van Assche wrote:
> > +
> > +void blk_pm_runtime_lock(struct request_queue *q)
> > +{
> > +   spin_lock(&q->rpm_lock);
> > +   wait_event_interruptible_locked(q->rpm_wq,
> > +                     q->rpm_owner == NULL || q->rpm_owner == current);
> > +   if (q->rpm_owner == NULL)
> > +           q->rpm_owner = current;
> > +   q->rpm_nesting_level++;
> > +   spin_unlock(&q->rpm_lock);
> > +}
> 
> The lock which wait_event_interruptible_locked want to hold is the wq.lock.

The above code is indeed wrong. This is what I think it should be changed
into:

+void blk_pm_runtime_lock(struct request_queue *q)
+{
+       might_sleep();
+
+       spin_lock(&q->rpm_lock);
+       wait_event_exclusive_cmd(q->rpm_wq,
+                       q->rpm_owner == NULL || q->rpm_owner == current,
+                       spin_unlock(&q->rpm_lock), spin_lock(&q->rpm_lock));
+       if (q->rpm_owner == NULL)
+               q->rpm_owner = current;
+       q->rpm_nesting_level++;
+       spin_unlock(&q->rpm_lock);
+}

Bart.

Reply via email to