From nobody Tue Dec 2 00:46:05 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 31A5917E4 for ; Sun, 23 Nov 2025 01:02:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763859753; cv=none; b=s62ZT97eGq7xojl5ZHEKOulsSMgPtNf/fnTNVKA/Dpyo/+3/G9CxmcatSwBUReXvXB+aBQpIQu4jeAjUM9AUL0PibXAkRyTXaJabuncTGImphjlmMtfn2Ub/zplRowWjF+Em1XaFp3qIuPJKTvwy6wHE2squFo2b9wanEGLNE0s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763859753; c=relaxed/simple; bh=4qgIq4sGlR8FC3YkkhBkNuBtNinv+J/BDtV3MqvEb6Y=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=rt5SvCfxdOHnWGQ9q2FW5lu3qWAcK24N/a4kJ5HRghSxFuwGsCAmOAWD59mn+uQkA96kDbNWYb1QcA+T+jmMXGQc/zoeyjTI5OWLj49T0C+PhJ4gkFmo9Z4+/c6zBd3a8++JgE0a1SAUXanhoSXqDFIGgVqb1Oo9qmxJ7mJKSuI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=aVGJSjwu; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="aVGJSjwu" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1763859750; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=06YhTBmGv1MwSLgaZGQbKQ0vwhhFybE53YypujCshr8=; b=aVGJSjwuj5U/BdoNxTPOyJchykfZHsKHgu4zb0ICmgMMlrFwepafDJ+lHwCxo8Md3Hb7iF Sn3NIC7JSeMavScKL55BSOSuNunfrDUys+P1UpfbxL6Ot2xG3xJPllWXlpGWo43wITFhvu jzmvCJ6BT5XNXAM17R6Oipfq5shRKws= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-186-WZbPWuTKNBefqxHJR8NnDA-1; Sat, 22 Nov 2025 20:02:26 -0500 X-MC-Unique: WZbPWuTKNBefqxHJR8NnDA-1 X-Mimecast-MFC-AGG-ID: WZbPWuTKNBefqxHJR8NnDA_1763859745 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D1A441956089; Sun, 23 Nov 2025 01:02:24 +0000 (UTC) Received: from llong-thinkpadp16vgen1.westford.csb (unknown [10.22.64.37]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 710501956056; Sun, 23 Nov 2025 01:02:22 +0000 (UTC) From: Waiman Long To: Peter Zijlstra , Ingo Molnar , Will Deacon , Boqun Feng Cc: linux-kernel@vger.kernel.org, Sebastian Andrzej Siewior , Waiman Long Subject: [PATCH] locking/rwsem: Redo __rwsem_init() Date: Sat, 22 Nov 2025 20:01:57 -0500 Message-ID: <20251123010157.2076095-1-longman@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 Content-Type: text/plain; charset="utf-8" This is a rwsem version of the Sebastian's commit 3572e2edc7b6 ("locking/mutex: Redo __mutex_init()"). The aim is to avoid storing the lock name strings which consume memory that are never used. The __rwsem_init() will be split into a _generic version with lockdep (CONFIG_DEBUG_LOCK_ALLOC) disabled and a _lockdep version when it is enabled. This will make the rwsem code behavior similar to the mutex code. This results in the following kernel size reduction with defconfig based config files: text data bss dec filename 30200741 8165526 1188464 39554731 vmlinux 30200725 8161430 1188464 39550619 vmlinux (patched) 32417939 8475218 12946524 53839681 vmlinux.lockdep 32417945 8475218 12946524 53839687 vmlinux.lockdep (patched) 27119989 7195918 2075852 36391759 vmlinux.preempt_rt 27119996 7195918 2075852 36391766 vmlinux.preempt_rt (patched) 29349572 7509862 13792416 50651850 vmlinux.preempt_rt.lockdep The kernel size reduction for the lockdep disabled cases isn't that noticeable when compared with the mutex case as there is an order of magnitude more mutex_init() calls than the init_rwsem() calls in the kernel. Signed-off-by: Waiman Long Reviewed-by: Sebastian Andrzej Siewior --- include/linux/rwsem.h | 45 +++++++++++++++++++++++++++++++++------ kernel/locking/rwsem.c | 48 ++++++++++++++++++++++++++++-------------- 2 files changed, 71 insertions(+), 22 deletions(-) diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h index f1aaf676a874..4045ddf2b698 100644 --- a/include/linux/rwsem.h +++ b/include/linux/rwsem.h @@ -111,15 +111,32 @@ static inline void rwsem_assert_held_write_nolockdep(= const struct rw_semaphore * #define DECLARE_RWSEM(name) \ struct rw_semaphore name =3D __RWSEM_INITIALIZER(name) =20 -extern void __init_rwsem(struct rw_semaphore *sem, const char *name, - struct lock_class_key *key); +#ifndef CONFIG_DEBUG_LOCK_ALLOC +extern void rwsem_init_generic(struct rw_semaphore *sem); + +static inline void __init_rwsem(struct rw_semaphore *sem, const char *name, + struct lock_class_key *key) +{ + rwsem_init_generic(sem); +} + +#define init_rwsem(sem) rwsem_init_generic(sem) +#else +extern void rwsem_init_lockdep(struct rw_semaphore *sem, const char *name, + struct lock_class_key *key); +static inline void __init_rwsem(struct rw_semaphore *sem, const char *name, + struct lock_class_key *key) +{ + rwsem_init_lockdep(sem, name, key); +} =20 #define init_rwsem(sem) \ do { \ static struct lock_class_key __key; \ \ - __init_rwsem((sem), #sem, &__key); \ + rwsem_init_lockdep((sem), #sem, &__key); \ } while (0) +#endif /* CONFIG_DEBUG_LOCK_ALLOC */ =20 /* * This is the same regardless of which rwsem implementation that is being= used. @@ -164,15 +181,31 @@ struct rw_semaphore { #define DECLARE_RWSEM(lockname) \ struct rw_semaphore lockname =3D __RWSEM_INITIALIZER(lockname) =20 -extern void __init_rwsem(struct rw_semaphore *rwsem, const char *name, - struct lock_class_key *key); +#ifndef CONFIG_DEBUG_LOCK_ALLOC +extern void rwsem_rt_init_generic(struct rw_semaphore *rwsem); +static inline void __init_rwsem(struct rw_semaphore *rwsem, const char *n= ame, + struct lock_class_key *key) +{ + rwsem_rt_init_generic(rwsem); +} + +#define init_rwsem(sem) rwsem_rt_init_generic(sem) +#else +extern void rwsem_rt_init_lockdep(struct rw_semaphore *rwsem, const char *= name, + struct lock_class_key *key); +static inline void __init_rwsem(struct rw_semaphore *rwsem, const char *n= ame, + struct lock_class_key *key) +{ + rwsem_rt_init_lockdep(rwsem, name, key); +} =20 #define init_rwsem(sem) \ do { \ static struct lock_class_key __key; \ \ - __init_rwsem((sem), #sem, &__key); \ + rwsem_rt_init_lockdep((sem), #sem, &__key); \ } while (0) +#endif /* CONFIG_DEBUG_LOCK_ALLOC */ =20 static __always_inline int rwsem_is_locked(const struct rw_semaphore *sem) { diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index 24df4d98f7d2..ffb09e0520c9 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -306,16 +306,8 @@ rwsem_owner_flags(struct rw_semaphore *sem, unsigned l= ong *pflags) /* * Initialize an rwsem: */ -void __init_rwsem(struct rw_semaphore *sem, const char *name, - struct lock_class_key *key) +static inline void __rwsem_init_generic(struct rw_semaphore *sem) { -#ifdef CONFIG_DEBUG_LOCK_ALLOC - /* - * Make sure we are not reinitializing a held semaphore: - */ - debug_check_no_locks_freed((void *)sem, sizeof(*sem)); - lockdep_init_map_wait(&sem->dep_map, name, key, 0, LD_WAIT_SLEEP); -#endif #ifdef CONFIG_DEBUG_RWSEMS sem->magic =3D sem; #endif @@ -327,7 +319,26 @@ void __init_rwsem(struct rw_semaphore *sem, const char= *name, osq_lock_init(&sem->osq); #endif } -EXPORT_SYMBOL(__init_rwsem); + +#ifndef CONFIG_DEBUG_LOCK_ALLOC +void rwsem_init_generic(struct rw_semaphore *sem) +{ + __rwsem_init_generic(sem); +} +EXPORT_SYMBOL(rwsem_init_generic); +#else +void rwsem_init_lockdep(struct rw_semaphore *sem, const char *name, + struct lock_class_key *key) +{ + /* + * Make sure we are not reinitializing a held semaphore: + */ + debug_check_no_locks_freed((void *)sem, sizeof(*sem)); + lockdep_init_map_wait(&sem->dep_map, name, key, 0, LD_WAIT_SLEEP); + __rwsem_init_generic(sem); +} +EXPORT_SYMBOL(rwsem_init_lockdep); +#endif /* CONFIG_DEBUG_LOCK_ALLOC */ =20 enum rwsem_waiter_type { RWSEM_WAITING_FOR_WRITE, @@ -1449,17 +1460,22 @@ static inline void __downgrade_write(struct rw_sema= phore *sem) =20 #include "rwbase_rt.c" =20 -void __init_rwsem(struct rw_semaphore *sem, const char *name, - struct lock_class_key *key) +#ifndef CONFIG_DEBUG_LOCK_ALLOC +void rwsem_rt_init_generic(struct rw_semaphore *sem) +{ + init_rwbase_rt(&(sem)->rwbase); +} +EXPORT_SYMBOL(rwsem_rt_init_generic); +#else +void rwsem_rt_init_lockdep(struct rw_semaphore *sem, const char *name, + struct lock_class_key *key) { init_rwbase_rt(&(sem)->rwbase); - -#ifdef CONFIG_DEBUG_LOCK_ALLOC debug_check_no_locks_freed((void *)sem, sizeof(*sem)); lockdep_init_map_wait(&sem->dep_map, name, key, 0, LD_WAIT_SLEEP); -#endif } -EXPORT_SYMBOL(__init_rwsem); +EXPORT_SYMBOL(rwsem_rt_init_lockdep); +#endif /* CONFIG_DEBUG_LOCK_ALLOC */ =20 static inline void __down_read(struct rw_semaphore *sem) { --=20 2.51.1