http://www.scs.ch/~frey/linux/kernelthreads.html /* We need to do a memory barrier here to be sure that the flags are visible on all CPUs. */ mb(); kill_proc(kthread->thread->pid, SIGKILL, 1); /* block till thread terminated */ down(&kthread->startstop_sem); Looking at kernel/sched.c: 3333 3334 int fastcall __sched wait_for_completion_interruptible(struct completion *x) 3335 { 3336 int ret = 0; 3337 3338 might_sleep(); 3339 3340 spin_lock_irq(&x->wait.lock); 3341 if (!x->done) { 3342 DECLARE_WAITQUEUE(wait, current); 3343 3344 wait.flags |= WQ_FLAG_EXCLUSIVE; 3345 __add_wait_queue_tail(&x->wait, &wait); 3346 do { 3347 if (signal_pending(current)) { 3348 ret = -ERESTARTSYS; 3349 __remove_wait_queue(&x->wait, &wait); 3350 goto out; 3351 } 3352 __set_current_state(TASK_INTERRUPTIBLE); 3353 spin_unlock_irq(&x->wait.lock); 3354 schedule(); 3355 spin_lock_irq(&x->wait.lock); 3356 } while (!x->done); 3357 __remove_wait_queue(&x->wait, &wait); 3358 } 3359 x->done--; 3360 out: 3361 spin_unlock_irq(&x->wait.lock); 3362 3363 return ret; 3364 } Your construction is very similar to sched.c. add_wait_queue() will not block, or "wait". The reason is because it is just a simple list_add() call. Notice also that the above schedule() is after the signal_pending() processing, whereas yours is the opposite. Another big difference is that the above implementation uses spin lock IRQ, and therefore signal can only come into the small windows just before schedule(), after that it is disabled immediately again. Correct? Neither can I explain your program's behavior either, as it does not have any spin locks, and so signal can come in anytime? > /* the thread will sleep on this wait queue until it gets woken up */ > add_wait_queue(&mkthread_waitqueue, &wait); > > for (;;) { > > /* guard against spurious wake up */ > while (!condition) { > /* must be set before calling schedule() to > * avoid race condition */ > set_current_state(TASK_INTERRUPTIBLE); > > /* remove current from run queue and schedule a new process */ > schedule(); > } > > /* we wake up here */ > /* check for pending SIGKILL signal, die if there is any */ > if (signal_pending(current)) { > kthread_debug("SIGKILL pending\n"); > break; > } > > /* is there a race condition ? */ > condition = 0; > kthread_debug("mkthread woke up!\n"); > } > > /* change task stae to TASK_RUNNING before removing from wait queue */ > Is the following really necessary? I saw the code calling remove_wait_queue() anytime. > set_current_state(TASK_RUNNING); > remove_wait_queue(&mkthread_waitqueue, &wait); > > -- To unsubscribe from this list: send an email with "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx Please read the FAQ at http://kernelnewbies.org/FAQ