xref: /OK3568_Linux_fs/kernel/scripts/coccinelle/locks/mini_lock.cocci (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun// SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun/// Find missing unlocks.  This semantic match considers the specific case
3*4882a593Smuzhiyun/// where the unlock is missing from an if branch, and there is a lock
4*4882a593Smuzhiyun/// before the if and an unlock after the if.  False positives are due to
5*4882a593Smuzhiyun/// cases where the if branch represents a case where the function is
6*4882a593Smuzhiyun/// supposed to exit with the lock held, or where there is some preceding
7*4882a593Smuzhiyun/// function call that releases the lock.
8*4882a593Smuzhiyun///
9*4882a593Smuzhiyun// Confidence: Moderate
10*4882a593Smuzhiyun// Copyright: (C) 2010-2012 Nicolas Palix.
11*4882a593Smuzhiyun// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
12*4882a593Smuzhiyun// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
13*4882a593Smuzhiyun// URL: http://coccinelle.lip6.fr/
14*4882a593Smuzhiyun// Comments:
15*4882a593Smuzhiyun// Options: --no-includes --include-headers
16*4882a593Smuzhiyun
17*4882a593Smuzhiyunvirtual context
18*4882a593Smuzhiyunvirtual org
19*4882a593Smuzhiyunvirtual report
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun@prelocked@
22*4882a593Smuzhiyunposition p1,p;
23*4882a593Smuzhiyunexpression E1;
24*4882a593Smuzhiyun@@
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun(
27*4882a593Smuzhiyunmutex_lock@p1
28*4882a593Smuzhiyun|
29*4882a593Smuzhiyunmutex_trylock@p1
30*4882a593Smuzhiyun|
31*4882a593Smuzhiyunspin_lock@p1
32*4882a593Smuzhiyun|
33*4882a593Smuzhiyunspin_trylock@p1
34*4882a593Smuzhiyun|
35*4882a593Smuzhiyunread_lock@p1
36*4882a593Smuzhiyun|
37*4882a593Smuzhiyunread_trylock@p1
38*4882a593Smuzhiyun|
39*4882a593Smuzhiyunwrite_lock@p1
40*4882a593Smuzhiyun|
41*4882a593Smuzhiyunwrite_trylock@p1
42*4882a593Smuzhiyun|
43*4882a593Smuzhiyunread_lock_irq@p1
44*4882a593Smuzhiyun|
45*4882a593Smuzhiyunwrite_lock_irq@p1
46*4882a593Smuzhiyun|
47*4882a593Smuzhiyunread_lock_irqsave@p1
48*4882a593Smuzhiyun|
49*4882a593Smuzhiyunwrite_lock_irqsave@p1
50*4882a593Smuzhiyun|
51*4882a593Smuzhiyunspin_lock_irq@p1
52*4882a593Smuzhiyun|
53*4882a593Smuzhiyunspin_lock_irqsave@p1
54*4882a593Smuzhiyun) (E1@p,...);
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun@looped@
57*4882a593Smuzhiyunposition r;
58*4882a593Smuzhiyun@@
59*4882a593Smuzhiyun
60*4882a593Smuzhiyunfor(...;...;...) { <+... return@r ...; ...+> }
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun@err exists@
63*4882a593Smuzhiyunexpression E1;
64*4882a593Smuzhiyunposition prelocked.p;
65*4882a593Smuzhiyunposition up != prelocked.p1;
66*4882a593Smuzhiyunposition r!=looped.r;
67*4882a593Smuzhiyunidentifier lock,unlock;
68*4882a593Smuzhiyun@@
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun*lock(E1@p,...);
71*4882a593Smuzhiyun... when != E1
72*4882a593Smuzhiyun    when any
73*4882a593Smuzhiyunif (...) {
74*4882a593Smuzhiyun  ... when != E1
75*4882a593Smuzhiyun*  return@r ...;
76*4882a593Smuzhiyun}
77*4882a593Smuzhiyun... when != E1
78*4882a593Smuzhiyun    when any
79*4882a593Smuzhiyun*unlock@up(E1,...);
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun@script:python depends on org@
82*4882a593Smuzhiyunp << prelocked.p1;
83*4882a593Smuzhiyunlock << err.lock;
84*4882a593Smuzhiyununlock << err.unlock;
85*4882a593Smuzhiyunp2 << err.r;
86*4882a593Smuzhiyun@@
87*4882a593Smuzhiyun
88*4882a593Smuzhiyuncocci.print_main(lock,p)
89*4882a593Smuzhiyuncocci.print_secs(unlock,p2)
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun@script:python depends on report@
92*4882a593Smuzhiyunp << prelocked.p1;
93*4882a593Smuzhiyunlock << err.lock;
94*4882a593Smuzhiyununlock << err.unlock;
95*4882a593Smuzhiyunp2 << err.r;
96*4882a593Smuzhiyun@@
97*4882a593Smuzhiyun
98*4882a593Smuzhiyunmsg = "preceding lock on line %s" % (p[0].line)
99*4882a593Smuzhiyuncoccilib.report.print_report(p2[0],msg)
100