]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commit
tcp: Don't acquire inet_listen_hashbucket::lock with disabled BH.
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Wed, 9 Feb 2022 18:56:57 +0000 (19:56 +0100)
committerStefan Bader <stefan.bader@canonical.com>
Wed, 27 Apr 2022 09:59:11 +0000 (11:59 +0200)
commit1c153564774087ee1d88a077e88946cc33703d5d
treee611e9c0a053fe310697819d9f95f6cd28217c8c
parent6ceb4560d576903cc2288f83f2646e061eb6dd43
tcp: Don't acquire inet_listen_hashbucket::lock with disabled BH.

BugLink: https://bugs.launchpad.net/bugs/1969107
[ Upstream commit 4f9bf2a2f5aacf988e6d5e56b961ba45c5a25248 ]

Commit
   9652dc2eb9e40 ("tcp: relax listening_hash operations")

removed the need to disable bottom half while acquiring
listening_hash.lock. There are still two callers left which disable
bottom half before the lock is acquired.

On PREEMPT_RT the softirqs are preemptible and local_bh_disable() acts
as a lock to ensure that resources, that are protected by disabling
bottom halves, remain protected.
This leads to a circular locking dependency if the lock acquired with
disabled bottom halves is also acquired with enabled bottom halves
followed by disabling bottom halves. This is the reverse locking order.
It has been observed with inet_listen_hashbucket::lock:

local_bh_disable() + spin_lock(&ilb->lock):
  inet_listen()
    inet_csk_listen_start()
      sk->sk_prot->hash() := inet_hash()
local_bh_disable()
__inet_hash()
  spin_lock(&ilb->lock);
    acquire(&ilb->lock);

Reverse order: spin_lock(&ilb2->lock) + local_bh_disable():
  tcp_seq_next()
    listening_get_next()
      spin_lock(&ilb2->lock);
acquire(&ilb2->lock);

  tcp4_seq_show()
    get_tcp4_sock()
      sock_i_ino()
read_lock_bh(&sk->sk_callback_lock);
  acquire(softirq_ctrl) // <---- whoops
  acquire(&sk->sk_callback_lock)

Drop local_bh_disable() around __inet_hash() which acquires
listening_hash->lock. Split inet_unhash() and acquire the
listen_hashbucket lock without disabling bottom halves; the inet_ehash
lock with disabled bottom halves.

Reported-by: Mike Galbraith <efault@gmx.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Link: https://lkml.kernel.org/r/12d6f9879a97cd56c09fb53dee343cbb14f7f1f7.camel@gmx.de
Link: https://lkml.kernel.org/r/X9CheYjuXWc75Spa@hirez.programming.kicks-ass.net
Link: https://lore.kernel.org/r/YgQOebeZ10eNx1W6@linutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
(cherry picked from commit aa9c9fd0ef9d83bdca5203fa72ebeadedd2a8400)
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
net/ipv4/inet_hashtables.c
net/ipv6/inet6_hashtables.c