Skip to contentSkip to conversation

remove sleep_on from sunrpc

PATCH In review Manfred Spraul 2 participants 2 messages Jan 17, 2004 – Jan 18, 2004

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

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(&current->sighand->siglock, flags);
+	remove_wait_queue(&rpciod_killer, &wait);
+	spin_lock_irq(&current->sighand->siglock);
 	recalc_sigpending();
-	spin_unlock_irqrestore(&current->sighand->siglock, flags);
+	spin_unlock_irq(&current->sighand->siglock);
 out:
 	up(&rpciod_sema);
 }
#1 lore raw
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(&current->sighand->siglock, flags);
+	remove_wait_queue(&rpciod_killer, &wait);
+	spin_lock_irq(&current->sighand->siglock);
 	recalc_sigpending();
-	spin_unlock_irqrestore(&current->sighand->siglock, flags);
+	spin_unlock_irq(&current->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