1/// Find functions that refer to GFP_KERNEL but are called with locks held. 2//# The proposed change of converting the GFP_KERNEL is not necessarily the 3//# correct one. It may be desired to unlock the lock, or to not call the 4//# function under the lock in the first place. 5/// 6// Confidence: Moderate 7// Copyright: (C) 2012 Nicolas Palix. GPLv2. 8// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. 9// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. 10// URL: http://coccinelle.lip6.fr/ 11// Comments: 12// Options: --no-includes --include-headers 13 14virtual patch 15virtual context 16virtual org 17virtual report 18 19@gfp exists@ 20identifier fn; 21position p; 22@@ 23 24fn(...) { 25 ... when != read_unlock_irq(...) 26 when != write_unlock_irq(...) 27 when != read_unlock_irqrestore(...) 28 when != write_unlock_irqrestore(...) 29 when != spin_unlock(...) 30 when != spin_unlock_irq(...) 31 when != spin_unlock_irqrestore(...) 32 when != local_irq_enable(...) 33 when any 34 GFP_KERNEL@p 35 ... when any 36} 37 38@locked exists@ 39identifier gfp.fn; 40position p1,p2; 41@@ 42 43( 44read_lock_irq@p1 45| 46write_lock_irq@p1 47| 48read_lock_irqsave@p1 49| 50write_lock_irqsave@p1 51| 52spin_lock@p1 53| 54spin_trylock@p1 55| 56spin_lock_irq@p1 57| 58spin_lock_irqsave@p1 59| 60local_irq_disable@p1 61) 62 (...) 63... when != read_unlock_irq(...) 64 when != write_unlock_irq(...) 65 when != read_unlock_irqrestore(...) 66 when != write_unlock_irqrestore(...) 67 when != spin_unlock(...) 68 when != spin_unlock_irq(...) 69 when != spin_unlock_irqrestore(...) 70 when != local_irq_enable(...) 71fn@p2(...) 72 73@depends on locked && patch@ 74position gfp.p; 75@@ 76 77- GFP_KERNEL@p 78+ GFP_ATOMIC 79 80@depends on locked && !patch@ 81position gfp.p; 82@@ 83 84* GFP_KERNEL@p 85 86@script:python depends on !patch && org@ 87p << gfp.p; 88fn << gfp.fn; 89p1 << locked.p1; 90p2 << locked.p2; 91@@ 92 93cocci.print_main("lock",p1) 94cocci.print_secs("call",p2) 95cocci.print_secs("GFP_KERNEL",p) 96 97@script:python depends on !patch && report@ 98p << gfp.p; 99fn << gfp.fn; 100p1 << locked.p1; 101p2 << locked.p2; 102@@ 103 104msg = "ERROR: function %s called on line %s inside lock on line %s but uses GFP_KERNEL" % (fn,p2[0].line,p1[0].line) 105coccilib.report.print_report(p[0], msg) 106