summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_lock.c
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2010-01-07 00:47:50 +0000
committerattilio <attilio@FreeBSD.org>2010-01-07 00:47:50 +0000
commit2e14be290b5b8c1dd99a985297642637367d2604 (patch)
tree15f9f7f63468c6f258e3e3f4d51a51c0dac511a9 /sys/kern/kern_lock.c
parent9b6b3618fec2df610c856eeeb69b75306239e21a (diff)
downloadFreeBSD-src-2e14be290b5b8c1dd99a985297642637367d2604.zip
FreeBSD-src-2e14be290b5b8c1dd99a985297642637367d2604.tar.gz
Exclusive waiters sleeping with LK_SLEEPFAIL on and using interruptible
sleeps/timeout may have left spourious lk_exslpfail counts on, so clean it up even when accessing a shared queue acquisition, giving to lk_exslpfail the value of 'upper limit'. In the worst case scenario, infact (mixed interruptible sleep / LK_SLEEPFAIL waiters) what may happen is that both queues are awaken even if that's not necessary, but still no harm. Reported by: Lucius Windschuh <lwindschuh at googlemail dot com> Reviewed by: kib Tested by: pho, Lucius Windschuh <lwindschuh at googlemail dot com>
Diffstat (limited to 'sys/kern/kern_lock.c')
-rw-r--r--sys/kern/kern_lock.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c
index 531c851..6783a43 100644
--- a/sys/kern/kern_lock.c
+++ b/sys/kern/kern_lock.c
@@ -300,7 +300,14 @@ wakeupshlk(struct lock *lk, const char *file, int line)
}
} else {
- MPASS(lk->lk_exslpfail == 0);
+
+ /*
+ * Exclusive waiters sleeping with LK_SLEEPFAIL on
+ * and using interruptible sleeps/timeout may have
+ * left spourious lk_exslpfail counts on, so clean
+ * it up anyway.
+ */
+ lk->lk_exslpfail = 0;
queue = SQ_SHARED_QUEUE;
}
@@ -959,7 +966,14 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
queue = SQ_SHARED_QUEUE;
}
} else {
- MPASS(lk->lk_exslpfail == 0);
+
+ /*
+ * Exclusive waiters sleeping with LK_SLEEPFAIL
+ * on and using interruptible sleeps/timeout
+ * may have left spourious lk_exslpfail counts
+ * on, so clean it up anyway.
+ */
+ lk->lk_exslpfail = 0;
queue = SQ_SHARED_QUEUE;
}
@@ -1037,8 +1051,16 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
queue = SQ_EXCLUSIVE_QUEUE;
v &= ~LK_EXCLUSIVE_WAITERS;
} else {
+
+ /*
+ * Exclusive waiters sleeping with
+ * LK_SLEEPFAIL on and using
+ * interruptible sleeps/timeout may
+ * have left spourious lk_exslpfail
+ * counts on, so clean it up anyway.
+ */
MPASS(v & LK_SHARED_WAITERS);
- MPASS(lk->lk_exslpfail == 0);
+ lk->lk_exslpfail = 0;
queue = SQ_SHARED_QUEUE;
v &= ~LK_SHARED_WAITERS;
}
OpenPOWER on IntegriCloud