From: Trond Myklebust --=-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(); _