From: Sebastian Andrzej Siewior Date: Wed, 31 Aug 2016 17:54:09 +0200 Subject: [PATCH 203/353] net: add a lock around icmp_sk() Origin: https://git.kernel.org/cgit/linux/kernel/git/rt/linux-stable-rt.git/commit?id=ed4da37a0640885893991fdf679ea57a89643875 It looks like the this_cpu_ptr() access in icmp_sk() is protected with local_bh_disable(). To avoid missing serialization in -RT I am adding here a local lock. No crash has been observed, this is just precaution. Cc: stable-rt@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior --- net/ipv4/icmp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index aa179e6461e1..47ebb0e0445c 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -77,6 +77,7 @@ #include #include #include +#include #include #include #include @@ -204,6 +205,8 @@ static const struct icmp_control icmp_pointers[NR_ICMP_TYPES+1]; * * On SMP we have one ICMP socket per-cpu. */ +static DEFINE_LOCAL_IRQ_LOCK(icmp_sk_lock); + static struct sock *icmp_sk(struct net *net) { return *this_cpu_ptr(net->ipv4.icmp_sk); @@ -214,12 +217,16 @@ static inline struct sock *icmp_xmit_lock(struct net *net) { struct sock *sk; + if (!local_trylock(icmp_sk_lock)) + return NULL; + sk = icmp_sk(net); if (unlikely(!spin_trylock(&sk->sk_lock.slock))) { /* This can happen if the output path signals a * dst_link_failure() for an outgoing ICMP packet. */ + local_unlock(icmp_sk_lock); return NULL; } return sk; @@ -228,6 +235,7 @@ static inline struct sock *icmp_xmit_lock(struct net *net) static inline void icmp_xmit_unlock(struct sock *sk) { spin_unlock(&sk->sk_lock.slock); + local_unlock(icmp_sk_lock); } int sysctl_icmp_msgs_per_sec __read_mostly = 1000;