[patch 09/23] SLUB: Add get() and kick() methods

From: Christoph Lameter
Date: Tue Nov 06 2007 - 20:15:38 EST


Add the two methods needed for defragmentation and add the display of the
methods via the proc interface.

Add documentation explaining the use of these methods.

Reviewed-by: Rik van Riel <riel@xxxxxxxxxx>
Signed-off-by: Christoph Lameter <clameter@xxxxxxx>
---
include/linux/slab.h | 3 +++
include/linux/slub_def.h | 31 +++++++++++++++++++++++++++++++
mm/slub.c | 32 ++++++++++++++++++++++++++++++--
3 files changed, 64 insertions(+), 2 deletions(-)

Index: linux-2.6/include/linux/slab.h
===================================================================
--- linux-2.6.orig/include/linux/slab.h 2007-10-17 13:35:53.000000000 -0700
+++ linux-2.6/include/linux/slab.h 2007-11-06 12:37:51.000000000 -0800
@@ -56,6 +56,9 @@ struct kmem_cache *kmem_cache_create(con
void (*)(struct kmem_cache *, void *));
void kmem_cache_destroy(struct kmem_cache *);
int kmem_cache_shrink(struct kmem_cache *);
+void kmem_cache_setup_defrag(struct kmem_cache *s,
+ void *(*get)(struct kmem_cache *, int nr, void **),
+ void (*kick)(struct kmem_cache *, int nr, void **, void *private));
void kmem_cache_free(struct kmem_cache *, void *);
unsigned int kmem_cache_size(struct kmem_cache *);
const char *kmem_cache_name(struct kmem_cache *);
Index: linux-2.6/include/linux/slub_def.h
===================================================================
--- linux-2.6.orig/include/linux/slub_def.h 2007-11-06 12:37:44.000000000 -0800
+++ linux-2.6/include/linux/slub_def.h 2007-11-06 12:37:51.000000000 -0800
@@ -51,6 +51,37 @@ struct kmem_cache {
int objects; /* Number of objects in slab */
int refcount; /* Refcount for slab cache destroy */
void (*ctor)(struct kmem_cache *, void *);
+ /*
+ * Called with slab lock held and interrupts disabled.
+ * No slab operation may be performed in get().
+ *
+ * Parameters passed are the number of objects to process
+ * and an array of pointers to objects for which we
+ * need references.
+ *
+ * Returns a pointer that is passed to the kick function.
+ * If all objects cannot be moved then the pointer may
+ * indicate that this wont work and then kick can simply
+ * remove the references that were already obtained.
+ *
+ * The array passed to get() is also passed to kick(). The
+ * function may remove objects by setting array elements to NULL.
+ */
+ void *(*get)(struct kmem_cache *, int nr, void **);
+
+ /*
+ * Called with no locks held and interrupts enabled.
+ * Any operation may be performed in kick().
+ *
+ * Parameters passed are the number of objects in the array,
+ * the array of pointers to the objects and the pointer
+ * returned by get().
+ *
+ * Success is checked by examining the number of remaining
+ * objects in the slab.
+ */
+ void (*kick)(struct kmem_cache *, int nr, void **, void *private);
+
int inuse; /* Offset to metadata */
int align; /* Alignment */
int defrag_ratio; /*
Index: linux-2.6/mm/slub.c
===================================================================
--- linux-2.6.orig/mm/slub.c 2007-11-06 12:37:47.000000000 -0800
+++ linux-2.6/mm/slub.c 2007-11-06 12:37:51.000000000 -0800
@@ -2760,6 +2760,20 @@ void kfree(const void *x)
}
EXPORT_SYMBOL(kfree);

+void kmem_cache_setup_defrag(struct kmem_cache *s,
+ void *(*get)(struct kmem_cache *, int nr, void **),
+ void (*kick)(struct kmem_cache *, int nr, void **, void *private))
+{
+ /*
+ * Defragmentable slabs must have a ctor otherwise objects may be
+ * in an undetermined state after they are allocated.
+ */
+ BUG_ON(!s->ctor);
+ s->get = get;
+ s->kick = kick;
+}
+EXPORT_SYMBOL(kmem_cache_setup_defrag);
+
static unsigned long count_partial(struct kmem_cache_node *n)
{
unsigned long flags;
@@ -3058,7 +3072,7 @@ static int slab_unmergeable(struct kmem_
if (slub_nomerge || (s->flags & SLUB_NEVER_MERGE))
return 1;

- if (s->ctor)
+ if (s->ctor || s->kick || s->get)
return 1;

/*
@@ -3795,7 +3809,21 @@ static ssize_t ops_show(struct kmem_cach

if (s->ctor) {
x += sprintf(buf + x, "ctor : ");
- x += sprint_symbol(buf + x, (unsigned long)s->ops->ctor);
+ x += sprint_symbol(buf + x, (unsigned long)s->ctor);
+ x += sprintf(buf + x, "\n");
+ }
+
+ if (s->get) {
+ x += sprintf(buf + x, "get : ");
+ x += sprint_symbol(buf + x,
+ (unsigned long)s->get);
+ x += sprintf(buf + x, "\n");
+ }
+
+ if (s->kick) {
+ x += sprintf(buf + x, "kick : ");
+ x += sprint_symbol(buf + x,
+ (unsigned long)s->kick);
x += sprintf(buf + x, "\n");
}
return x;

--
-
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/