On Thu, May 09, 2019 at 11:32:57AM +0100, Chris Wilson wrote: > Quoting Daniel Vetter (2019-05-06 08:45:53) > > +/** > > + * printk_safe_up - release the semaphore in console_unlock > > + * @sem: the semaphore to release > > + * > > + * Release the semaphore. Unlike mutexes, up() may be called from any > > + * context and even by tasks which have never called down(). > > + * > > + * NOTE: This is a special version of up() for console_unlock only. It is only > > + * safe if there are no killable, interruptible or timing out down() calls. > > + */ > > +void printk_safe_up(struct semaphore *sem) > > +{ > > + unsigned long flags; > > + struct semaphore_waiter *waiter = NULL; > > + > > + raw_spin_lock_irqsave(&sem->lock, flags); > > + if (likely(list_empty(&sem->wait_list))) { > > + sem->count++; > > + } else { > > + waiter = list_first_entry(&sem->wait_list, > > + struct semaphore_waiter, list); > > + list_del(&waiter->list); > > + waiter->up = true; > > + } > > + raw_spin_unlock_irqrestore(&sem->lock, flags); > > + > > + if (waiter) > > + wake_up_process(waiter->task); > > From comparing against __down_common() there's a risk here that as soon > as waiter->up == true, the waiter may complete and make the onstack > struct semaphore_waiter invalid. If you store waiter->task locally under > the spinlock that problem is resolved. > > Then there is the issue of an unprotected dereference of the task in > wake_up_process() -- I think you can wrap this function with > rcu_read_lock() to keep that safe, and wake_up_process() should be a > no-op if it races against process termination. task_struct is not RCU protected, see task_rcu_dereference() for magic. _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx