ipv6: sr: Use nested-BH locking for hmac_storage
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Mon, 12 May 2025 09:27:25 +0000 (11:27 +0200)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 15 May 2025 13:23:31 +0000 (15:23 +0200)
hmac_storage 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.

Add a local_lock_t to the data structure 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/20250512092736.229935-5-bigeasy@linutronix.de
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/ipv6/seg6_hmac.c

index bbf5b84a70fcabe0d380814aa4d99b95006925b8..f78ecb6ad83834bf6614ecb0b4e894af6a18acfb 100644 (file)
 #include <net/seg6_hmac.h>
 #include <linux/random.h>
 
-static DEFINE_PER_CPU(char [SEG6_HMAC_RING_SIZE], hmac_ring);
+struct hmac_storage {
+       local_lock_t bh_lock;
+       char hmac_ring[SEG6_HMAC_RING_SIZE];
+};
+
+static DEFINE_PER_CPU(struct hmac_storage, hmac_storage) = {
+       .bh_lock = INIT_LOCAL_LOCK(bh_lock),
+};
 
 static int seg6_hmac_cmpfn(struct rhashtable_compare_arg *arg, const void *obj)
 {
@@ -187,7 +194,8 @@ int seg6_hmac_compute(struct seg6_hmac_info *hinfo, struct ipv6_sr_hdr *hdr,
         */
 
        local_bh_disable();
-       ring = this_cpu_ptr(hmac_ring);
+       local_lock_nested_bh(&hmac_storage.bh_lock);
+       ring = this_cpu_ptr(hmac_storage.hmac_ring);
        off = ring;
 
        /* source address */
@@ -212,6 +220,7 @@ int seg6_hmac_compute(struct seg6_hmac_info *hinfo, struct ipv6_sr_hdr *hdr,
 
        dgsize = __do_hmac(hinfo, ring, plen, tmp_out,
                           SEG6_HMAC_MAX_DIGESTSIZE);
+       local_unlock_nested_bh(&hmac_storage.bh_lock);
        local_bh_enable();
 
        if (dgsize < 0)