/// Find functions that refer to GFP_KERNEL but are called with locks held. //# The proposed change of converting the GFP_KERNEL is not necessarily the //# correct one. It may be desired to unlock the lock, or to not call the //# function under the lock in the first place. /// // Confidence: Moderate // Copyright: (C) 2012 Nicolas Palix. GPLv2. // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. // URL: http://coccinelle.lip6.fr/ // Comments: // Options: --no-includes --include-headers virtual patch virtual context virtual org virtual report @gfp exists@ identifier fn; position p; @@ fn(...) { ... when != read_unlock_irq(...) when != write_unlock_irq(...) when != read_unlock_irqrestore(...) when != write_unlock_irqrestore(...) when != spin_unlock(...) when != spin_unlock_irq(...) when != spin_unlock_irqrestore(...) when != local_irq_enable(...) when any GFP_KERNEL@p ... when any } @locked exists@ identifier gfp.fn; position p1,p2; @@ ( read_lock_irq@p1 | write_lock_irq@p1 | read_lock_irqsave@p1 | write_lock_irqsave@p1 | spin_lock@p1 | spin_trylock@p1 | spin_lock_irq@p1 | spin_lock_irqsave@p1 | local_irq_disable@p1 ) (...) ... when != read_unlock_irq(...) when != write_unlock_irq(...) when != read_unlock_irqrestore(...) when != write_unlock_irqrestore(...) when != spin_unlock(...) when != spin_unlock_irq(...) when != spin_unlock_irqrestore(...) when != local_irq_enable(...) fn@p2(...) @depends on locked && patch@ position gfp.p; @@ - GFP_KERNEL@p + GFP_ATOMIC @depends on locked && !patch@ position gfp.p; @@ * GFP_KERNEL@p @script:python depends on !patch && org@ p << gfp.p; fn << gfp.fn; p1 << locked.p1; p2 << locked.p2; @@ cocci.print_main("lock",p1) cocci.print_secs("call",p2) cocci.print_secs("GFP_KERNEL",p) @script:python depends on !patch && report@ p << gfp.p; fn << gfp.fn; p1 << locked.p1; p2 << locked.p2; @@ msg = "ERROR: function %s called on line %s inside lock on line %s but uses GFP_KERNEL" % (fn,p2[0].line,p1[0].line) coccilib.report.print_report(p[0], msg) 'qt'>
diff options
context:
space:
mode:
authorMahesh Bandewar <maheshb@google.com>2016-12-21 17:30:16 -0800
committerDavid S. Miller <davem@davemloft.net>2016-12-23 17:53:47 -0500
commite252536068efd1578c6e23e7323527c5e6e980bd (patch)
tree9ce475c5704e5fd34e5dac3afdb40b9da07e1b81
parentb1227d019fa98c43381ad8827baf7efbe2923ed1 (diff)
ipvlan: fix multicast processing
In an IPvlan setup when master is set in loopback mode e.g. ethtool -K eth0 set loopback on where eth0 is master device for IPvlan setup. The failure is caused by the faulty logic that determines if the packet is from TX-path vs. RX-path by just looking at the mac- addresses on the packet while processing multicast packets. In the loopback-mode where this crash was happening, the packets that are sent out are reflected by the NIC and are processed on the RX path, but mac-address check tricks into thinking this packet is from TX path and falsely uses dev_forward_skb() to pass packets to the slave (virtual) devices. This patch records the path while queueing packets and eliminates logic of looking at mac-addresses for the same decision. ------------[ cut here ]------------ kernel BUG at include/linux/skbuff.h:1737! Call Trace: [<ffffffff921fbbc2>] dev_forward_skb+0x92/0xd0 [<ffffffffc031ac65>] ipvlan_process_multicast+0x395/0x4c0 [ipvlan] [<ffffffffc031a9a7>] ? ipvlan_process_multicast+0xd7/0x4c0 [ipvlan] [<ffffffff91cdfea7>] ? process_one_work+0x147/0x660 [<ffffffff91cdff09>] process_one_work+0x1a9/0x660 [<ffffffff91cdfea7>] ? process_one_work+0x147/0x660 [<ffffffff91ce086d>] worker_thread+0x11d/0x360 [<ffffffff91ce0750>] ? rescuer_thread+0x350/0x350 [<ffffffff91ce960b>] kthread+0xdb/0xe0 [<ffffffff91c05c70>] ? _raw_spin_unlock_irq+0x30/0x50 [<ffffffff91ce9530>] ? flush_kthread_worker+0xc0/0xc0 [<ffffffff92348b7a>] ret_from_fork+0x9a/0xd0 [<ffffffff91ce9530>] ? flush_kthread_worker+0xc0/0xc0 Fixes: ba35f8588f47 ("ipvlan: Defer multicast / broadcast processing to a work-queue") Signed-off-by: Mahesh Bandewar <maheshb@google.com> CC: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat