diff mbox

linux/compiler.h: Add __must_hold macro for functions called with a lock held

Message ID 20121008020610.GA9197@leaf (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Josh Triplett Oct. 8, 2012, 2:06 a.m. UTC
linux/compiler.h has macros to denote functions that acquire or release
locks, but not to denote functions called with a lock held that return
with the lock still held.  Add a __must_hold macro to cover that case.

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Reported-by: Ed Cashin <ecashin@coraid.com>
Tested-by: Ed Cashin <ecashin@coraid.com>
---
 include/linux/compiler.h |    2 ++
 1 file changed, 2 insertions(+)

Comments

Andrew Morton Oct. 9, 2012, 8:06 p.m. UTC | #1
On Sun, 7 Oct 2012 19:06:10 -0700
Josh Triplett <josh@joshtriplett.org> wrote:

> linux/compiler.h has macros to denote functions that acquire or release
> locks, but not to denote functions called with a lock held that return
> with the lock still held.  Add a __must_hold macro to cover that case.

hum.  How does this work?  Any code examples and sample sparse output? 
Does it apply to all lock types, etc?

IOW, where is all this stuff documented?

--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ed Cashin Oct. 9, 2012, 8:35 p.m. UTC | #2
On Oct 9, 2012, at 4:06 PM, Andrew Morton wrote:

> On Sun, 7 Oct 2012 19:06:10 -0700
> Josh Triplett <josh@joshtriplett.org> wrote:
> 
>> linux/compiler.h has macros to denote functions that acquire or release
>> locks, but not to denote functions called with a lock held that return
>> with the lock still held.  Add a __must_hold macro to cover that case.
> 
> hum.  How does this work?  Any code examples and sample sparse output? 
> Does it apply to all lock types, etc?

I accidentally found a bug in sparse where sparse should have
been complaining about the locking in the aoe driver's
aoenet.c:tx function, which enters with the txlock spinlock held
and releases and reacquires it inside a loop.

When I modified the loop contents between lock release and
acquisition in a patch that I'm preparing now, sparse began
complaining about context imbalance.  (Before the modifications
to the tx function, sparse was exhibiting a bug by *not*
complaining.)  Here's the complaint:

  CHECK   drivers/block/aoe/aoenet.c
/build/ecashin/git/linux/arch/x86/include/asm/spinlock.h:81:9: warning: context imbalance in 'tx' - unexpected unlock
  CC [M]  drivers/block/aoe/aoenet.o

... although I used a smaller file to hone in on the issue when
discussing it on the linux-sparse mailing list:

  http://thread.gmane.org/gmane.comp.parsers.sparse/3091

Josh Triplett suggested I add an annotation telling sparse that
the function enters and exits with the lock held, but after
reading the sparse man page, where the context feature is
described, it looked like that meant specifying a 1 for both
parameters: __attribute__((context(x,1,1))), but there was no
macro for that.

The new patch from Josh Triplett adds the macro that I can use to
keep sparse informed about the locking requirements for the tx
function.

> IOW, where is all this stuff documented?

It wasn't real easy to find it, but it's basically something you
can infer from reading include/linux/compiler.h and the sparse.1
man page that's included with sparse.  I think a brief mention in
Documentation/sparse.txt of the relationship between the
sparse "context" feature and the locking annotations like
__acquires and __must_hold would be a nice addition.

I can take a stab at it if folks agree.
Josh Triplett Oct. 9, 2012, 8:36 p.m. UTC | #3
On Tue, Oct 09, 2012 at 01:06:37PM -0700, Andrew Morton wrote:
> On Sun, 7 Oct 2012 19:06:10 -0700
> Josh Triplett <josh@joshtriplett.org> wrote:
> 
> > linux/compiler.h has macros to denote functions that acquire or release
> > locks, but not to denote functions called with a lock held that return
> > with the lock still held.  Add a __must_hold macro to cover that case.
> 
> hum.  How does this work?  Any code examples and sample sparse output? 
> Does it apply to all lock types, etc?

It applies to all the same lock types that __acquires and __releases
apply to: currently everything since Sparse doesn't actually do anything
with the parameter, just the context value.

Various code examples already exist in the kernel tree for __acquires
and __releases, and the mailing list contains many reports of the Sparse
context warnings.

Just as __acquires and __release annotate functions that return with a
lock acquired and get called with a lock that they drop (respectively),
__must_hold annotates a function called with a lock acquired that return
with that lock still acquired.

> IOW, where is all this stuff documented?

The Sparse manpage documents the context bits reasonably well.  Other
than that, nowhere that I know of other than the Sparse testsuite and
the source trees of projects like Linux that use Sparse.

- Josh Triplett
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sam Ravnborg Oct. 13, 2012, 9:41 a.m. UTC | #4
On Tue, Oct 09, 2012 at 01:36:28PM -0700, Josh Triplett wrote:
> On Tue, Oct 09, 2012 at 01:06:37PM -0700, Andrew Morton wrote:
> > On Sun, 7 Oct 2012 19:06:10 -0700
> > Josh Triplett <josh@joshtriplett.org> wrote:
> > 
> > > linux/compiler.h has macros to denote functions that acquire or release
> > > locks, but not to denote functions called with a lock held that return
> > > with the lock still held.  Add a __must_hold macro to cover that case.
> > 
> > hum.  How does this work?  Any code examples and sample sparse output? 
> > Does it apply to all lock types, etc?
> 
> It applies to all the same lock types that __acquires and __releases
> apply to: currently everything since Sparse doesn't actually do anything
> with the parameter, just the context value.
> 
> Various code examples already exist in the kernel tree for __acquires
> and __releases, and the mailing list contains many reports of the Sparse
> context warnings.
> 
> Just as __acquires and __release annotate functions that return with a
> lock acquired and get called with a lock that they drop (respectively),
> __must_hold annotates a function called with a lock acquired that return
> with that lock still acquired.
> 
> > IOW, where is all this stuff documented?
> 
> The Sparse manpage documents the context bits reasonably well.  Other
> than that, nowhere that I know of other than the Sparse testsuite and
> the source trees of projects like Linux that use Sparse.

The kernel specific macros should be documented in:

    Documentation/sparse.txt

For now only __bitwise is documentd, but when we introduce new
sparse annotation macros in the kernel the documentation should
be mandatory.

	Sam
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index f430e41..b121554 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -10,6 +10,7 @@ 
 # define __force	__attribute__((force))
 # define __nocast	__attribute__((nocast))
 # define __iomem	__attribute__((noderef, address_space(2)))
+# define __must_hold(x)	__attribute__((context(x,1,1)))
 # define __acquires(x)	__attribute__((context(x,0,1)))
 # define __releases(x)	__attribute__((context(x,1,0)))
 # define __acquire(x)	__context__(x,1)
@@ -33,6 +34,7 @@  extern void __chk_io_ptr(const volatile void __iomem *);
 # define __chk_user_ptr(x) (void)0
 # define __chk_io_ptr(x) (void)0
 # define __builtin_warning(x, y...) (1)
+# define __must_hold(x)
 # define __acquires(x)
 # define __releases(x)
 # define __acquire(x) (void)0