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