xref: /linux/scripts/coccinelle/locks/mini_lock.cocci (revision 32d0572a75c81a2c70394f9e110ca080b9a733b1)
154c05628SNicolas Palix/// Find missing unlocks.  This semantic match considers the specific case
254c05628SNicolas Palix/// where the unlock is missing from an if branch, and there is a lock
354c05628SNicolas Palix/// before the if and an unlock after the if.  False positives are due to
454c05628SNicolas Palix/// cases where the if branch represents a case where the function is
554c05628SNicolas Palix/// supposed to exit with the lock held, or where there is some preceding
654c05628SNicolas Palix/// function call that releases the lock.
754c05628SNicolas Palix///
854c05628SNicolas Palix// Confidence: Moderate
929a36d4dSJulia Lawall// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
1029a36d4dSJulia Lawall// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
1129a36d4dSJulia Lawall// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
1254c05628SNicolas Palix// URL: http://coccinelle.lip6.fr/
1354c05628SNicolas Palix// Comments:
1493f14468SNicolas Palix// Options: --no-includes --include-headers
1554c05628SNicolas Palix
1629a36d4dSJulia Lawallvirtual context
1754c05628SNicolas Palixvirtual org
1854c05628SNicolas Palixvirtual report
1954c05628SNicolas Palix
2054c05628SNicolas Palix@prelocked@
2154c05628SNicolas Palixposition p1,p;
2254c05628SNicolas Palixexpression E1;
2354c05628SNicolas Palix@@
2454c05628SNicolas Palix
2554c05628SNicolas Palix(
2654c05628SNicolas Palixmutex_lock@p1
2754c05628SNicolas Palix|
2854c05628SNicolas Palixmutex_trylock@p1
2954c05628SNicolas Palix|
3054c05628SNicolas Palixspin_lock@p1
3154c05628SNicolas Palix|
3254c05628SNicolas Palixspin_trylock@p1
3354c05628SNicolas Palix|
3454c05628SNicolas Palixread_lock@p1
3554c05628SNicolas Palix|
3654c05628SNicolas Palixread_trylock@p1
3754c05628SNicolas Palix|
3854c05628SNicolas Palixwrite_lock@p1
3954c05628SNicolas Palix|
4054c05628SNicolas Palixwrite_trylock@p1
4154c05628SNicolas Palix|
4254c05628SNicolas Palixread_lock_irq@p1
4354c05628SNicolas Palix|
4454c05628SNicolas Palixwrite_lock_irq@p1
4554c05628SNicolas Palix|
4654c05628SNicolas Palixread_lock_irqsave@p1
4754c05628SNicolas Palix|
4854c05628SNicolas Palixwrite_lock_irqsave@p1
4954c05628SNicolas Palix|
5054c05628SNicolas Palixspin_lock_irq@p1
5154c05628SNicolas Palix|
5254c05628SNicolas Palixspin_lock_irqsave@p1
5354c05628SNicolas Palix) (E1@p,...);
5454c05628SNicolas Palix
5554c05628SNicolas Palix@looped@
5654c05628SNicolas Palixposition r;
5754c05628SNicolas Palix@@
5854c05628SNicolas Palix
5954c05628SNicolas Palixfor(...;...;...) { <+... return@r ...; ...+> }
6054c05628SNicolas Palix
6129a36d4dSJulia Lawall@err exists@
6254c05628SNicolas Palixexpression E1;
6354c05628SNicolas Palixposition prelocked.p;
6454c05628SNicolas Palixposition up != prelocked.p1;
6554c05628SNicolas Palixposition r!=looped.r;
6654c05628SNicolas Palixidentifier lock,unlock;
6754c05628SNicolas Palix@@
6854c05628SNicolas Palix
6929a36d4dSJulia Lawall*lock(E1@p,...);
70*32d0572aSJulia Lawall... when != E1
71*32d0572aSJulia Lawall    when any
7254c05628SNicolas Palixif (...) {
7354c05628SNicolas Palix  ... when != E1
7429a36d4dSJulia Lawall*  return@r ...;
7554c05628SNicolas Palix}
76*32d0572aSJulia Lawall... when != E1
77*32d0572aSJulia Lawall    when any
7829a36d4dSJulia Lawall*unlock@up(E1,...);
7954c05628SNicolas Palix
8054c05628SNicolas Palix@script:python depends on org@
8154c05628SNicolas Palixp << prelocked.p1;
8254c05628SNicolas Palixlock << err.lock;
8354c05628SNicolas Palixunlock << err.unlock;
8454c05628SNicolas Palixp2 << err.r;
8554c05628SNicolas Palix@@
8654c05628SNicolas Palix
8754c05628SNicolas Palixcocci.print_main(lock,p)
8854c05628SNicolas Palixcocci.print_secs(unlock,p2)
8954c05628SNicolas Palix
9054c05628SNicolas Palix@script:python depends on report@
9154c05628SNicolas Palixp << prelocked.p1;
9254c05628SNicolas Palixlock << err.lock;
9354c05628SNicolas Palixunlock << err.unlock;
9454c05628SNicolas Palixp2 << err.r;
9554c05628SNicolas Palix@@
9654c05628SNicolas Palix
9754c05628SNicolas Palixmsg = "preceding lock on line %s" % (p[0].line)
9854c05628SNicolas Palixcoccilib.report.print_report(p2[0],msg)
99