git: eac22dd48079 - main - lockmgr: shrink struct lock by 8 bytes on LP64

Mateusz Guzik mjg at FreeBSD.org
Mon Feb 15 13:58:52 UTC 2021


The branch main has been updated by mjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=eac22dd48079d5cccecb07f4e60b44bb692167f8

commit eac22dd48079d5cccecb07f4e60b44bb692167f8
Author:     Mateusz Guzik <mjg at FreeBSD.org>
AuthorDate: 2021-02-15 04:24:17 +0000
Commit:     Mateusz Guzik <mjg at FreeBSD.org>
CommitDate: 2021-02-15 13:57:25 +0000

    lockmgr: shrink struct lock by 8 bytes on LP64
    
    Currently the struct has a 4 byte padding stemming from 3 ints.
    
    1. prio comfortably fits in short, unfortunately there is no dedicated
       type for it and plumbing it throughout the codebase is not worth it
       right now, instead an assert is added which covers also flags for
       safety
    2. lk_exslpfail can in principle exceed u_short, but the count is
       already not considered reliable and it only ever gets modified
       straight to 0. In other words it can be incrementing with an upper
       bound of USHRT_MAX
    
    With these in place struct lock shrinks from 48 to 40 bytes.
    
    Reviewed by:    kib (previous version)
    Differential Revision:  https://reviews.freebsd.org/D28680
---
 sys/kern/kern_lock.c | 18 +++++++++++++-----
 sys/kern/subr_lock.c |  1 +
 sys/sys/_lockmgr.h   |  4 ++--
 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" */
 


More information about the dev-commits-src-main mailing list