From: Trond Myklebust <trond.myklebust@fys.uio.no>

--=-HT9F/x8+F4NM0LHwrnu+
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Close some potential scheduler races in rpciod.

Cheers,
  Trond

--=-HT9F/x8+F4NM0LHwrnu+
Content-Disposition: attachment; filename=linux-2.6.4-07-rpc_fixes2.dif
Content-Transfer-Encoding: base64
Content-Type: text/plain; name=linux-2.6.4-07-rpc_fixes2.dif; charset=ISO-8859-1

IHNjaGVkLmMgfCAgIDMxICsrKysrKysrKysrKysrKysrKysrKysrKy0tLS0tLS0NCiAxIGZpbGVz
IGNoYW5nZWQsIDI0IGluc2VydGlvbnMoKyksIDcgZGVsZXRpb25zKC0pDQoNCmRpZmYgLXUgLS1y
ZWN1cnNpdmUgLS1uZXctZmlsZSAtLXNob3ctYy1mdW5jdGlvbiBsaW51eC0yLjYuMy0yNC1ycGNf
dGhyb3R0bGUvbmV0L3N1bnJwYy9zY2hlZC5jIGxpbnV4LTIuNi4zLTI1LXJwY19maXhlczIvbmV0
L3N1bnJwYy9zY2hlZC5jDQotLS0gbGludXgtMi42LjMtMjQtcnBjX3Rocm90dGxlL25ldC9zdW5y
cGMvc2NoZWQuYwkyMDA0LTAzLTAzIDIyOjQ5OjI5LjAwMDAwMDAwMCAtMDUwMA0KKysrIGxpbnV4
LTIuNi4zLTI1LXJwY19maXhlczIvbmV0L3N1bnJwYy9zY2hlZC5jCTIwMDQtMDMtMDMgMjI6NDI6
MDAuMDAwMDAwMDAwIC0wNTAwDQpAQCAtNzg2LDIxICs3ODYsMjIgQEAgX19ycGNfc2NoZWR1bGUo
dm9pZCkNCiANCiAJZHByaW50aygiUlBDOiAgICAgIHJwY19zY2hlZHVsZSBlbnRlclxuIik7DQog
CXdoaWxlICgxKSB7DQotCQlzcGluX2xvY2tfYmgoJnJwY19xdWV1ZV9sb2NrKTsNCiANCiAJCXRh
c2tfZm9yX2ZpcnN0KHRhc2ssICZzY2hlZHEudGFza3NbMF0pIHsNCiAJCQlfX3JwY19yZW1vdmVf
d2FpdF9xdWV1ZSh0YXNrKTsNCiAJCQlzcGluX3VubG9ja19iaCgmcnBjX3F1ZXVlX2xvY2spOw0K
IA0KIAkJCV9fcnBjX2V4ZWN1dGUodGFzayk7DQorCQkJc3Bpbl9sb2NrX2JoKCZycGNfcXVldWVf
bG9jayk7DQogCQl9IGVsc2Ugew0KLQkJCXNwaW5fdW5sb2NrX2JoKCZycGNfcXVldWVfbG9jayk7
DQogCQkJYnJlYWs7DQogCQl9DQogDQogCQlpZiAoKytjb3VudCA+PSAyMDAgfHwgbmVlZF9yZXNj
aGVkKCkpIHsNCiAJCQljb3VudCA9IDA7DQorCQkJc3Bpbl91bmxvY2tfYmgoJnJwY19xdWV1ZV9s
b2NrKTsNCiAJCQlzY2hlZHVsZSgpOw0KKwkJCXNwaW5fbG9ja19iaCgmcnBjX3F1ZXVlX2xvY2sp
Ow0KIAkJfQ0KIAl9DQogCWRwcmludGsoIlJQQzogICAgICBycGNfc2NoZWR1bGUgbGVhdmVcbiIp
Ow0KQEAgLTExMTQsMjcgKzExMTUsNDEgQEAgcnBjaW9kKHZvaWQgKnB0cikNCiAJYWxsb3dfc2ln
bmFsKFNJR0tJTEwpOw0KIA0KIAlkcHJpbnRrKCJSUEM6IHJwY2lvZCBzdGFydGluZyAocGlkICVk
KVxuIiwgcnBjaW9kX3BpZCk7DQorCXNwaW5fbG9ja19iaCgmcnBjX3F1ZXVlX2xvY2spOw0KIAl3
aGlsZSAocnBjaW9kX3VzZXJzKSB7DQorCQlERUZJTkVfV0FJVCh3YWl0KTsNCiAJCWlmIChzaWdu
YWxsZWQoKSkgew0KKwkJCXNwaW5fdW5sb2NrX2JoKCZycGNfcXVldWVfbG9jayk7DQogCQkJcnBj
aW9kX2tpbGxhbGwoKTsNCiAJCQlmbHVzaF9zaWduYWxzKGN1cnJlbnQpOw0KKwkJCXNwaW5fbG9j
a19iaCgmcnBjX3F1ZXVlX2xvY2spOw0KIAkJfQ0KIAkJX19ycGNfc2NoZWR1bGUoKTsNCi0JCWlm
IChjdXJyZW50LT5mbGFncyAmIFBGX0ZSRUVaRSkNCisJCWlmIChjdXJyZW50LT5mbGFncyAmIFBG
X0ZSRUVaRSkgew0KKwkJCXNwaW5fdW5sb2NrX2JoKCZycGNfcXVldWVfbG9jayk7DQogCQkJcmVm
cmlnZXJhdG9yKFBGX0lPVEhSRUFEKTsNCisJCQlzcGluX2xvY2tfYmgoJnJwY19xdWV1ZV9sb2Nr
KTsNCisJCX0NCiANCiAJCWlmICgrK3JvdW5kcyA+PSA2NCkgewkvKiBzYWZlZ3VhcmQgKi8NCisJ
CQlzcGluX3VubG9ja19iaCgmcnBjX3F1ZXVlX2xvY2spOw0KIAkJCXNjaGVkdWxlKCk7DQogCQkJ
cm91bmRzID0gMDsNCisJCQlzcGluX2xvY2tfYmgoJnJwY19xdWV1ZV9sb2NrKTsNCiAJCX0NCiAN
Ci0JCWlmICghcnBjaW9kX3Rhc2tfcGVuZGluZygpKSB7DQotCQkJZHByaW50aygiUlBDOiBycGNp
b2QgYmFjayB0byBzbGVlcFxuIik7DQotCQkJd2FpdF9ldmVudF9pbnRlcnJ1cHRpYmxlKHJwY2lv
ZF9pZGxlLCBycGNpb2RfdGFza19wZW5kaW5nKCkpOw0KLQkJCWRwcmludGsoIlJQQzogc3dpdGNo
IHRvIHJwY2lvZFxuIik7DQorCQlkcHJpbnRrKCJSUEM6IHJwY2lvZCBiYWNrIHRvIHNsZWVwXG4i
KTsNCisJCXByZXBhcmVfdG9fd2FpdCgmcnBjaW9kX2lkbGUsICZ3YWl0LCBUQVNLX0lOVEVSUlVQ
VElCTEUpOw0KKwkJaWYgKCFycGNpb2RfdGFza19wZW5kaW5nKCkgJiYgIXNpZ25hbGxlZCgpKSB7
DQorCQkJc3Bpbl91bmxvY2tfYmgoJnJwY19xdWV1ZV9sb2NrKTsNCisJCQlzY2hlZHVsZSgpOw0K
IAkJCXJvdW5kcyA9IDA7DQorCQkJc3Bpbl9sb2NrX2JoKCZycGNfcXVldWVfbG9jayk7DQogCQl9
DQorCQlmaW5pc2hfd2FpdCgmcnBjaW9kX2lkbGUsICZ3YWl0KTsNCisJCWRwcmludGsoIlJQQzog
c3dpdGNoIHRvIHJwY2lvZFxuIik7DQogCX0NCisJc3Bpbl91bmxvY2tfYmgoJnJwY19xdWV1ZV9s
b2NrKTsNCiANCiAJZHByaW50aygiUlBDOiBycGNpb2Qgc2h1dGRvd24gY29tbWVuY2VzXG4iKTsN
CiAJaWYgKCFsaXN0X2VtcHR5KCZhbGxfdGFza3MpKSB7DQpAQCAtMTE1OCw3ICsxMTczLDkgQEAg
cnBjaW9kX2tpbGxhbGwodm9pZCkNCiAJd2hpbGUgKCFsaXN0X2VtcHR5KCZhbGxfdGFza3MpKSB7
DQogCQljbGVhcl90aHJlYWRfZmxhZyhUSUZfU0lHUEVORElORyk7DQogCQlycGNfa2lsbGFsbF90
YXNrcyhOVUxMKTsNCisJCXNwaW5fbG9ja19iaCgmcnBjX3F1ZXVlX2xvY2spOw0KIAkJX19ycGNf
c2NoZWR1bGUoKTsNCisJCXNwaW5fdW5sb2NrX2JoKCZycGNfcXVldWVfbG9jayk7DQogCQlpZiAo
IWxpc3RfZW1wdHkoJmFsbF90YXNrcykpIHsNCiAJCQlkcHJpbnRrKCJycGNpb2Rfa2lsbGFsbDog
d2FpdGluZyBmb3IgdGFza3MgdG8gZXhpdFxuIik7DQogCQkJeWllbGQoKTsNCg==

