down_interruptible() return non-zero value once signal is received and trying down_interruptible again in loop return value is always non-zero

Josh Cartwright joshc at eso.teric.us
Sun Oct 20 11:32:21 EDT 2013


On Fri, Oct 18, 2013 at 05:56:41PM +0530, Mushtaq Khan wrote:
> Hi,
> 
> In kernel driver, using Semaphore to block on resources (Descriptors and
> memory).
> Semaphore is initialized in locking state using call "init_MTEX_LOCKED()",
> when resources are not available process calls down_interruptible() and
> blocks. Once resources are freed up() is called, and blocked process is
> unblocked. up() is called from interrupt context which frees resources on
> receiving ACK-Interrupt.
> Following is the code snippet for blocking:
> do {
>     ret = down_interruptible(sem)
>     if (ret == 0) {
>         break;
>     } else {
>         printk("Semaphore is not acquired try again\n");
>         continue;
>    }
> } while (1);
> 
> While loop is used to make sure down_interrptible() is called until process
> acquires the semaphore. If process receives signal, process unblocks from
> down_interrptible() without acquiring the semaphore.
> Issue am seeing is once signal is received under the blocking state, again
> trying to acquire semaphore using down_interruptible() return value is
> always non-zero and process is looping in while loop.

Yes.  This happens because there is a signal pending for the calling
thread.  If you follow the down_interruptible() code path, you see that
the first thing in the loop in __down_common (kernel/semaphore.c) is
that signal_pending_state() is called to see if there is a pending
signal, and if so, it immediately returns -EINTR.

Using down_interruptible() in the method above is ill-advised.  It's
expected that if you are interrupted, you will propagate that
'interrupted' condition to your caller (and eventually back out to
usermode).

   Josh



More information about the Kernelnewbies mailing list