Re: 2.6.14-rc1-git-now still dying in mm/slab - this time line 1849

From: Alok Kataria
Date: Sun Sep 25 2005 - 09:20:28 EST


On Sat, 2005-09-24 at 05:35, Christoph Lameter wrote:
Comments on the code:

@@ -2852,6 +2860,8 @@

cache_alloc_debugcheck_before(cachep, flags);
local_irq_save(save_flags);
+ if (nodeid == numa_node_id())
+ ____cache_alloc(cachep, flags);
ptr = __cache_alloc_node(cachep, flags, nodeid);

This should be

ptr = ___cache_alloc(cachep, flags)
else
ptr = __cache_alloc_node(...)

right?

local_irq_restore(save_flags);
ptr = cache_alloc_debugcheck_after(cachep, flags, ptr,
__builtin_return_address(0));

Oh a major blunder !! Updated the patch

--
As pointed by Christoph, In kmalloc_node we are cheking if, the allocation is for the
same node when interrupts are "on", this may lead to an allocation on another node than intended.
This patch just shifts the check for the current node in __cache_alloc_node when interrupts
are disabled.

Signed-off-by: Alok N Kataria <alokk@xxxxxxxxxxxxxx>
Cc : Christoph Lameter <clameter@xxxxxxx>

Index: linux-2.6.13/mm/slab.c
===================================================================
--- linux-2.6.13.orig/mm/slab.c 2005-09-25 18:48:16.068349500 +0530
+++ linux-2.6.13/mm/slab.c 2005-09-25 18:48:18.484500500 +0530
@@ -2508,16 +2508,12 @@
#define cache_alloc_debugcheck_after(a,b,objp,d) (objp)
#endif

-
-static inline void *__cache_alloc(kmem_cache_t *cachep, unsigned int __nocast flags)
+static inline void *____cache_alloc(kmem_cache_t *cachep, unsigned int __nocast flags)
{
- unsigned long save_flags;
void* objp;
struct array_cache *ac;

- cache_alloc_debugcheck_before(cachep, flags);
-
- local_irq_save(save_flags);
+ check_irq_off();
ac = ac_data(cachep);
if (likely(ac->avail)) {
STATS_INC_ALLOCHIT(cachep);
@@ -2527,6 +2523,18 @@
STATS_INC_ALLOCMISS(cachep);
objp = cache_alloc_refill(cachep, flags);
}
+ return objp;
+}
+
+static inline void *__cache_alloc(kmem_cache_t *cachep, unsigned int __nocast flags)
+{
+ unsigned long save_flags;
+ void* objp;
+
+ cache_alloc_debugcheck_before(cachep, flags);
+
+ local_irq_save(save_flags);
+ objp = ____cache_alloc(cachep, flags);
local_irq_restore(save_flags);
objp = cache_alloc_debugcheck_after(cachep, flags, objp,
__builtin_return_address(0));
@@ -2844,7 +2852,7 @@
unsigned long save_flags;
void *ptr;

- if (nodeid == numa_node_id() || nodeid == -1)
+ if (nodeid == -1)
return __cache_alloc(cachep, flags);

if (unlikely(!cachep->nodelists[nodeid])) {
@@ -2855,7 +2863,10 @@

cache_alloc_debugcheck_before(cachep, flags);
local_irq_save(save_flags);
- ptr = __cache_alloc_node(cachep, flags, nodeid);
+ if (nodeid == numa_node_id())
+ ptr = ____cache_alloc(cachep, flags);
+ else
+ ptr = __cache_alloc_node(cachep, flags, nodeid);
local_irq_restore(save_flags);
ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, __builtin_return_address(0));

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/