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. -Chris _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx