xref: /dragonfly/test/cocci/unlock_return.cocci (revision 479ab7f0)
1//
2// Look for missing lock releases before returning from an error path.
3//
4// Target: DragonFly
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//         (original code, adapted for DragonFly by swildner)
9// URL: http://coccinelle.lip6.fr/
10// URL: http://coccinellery.org/
11//
12// Applies to kernel code.
13//
14// NOTES
15// -----
16// * The results of running this patch have to be carefully reviewed.
17//   Some functions legally return with the lock held, even if the
18//   below pattern matches. Some other functions begin with the lock
19//   held, only to release and then reacquire it again.
20//
21// * Consider using -timeout because it might run a long time
22//   (indefinitely?) on some files.
23//
24
25// ACPI_SERIAL_BEGIN(...) / ACPI_SERIAL_END(...)
26//
27@rcu_ACPI_SERIAL_BEGIN exists@
28position p1;
29expression E;
30@@
31
32ACPI_SERIAL_BEGIN@p1(E);
33...
34ACPI_SERIAL_END(E);
35
36@exists@
37position rcu_ACPI_SERIAL_BEGIN.p1;
38expression E;
39@@
40
41*ACPI_SERIAL_BEGIN@p1(E);
42... when != ACPI_SERIAL_END(E);
43?*return ...;
44
45// crit_enter() / crit_exit()
46//
47@rcu_crit_enter exists@
48position p1;
49@@
50
51crit_enter@p1();
52...
53crit_exit();
54
55@exists@
56position rcu_crit_enter.p1;
57@@
58
59*crit_enter@p1();
60... when != crit_exit();
61?*return ...;
62
63// get_mplock() / rel_mplock()
64//
65@rcu_get_mplock exists@
66position p1;
67@@
68
69get_mplock@p1();
70...
71rel_mplock();
72
73@exists@
74position rcu_get_mplock.p1;
75@@
76
77*get_mplock@p1();
78... when != rel_mplock();
79?*return ...;
80
81// lockmgr(..., {LK_EXCLUSIVE,LK_SHARED}) / lockmgr(..., LK_RELEASE)
82//
83@rcu_lockmgr exists@
84position p1;
85expression E;
86@@
87
88lockmgr@p1(E,\(LK_SHARED\|LK_EXCLUSIVE\));
89...
90lockmgr(E,LK_RELEASE);
91
92@exists@
93position rcu_lockmgr.p1;
94expression E;
95@@
96
97*lockmgr@p1(E,\(LK_SHARED\|LK_EXCLUSIVE\));
98... when != lockmgr(E,LK_RELEASE);
99?*return ...;
100
101// lwkt_gettoken(...) / lwkt_reltoken(...)
102//
103@rcu_lwkt_gettoken exists@
104position p1;
105expression E;
106@@
107
108lwkt_gettoken@p1(E);
109...
110lwkt_reltoken(E);
111
112@exists@
113position rcu_lwkt_gettoken.p1;
114expression E;
115@@
116
117*lwkt_gettoken@p1(E);
118... when != lwkt_reltoken(E);
119?*return ...;
120
121// lwkt_serialize_enter(...) / lwkt_serialize_exit(...)
122//
123@rcu_lwkt_serialize_enter exists@
124position p1;
125expression E;
126@@
127
128lwkt_serialize_enter@p1(E);
129...
130lwkt_serialize_exit(E);
131
132@exists@
133position rcu_lwkt_serialize_enter.p1;
134expression E;
135@@
136
137*lwkt_serialize_enter@p1(E);
138... when != lwkt_serialize_exit(E);
139?*return ...;
140
141// nlookup_init(...) / nlookup_done(...)
142//
143@rcu_nlookup_init exists@
144position p1;
145expression E;
146@@
147
148nlookup_init@p1(E,...);
149...
150nlookup_done(E);
151
152@exists@
153position rcu_nlookup_init.p1;
154expression E;
155@@
156
157*nlookup_init@p1(E,...);
158... when != nlookup_done(E);
159?*return ...;
160
161// spin_lock(...) / spin_unlock(...)
162//
163@rcu_spin_lock exists@
164position p1;
165expression E;
166@@
167
168spin_lock@p1(E);
169...
170spin_unlock(E);
171
172@exists@
173position rcu_spin_lock.p1;
174expression E;
175@@
176
177*spin_lock@p1(E);
178... when != spin_unlock(E);
179?*return ...;
180
181// vm_object_hold(...) / vm_object_drop(...)
182//
183@rcu_vm_object_hold exists@
184position p1;
185expression E;
186@@
187
188vm_object_hold@p1(E);
189...
190vm_object_drop(E);
191
192@exists@
193position rcu_vm_object_hold.p1;
194expression E;
195@@
196
197*vm_object_hold@p1(E);
198... when != vm_object_drop(E);
199?*return ...;
200
201// vn_lock(...) / vn_unlock(...)
202//
203@rcu_vn_lock exists@
204position p1;
205expression E;
206@@
207
208(
209vn_lock@p1(E,...);
210|
211vget@p1(E);
212)
213...
214(
215vn_unlock(E);
216|
217vput(E);
218)
219
220@exists@
221position rcu_vn_lock.p1;
222expression E;
223@@
224
225(
226*vn_lock@p1(E,...);
227|
228*vget@p1(E);
229)
230... when != \(vn_unlock\|vput\)(E);
231?*return ...;
232
233// wlan_serialize_enter() / wlan_serialize_exit()
234//
235@rcu_wlan_serialize_enter exists@
236position p1;
237@@
238
239wlan_serialize_enter@p1();
240...
241wlan_serialize_exit();
242
243@exists@
244position rcu_wlan_serialize_enter.p1;
245@@
246
247*wlan_serialize_enter@p1();
248... when != wlan_serialize_exit();
249?*return ...;
250