Message ID | 1510708550.2043.5.camel@edumazet-glaptop3.roam.corp.google.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
Series | [net] bpf: fix lockdep splat | expand |
From: Eric Dumazet <eric.dumazet@gmail.com> Date: Tue, 14 Nov 2017 17:15:50 -0800 > From: Eric Dumazet <edumazet@google.com> > > pcpu_freelist_pop() needs the same lockdep awareness than > pcpu_freelist_populate() to avoid a false positive. ... > Fixes: e19494edab82 ("bpf: introduce percpu_freelist") > Signed-off-by: Eric Dumazet <edumazet@google.com> Applied and queued up for -stable, thanks Eric.
On 11/15/2017 02:15 AM, Eric Dumazet wrote: > From: Eric Dumazet <edumazet@google.com> > > pcpu_freelist_pop() needs the same lockdep awareness than > pcpu_freelist_populate() to avoid a false positive. > > [ INFO: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected ] > [...] > Fixes: e19494edab82 ("bpf: introduce percpu_freelist") > Signed-off-by: Eric Dumazet <edumazet@google.com> Already got applied, but fwiw: Acked-by: Daniel Borkmann <daniel@iogearbox.net> Thanks, Eric!
diff --git a/kernel/bpf/percpu_freelist.c b/kernel/bpf/percpu_freelist.c index 5c51d1985b5102fbba64929b5626d41fb4b88b66..673fa6fe2d73cf815daf8a0c2eb0ce6eab15b41e 100644 --- a/kernel/bpf/percpu_freelist.c +++ b/kernel/bpf/percpu_freelist.c @@ -78,8 +78,10 @@ struct pcpu_freelist_node *pcpu_freelist_pop(struct pcpu_freelist *s) { struct pcpu_freelist_head *head; struct pcpu_freelist_node *node; + unsigned long flags; int orig_cpu, cpu; + local_irq_save(flags); orig_cpu = cpu = raw_smp_processor_id(); while (1) { head = per_cpu_ptr(s->freelist, cpu); @@ -87,14 +89,16 @@ struct pcpu_freelist_node *pcpu_freelist_pop(struct pcpu_freelist *s) node = head->first; if (node) { head->first = node->next; - raw_spin_unlock(&head->lock); + raw_spin_unlock_irqrestore(&head->lock, flags); return node; } raw_spin_unlock(&head->lock); cpu = cpumask_next(cpu, cpu_possible_mask); if (cpu >= nr_cpu_ids) cpu = 0; - if (cpu == orig_cpu) + if (cpu == orig_cpu) { + local_irq_restore(flags); return NULL; + } } }