Re: [PATCH net v2] ipv6: sr: fix several BUGs when preemption is enabled

2017-01-12 Thread David Lebrun
On 01/12/2017 09:26 PM, David Lebrun wrote:
> From: Vivien Didelot 

No idea where does that come from, resending patch. Sorry about that Vivien.

David



signature.asc
Description: OpenPGP digital signature


[PATCH net v2] ipv6: sr: fix several BUGs when preemption is enabled

2017-01-12 Thread David Lebrun
From: Vivien Didelot 

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 [] 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]  c962fc18 813607b2  
81a7f782
[   20.455528]  c962fc48 813778dc  
001dcf98
[   20.456539]  a003bd08 81af93e0 c962fc58 
81377905
[   20.456539] Call Trace:
[   20.456539]  [] dump_stack+0x63/0x7f
[   20.456539]  [] check_preemption_disabled+0xd1/0xe3
[   20.456539]  [] debug_smp_processor_id+0x17/0x19
[   20.460260]  [] seg6_hmac_init+0xfa/0x192 [ipv6]
[   20.460260]  [] seg6_init+0x39/0x6f [ipv6]
[   20.460260]  [] inet6_init+0x21a/0x321 [ipv6]
[   20.460260]  [] ? 0xa0061000
[   20.460260]  [] do_one_initcall+0x8b/0x115
[   20.460260]  [] do_init_module+0x53/0x1c4
[   20.460260]  [] load_module+0x1153/0x14ec
[   20.460260]  [] SYSC_finit_module+0x8c/0xb9
[   20.460260]  [] ? SYSC_finit_module+0x8c/0xb9
[   20.460260]  [] SyS_finit_module+0x9/0xb
[   20.460260]  [] do_syscall_64+0x62/0x75
[   20.460260]  [] 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 
---
 net/ipv6/seg6_hmac.c | 2 +-
 net/ipv6/seg6_iptunnel.c | 4 
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c
index ef1c8a4..03a0648 100644
--- a/net/ipv6/seg6_hmac.c
+++ b/net/ipv6/seg6_hmac.c
@@ -400,7 +400,7 @@ static int seg6_hmac_init_algo(void)
*p_tfm = tfm;
}
 
-   p_tfm = this_cpu_ptr(algo->tfms);
+   p_tfm = raw_cpu_ptr(algo->tfms);
tfm = *p_tfm;
 
shsize = sizeof(*shash) + crypto_shash_descsize(tfm);
diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c
index bbfca22..1d60cb1 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)
slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate);
 
 #ifdef CONFIG_DST_CACHE
+   preempt_disable();
dst = dst_cache_get(>cache);
+   preempt_enable();
 #endif
 
if (unlikely(!dst)) {
@@ -286,7 +288,9 @@ int seg6_output(struct net *net, struct sock *sk, struct 
sk_buff *skb)
}
 
 #ifdef CONFIG_DST_CACHE
+   preempt_disable();
dst_cache_set_ip6(>cache, dst, );
+   preempt_enable();
 #endif
}
 
-- 
2.7.3