--=-HT9F/x8+F4NM0LHwrnu+--



---

 25-akpm/net/sunrpc/sched.c |   31 ++++++++++++++++++++++++-------
 1 files changed, 24 insertions(+), 7 deletions(-)

diff -puN net/sunrpc/sched.c~nfs-07-rpc_fixes net/sunrpc/sched.c
--- 25/net/sunrpc/sched.c~nfs-07-rpc_fixes	2004-03-14 15:12:40.725539248 -0800
+++ 25-akpm/net/sunrpc/sched.c	2004-03-14 15:12:40.727538944 -0800
@@ -786,21 +786,22 @@ __rpc_schedule(void)
 
 	dprintk("RPC:      rpc_schedule enter\n");
 	while (1) {
-		spin_lock_bh(&rpc_queue_lock);
 
 		task_for_first(task, &schedq.tasks[0]) {
 			__rpc_remove_wait_queue(task);
 			spin_unlock_bh(&rpc_queue_lock);
 
 			__rpc_execute(task);
+			spin_lock_bh(&rpc_queue_lock);
 		} else {
-			spin_unlock_bh(&rpc_queue_lock);
 			break;
 		}
 
 		if (++count >= 200 || need_resched()) {
 			count = 0;
+			spin_unlock_bh(&rpc_queue_lock);
 			schedule();
+			spin_lock_bh(&rpc_queue_lock);
 		}
 	}
 	dprintk("RPC:      rpc_schedule leave\n");
