diff options
author | David Lebrun <david.lebrun@uclouvain.be> | 2017-01-12 15:30:01 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-01-13 12:29:55 -0500 |
commit | fa79581ea66ca43d56ef065346ac5be767fcb418 (patch) | |
tree | d683a22fc392c9eca7ff842e00c8c36df94b8005 | |
parent | 148d3d021cf9724fcf189ce4e525a094bbf5ce89 (diff) |
ipv6: sr: fix several BUGs when preemption is enabled
When CONFIG_PREEMPT=y, CONFIG_IPV6=m and CONFIG_SEG6_HMAC=y,
seg6_hmac_init() is called during the initialization of the ipv6 module.
This causes a subsequent call to smp_processor_id() with preemption
enabled, resulting in the following trace.
[ 20.451460] BUG: using smp_processor_id() in preemptible [00000000] code: systemd/1
[ 20.452556] caller is debug_smp_processor_id+0x17/0x19
[ 20.453304] CPU: 0 PID: 1 Comm: systemd Not tainted 4.9.0-rc5-00973-g46738b1 #1
[ 20.454406] ffffc9000062fc18 ffffffff813607b2 0000000000000000 ffffffff81a7f782
[ 20.455528] ffffc9000062fc48 ffffffff813778dc 0000000000000000 00000000001dcf98
[ 20.456539] ffffffffa003bd08 ffffffff81af93e0 ffffc9000062fc58 ffffffff81377905
[ 20.456539] Call Trace:
[ 20.456539] [<ffffffff813607b2>] dump_stack+0x63/0x7f
[ 20.456539] [<ffffffff813778dc>] check_preemption_disabled+0xd1/0xe3
[ 20.456539] [<ffffffff81377905>] debug_smp_processor_id+0x17/0x19
[ 20.460260] [<ffffffffa0061f3b>] seg6_hmac_init+0xfa/0x192 [ipv6]
[ 20.460260] [<ffffffffa0061ccc>] seg6_init+0x39/0x6f [ipv6]
[ 20.460260] [<ffffffffa006121a>] inet6_init+0x21a/0x321 [ipv6]
[ 20.460260] [<ffffffffa0061000>] ? 0xffffffffa0061000
[ 20.460260] [<ffffffff81000457>] do_one_initcall+0x8b/0x115
[ 20.460260] [<ffffffff811328a3>] do_init_module+0x53/0x1c4
[ 20.460260] [<ffffffff8110650a>] load_module+0x1153/0x14ec
[ 20.460260] [<ffffffff81106a7b>] SYSC_finit_module+0x8c/0xb9
[ 20.460260] [<ffffffff81106a7b>] ? SYSC_finit_module+0x8c/0xb9
[ 20.460260] [<ffffffff81106abc>] SyS_finit_module+0x9/0xb
[ 20.460260] [<ffffffff810014d1>] do_syscall_64+0x62/0x75
[ 20.460260] [<ffffffff816834f0>] entry_SYSCALL64_slow_path+0x25/0x25
Moreover, dst_cache_* functions also call smp_processor_id(), generating
a similar trace.
This patch uses raw_cpu_ptr() in seg6_hmac_init() rather than this_cpu_ptr()
and disable preemption when using dst_cache_* functions.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv6/seg6_hmac.c | 2 | ||||
-rw-r--r-- | net/ipv6/seg6_iptunnel.c | 4 |
2 files changed, 5 insertions, 1 deletions
diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c index ef1c8a46e7ac..03a064803626 100644 --- a/net/ipv6/seg6_hmac.c +++ b/net/ipv6/seg6_hmac.c | |||
@@ -400,7 +400,7 @@ static int seg6_hmac_init_algo(void) | |||
400 | *p_tfm = tfm; | 400 | *p_tfm = tfm; |
401 | } | 401 | } |
402 | 402 | ||
403 | p_tfm = this_cpu_ptr(algo->tfms); | 403 | p_tfm = raw_cpu_ptr(algo->tfms); |
404 | tfm = *p_tfm; | 404 | tfm = *p_tfm; |
405 | 405 | ||
406 | shsize = sizeof(*shash) + crypto_shash_descsize(tfm); | 406 | shsize = sizeof(*shash) + crypto_shash_descsize(tfm); |
diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c index bbfca22c34ae..1d60cb132835 100644 --- a/net/ipv6/seg6_iptunnel.c +++ b/net/ipv6/seg6_iptunnel.c | |||
@@ -265,7 +265,9 @@ int seg6_output(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
265 | slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate); | 265 | slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate); |
266 | 266 | ||
267 | #ifdef CONFIG_DST_CACHE | 267 | #ifdef CONFIG_DST_CACHE |
268 | preempt_disable(); | ||
268 | dst = dst_cache_get(&slwt->cache); | 269 | dst = dst_cache_get(&slwt->cache); |
270 | preempt_enable(); | ||
269 | #endif | 271 | #endif |
270 | 272 | ||
271 | if (unlikely(!dst)) { | 273 | if (unlikely(!dst)) { |
@@ -286,7 +288,9 @@ int seg6_output(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
286 | } | 288 | } |
287 | 289 | ||
288 | #ifdef CONFIG_DST_CACHE | 290 | #ifdef CONFIG_DST_CACHE |
291 | preempt_disable(); | ||
289 | dst_cache_set_ip6(&slwt->cache, dst, &fl6.saddr); | 292 | dst_cache_set_ip6(&slwt->cache, dst, &fl6.saddr); |
293 | preempt_enable(); | ||
290 | #endif | 294 | #endif |
291 | } | 295 | } |
292 | 296 | ||