SLUB: Add support for kmem_cache_ops Change the constructor parameter to be a pointer to a kmem_cache_ops structure. kmem_cache_ops is created with the constructor. Later patches populate kmem_cache_ops with more operations.. Create a KMEM_CACHE_OPS macro that allows the specification of a the kmem_cache_ops parameter. Code to handle kmem_cache_ops is added to SLUB. SLAB and SLOB are updated to be able to accept a kmem_cache_ops structure but will ignore it. Signed-off-by: Christoph Lameter --- drivers/mtd/ubi/eba.c | 6 ++++- drivers/usb/mon/mon_text.c | 6 ++++- fs/block_dev.c | 6 ++++- fs/cifs/cifsfs.c | 6 ++++- fs/ext2/super.c | 6 ++++- fs/ext3/super.c | 6 ++++- fs/ext4/super.c | 6 ++++- fs/fuse/inode.c | 6 ++++- fs/inode.c | 8 +++++- fs/isofs/inode.c | 6 ++++- fs/locks.c | 6 ++++- fs/nfs/inode.c | 6 ++++- fs/proc/inode.c | 6 ++++- fs/reiserfs/super.c | 6 ++++- fs/udf/super.c | 6 ++++- fs/xfs/linux-2.6/kmem.h | 7 +++++ include/linux/slab.h | 17 ++++++++++---- include/linux/slub_def.h | 1 ipc/mqueue.c | 6 ++++- kernel/fork.c | 6 ++++- lib/idr.c | 6 ++++- lib/radix-tree.c | 6 ++++- mm/rmap.c | 7 +++++ mm/shmem.c | 6 ++++- mm/slab.c | 9 +++++-- mm/slob.c | 7 ++++- mm/slub.c | 53 +++++++++++++++++++++++++-------------------- net/socket.c | 6 ++++- net/sunrpc/rpc_pipe.c | 6 ++++- 29 files changed, 177 insertions(+), 58 deletions(-) Index: linux-2.6/include/linux/slab.h =================================================================== --- linux-2.6.orig/include/linux/slab.h 2007-07-29 13:14:11.000000000 -0700 +++ linux-2.6/include/linux/slab.h 2007-07-29 13:15:18.000000000 -0700 @@ -43,15 +43,20 @@ #define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \ (unsigned long)ZERO_SIZE_PTR) +struct kmem_cache; + /* * struct kmem_cache related prototypes */ void __init kmem_cache_init(void); int slab_is_available(void); +struct kmem_cache_ops { + void (*ctor)(void *, struct kmem_cache *, unsigned long); +}; + struct kmem_cache *kmem_cache_create(const char *, size_t, size_t, - unsigned long, - void (*)(void *, struct kmem_cache *, unsigned long)); + unsigned long, const struct kmem_cache_ops *); void kmem_cache_destroy(struct kmem_cache *); int kmem_cache_shrink(struct kmem_cache *); void kmem_cache_free(struct kmem_cache *, void *); @@ -67,9 +72,11 @@ int kmem_ptr_validate(struct kmem_cache * f.e. add ____cacheline_aligned_in_smp to the struct declaration * then the objects will be properly aligned in SMP configurations. */ -#define KMEM_CACHE(__struct, __flags) kmem_cache_create(#__struct,\ - sizeof(struct __struct), __alignof__(struct __struct),\ - (__flags), NULL) +#define KMEM_CACHE_OPS(__struct, __flags, __ops) \ + kmem_cache_create(#__struct, sizeof(struct __struct), \ + __alignof__(struct __struct), (__flags), (__ops)) + +#define KMEM_CACHE(__struct, __flags) KMEM_CACHE_OPS(__struct, __flags, NULL) /* * The largest kmalloc size supported by the slab allocators is Index: linux-2.6/mm/slub.c =================================================================== --- linux-2.6.orig/mm/slub.c 2007-07-29 13:14:12.000000000 -0700 +++ linux-2.6/mm/slub.c 2007-07-29 13:15:18.000000000 -0700 @@ -293,6 +293,9 @@ static inline int check_valid_pointer(st return 1; } +struct kmem_cache_ops slub_default_ops = { +}; + /* * Slow version of get and set free pointer. * @@ -1002,7 +1005,7 @@ static void kmem_cache_open_debug_check( if (s->objsize >= 65535 * sizeof(void *)) { BUG_ON(s->flags & (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | SLAB_DESTROY_BY_RCU)); - BUG_ON(s->ctor); + BUG_ON(s->ops && s->ops->ctor); } else /* @@ -1065,8 +1068,8 @@ static void setup_object(struct kmem_cac void *object) { setup_object_debug(s, page, object); - if (unlikely(s->ctor)) - s->ctor(object, s, 0); + if (unlikely(s->ops && s->ops->ctor)) + s->ops->ctor(object, s, 0); } static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node) @@ -1974,7 +1977,7 @@ static int calculate_sizes(struct kmem_c * then we should never poison the object itself. */ if ((flags & SLAB_POISON) && !(flags & SLAB_DESTROY_BY_RCU) && - !s->ctor) + (!s->ops || !s->ops->ctor)) s->flags |= __OBJECT_POISON; else s->flags &= ~__OBJECT_POISON; @@ -2003,7 +2006,7 @@ static int calculate_sizes(struct kmem_c s->inuse = size; if (((flags & (SLAB_DESTROY_BY_RCU | SLAB_POISON)) || - s->ctor)) { + (s->ops && s->ops->ctor))) { /* * Relocate free pointer after the object if it is not * permitted to overwrite the first word of the object on @@ -2073,11 +2076,11 @@ static int calculate_sizes(struct kmem_c static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags, const char *name, size_t size, size_t align, unsigned long flags, - void (*ctor)(void *, struct kmem_cache *, unsigned long)) + const struct kmem_cache_ops *ops) { memset(s, 0, kmem_size); s->name = name; - s->ctor = ctor; + s->ops = ops; s->objsize = size; s->flags = flags; s->align = align; @@ -2262,7 +2265,7 @@ static struct kmem_cache *create_kmalloc down_write(&slub_lock); if (!kmem_cache_open(s, gfp_flags, name, size, ARCH_KMALLOC_MINALIGN, - flags, NULL)) + flags, &slub_default_ops)) goto panic; list_add(&s->list, &slab_caches); @@ -2613,28 +2616,28 @@ static int slab_unmergeable(struct kmem_ if (slub_nomerge || (s->flags & SLUB_NEVER_MERGE)) return 1; - if (s->ctor) - return 1; - /* * We may have set a slab to be unmergeable during bootstrap. */ if (s->refcount < 0) return 1; + if (s->ops != &slub_default_ops) + return 1; + return 0; } static struct kmem_cache *find_mergeable(size_t size, size_t align, unsigned long flags, - void (*ctor)(void *, struct kmem_cache *, unsigned long)) + const struct kmem_cache_ops *ops) { struct kmem_cache *s; if (slub_nomerge || (flags & SLUB_NEVER_MERGE)) return NULL; - if (ctor) + if (ops != &slub_default_ops) return NULL; size = ALIGN(size, sizeof(void *)); @@ -2668,12 +2671,14 @@ static struct kmem_cache *find_mergeable struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align, unsigned long flags, - void (*ctor)(void *, struct kmem_cache *, unsigned long)) + const struct kmem_cache_ops *ops) { struct kmem_cache *s; + if (!ops) + ops = &slub_default_ops; down_write(&slub_lock); - s = find_mergeable(size, align, flags, ctor); + s = find_mergeable(size, align, flags, ops); if (s) { s->refcount++; /* @@ -2690,7 +2695,7 @@ struct kmem_cache *kmem_cache_create(con s = kmalloc(kmem_size, GFP_KERNEL); if (s) { if (kmem_cache_open(s, GFP_KERNEL, name, - size, align, flags, ctor)) { + size, align, flags, ops)) { list_add(&s->list, &slab_caches); up_write(&slub_lock); if (sysfs_slab_add(s)) @@ -3308,16 +3313,18 @@ static ssize_t order_show(struct kmem_ca } SLAB_ATTR_RO(order); -static ssize_t ctor_show(struct kmem_cache *s, char *buf) +static ssize_t ops_show(struct kmem_cache *s, char *buf) { - if (s->ctor) { - int n = sprint_symbol(buf, (unsigned long)s->ctor); + int x = 0; - return n + sprintf(buf + n, "\n"); + if (s->ops && s->ops->ctor) { + x += sprintf(buf + x, "ctor : "); + x += sprint_symbol(buf + x, (unsigned long)s->ops->ctor); + x += sprintf(buf + x, "\n"); } - return 0; + return x; } -SLAB_ATTR_RO(ctor); +SLAB_ATTR_RO(ops); static ssize_t aliases_show(struct kmem_cache *s, char *buf) { @@ -3552,7 +3559,7 @@ static struct attribute * slab_attrs[] = &slabs_attr.attr, &partial_attr.attr, &cpu_slabs_attr.attr, - &ctor_attr.attr, + &ops_attr.attr, &aliases_attr.attr, &align_attr.attr, &sanity_checks_attr.attr, Index: linux-2.6/mm/slab.c =================================================================== --- linux-2.6.orig/mm/slab.c 2007-07-29 13:14:12.000000000 -0700 +++ linux-2.6/mm/slab.c 2007-07-29 13:15:18.000000000 -0700 @@ -2100,7 +2100,7 @@ static int __init_refok setup_cpu_cache( * @size: The size of objects to be created in this cache. * @align: The required alignment for the objects. * @flags: SLAB flags - * @ctor: A constructor for the objects. + * @ops: Callbacks. * * Returns a ptr to the cache on success, NULL on failure. * Cannot be called within a int, but can be interrupted. @@ -2124,7 +2124,7 @@ static int __init_refok setup_cpu_cache( struct kmem_cache * kmem_cache_create (const char *name, size_t size, size_t align, unsigned long flags, - void (*ctor)(void*, struct kmem_cache *, unsigned long)) + const struct kmem_cache_ops *ops) { size_t left_over, slab_size, ralign; struct kmem_cache *cachep = NULL, *pc; @@ -2353,7 +2353,10 @@ kmem_cache_create (const char *name, siz */ BUG_ON(ZERO_OR_NULL_PTR(cachep->slabp_cache)); } - cachep->ctor = ctor; + if (ops) + cachep->ctor = ops->ctor; + else + cachep->ctor = NULL; cachep->name = name; if (setup_cpu_cache(cachep)) { Index: linux-2.6/mm/slob.c =================================================================== --- linux-2.6.orig/mm/slob.c 2007-07-29 13:14:12.000000000 -0700 +++ linux-2.6/mm/slob.c 2007-07-29 13:15:18.000000000 -0700 @@ -503,7 +503,7 @@ struct kmem_cache { struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align, unsigned long flags, - void (*ctor)(void*, struct kmem_cache *, unsigned long)) + const struct kmem_cache_ops *ops) { struct kmem_cache *c; @@ -517,7 +517,10 @@ struct kmem_cache *kmem_cache_create(con c->size += sizeof(struct slob_rcu); } c->flags = flags; - c->ctor = ctor; + if (ops) + c->ctor = ops->ctor; + else + c->ctor = NULL; /* ignore alignment unless it's forced */ c->align = (flags & SLAB_HWCACHE_ALIGN) ? SLOB_ALIGN : 0; if (c->align < ARCH_SLAB_MINALIGN) Index: linux-2.6/fs/block_dev.c =================================================================== --- linux-2.6.orig/fs/block_dev.c 2007-07-29 13:14:08.000000000 -0700 +++ linux-2.6/fs/block_dev.c 2007-07-29 13:15:18.000000000 -0700 @@ -469,6 +469,10 @@ static void init_once(void * foo, struct inode_init_once(&ei->vfs_inode); } +static struct kmem_cache_ops init_once_cache_ops = { + .ctor = init_once +}; + static inline void __bd_forget(struct inode *inode) { list_del_init(&inode->i_devices); @@ -517,7 +521,7 @@ void __init bdev_cache_init(void) bdev_cachep = kmem_cache_create("bdev_cache", sizeof(struct bdev_inode), 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD|SLAB_PANIC), - init_once); + &init_once_cache_ops); err = register_filesystem(&bd_type); if (err) panic("Cannot register bdev pseudo-fs"); Index: linux-2.6/fs/cifs/cifsfs.c =================================================================== --- linux-2.6.orig/fs/cifs/cifsfs.c 2007-07-29 13:14:08.000000000 -0700 +++ linux-2.6/fs/cifs/cifsfs.c 2007-07-29 13:15:18.000000000 -0700 @@ -712,6 +712,10 @@ cifs_init_once(void *inode, struct kmem_ INIT_LIST_HEAD(&cifsi->lockList); } +static struct kmem_cache_ops cifs_cache_ops = { + .ctor = cifs_init_once +}; + static int cifs_init_inodecache(void) { @@ -719,7 +723,7 @@ cifs_init_inodecache(void) sizeof (struct cifsInodeInfo), 0, (SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD), - cifs_init_once); + &cifs_cache_ops); if (cifs_inode_cachep == NULL) return -ENOMEM; Index: linux-2.6/fs/ext2/super.c =================================================================== --- linux-2.6.orig/fs/ext2/super.c 2007-07-29 13:14:08.000000000 -0700 +++ linux-2.6/fs/ext2/super.c 2007-07-29 13:15:18.000000000 -0700 @@ -168,13 +168,17 @@ static void init_once(void * foo, struct inode_init_once(&ei->vfs_inode); } +static struct kmem_cache_ops init_once_cache_ops = { + .ctor = init_once +}; + static int init_inodecache(void) { ext2_inode_cachep = kmem_cache_create("ext2_inode_cache", sizeof(struct ext2_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD), - init_once); + &init_once_cache_ops); if (ext2_inode_cachep == NULL) return -ENOMEM; return 0; Index: linux-2.6/fs/ext3/super.c =================================================================== --- linux-2.6.orig/fs/ext3/super.c 2007-07-29 13:14:08.000000000 -0700 +++ linux-2.6/fs/ext3/super.c 2007-07-29 13:15:18.000000000 -0700 @@ -484,13 +484,17 @@ static void init_once(void * foo, struct inode_init_once(&ei->vfs_inode); } +static struct kmem_cache_ops init_once_cache_ops = { + .ctor = init_once +}; + static int init_inodecache(void) { ext3_inode_cachep = kmem_cache_create("ext3_inode_cache", sizeof(struct ext3_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD), - init_once); + &init_once_cache_ops); if (ext3_inode_cachep == NULL) return -ENOMEM; return 0; Index: linux-2.6/fs/inode.c =================================================================== --- linux-2.6.orig/fs/inode.c 2007-07-29 13:14:08.000000000 -0700 +++ linux-2.6/fs/inode.c 2007-07-29 13:15:18.000000000 -0700 @@ -216,6 +216,10 @@ static void init_once(void * foo, struct inode_init_once(inode); } +static struct kmem_cache_ops init_once_cache_ops = { + .ctor = init_once +}; + /* * inode_lock must be held */ @@ -262,7 +266,7 @@ EXPORT_SYMBOL(clear_inode); /* * dispose_list - dispose of the contents of a local list - * @head: the head of the list to free +/ * @head: the head of the list to free * * Dispose-list gets a local list with local inodes in it, so it doesn't * need to worry about list corruption and SMP locks. @@ -1388,7 +1392,7 @@ void __init inode_init(unsigned long mem 0, (SLAB_RECLAIM_ACCOUNT|SLAB_PANIC| SLAB_MEM_SPREAD), - init_once); + &init_once_cache_ops); register_shrinker(&icache_shrinker); /* Hash may have been set up in inode_init_early */ Index: linux-2.6/fs/locks.c =================================================================== --- linux-2.6.orig/fs/locks.c 2007-07-29 13:14:08.000000000 -0700 +++ linux-2.6/fs/locks.c 2007-07-29 13:15:18.000000000 -0700 @@ -206,6 +206,10 @@ static void init_once(void *foo, struct locks_init_lock(lock); } +static struct kmem_cache_ops init_once_cache_ops = { + .ctor = init_once +}; + static void locks_copy_private(struct file_lock *new, struct file_lock *fl) { if (fl->fl_ops) { @@ -2276,7 +2280,7 @@ static int __init filelock_init(void) { filelock_cache = kmem_cache_create("file_lock_cache", sizeof(struct file_lock), 0, SLAB_PANIC, - init_once); + &init_once_cache_ops); return 0; } Index: linux-2.6/fs/nfs/inode.c =================================================================== --- linux-2.6.orig/fs/nfs/inode.c 2007-07-29 13:14:08.000000000 -0700 +++ linux-2.6/fs/nfs/inode.c 2007-07-29 13:15:18.000000000 -0700 @@ -1166,13 +1166,17 @@ static void init_once(void * foo, struct nfs4_init_once(nfsi); } +static struct kmem_cache_ops init_once_cache_ops = { + .ctor = init_once +}; + static int __init nfs_init_inodecache(void) { nfs_inode_cachep = kmem_cache_create("nfs_inode_cache", sizeof(struct nfs_inode), 0, (SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD), - init_once); + &init_once_cache_ops); if (nfs_inode_cachep == NULL) return -ENOMEM; Index: linux-2.6/fs/reiserfs/super.c =================================================================== --- linux-2.6.orig/fs/reiserfs/super.c 2007-07-29 13:14:10.000000000 -0700 +++ linux-2.6/fs/reiserfs/super.c 2007-07-29 13:15:18.000000000 -0700 @@ -520,6 +520,10 @@ static void init_once(void *foo, struct #endif } +static struct kmem_cache_ops init_once_cache_ops = { + .ctor = init_once +}; + static int init_inodecache(void) { reiserfs_inode_cachep = kmem_cache_create("reiser_inode_cache", @@ -527,7 +531,7 @@ static int init_inodecache(void) reiserfs_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD), - init_once); + &init_once_cache_ops); if (reiserfs_inode_cachep == NULL) return -ENOMEM; return 0; Index: linux-2.6/fs/xfs/linux-2.6/kmem.h =================================================================== --- linux-2.6.orig/fs/xfs/linux-2.6/kmem.h 2007-07-29 13:14:10.000000000 -0700 +++ linux-2.6/fs/xfs/linux-2.6/kmem.h 2007-07-29 13:15:18.000000000 -0700 @@ -81,7 +81,12 @@ static inline kmem_zone_t * kmem_zone_init_flags(int size, char *zone_name, unsigned long flags, void (*construct)(void *, kmem_zone_t *, unsigned long)) { - return kmem_cache_create(zone_name, size, 0, flags, construct); + struct kmem_cache_ops *ops = + kmalloc(sizeof(struct kmem_cache_ops), GFP_KERNEL); + if (!ops) + return NULL; + + return kmem_cache_create(zone_name, size, 0, flags, ops); } static inline void Index: linux-2.6/ipc/mqueue.c =================================================================== --- linux-2.6.orig/ipc/mqueue.c 2007-07-29 13:14:12.000000000 -0700 +++ linux-2.6/ipc/mqueue.c 2007-07-29 13:15:18.000000000 -0700 @@ -218,6 +218,10 @@ static void init_once(void *foo, struct inode_init_once(&p->vfs_inode); } +static struct kmem_cache_ops init_once_cache_ops = { + .ctor = init_once +}; + static struct inode *mqueue_alloc_inode(struct super_block *sb) { struct mqueue_inode_info *ei; @@ -1253,7 +1257,7 @@ static int __init init_mqueue_fs(void) mqueue_inode_cachep = kmem_cache_create("mqueue_inode_cache", sizeof(struct mqueue_inode_info), 0, - SLAB_HWCACHE_ALIGN, init_once); + SLAB_HWCACHE_ALIGN, &init_once_cache_ops); if (mqueue_inode_cachep == NULL) return -ENOMEM; Index: linux-2.6/kernel/fork.c =================================================================== --- linux-2.6.orig/kernel/fork.c 2007-07-29 13:14:12.000000000 -0700 +++ linux-2.6/kernel/fork.c 2007-07-29 13:15:18.000000000 -0700 @@ -1441,12 +1441,16 @@ static void sighand_ctor(void *data, str INIT_LIST_HEAD(&sighand->signalfd_list); } +static struct kmem_cache_ops sighand_cache_ops = { + .ctor = &sighand_ctor +}; + void __init proc_caches_init(void) { sighand_cachep = kmem_cache_create("sighand_cache", sizeof(struct sighand_struct), 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_DESTROY_BY_RCU, - sighand_ctor); + &sighand_cache_ops); signal_cachep = kmem_cache_create("signal_cache", sizeof(struct signal_struct), 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); Index: linux-2.6/mm/rmap.c =================================================================== --- linux-2.6.orig/mm/rmap.c 2007-07-29 13:14:12.000000000 -0700 +++ linux-2.6/mm/rmap.c 2007-07-29 13:15:18.000000000 -0700 @@ -146,10 +146,15 @@ static void anon_vma_ctor(void *data, st INIT_LIST_HEAD(&anon_vma->head); } +static struct kmem_cache_ops anon_vma_cache_ops = { + .ctor = anon_vma_ctor +}; + void __init anon_vma_init(void) { anon_vma_cachep = kmem_cache_create("anon_vma", sizeof(struct anon_vma), - 0, SLAB_DESTROY_BY_RCU|SLAB_PANIC, anon_vma_ctor); + 0, SLAB_DESTROY_BY_RCU|SLAB_PANIC, + &anon_vma_cache_ops); } /* Index: linux-2.6/mm/shmem.c =================================================================== --- linux-2.6.orig/mm/shmem.c 2007-07-29 13:14:12.000000000 -0700 +++ linux-2.6/mm/shmem.c 2007-07-29 13:15:18.000000000 -0700 @@ -2318,11 +2318,15 @@ static void init_once(void *foo, struct #endif } +static struct kmem_cache_ops init_once_cache_ops = { + .ctor = init_once +}; + static int init_inodecache(void) { shmem_inode_cachep = kmem_cache_create("shmem_inode_cache", sizeof(struct shmem_inode_info), - 0, 0, init_once); + 0, 0, &init_once_cache_ops); if (shmem_inode_cachep == NULL) return -ENOMEM; return 0; Index: linux-2.6/drivers/mtd/ubi/eba.c =================================================================== --- linux-2.6.orig/drivers/mtd/ubi/eba.c 2007-07-29 13:14:05.000000000 -0700 +++ linux-2.6/drivers/mtd/ubi/eba.c 2007-07-29 13:15:18.000000000 -0700 @@ -946,6 +946,10 @@ static void ltree_entry_ctor(void *obj, init_rwsem(&le->mutex); } +static struct kmem_cache_ops ltree_entry_cache_ops = { + .ctor = ltree_entry_ctor +}; + /** * ubi_eba_copy_leb - copy logical eraseblock. * @ubi: UBI device description object @@ -1149,7 +1153,7 @@ int ubi_eba_init_scan(struct ubi_device if (ubi_devices_cnt == 0) { ltree_slab = kmem_cache_create("ubi_ltree_slab", sizeof(struct ltree_entry), 0, - 0, <ree_entry_ctor); + 0, <ree_entry_cache_ops); if (!ltree_slab) return -ENOMEM; } Index: linux-2.6/drivers/usb/mon/mon_text.c =================================================================== --- linux-2.6.orig/drivers/usb/mon/mon_text.c 2007-07-29 13:14:07.000000000 -0700 +++ linux-2.6/drivers/usb/mon/mon_text.c 2007-07-29 13:15:18.000000000 -0700 @@ -340,7 +340,7 @@ static int mon_text_open(struct inode *i snprintf(rp->slab_name, SLAB_NAME_SZ, "mon_text_%p", rp); rp->e_slab = kmem_cache_create(rp->slab_name, sizeof(struct mon_event_text), sizeof(long), 0, - mon_text_ctor); + &mon_text_cache_ops); if (rp->e_slab == NULL) { rc = -ENOMEM; goto err_slab; @@ -727,6 +727,10 @@ static void mon_text_ctor(void *mem, str memset(mem, 0xe5, sizeof(struct mon_event_text)); } +static struct kmem_cache_ops mon_text_cache_ops = { + .ctor = mon_text_ctor +}; + int __init mon_text_init(void) { struct dentry *mondir; Index: linux-2.6/fs/fuse/inode.c =================================================================== --- linux-2.6.orig/fs/fuse/inode.c 2007-07-29 13:14:08.000000000 -0700 +++ linux-2.6/fs/fuse/inode.c 2007-07-29 13:15:18.000000000 -0700 @@ -691,6 +691,10 @@ static void fuse_inode_init_once(void *f inode_init_once(inode); } +static struct kmem_cache_ops fuse_cache_ops = { + .ctor = fuse_inode_init_once +}; + static int __init fuse_fs_init(void) { int err; @@ -706,7 +710,7 @@ static int __init fuse_fs_init(void) fuse_inode_cachep = kmem_cache_create("fuse_inode", sizeof(struct fuse_inode), 0, SLAB_HWCACHE_ALIGN, - fuse_inode_init_once); + &fuse_cache_ops); err = -ENOMEM; if (!fuse_inode_cachep) goto out_unreg2; Index: linux-2.6/fs/udf/super.c =================================================================== --- linux-2.6.orig/fs/udf/super.c 2007-07-29 13:14:10.000000000 -0700 +++ linux-2.6/fs/udf/super.c 2007-07-29 13:15:18.000000000 -0700 @@ -142,13 +142,17 @@ static void init_once(void *foo, struct inode_init_once(&ei->vfs_inode); } +static struct kmem_cache_ops init_once_cache_ops = { + .ctor = init_once +}; + static int init_inodecache(void) { udf_inode_cachep = kmem_cache_create("udf_inode_cache", sizeof(struct udf_inode_info), 0, (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD), - init_once); + &init_once_cache_ops); if (!udf_inode_cachep) return -ENOMEM; return 0; Index: linux-2.6/fs/isofs/inode.c =================================================================== --- linux-2.6.orig/fs/isofs/inode.c 2007-07-29 13:14:08.000000000 -0700 +++ linux-2.6/fs/isofs/inode.c 2007-07-29 13:15:18.000000000 -0700 @@ -80,13 +80,17 @@ static void init_once(void *foo, struct inode_init_once(&ei->vfs_inode); } +static struct kmem_cache_ops init_once_cache_ops = { + .ctor = init_once +}; + static int init_inodecache(void) { isofs_inode_cachep = kmem_cache_create("isofs_inode_cache", sizeof(struct iso_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD), - init_once); + &init_once_cache_ops); if (isofs_inode_cachep == NULL) return -ENOMEM; return 0; Index: linux-2.6/fs/proc/inode.c =================================================================== --- linux-2.6.orig/fs/proc/inode.c 2007-07-29 13:14:10.000000000 -0700 +++ linux-2.6/fs/proc/inode.c 2007-07-29 13:15:18.000000000 -0700 @@ -113,13 +113,17 @@ static void init_once(void * foo, struct inode_init_once(&ei->vfs_inode); } +static struct kmem_cache_ops init_once_cache_ops = { + .ctor = init_once +}; + int __init proc_init_inodecache(void) { proc_inode_cachep = kmem_cache_create("proc_inode_cache", sizeof(struct proc_inode), 0, (SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD), - init_once); + &init_once_cache_ops); if (proc_inode_cachep == NULL) return -ENOMEM; return 0; Index: linux-2.6/include/linux/slub_def.h =================================================================== --- linux-2.6.orig/include/linux/slub_def.h 2007-07-29 13:14:11.000000000 -0700 +++ linux-2.6/include/linux/slub_def.h 2007-07-29 13:15:18.000000000 -0700 @@ -42,6 +42,7 @@ struct kmem_cache { int objects; /* Number of objects in slab */ int refcount; /* Refcount for slab cache destroy */ void (*ctor)(void *, struct kmem_cache *, unsigned long); + const struct kmem_cache_ops *ops; int inuse; /* Offset to metadata */ int align; /* Alignment */ const char *name; /* Name (only for display!) */ Index: linux-2.6/fs/ext4/super.c =================================================================== --- linux-2.6.orig/fs/ext4/super.c 2007-07-29 13:14:08.000000000 -0700 +++ linux-2.6/fs/ext4/super.c 2007-07-29 13:15:18.000000000 -0700 @@ -535,13 +535,17 @@ static void init_once(void * foo, struct inode_init_once(&ei->vfs_inode); } +struct init_once_cache_ops = { + .ctor = init_once +}; + static int init_inodecache(void) { ext4_inode_cachep = kmem_cache_create("ext4_inode_cache", sizeof(struct ext4_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD), - init_once); + &init_once_cache_ops); if (ext4_inode_cachep == NULL) return -ENOMEM; return 0; Index: linux-2.6/lib/idr.c =================================================================== --- linux-2.6.orig/lib/idr.c 2007-07-29 13:14:12.000000000 -0700 +++ linux-2.6/lib/idr.c 2007-07-29 13:16:46.000000000 -0700 @@ -586,11 +586,15 @@ static void idr_cache_ctor(void * idr_la memset(idr_layer, 0, sizeof(struct idr_layer)); } +struct kmem_cache_ops idr_cache_ops = { + .ctor = idr_cache_ctor +}; + static int init_id_cache(void) { if (!idr_layer_cache) idr_layer_cache = kmem_cache_create("idr_layer_cache", - sizeof(struct idr_layer), 0, 0, idr_cache_ctor); + sizeof(struct idr_layer), 0, 0, &idr_cache_ops); return 0; } Index: linux-2.6/lib/radix-tree.c =================================================================== --- linux-2.6.orig/lib/radix-tree.c 2007-07-29 13:14:12.000000000 -0700 +++ linux-2.6/lib/radix-tree.c 2007-07-29 13:15:18.000000000 -0700 @@ -1017,11 +1017,15 @@ static int radix_tree_callback(struct no return NOTIFY_OK; } +static struct kmem_cache_ops radix_cache_ops = { + .ctor = radix_tree_node_ctor +}; + void __init radix_tree_init(void) { radix_tree_node_cachep = kmem_cache_create("radix_tree_node", sizeof(struct radix_tree_node), 0, - SLAB_PANIC, radix_tree_node_ctor); + SLAB_PANIC, &radix_cache_ops); radix_tree_init_maxindex(); hotcpu_notifier(radix_tree_callback, 0); } Index: linux-2.6/net/sunrpc/rpc_pipe.c =================================================================== --- linux-2.6.orig/net/sunrpc/rpc_pipe.c 2007-07-29 13:14:12.000000000 -0700 +++ linux-2.6/net/sunrpc/rpc_pipe.c 2007-07-29 13:15:18.000000000 -0700 @@ -859,6 +859,10 @@ init_once(void * foo, struct kmem_cache rpci->ops = NULL; } +static struct kmem_cache_ops init_once_cache_ops = { + .ctor = init_once +}; + int register_rpc_pipefs(void) { int err; @@ -867,7 +871,7 @@ int register_rpc_pipefs(void) sizeof(struct rpc_inode), 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD), - init_once); + &init_once_cache_ops); if (!rpc_inode_cachep) return -ENOMEM; err = register_filesystem(&rpc_pipe_fs_type); Index: linux-2.6/net/socket.c =================================================================== --- linux-2.6.orig/net/socket.c 2007-07-29 13:14:12.000000000 -0700 +++ linux-2.6/net/socket.c 2007-07-29 13:15:18.000000000 -0700 @@ -264,6 +264,10 @@ static void init_once(void *foo, struct inode_init_once(&ei->vfs_inode); } +struct kmem_cache_ops init_once_cache_ops = { + .ctor = init_once +}; + static int init_inodecache(void) { sock_inode_cachep = kmem_cache_create("sock_inode_cache", @@ -272,7 +276,7 @@ static int init_inodecache(void) (SLAB_HWCACHE_ALIGN | SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD), - init_once); + &init_once_cache_ops); if (sock_inode_cachep == NULL) return -ENOMEM; return 0;