remove sleep_on from sunrpc
Subsystems (3)
PATCH 1/1 remove sleep_on from sunrpc
sunrpc uses sleep_on to wait until the rpciod thread has died. This could race if rpciod_down is called without lock_kernel. Right now all calls in the main tree are under lock_kernel, but rpciod is an exported function and sleep_on should die.
Additionally, I've replaced spin_lock_irqsave() with spin_lock_irq():rpciod_down sleeps, interrupts are guaranteed to be enabled.
--
Manfred
net/sunrpc/sched.c +10 -5
@@ -1060,7 +1060,7 @@void rpciod_down (void ) { -unsigned long flags; +DECLARE_WAITQUEUE (wait, current);down (&rpciod_sema);dprintk ("rpciod_down pid %d sema %d\n" , rpciod_pid, rpciod_users);
@@ -1085,17 +1085,22 @@/* * Display a message if we're going to wait longer. */ -while (rpciod_pid) { +add_wait_queue (&rpciod_killer, &wait); +for (;;) { +set_current_state (TASK_INTERRUPTIBLE ); +if (rpciod_pid ==0 ) +break ;dprintk ("rpciod_down: waiting for pid %d to exit\n" , rpciod_pid);if (signalled ()) {dprintk ("rpciod_down: caught signal\n" );break ; } -interruptible_sleep_on (&rpciod_killer); +schedule (); } -spin_lock_irqsave (¤t->sighand->siglock, flags); +remove_wait_queue (&rpciod_killer, &wait); +spin_lock_irq (¤t->sighand->siglock);recalc_sigpending (); -spin_unlock_irqrestore (¤t->sighand->siglock, flags); +spin_unlock_irq (¤t->sighand->siglock); out:up (&rpciod_sema); }
Quoted 13 lines · Manfred Spraul
net/sunrpc/sched.c +6
-2-while (rpciod_pid) { +add_wait_queue (&rpciod_killer, &wait); +for (;;) { +set_current_state (TASK_INTERRUPTIBLE ); +if (rpciod_pid ==0 ) +break ;dprintk ("rpciod_down: waiting for pid %d to exit\n" , rpciod_pid);if (signalled ()) {dprintk ("rpciod_down: caught signal\n" );break ; } -interruptible_sleep_on (&rpciod_killer); +schedule ();
net/sunrpc/sched.c line 1106
Quoted 10 lines
net/sunrpc/sched.c +3
-2} -spin_lock_irqsave (¤t->sighand->siglock, flags); +remove_wait_queue (&rpciod_killer, &wait); +spin_lock_irq (¤t->sighand->siglock);recalc_sigpending (); -spin_unlock_irqrestore (¤t->sighand->siglock, flags); +spin_unlock_irq (¤t->sighand->siglock); out:up (&rpciod_sema); }
Aren't you forgetting to set_current_state(TASK_RUNNING) after the loop?
Signature · 2 lines
Peter Osterlund - [email protected] http://w1.894.telia.com/~u89404340