diff options
author | jkim <jkim@FreeBSD.org> | 2006-11-17 20:43:01 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2006-11-17 20:43:01 +0000 |
commit | edc10a6695602b387851a4829c5b186ed1053cd2 (patch) | |
tree | 5763ff35e9b8735dced7729276fc5925779446b3 /sys/kern/sysv_msg.c | |
parent | 500c68689fe5387192dc5847af52413cf40bc4e3 (diff) | |
download | FreeBSD-src-edc10a6695602b387851a4829c5b186ed1053cd2.zip FreeBSD-src-edc10a6695602b387851a4829c5b186ed1053cd2.tar.gz |
Fix msgsnd(3)/msgrcv(3) deadlock under heavy resource pressure by timing out
msgsnd and rechecking resources. This problem was found while I was running
Linux Test Project test suite (test cases: msgctl08, msgctl09).
Change `msgwait' to `msgsnd' and `msgrcv' to distinguish its sleeping
conditions. Few cosmetic changes to debugging messages.
Diffstat (limited to 'sys/kern/sysv_msg.c')
-rw-r--r-- | sys/kern/sysv_msg.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c index a3db14c..b116c21 100644 --- a/sys/kern/sysv_msg.c +++ b/sys/kern/sysv_msg.c @@ -780,12 +780,16 @@ msgsnd(td, uap) msqkptr->u.msg_perm.mode |= MSG_LOCKED; we_own_it = 1; } - DPRINTF(("goodnight\n")); + DPRINTF(("msgsnd: goodnight\n")); error = msleep(msqkptr, &msq_mtx, (PZERO - 4) | PCATCH, - "msgwait", 0); - DPRINTF(("good morning, error=%d\n", error)); + "msgsnd", hz); + DPRINTF(("msgsnd: good morning, error=%d\n", error)); if (we_own_it) msqkptr->u.msg_perm.mode &= ~MSG_LOCKED; + if (error == EWOULDBLOCK) { + DPRINTF(("msgsnd: timed out\n")); + continue; + } if (error != 0) { DPRINTF(("msgsnd: interrupted system call\n")); error = EINTR; @@ -1178,11 +1182,11 @@ msgrcv(td, uap) DPRINTF(("msgrcv: goodnight\n")); error = msleep(msqkptr, &msq_mtx, (PZERO - 4) | PCATCH, - "msgwait", 0); + "msgrcv", 0); DPRINTF(("msgrcv: good morning (error=%d)\n", error)); if (error != 0) { - DPRINTF(("msgsnd: interrupted system call\n")); + DPRINTF(("msgrcv: interrupted system call\n")); error = EINTR; goto done2; } |