How about this patch making kzalloc a macro?
---
Make kzalloc a macro and use __GFP_ZERO for zeroed slab allocations
kzalloc is right now a function call. The optimization that the kmalloc macro
provides does not work for kzalloc invocations. kmalloc also determines the
slab to use at compile time and fails the compilation if the size is too big.
kzalloc cannot do not.
Moreover there is no kzalloc_node.
This patch adds the ability to the slab allocator to indicate that an entity
should be zeroed by using __GFP_ZERO in the same way to the page allocator.
__GFP_ZERO may be specified when using any slab allocation operation.
Then kzalloc can be defined as a simple macro which will then perform all the
compile time checks of kmalloc and also check the sizes.
Signed-off-by: Christoph Lameter
Index: linux-2.6.14-rc2/include/linux/slab.h
===================================================================
--- linux-2.6.14-rc2.orig/include/linux/slab.h 2005-09-19 20:00:41.000000000 -0700
+++ linux-2.6.14-rc2/include/linux/slab.h 2005-09-22 16:25:25.000000000 -0700
@@ -99,7 +99,7 @@ found:
return __kmalloc(size, flags);
}
-extern void *kzalloc(size_t, unsigned int __nocast);
+#define kzalloc(__size, __flags) kmalloc(__size, (__flags) | __GFP_ZERO)
/**
* kcalloc - allocate memory for an array. The memory is set to zero.
Index: linux-2.6.14-rc2/mm/slab.c
===================================================================
--- linux-2.6.14-rc2.orig/mm/slab.c 2005-09-22 11:58:45.000000000 -0700
+++ linux-2.6.14-rc2/mm/slab.c 2005-09-23 08:53:16.000000000 -0700
@@ -1190,7 +1190,7 @@ static void *kmem_getpages(kmem_cache_t
void *addr;
int i;
- flags |= cachep->gfpflags;
+ flags = (flags | cachep->gfpflags) & ~__GFP_ZERO;
if (likely(nodeid == -1)) {
page = alloc_pages(flags, cachep->gfporder);
} else {
@@ -2508,11 +2508,23 @@ cache_alloc_debugcheck_after(kmem_cache_
#define cache_alloc_debugcheck_after(a,b,objp,d) (objp)
#endif
+static inline void *obj_checkout(kmem_cache_t *cachep, unsigned int __nocast flags, void *objp)
+{
+ if (likely(objp)) {
+ objp = cache_alloc_debugcheck_after(cachep, flags, objp,
+ __builtin_return_address(0));
+ if (unlikely(flags & __GFP_ZERO))
+ memset(objp, 0, obj_reallen(cachep));
+ else
+ prefetchw(objp);
+ }
+ return objp;
+}
static inline void *__cache_alloc(kmem_cache_t *cachep, unsigned int __nocast flags)
{
unsigned long save_flags;
- void* objp;
+ void *objp;
struct array_cache *ac;
cache_alloc_debugcheck_before(cachep, flags);
@@ -2528,10 +2540,7 @@ static inline void *__cache_alloc(kmem_c
objp = cache_alloc_refill(cachep, flags);
}
local_irq_restore(save_flags);
- objp = cache_alloc_debugcheck_after(cachep, flags, objp,
- __builtin_return_address(0));
- prefetchw(objp);
- return objp;
+ return obj_checkout(cachep, flags, objp);
}
#ifdef CONFIG_NUMA
@@ -2550,14 +2559,23 @@ static void *__cache_alloc_node(kmem_cac
l3 = cachep->nodelists[nodeid];
BUG_ON(!l3);
+ cache_alloc_debugcheck_before(cachep, flags);
+
retry:
spin_lock(&l3->list_lock);
entry = l3->slabs_partial.next;
if (entry == &l3->slabs_partial) {
l3->free_touched = 1;
entry = l3->slabs_free.next;
- if (entry == &l3->slabs_free)
- goto must_grow;
+ if (entry == &l3->slabs_free) {
+ spin_unlock(&l3->list_lock);
+ x = cache_grow(cachep, flags, nodeid);
+
+ if (!x)
+ return NULL;
+
+ goto retry;
+ }
}
slabp = list_entry(entry, struct slab, list);
@@ -2590,18 +2608,7 @@ retry:
}
spin_unlock(&l3->list_lock);
- goto done;
-
-must_grow:
- spin_unlock(&l3->list_lock);
- x = cache_grow(cachep, flags, nodeid);
-
- if (!x)
- return NULL;
-
- goto retry;
-done:
- return obj;
+ return obj_checkout(cachep, flags, obj);
}
#endif
@@ -2980,20 +2987,6 @@ void kmem_cache_free(kmem_cache_t *cache
EXPORT_SYMBOL(kmem_cache_free);
/**
- * kzalloc - allocate memory. The memory is set to zero.
- * @size: how many bytes of memory are required.
- * @flags: the type of memory to allocate.
- */
-void *kzalloc(size_t size, unsigned int __nocast flags)
-{
- void *ret = kmalloc(size, flags);
- if (ret)
- memset(ret, 0, size);
- return ret;
-}
-EXPORT_SYMBOL(kzalloc);
-
-/**
* kfree - free previously allocated memory
* @objp: pointer returned by kmalloc.
*
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
|
|