Avoid a possible circular locking dependency by taking the softirq_ctrl.lock before taking raw_v6_hashinfo.lock in raw_seq_start(), keeping locking order consistent. Lockdep splat: [ 254.623863] ====================================================== [ 254.623864] WARNING: possible circular locking dependency detected [ 254.623865] 5.10.65-rt53+ #1 Tainted: G S W I [ 254.623866] ------------------------------------------------------ [ 254.623866] read_all/3963 is trying to acquire lock: [ 254.623867] ffffa05cde218220 ((softirq_ctrl.lock).lock){+.+.}-{2:2}, at: __local_bh_disable_ip+0x116/0x2f0 [ 254.623876] but task is already holding lock: [ 254.623877] ffffffffb68e93e0 (raw_v6_hashinfo.lock){++.+}-{0:0}, at: raw_seq_start+0x25/0x60 [ 254.623883] which lock already depends on the new lock. ... [ 254.623974] Possible unsafe locking scenario: [ 254.623975] CPU0 CPU1 [ 254.623975] ---- ---- [ 254.623975] lock(raw_v6_hashinfo.lock); [ 254.623976] lock((softirq_ctrl.lock).lock); [ 254.623977] lock(raw_v6_hashinfo.lock); [ 254.623978] lock((softirq_ctrl.lock).lock); [ 254.623978] *** DEADLOCK *** [ 254.623979] 3 locks held by read_all/3963: [ 254.623980] #0: ffffa055d0c35990 (&p->lock){+.+.}-{0:0}, at: seq_read_iter+0x56/0x420 [ 254.623983] #1: ffffffffb68e93e0 (raw_v6_hashinfo.lock){++.+}-{0:0}, at: raw_seq_start+0x25/0x60 [ 254.623986] #2: ffffffffb64c8fa0 (rcu_read_lock){....}-{1:2}, at: rt_read_lock+0x7d/0x1e0 Reported-by: Chunyu Hu <chuhu@xxxxxxxxxx> Signed-off-by: Luis Claudio R. Goncalves <lgoncalv@xxxxxxxxxx> --- net/ipv4/raw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index a0188eb2689f..584d08679e3a 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -1051,7 +1051,7 @@ void *raw_seq_start(struct seq_file *seq, loff_t *pos) { struct raw_hashinfo *h = PDE_DATA(file_inode(seq->file)); - read_lock(&h->lock); + read_lock_bh(&h->lock); return *pos ? raw_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; } EXPORT_SYMBOL_GPL(raw_seq_start); @@ -1073,7 +1073,7 @@ void raw_seq_stop(struct seq_file *seq, void *v) { struct raw_hashinfo *h = PDE_DATA(file_inode(seq->file)); - read_unlock(&h->lock); + read_unlock_bh(&h->lock); } EXPORT_SYMBOL_GPL(raw_seq_stop);