diff options
-rw-r--r-- | sys/kern/kern_lock.c | 18 | ||||
-rw-r--r-- | sys/kern/subr_lock.c | 1 | ||||
-rw-r--r-- | sys/sys/_lockmgr.h | 4 | ||||
-rw-r--r-- | sys/sys/param.h | 7 |
4 files changed, 20 insertions, 10 deletions
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index 091abcda2a1e..5cefcf7a597b 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/kdb.h> #include <sys/ktr.h> +#include <sys/limits.h> #include <sys/lock.h> #include <sys/lock_profile.h> #include <sys/lockmgr.h> @@ -61,6 +62,12 @@ __FBSDID("$FreeBSD$"); PMC_SOFT_DECLARE( , , lock, failed); #endif +/* + * Hack. There should be prio_t or similar so that this is not necessary. + */ +_Static_assert((PRILASTFLAG * 2) - 1 <= USHRT_MAX, + "prio flags wont fit in u_short pri in struct lock"); + CTASSERT(LK_UNLOCKED == (LK_UNLOCKED & ~(LK_ALL_WAITERS | LK_EXCLUSIVE_SPINNERS))); @@ -280,8 +287,10 @@ sleeplk(struct lock *lk, u_int flags, struct lock_object *ilk, if (flags & LK_INTERLOCK) class->lc_unlock(ilk); - if (queue == SQ_EXCLUSIVE_QUEUE && (flags & LK_SLEEPFAIL) != 0) - lk->lk_exslpfail++; + if (queue == SQ_EXCLUSIVE_QUEUE && (flags & LK_SLEEPFAIL) != 0) { + if (lk->lk_exslpfail < USHRT_MAX) + lk->lk_exslpfail++; + } GIANT_SAVE(); sleepq_add(&lk->lock_object, NULL, wmesg, SLEEPQ_LK | (catch ? SLEEPQ_INTERRUPTIBLE : 0), queue); @@ -345,7 +354,7 @@ retry_sleepq: realexslp = sleepq_sleepcnt(&lk->lock_object, SQ_EXCLUSIVE_QUEUE); if ((x & LK_EXCLUSIVE_WAITERS) != 0 && realexslp != 0) { - if (lk->lk_exslpfail < realexslp) { + if (lk->lk_exslpfail != USHRT_MAX && lk->lk_exslpfail < realexslp) { lk->lk_exslpfail = 0; queue = SQ_EXCLUSIVE_QUEUE; v |= (x & LK_SHARED_WAITERS); @@ -362,7 +371,6 @@ retry_sleepq: SLEEPQ_LK, 0, SQ_EXCLUSIVE_QUEUE); queue = SQ_SHARED_QUEUE; } - } else { /* * Exclusive waiters sleeping with LK_SLEEPFAIL on @@ -1170,7 +1178,7 @@ lockmgr_xunlock_hard(struct lock *lk, uintptr_t x, u_int flags, struct lock_obje MPASS((x & LK_EXCLUSIVE_SPINNERS) == 0); realexslp = sleepq_sleepcnt(&lk->lock_object, SQ_EXCLUSIVE_QUEUE); if ((x & LK_EXCLUSIVE_WAITERS) != 0 && realexslp != 0) { - if (lk->lk_exslpfail < realexslp) { + if (lk->lk_exslpfail != USHRT_MAX && lk->lk_exslpfail < realexslp) { lk->lk_exslpfail = 0; queue = SQ_EXCLUSIVE_QUEUE; v |= (x & LK_SHARED_WAITERS); diff --git a/sys/kern/subr_lock.c b/sys/kern/subr_lock.c index b69ee349482c..a74f7e62db4a 100644 --- a/sys/kern/subr_lock.c +++ b/sys/kern/subr_lock.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/kernel.h> #include <sys/ktr.h> +#include <sys/limits.h> #include <sys/lock.h> #include <sys/lock_profile.h> #include <sys/malloc.h> diff --git a/sys/sys/_lockmgr.h b/sys/sys/_lockmgr.h index 62e50df1ac4e..b0d164bdb4dc 100644 --- a/sys/sys/_lockmgr.h +++ b/sys/sys/_lockmgr.h @@ -40,9 +40,9 @@ struct lock { struct lock_object lock_object; volatile uintptr_t lk_lock; - u_int lk_exslpfail; + u_short lk_exslpfail; + u_short lk_pri; int lk_timo; - int lk_pri; #ifdef DEBUG_LOCKS struct stack lk_stack; #endif diff --git a/sys/sys/param.h b/sys/sys/param.h index 058aef99e077..fa02b55d1f1b 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -227,9 +227,10 @@ ((off_t)(db) << DEV_BSHIFT) #endif -#define PRIMASK 0x0ff -#define PCATCH 0x100 /* OR'd with pri for tsleep to check signals */ -#define PDROP 0x200 /* OR'd with pri to stop re-entry of interlock mutex */ +#define PRIMASK 0x0ff +#define PCATCH 0x100 /* OR'd with pri for tsleep to check signals */ +#define PDROP 0x200 /* OR'd with pri to stop re-entry of interlock mutex */ +#define PRILASTFLAG 0x200 /* Last flag defined above */ #define NZERO 0 /* default "nice" */ |