Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net/tcp_sigpool: Use nested-BH locking for sigpool_scratch.

sigpool_scratch is a per-CPU variable and relies on disabled BH for its
locking. Without per-CPU locking in local_bh_disable() on PREEMPT_RT
this data structure requires explicit locking.

Make a struct with a pad member (original sigpool_scratch) and a
local_lock_t and use local_lock_nested_bh() for locking. This change
adds only lockdep coverage and does not alter the functional behaviour
for !PREEMPT_RT.

Cc: David Ahern <dsahern@kernel.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Link: https://patch.msgid.link/20240620132727.660738-6-bigeasy@linutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Sebastian Andrzej Siewior and committed by
Jakub Kicinski
585aa621 bdacf3e3

+13 -4
+13 -4
net/ipv4/tcp_sigpool.c
··· 10 10 #include <net/tcp.h> 11 11 12 12 static size_t __scratch_size; 13 - static DEFINE_PER_CPU(void __rcu *, sigpool_scratch); 13 + struct sigpool_scratch { 14 + local_lock_t bh_lock; 15 + void __rcu *pad; 16 + }; 17 + 18 + static DEFINE_PER_CPU(struct sigpool_scratch, sigpool_scratch) = { 19 + .bh_lock = INIT_LOCAL_LOCK(bh_lock), 20 + }; 14 21 15 22 struct sigpool_entry { 16 23 struct crypto_ahash *hash; ··· 79 72 break; 80 73 } 81 74 82 - old_scratch = rcu_replace_pointer(per_cpu(sigpool_scratch, cpu), 75 + old_scratch = rcu_replace_pointer(per_cpu(sigpool_scratch.pad, cpu), 83 76 scratch, lockdep_is_held(&cpool_mutex)); 84 77 if (!cpu_online(cpu) || !old_scratch) { 85 78 kfree(old_scratch); ··· 100 93 int cpu; 101 94 102 95 for_each_possible_cpu(cpu) 103 - kfree(rcu_replace_pointer(per_cpu(sigpool_scratch, cpu), 96 + kfree(rcu_replace_pointer(per_cpu(sigpool_scratch.pad, cpu), 104 97 NULL, lockdep_is_held(&cpool_mutex))); 105 98 __scratch_size = 0; 106 99 } ··· 284 277 /* Pairs with tcp_sigpool_reserve_scratch(), scratch area is 285 278 * valid (allocated) until tcp_sigpool_end(). 286 279 */ 287 - c->scratch = rcu_dereference_bh(*this_cpu_ptr(&sigpool_scratch)); 280 + local_lock_nested_bh(&sigpool_scratch.bh_lock); 281 + c->scratch = rcu_dereference_bh(*this_cpu_ptr(&sigpool_scratch.pad)); 288 282 return 0; 289 283 } 290 284 EXPORT_SYMBOL_GPL(tcp_sigpool_start); ··· 294 286 { 295 287 struct crypto_ahash *hash = crypto_ahash_reqtfm(c->req); 296 288 289 + local_unlock_nested_bh(&sigpool_scratch.bh_lock); 297 290 rcu_read_unlock_bh(); 298 291 ahash_request_free(c->req); 299 292 crypto_free_ahash(hash);