0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /// Find functions that refer to GFP_KERNEL but are called with locks held.
0003 //# The proposed change of converting the GFP_KERNEL is not necessarily the
0004 //# correct one. It may be desired to unlock the lock, or to not call the
0005 //# function under the lock in the first place.
0006 ///
0007 // Confidence: Moderate
0008 // Copyright: (C) 2012 Nicolas Palix.
0009 // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.
0010 // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.
0011 // URL: https://coccinelle.gitlabpages.inria.fr/website
0012 // Comments:
0013 // Options: --no-includes --include-headers
0014
0015 virtual patch
0016 virtual context
0017 virtual org
0018 virtual report
0019
0020 @gfp exists@
0021 identifier fn;
0022 position p;
0023 @@
0024
0025 fn(...) {
0026 ... when != read_unlock_irq(...)
0027 when != write_unlock_irq(...)
0028 when != read_unlock_irqrestore(...)
0029 when != write_unlock_irqrestore(...)
0030 when != spin_unlock(...)
0031 when != spin_unlock_irq(...)
0032 when != spin_unlock_irqrestore(...)
0033 when != local_irq_enable(...)
0034 when any
0035 GFP_KERNEL@p
0036 ... when any
0037 }
0038
0039 @locked exists@
0040 identifier gfp.fn;
0041 position p1,p2;
0042 @@
0043
0044 (
0045 read_lock_irq@p1
0046 |
0047 write_lock_irq@p1
0048 |
0049 read_lock_irqsave@p1
0050 |
0051 write_lock_irqsave@p1
0052 |
0053 spin_lock@p1
0054 |
0055 spin_trylock@p1
0056 |
0057 spin_lock_irq@p1
0058 |
0059 spin_lock_irqsave@p1
0060 |
0061 local_irq_disable@p1
0062 )
0063 (...)
0064 ... when != read_unlock_irq(...)
0065 when != write_unlock_irq(...)
0066 when != read_unlock_irqrestore(...)
0067 when != write_unlock_irqrestore(...)
0068 when != spin_unlock(...)
0069 when != spin_unlock_irq(...)
0070 when != spin_unlock_irqrestore(...)
0071 when != local_irq_enable(...)
0072 fn@p2(...)
0073
0074 @depends on locked && patch@
0075 position gfp.p;
0076 @@
0077
0078 - GFP_KERNEL@p
0079 + GFP_ATOMIC
0080
0081 @depends on locked && !patch@
0082 position gfp.p;
0083 @@
0084
0085 * GFP_KERNEL@p
0086
0087 @script:python depends on !patch && org@
0088 p << gfp.p;
0089 fn << gfp.fn;
0090 p1 << locked.p1;
0091 p2 << locked.p2;
0092 @@
0093
0094 cocci.print_main("lock",p1)
0095 cocci.print_secs("call",p2)
0096 cocci.print_secs("GFP_KERNEL",p)
0097
0098 @script:python depends on !patch && report@
0099 p << gfp.p;
0100 fn << gfp.fn;
0101 p1 << locked.p1;
0102 p2 << locked.p2;
0103 @@
0104
0105 msg = "ERROR: function %s called on line %s inside lock on line %s but uses GFP_KERNEL" % (fn,p2[0].line,p1[0].line)
0106 coccilib.report.print_report(p[0], msg)