* [PATCH] Prevent deadlock in svc_defer
@ 2004-08-04 7:07 Olaf Kirch
0 siblings, 0 replies; only message in thread
From: Olaf Kirch @ 2004-08-04 7:07 UTC (permalink / raw)
To: nfs
[-- Attachment #1: Type: text/plain, Size: 1526 bytes --]
Hi,
The svc_defer stuff introduced into svcsock.c recently is using spin_lock
rather than spin_lock_bh when grabbing sv_lock. This can cause deadlocks
as shown in this abridged stack dump:
0xc00000000fff76d0 0xc00000000020f8a0 .__spin_yield +0x44
0xc00000000fff76d0 0xc00000000020fa2c (lr) ._raw_spin_lock +0x58
0xc00000000fff7750 0xc00000000020fa2c ._raw_spin_lock +0x58
0xc00000000fff77d0 0xc000000000374558 .svc_sock_enqueue +0x80
0xc00000000fff7860 0xc000000000375678 .svc_tcp_data_ready +0x5c
[...]
0xc00000000fff7b20 0xc000000000303c38 .ip_local_deliver +0xf4
[...]
0xc00000000fff7e50 0xc0000000002dba00 .net_rx_action +0x150
0xc00000000fff7f00 0xc000000000064638 .__do_softirq +0xa8
0xc00000000fff7f90 0xc000000000017530 .call_do_softirq +0x14
0xc0000003c0b17520 0xc000000000011f30 .do_softirq +0x90
0xc0000003c0b175b0 0xc000000000012ec8 .do_IRQ +0x10c
0xc0000003c0b17640 0xc00000000000b034 HardwareInterrupt_entry +0x14
--- Exception: 500: (Hardware Interrupt) at ._raw_spin_lock +0x28
0xc0000003c0b17930 0xc00000000020f9fc ._raw_spin_lock +0x28
0xc0000003c0b17930 0xc00000000037591c (lr) .svc_revisit +0x64
0xc0000003c0b179b0 0xc00000000037591c .svc_revisit +0x64
0xc0000003c0b17a60 0xc00000000037cb2c .cache_revisit_request +0x18c
0xc0000003c0b17b00 0xc00000000037ea80 .cache_check +0x2b4
0xc0000003c0b17bc0 0xd0000000008d5ab0 .fh_verify +0x634
The attached patch should fix this problem.
Olaf
--
Olaf Kirch | The Hardware Gods hate me.
okir@suse.de |
---------------+
[-- Attachment #2: nfsd-cache-revisit-deadlock --]
[-- Type: text/plain, Size: 1516 bytes --]
Index: linux-2.6.5/net/sunrpc/svcsock.c
===================================================================
--- linux-2.6.5.orig/net/sunrpc/svcsock.c 2004-08-04 08:58:54.000000000 +0200
+++ linux-2.6.5/net/sunrpc/svcsock.c 2004-08-04 09:04:12.000000000 +0200
@@ -1505,9 +1505,9 @@
dprintk("revisit queued\n");
svsk = dr->svsk;
dr->svsk = NULL;
- spin_lock(&serv->sv_lock);
+ spin_lock_bh(&serv->sv_lock);
list_add(&dr->handle.recent, &svsk->sk_deferred);
- spin_unlock(&serv->sv_lock);
+ spin_unlock_bh(&serv->sv_lock);
set_bit(SK_DEFERRED, &svsk->sk_flags);
svc_sock_enqueue(svsk);
svc_sock_put(svsk);
@@ -1538,10 +1538,10 @@
dr->argslen = rqstp->rq_arg.len >> 2;
memcpy(dr->args, rqstp->rq_arg.head[0].iov_base-skip, dr->argslen<<2);
}
- spin_lock(&rqstp->rq_server->sv_lock);
+ spin_lock_bh(&rqstp->rq_server->sv_lock);
rqstp->rq_sock->sk_inuse++;
dr->svsk = rqstp->rq_sock;
- spin_unlock(&rqstp->rq_server->sv_lock);
+ spin_unlock_bh(&rqstp->rq_server->sv_lock);
dr->handle.revisit = svc_revisit;
return &dr->handle;
@@ -1571,7 +1571,7 @@
if (!test_bit(SK_DEFERRED, &svsk->sk_flags))
return NULL;
- spin_lock(&serv->sv_lock);
+ spin_lock_bh(&serv->sv_lock);
clear_bit(SK_DEFERRED, &svsk->sk_flags);
if (!list_empty(&svsk->sk_deferred)) {
dr = list_entry(svsk->sk_deferred.next,
@@ -1580,6 +1580,6 @@
list_del_init(&dr->handle.recent);
set_bit(SK_DEFERRED, &svsk->sk_flags);
}
- spin_unlock(&serv->sv_lock);
+ spin_unlock_bh(&serv->sv_lock);
return dr;
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2004-08-04 7:07 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-08-04 7:07 [PATCH] Prevent deadlock in svc_defer Olaf Kirch
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.