@@ -1114,27 +1115,41 @@ rpciod(void *ptr)
 	allow_signal(SIGKILL);
 
 	dprintk("RPC: rpciod starting (pid %d)\n", rpciod_pid);
+	spin_lock_bh(&rpc_queue_lock);
 	while (rpciod_users) {
+		DEFINE_WAIT(wait);
 		if (signalled()) {
+			spin_unlock_bh(&rpc_queue_lock);
 			rpciod_killall();
 			flush_signals(current);
+			spin_lock_bh(&rpc_queue_lock);
 		}
 		__rpc_schedule();
-		if (current->flags & PF_FREEZE)
+		if (current->flags & PF_FREEZE) {
+			spin_unlock_bh(&rpc_queue_lock);
 			refrigerator(PF_IOTHREAD);
+			spin_lock_bh(&rpc_queue_lock);
+		}
 
 		if (++rounds >= 64) {	/* safeguard */
+			spin_unlock_bh(&rpc_queue_lock);
 			schedule();
 			rounds = 0;
+			spin_lock_bh(&rpc_queue_lock);
 		}
 
-		if (!rpciod_task_pending()) {
-			dprintk("RPC: rpciod back to sleep\n");
-			wait_event_interruptible(rpciod_idle, rpciod_task_pending());
-			dprintk("RPC: switch to rpciod\n");
+		dprintk("RPC: rpciod back to sleep\n");
+		prepare_to_wait(&rpciod_idle, &wait, TASK_INTERRUPTIBLE);
+		if (!rpciod_task_pending() && !signalled()) {
+			spin_unlock_bh(&rpc_queue_lock);
+			schedule();
 			rounds = 0;
+			spin_lock_bh(&rpc_queue_lock);
 		}
+		finish_wait(&rpciod_idle, &wait);
+		dprintk("RPC: switch to rpciod\n");
 	}
+	spin_unlock_bh(&rpc_queue_lock);
 
 	dprintk("RPC: rpciod shutdown commences\n");
 	if (!list_empty(&all_tasks)) {
@@ -1158,7 +1173,9 @@ rpciod_killall(void)
 	while (!list_empty(&all_tasks)) {
 		clear_thread_flag(TIF_SIGPENDING);
 		rpc_killall_tasks(NULL);
+		spin_lock_bh(&rpc_queue_lock);
 		__rpc_schedule();
+		spin_unlock_bh(&rpc_queue_lock);
 		if (!list_empty(&all_tasks)) {
 			dprintk("rpciod_killall: waiting for tasks to exit\n");
 			yield();

_