On (05/09/19 22:06), Daniel Vetter wrote: [..] > +/* Functions for the contended case */ > + > +struct semaphore_waiter { > + struct list_head list; > + struct task_struct *task; > + bool up; > +}; > + > /** > * up - release the semaphore > * @sem: the semaphore to release > @@ -179,24 +187,25 @@ EXPORT_SYMBOL(down_timeout); > void up(struct semaphore *sem) > { > unsigned long flags; > + struct semaphore_waiter *waiter; > + DEFINE_WAKE_Q(wake_q); > > raw_spin_lock_irqsave(&sem->lock, flags); > - if (likely(list_empty(&sem->wait_list))) > + if (likely(list_empty(&sem->wait_list))) { > sem->count++; > - else > - __up(sem); > + } else { > + waiter = list_first_entry(&sem->wait_list, > + struct semaphore_waiter, list); > + list_del(&waiter->list); > + waiter->up = true; > + wake_q_add(&wake_q, waiter->task); > + } > raw_spin_unlock_irqrestore(&sem->lock, flags); So the new code still can printk/WARN under sem->lock in some buggy cases. E.g. wake_q_add() get_task_struct() refcount_inc_checked() WARN_ONCE() Are we fine with that? -ss _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel