Improve our unlock_return.cocci (now finds much more candidates).
[dragonfly.git] / test / cocci / unlock_return.cocci
1 //
2 // Look for missing lock releases before returning from an error path.
3 //
4 // Target: Linux
5 // Copyright:  2012 - LIP6/INRIA
6 // License:  Licensed under ISC. See LICENSE or http://www.isc.org/software/license
7 // Author: Julia Lawall <Julia.Lawall@lip6.fr>
8 // URL: http://coccinelle.lip6.fr/ 
9 // URL: http://coccinellery.org/ 
10 //
11 // Applies to kernel code.
12 //
13 // NOTES
14 // -----
15 // * The results of running this patch have to be carefully reviewed.
16 //   Some functions legally return with the lock held, even if the
17 //   below pattern matches. Some other functions begin with the lock
18 //   held, only to release and then reacquire it again.
19 //
20 // * Consider using -timeout because it might run a long time
21 //   (indefinitely?) on some files.
22 //
23
24 // crit_enter() / crit_exit()
25 //
26 @rcu_crit_enter exists@
27 position p1;
28 @@
29
30 crit_enter@p1();
31 ...
32 crit_exit();
33
34 @exists@
35 position rcu_crit_enter.p1;
36 @@
37
38 *crit_enter@p1();
39 ... when != crit_exit();
40 ?*return ...;
41
42 // get_mplock() / rel_mplock()
43 //
44 @rcu_get_mplock exists@
45 position p1;
46 @@
47
48 get_mplock@p1();
49 ...
50 rel_mplock();
51
52 @exists@
53 position rcu_get_mplock.p1;
54 @@
55
56 *get_mplock@p1();
57 ... when != rel_mplock();
58 ?*return ...;
59
60 // lockmgr(..., {LK_EXCLUSIVE,LK_SHARED}) / lockmgr(..., LK_RELEASE)
61 //
62 @rcu_lockmgr exists@
63 position p1;
64 expression E;
65 @@
66
67 lockmgr@p1(E,\(LK_SHARED\|LK_EXCLUSIVE\));
68 ...
69 lockmgr(E,LK_RELEASE);
70
71 @exists@
72 position rcu_lockmgr.p1;
73 expression E;
74 @@
75
76 *lockmgr@p1(E,\(LK_SHARED\|LK_EXCLUSIVE\));
77 ... when != lockmgr(E,LK_RELEASE);
78 ?*return ...;
79
80 // lwkt_gettoken(...) / lwkt_reltoken(...)
81 //
82 @rcu_lwkt_gettoken exists@
83 position p1;
84 expression E;
85 @@
86
87 lwkt_gettoken@p1(E);
88 ...
89 lwkt_reltoken(E);
90
91 @exists@
92 position rcu_lwkt_gettoken.p1;
93 expression E;
94 @@
95
96 *lwkt_gettoken@p1(E);
97 ... when != lwkt_reltoken(E);
98 ?*return ...;
99
100 // lwkt_serialize_enter(...) / lwkt_serialize_exit(...)
101 //
102 @rcu_lwkt_serialize_enter exists@
103 position p1;
104 expression E;
105 @@
106
107 lwkt_serialize_enter@p1(E);
108 ...
109 lwkt_serialize_exit(E);
110
111 @exists@
112 position rcu_lwkt_serialize_enter.p1;
113 expression E;
114 @@
115
116 *lwkt_serialize_enter@p1(E);
117 ... when != lwkt_serialize_exit(E);
118 ?*return ...;
119
120 // spin_lock(...) / spin_unlock(...)
121 //
122 @rcu_spin_lock exists@
123 position p1;
124 expression E;
125 @@
126
127 spin_lock@p1(E);
128 ...
129 spin_unlock(E);
130
131 @exists@
132 position rcu_spin_lock.p1;
133 expression E;
134 @@
135
136 *spin_lock@p1(E);
137 ... when != spin_unlock(E);
138 ?*return ...;
139
140 // vm_object_hold(...) / vm_object_drop(...)
141 //
142 @rcu_vm_object_hold exists@
143 position p1;
144 expression E;
145 @@
146
147 vm_object_hold@p1(E);
148 ...
149 vm_object_drop(E);
150
151 @exists@
152 position rcu_vm_object_hold.p1;
153 expression E;
154 @@
155
156 *vm_object_hold@p1(E);
157 ... when != vm_object_drop(E);
158 ?*return ...;