Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regarding semaphore up() and mutex_unlock() in linux kernel

I want to know why we can use the semaphore up() in interrupt context while the same variant of mutex i.e mutex_unlock() cannot be used in interrupt context. Below is snippet from kernel

/**
* mutex_unlock - release the mutex
* @lock: the mutex to be released
*
* Unlock a mutex that has been locked by this task previously.
*
* This function must not be used in interrupt context. Unlocking
* of a not locked mutex is not allowed.
*
* This function is similar to (but not equivalent to) up().
*/
void __sched mutex_unlock(struct mutex *lock)
{
  #ifndef CONFIG_DEBUG_LOCK_ALLOC
  if (__mutex_unlock_fast(lock))
    return;
#endif
__mutex_unlock_slowpath(lock, _RET_IP_);
}EXPORT_SYMBOL(mutex_unlock);


 /**
 * up - release the semaphore
* @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().
*/
void up(struct semaphore *sem)
{
  unsigned long flags;

  raw_spin_lock_irqsave(&sem->lock, flags);
  if (likely(list_empty(&sem->wait_list)))
    sem->count++;
  else
     __up(sem);
  raw_spin_unlock_irqrestore(&sem->lock, flags);
}
EXPORT_SYMBOL(up);
like image 498
Abhi Avatar asked Dec 20 '25 07:12

Abhi


1 Answers

mutex_unlock takes a mutex-internal spinlock in a non-irq-safe fashion - e.g. raw_spin_lock may sleep if CONFIG_PREEMPT_RT is set - so if the timing is right, your mutex_unlock in IRQ context will deadlock.

like image 167
Michael Foukarakis Avatar answered Dec 22 '25 06:12

Michael Foukarakis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!