]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: gro_cells: Reduce lock scope in gro_cell_poll
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Tue, 4 Nov 2025 15:34:35 +0000 (16:34 +0100)
committerJakub Kicinski <kuba@kernel.org>
Thu, 6 Nov 2025 01:41:29 +0000 (17:41 -0800)
One GRO-cell device's NAPI callback can nest into the GRO-cell of
another device if the underlying device is also using GRO-cell.
This is the case for IPsec over vxlan.
These two GRO-cells are separate devices. From lockdep's point of view
it is the same because each device is sharing the same lock class and so
it reports a possible deadlock assuming one device is nesting into
itself.

Hold the bh_lock only while accessing gro_cell::napi_skbs in
gro_cell_poll(). This reduces the locking scope and avoids acquiring the
same lock class multiple times.

Fixes: 25718fdcbdd2 ("net: gro_cells: Use nested-BH locking for gro_cell")
Reported-by: Gal Pressman <gal@nvidia.com>
Closes: https://lore.kernel.org/all/66664116-edb8-48dc-ad72-d5223696dd19@nvidia.com/
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Link: https://patch.msgid.link/20251104153435.ty88xDQt@linutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/core/gro_cells.c

index fd57b845de333ff0e397eeb95aa67926d4e4a730..a725d21159a6f164dd7251af99a81759ee77a38e 100644 (file)
@@ -60,9 +60,10 @@ static int gro_cell_poll(struct napi_struct *napi, int budget)
        struct sk_buff *skb;
        int work_done = 0;
 
-       __local_lock_nested_bh(&cell->bh_lock);
        while (work_done < budget) {
+               __local_lock_nested_bh(&cell->bh_lock);
                skb = __skb_dequeue(&cell->napi_skbs);
+               __local_unlock_nested_bh(&cell->bh_lock);
                if (!skb)
                        break;
                napi_gro_receive(napi, skb);
@@ -71,7 +72,6 @@ static int gro_cell_poll(struct napi_struct *napi, int budget)
 
        if (work_done < budget)
                napi_complete_done(napi, work_done);
-       __local_unlock_nested_bh(&cell->bh_lock);
        return work_done;
 }