From: Nikanth Karthikesan <knikanth@suse.de>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: mingo@elte.hu, jens.axboe@oracle.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] Detect and warn on atomic_inc/atomic_dec wrapping around
Date: Fri, 8 May 2009 16:16:53 +0530 [thread overview]
Message-ID: <200905081616.53684.knikanth@suse.de> (raw)
In-Reply-To: <200905081610.50202.knikanth@suse.de>
On Friday 08 May 2009 16:10:49 Nikanth Karthikesan wrote:
> On Friday 08 May 2009 05:53:16 Andrew Morton wrote:
> > On Thu, 30 Apr 2009 19:39:50 +0530
> >
> > Nikanth Karthikesan <knikanth@novell.com> wrote:
> > > Detect and warn on atomic_inc/atomic_dec overflow.
> > >
> > > Add a debug option to detect and warn when the 32-bit atomic_t
> > > overflows during atomic_inc and atomic_dec.
> > >
> > >
> > > ...
> > >
> > > --- a/include/asm-generic/atomic.h
> > > +++ b/include/asm-generic/atomic.h
> > > @@ -4,15 +4,51 @@
> > > * Copyright (C) 2005 Silicon Graphics, Inc.
> > > * Christoph Lameter
> > > *
> > > - * Allows to provide arch independent atomic definitions without the
> > > need to - * edit all arch specific atomic.h files.
> > > */
> > >
> > > +#include <linux/kernel.h>
> > > #include <asm/types.h>
> > > +#include <asm/bug.h>
> >
> > We're going to have real trouble making changes like this to a
> > low-level header file - sparc64 results below.
> >
> > > +/**
> > > + * atomic_inc - increment atomic variable
> > > + * @v: pointer of type atomic_t
> > > + *
> > > + * Atomically increments @v by 1.
> > > + */
> > > +static inline void atomic_inc(atomic_t *v)
> > > +{
> > > +#ifdef CONFIG_ENABLE_WARN_ATOMIC_INC_WRAP
> > > + WARN_ONCE((atomic_read(v) > (INT_MAX / 2)),
> > > + KERN_ERR "atomic inc overflow!");
> > > +#endif
> > > + raw_atomic_inc(v);
> > > +}
> >
> > Are we allowed to assume that atomic_inc==raw_atomic_inc for all
> > architectures which use this definition?
>
> No. Only for architectures that have HAVE_ARCH_DEBUG_ATOMIC. I missed
> enclosing the change with #ifdef HAVE_ARCH_DEBUG_ATOMIC. That should solve
> the problem as it wont be built for other architectures at all.
>
> > Do we know that atomic_read() is defined at this point?
>
> Yes.
>
> > We can avoid the problematic includes via
> >
> > extern void atomic_inc_screwed_up(atomic_t *v);
>
> This and even having atomic_inc defined as a c function instead of a macro
> has a problem. WARN_ONCE would warn only once even if more than 1 variable
> wraps around. So should we have atomic_inc itself as a macro instead?
>
> Also it would report the location in source as include/asm-generic/atomic.h
> instead of the caller. But it should be fine as stack trace would be
> printed.
>
> Anyway I have converted warn_once as an extern function.
>
> Changes from the previous version:
> 1. Enclose everything with #ifdef CONFIG_HAVE_ARCH_DEBUG_ATOMIC.
> 2. Make the warn_once as an extern function and remove the
> #include<asm/bug.h>. This is not required as CONFIG_HAVE_ARCH_DEBUG_ATOMIC
> is defined onlf for x86 and it does not have problem with this include. I
> think we could remove this and also make everything as macro?
>
If you think this would be better, here is a patch that does this. Having it
as a macro would warn for every variable that could overflow.
Thanks
Nikanth
Subject: atomic: detect and warn on atomic_inc/atomic_dec wrapping around
From: Nikanth Karthikesan <knikanth@novell.com>
Add a debug option to detect and warn when the 32-bit atomic_t overflows
during atomic_inc and atomic_dec.
We expect that overflow and underflow of an atomic_t is usually a bug.
There was a patch of this nature in -mm for a long time and it never
triggered false positives and it did find a couple of real bugs.
The option is default-y for now. It will have a fairly nasty impact on
.text size so we may decide to switch it to default-n prior to a kernel
release.
Signed-off-by: Nikanth Karthikesan <knikanth@suse.de>
Acked-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index df9e885..dd49be3 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -46,6 +46,7 @@ config X86
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZMA
+ select HAVE_ARCH_DEBUG_ATOMIC
config ARCH_DEFCONFIG
string
diff --git a/arch/x86/include/asm/atomic_32.h
b/arch/x86/include/asm/atomic_32.h
index 85b46fb..c6a17bb 100644
--- a/arch/x86/include/asm/atomic_32.h
+++ b/arch/x86/include/asm/atomic_32.h
@@ -78,24 +78,24 @@ static inline int atomic_sub_and_test(int i, atomic_t *v)
}
/**
- * atomic_inc - increment atomic variable
+ * raw_atomic_inc - increment atomic variable
* @v: pointer of type atomic_t
*
* Atomically increments @v by 1.
*/
-static inline void atomic_inc(atomic_t *v)
+static inline void raw_atomic_inc(atomic_t *v)
{
asm volatile(LOCK_PREFIX "incl %0"
: "+m" (v->counter));
}
/**
- * atomic_dec - decrement atomic variable
+ * raw_atomic_dec - decrement atomic variable
* @v: pointer of type atomic_t
*
* Atomically decrements @v by 1.
*/
-static inline void atomic_dec(atomic_t *v)
+static inline void raw_atomic_dec(atomic_t *v)
{
asm volatile(LOCK_PREFIX "decl %0"
: "+m" (v->counter));
diff --git a/arch/x86/include/asm/atomic_64.h
b/arch/x86/include/asm/atomic_64.h
index 8c21731..1183b85 100644
--- a/arch/x86/include/asm/atomic_64.h
+++ b/arch/x86/include/asm/atomic_64.h
@@ -77,12 +77,12 @@ static inline int atomic_sub_and_test(int i, atomic_t *v)
}
/**
- * atomic_inc - increment atomic variable
+ * raw_atomic_inc - increment atomic variable
* @v: pointer of type atomic_t
*
* Atomically increments @v by 1.
*/
-static inline void atomic_inc(atomic_t *v)
+static inline void raw_atomic_inc(atomic_t *v)
{
asm volatile(LOCK_PREFIX "incl %0"
: "=m" (v->counter)
@@ -90,12 +90,12 @@ static inline void atomic_inc(atomic_t *v)
}
/**
- * atomic_dec - decrement atomic variable
+ * raw_atomic_dec - decrement atomic variable
* @v: pointer of type atomic_t
*
* Atomically decrements @v by 1.
*/
-static inline void atomic_dec(atomic_t *v)
+static inline void raw_atomic_dec(atomic_t *v)
{
asm volatile(LOCK_PREFIX "decl %0"
: "=m" (v->counter)
diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h
index 3673a13..004b018 100644
--- a/include/asm-generic/atomic.h
+++ b/include/asm-generic/atomic.h
@@ -4,15 +4,56 @@
* Copyright (C) 2005 Silicon Graphics, Inc.
* Christoph Lameter
*
- * Allows to provide arch independent atomic definitions without the need to
- * edit all arch specific atomic.h files.
*/
#include <asm/types.h>
+#ifdef CONFIG_HAVE_ARCH_DEBUG_ATOMIC
+
+#include <linux/kernel.h>
+#include <asm/bug.h>
+
+#ifdef CONFIG_ENABLE_WARN_ATOMIC_INC_WRAP
+
+/**
+ * atomic_inc - increment atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1.
+ */
+#define atomic_inc(v) ({ \
+ WARN_ONCE((atomic_read(v) > (INT_MAX / 2)), \
+ KERN_ERR "atomic inc overflow!"); \
+ raw_atomic_inc(v); \
+})
+
+/**
+ * atomic_dec - decrement atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1.
+ */
+#define atomic_dec(v) ({ \
+ WARN_ONCE((atomic_read(v) < (INT_MIN / 2)), \
+ KERN_ERR "atomic dec underflow!"); \
+ raw_atomic_dec(v); \
+})
+
+#else /* CONFIG_ENABLE_WARN_ATOMIC_INC_WRAP */
+
+#define atomic_inc(v) raw_atomic_inc(v)
+#define atomic_dec(v) raw_atomic_dec(v)
+
+#endif /* !CONFIG_ENABLE_WARN_ATOMIC_INC_WRAP */
+
+#endif /* CONFIG_HAVE_ARCH_DEBUG_ATOMIC */
+
/*
* Suppport for atomic_long_t
*
+ * Allows to provide arch independent atomic definitions without the need to
+ * edit all arch specific atomic.h files.
+ *
* Casts for parameters are avoided for existing atomic functions in order to
* avoid issues with cast-as-lval under gcc 4.x and other limitations that
the
* macros of a platform may have.
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 812c282..773c1a4 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -17,6 +17,17 @@ config ENABLE_WARN_DEPRECATED
Disable this to suppress the "warning: 'foo' is deprecated
(declared at kernel/power/somefile.c:1234)" messages.
+config HAVE_ARCH_DEBUG_ATOMIC
+ bool
+
+config ENABLE_WARN_ATOMIC_INC_WRAP
+ bool "Enable warning on atomic_inc()/atomic_dec() wrap"
+ depends on HAVE_ARCH_DEBUG_ATOMIC
+ default y
+ help
+ Enable printing a warning when atomic_inc() or atomic_dec()
+ operation wraps around the 32-bit value.
+
config ENABLE_MUST_CHECK
bool "Enable __must_check logic"
default y
prev parent reply other threads:[~2009-05-08 10:45 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-04-29 6:51 [PATCH][RFC] Handle improbable possibility of io_context->refcount overflow Nikanth Karthikesan
2009-04-29 7:59 ` Andrew Morton
2009-04-29 10:03 ` Nikanth Karthikesan
2009-04-29 15:15 ` Andrew Morton
2009-04-30 7:28 ` Nikanth Karthikesan
2009-04-30 7:28 ` [PATCH v2] " Nikanth Karthikesan
2009-04-30 7:29 ` [PATCH] Detect and warn on atomic_inc/atomic_dec wrapping around Nikanth Karthikesan
2009-04-30 8:23 ` Ingo Molnar
2009-04-30 10:11 ` Nikanth Karthikesan
2009-04-30 10:47 ` Ingo Molnar
2009-04-30 12:08 ` Nikanth Karthikesan
2009-04-30 12:21 ` Ingo Molnar
2009-04-30 12:26 ` Nikanth Karthikesan
2009-04-30 12:50 ` Ingo Molnar
2009-04-30 13:29 ` Nikanth Karthikesan
2009-04-30 13:37 ` Ingo Molnar
2009-04-30 13:51 ` Nikanth Karthikesan
2009-04-30 14:05 ` Ingo Molnar
2009-04-30 14:09 ` Nikanth Karthikesan
2009-04-30 14:44 ` Ingo Molnar
2009-04-30 21:45 ` Andrew Morton
2009-05-01 4:57 ` Nikanth Karthikesan
2009-05-01 5:06 ` Andrew Morton
2009-05-01 5:13 ` Andrew Morton
2009-05-08 0:23 ` Andrew Morton
2009-05-08 10:40 ` Nikanth Karthikesan
2009-05-08 10:46 ` Nikanth Karthikesan [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200905081616.53684.knikanth@suse.de \
--to=knikanth@suse.de \
--cc=akpm@linux-foundation.org \
--cc=jens.axboe@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.