lkml.org 
[lkml]   [2008]   [Feb]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] Slub Freeoffset check overflow
* Christoph Lameter (clameter@sgi.com) wrote:
> On Thu, 28 Feb 2008, Mathieu Desnoyers wrote:
>
> > * Christoph Lameter (clameter@sgi.com) wrote:
> > > On Thu, 28 Feb 2008, Mathieu Desnoyers wrote:
> > >
> > > > In short, the we also use the versioning to check for change of slab.
>
> Then we do not need the page->end field anymore right? I will try
> to rediff your patch against current slab-mm and see how we can proceed
> from there.


Slub Freeoffset check overflow

Check for overflow of the freeoffset version number.

I just thought adding this check in CONFIG_SLUB_DEBUG makes sense. It's
really unlikely that enough interrupt handlers will nest over the slub
fast path, and each of them do about a million alloc/free on 32 bits or
a huge amount of alloc/free on 64 bits, but just in case, it seems good
to warn if we detect we are half-way to a version overflow.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
---
mm/slub.c | 32 ++++++++++++++++++++++++++------
1 file changed, 26 insertions(+), 6 deletions(-)

Index: linux-2.6-lttng/mm/slub.c
===================================================================
--- linux-2.6-lttng.orig/mm/slub.c 2008-02-29 08:05:01.000000000 -0500
+++ linux-2.6-lttng/mm/slub.c 2008-02-29 08:16:13.000000000 -0500
@@ -1660,7 +1660,7 @@ static __always_inline void *slab_alloc(
*/

#ifdef SLUB_FASTPATH
- unsigned long freeoffset, newoffset;
+ unsigned long freeoffset, newoffset, resoffset;

c = get_cpu_slab(s, raw_smp_processor_id());
do {
@@ -1682,8 +1682,18 @@ static __always_inline void *slab_alloc(
newoffset = freeoffset;
newoffset &= ~c->off_mask;
newoffset |= (unsigned long)object[c->offset] & c->off_mask;
- } while (cmpxchg_local(&c->freeoffset, freeoffset, newoffset)
- != freeoffset);
+ resoffset = cmpxchg_local(&c->freeoffset, freeoffset,
+ newoffset);
+#ifdef CONFIG_SLUB_DEBUG
+ /*
+ * Just to be paranoid : warn if we detect that enough
+ * allocations nested on top of us to get the counter to go
+ * half-way to overflow. That would be insane to do that much
+ * allocations in interrupt handers, but check it anyway.
+ */
+ WARN_ON(resoffset - freeoffset > -1UL >> 1);
+#endif
+ } while (resoffset != freeoffset);
#else
unsigned long flags;

@@ -1822,7 +1832,7 @@ static __always_inline void slab_free(st
struct kmem_cache_cpu *c;

#ifdef SLUB_FASTPATH
- unsigned long freeoffset, newoffset;
+ unsigned long freeoffset, newoffset, resoffset;

c = get_cpu_slab(s, raw_smp_processor_id());
debug_check_no_locks_freed(object, s->objsize);
@@ -1850,8 +1860,18 @@ static __always_inline void slab_free(st
newoffset = freeoffset + c->off_mask + 1;
newoffset &= ~c->off_mask;
newoffset |= (unsigned long)object & c->off_mask;
- } while (cmpxchg_local(&c->freeoffset, freeoffset, newoffset)
- != freeoffset);
+ resoffset = cmpxchg_local(&c->freeoffset, freeoffset,
+ newoffset);
+#ifdef CONFIG_SLUB_DEBUG
+ /*
+ * Just to be paranoid : warn if we detect that enough
+ * allocations nested on top of us to get the counter to go
+ * half-way to overflow. That would be insane to do that much
+ * allocations in interrupt handers, but check it anyway.
+ */
+ WARN_ON(resoffset - freeoffset > -1UL >> 1);
+#endif
+ } while (resoffset != freeoffset);
#else
unsigned long flags;

--
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68


\
 
 \ /
  Last update: 2008-02-29 14:31    [W:0.099 / U:3.044 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site