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.