Skip to content

Commit 585aa62

Browse files
Sebastian Andrzej Siewiorkuba-moo
authored andcommitted
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 <[email protected]> Signed-off-by: Sebastian Andrzej Siewior <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent bdacf3e commit 585aa62

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

net/ipv4/tcp_sigpool.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@
1010
#include <net/tcp.h>
1111

1212
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+
};
1421

1522
struct sigpool_entry {
1623
struct crypto_ahash *hash;
@@ -72,7 +79,7 @@ static int sigpool_reserve_scratch(size_t size)
7279
break;
7380
}
7481

75-
old_scratch = rcu_replace_pointer(per_cpu(sigpool_scratch, cpu),
82+
old_scratch = rcu_replace_pointer(per_cpu(sigpool_scratch.pad, cpu),
7683
scratch, lockdep_is_held(&cpool_mutex));
7784
if (!cpu_online(cpu) || !old_scratch) {
7885
kfree(old_scratch);
@@ -93,7 +100,7 @@ static void sigpool_scratch_free(void)
93100
int cpu;
94101

95102
for_each_possible_cpu(cpu)
96-
kfree(rcu_replace_pointer(per_cpu(sigpool_scratch, cpu),
103+
kfree(rcu_replace_pointer(per_cpu(sigpool_scratch.pad, cpu),
97104
NULL, lockdep_is_held(&cpool_mutex)));
98105
__scratch_size = 0;
99106
}
@@ -277,7 +284,8 @@ int tcp_sigpool_start(unsigned int id, struct tcp_sigpool *c) __cond_acquires(RC
277284
/* Pairs with tcp_sigpool_reserve_scratch(), scratch area is
278285
* valid (allocated) until tcp_sigpool_end().
279286
*/
280-
c->scratch = rcu_dereference_bh(*this_cpu_ptr(&sigpool_scratch));
287+
local_lock_nested_bh(&sigpool_scratch.bh_lock);
288+
c->scratch = rcu_dereference_bh(*this_cpu_ptr(&sigpool_scratch.pad));
281289
return 0;
282290
}
283291
EXPORT_SYMBOL_GPL(tcp_sigpool_start);
@@ -286,6 +294,7 @@ void tcp_sigpool_end(struct tcp_sigpool *c) __releases(RCU_BH)
286294
{
287295
struct crypto_ahash *hash = crypto_ahash_reqtfm(c->req);
288296

297+
local_unlock_nested_bh(&sigpool_scratch.bh_lock);
289298
rcu_read_unlock_bh();
290299
ahash_request_free(c->req);
291300
crypto_free_ahash(hash);

0 commit comments

Comments
 (0)