]>
Commit | Line | Data |
---|---|---|
e105007c | 1 | /// Find functions that refer to GFP_KERNEL but are called with locks held. |
29a36d4d JL |
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. | |
e105007c NP |
5 | /// |
6 | // Confidence: Moderate | |
29a36d4d JL |
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. | |
e105007c NP |
10 | // URL: http://coccinelle.lip6.fr/ |
11 | // Comments: | |
93f14468 | 12 | // Options: --no-includes --include-headers |
e105007c NP |
13 | |
14 | virtual patch | |
29a36d4d JL |
15 | virtual context |
16 | virtual org | |
17 | virtual report | |
e105007c NP |
18 | |
19 | @gfp exists@ | |
20 | identifier fn; | |
21 | position p; | |
22 | @@ | |
23 | ||
24 | fn(...) { | |
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 | ||
29a36d4d | 38 | @locked exists@ |
e105007c | 39 | identifier gfp.fn; |
29a36d4d | 40 | position p1,p2; |
e105007c NP |
41 | @@ |
42 | ||
43 | ( | |
29a36d4d | 44 | read_lock_irq@p1 |
e105007c | 45 | | |
29a36d4d | 46 | write_lock_irq@p1 |
e105007c | 47 | | |
29a36d4d | 48 | read_lock_irqsave@p1 |
e105007c | 49 | | |
29a36d4d | 50 | write_lock_irqsave@p1 |
e105007c | 51 | | |
29a36d4d | 52 | spin_lock@p1 |
e105007c | 53 | | |
29a36d4d | 54 | spin_trylock@p1 |
e105007c | 55 | | |
29a36d4d | 56 | spin_lock_irq@p1 |
e105007c | 57 | | |
29a36d4d | 58 | spin_lock_irqsave@p1 |
e105007c | 59 | | |
29a36d4d | 60 | local_irq_disable@p1 |
e105007c NP |
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(...) | |
29a36d4d | 71 | fn@p2(...) |
e105007c | 72 | |
29a36d4d | 73 | @depends on locked && patch@ |
e105007c NP |
74 | position gfp.p; |
75 | @@ | |
76 | ||
77 | - GFP_KERNEL@p | |
78 | + GFP_ATOMIC | |
29a36d4d JL |
79 | |
80 | @depends on locked && !patch@ | |
81 | position gfp.p; | |
82 | @@ | |
83 | ||
84 | * GFP_KERNEL@p | |
85 | ||
86 | @script:python depends on !patch && org@ | |
87 | p << gfp.p; | |
88 | fn << gfp.fn; | |
89 | p1 << locked.p1; | |
90 | p2 << locked.p2; | |
91 | @@ | |
92 | ||
93 | cocci.print_main("lock",p1) | |
94 | cocci.print_secs("call",p2) | |
95 | cocci.print_secs("GFP_KERNEL",p) | |
96 | ||
97 | @script:python depends on !patch && report@ | |
98 | p << gfp.p; | |
99 | fn << gfp.fn; | |
100 | p1 << locked.p1; | |
101 | p2 << locked.p2; | |
102 | @@ | |
103 | ||
104 | msg = "ERROR: function %s called on line %s inside lock on line %s but uses GFP_KERNEL" % (fn,p2[0].line,p1[0].line) | |
105 | coccilib.report.print_report(p[0], msg) |