From: Pavel Emelyanov <xemul-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
To: Christoph Lameter <clameter-sJ/iWh9BUns@public.gmane.org>
Cc: Linux Containers <containers-qjLDD68F18O7TbgM5vRIOg@public.gmane.org>
Subject: [PATCH 1/4] Add notification about some major slab events
Date: Mon, 17 Sep 2007 16:26:23 +0400 [thread overview]
Message-ID: <46EE726F.1010707@openvz.org> (raw)
In-Reply-To: <46EE70B4.6060902-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
According to Christoph, there are already multiple people who
want to control slab allocations and track memory for various
reasons. So this is an introduction of such a hooks.
The selected method of notification is srcu notifier blocks.
This is selected because the "call" path, i.e. when the
notification is done, is lockless and at the same time
notification handlers can sleep. Neither regular nor atomic
notifiers provide such facilities.
The events tracked are:
1. allocation of an object
2. freeing of an onbject
3. allocation of a new page for objects
4. freeing this page
More events can be added on demand.
The kmem cache marked with SLAB_NOTIFY flag will cause all the
events above to generate notifications. By default no caches
come with this flag.
To preserve the fast-paths and keep the stack from growing
the checks for the flag are made in a separate inline functions
and the actual notification is done in noinline ones.
Hopefully, this looks close to how Christoph sees it :)
Signed-off-by: Pavel Emelyanov <xemul-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
---
include/linux/slab.h | 1
include/linux/slub_def.h | 16 +++++++
mm/slub.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 121 insertions(+), 1 deletion(-)
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 3a5bad3..a3bd620 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -28,6 +28,7 @@
#define SLAB_DESTROY_BY_RCU 0x00080000UL /* Defer freeing slabs to RCU */
#define SLAB_MEM_SPREAD 0x00100000UL /* Spread some memory over cpuset */
#define SLAB_TRACE 0x00200000UL /* Trace allocations and frees */
+#define SLAB_NOTIFY 0x00400000UL /* Notify major events */
/* The following flags affect the page allocator grouping pages by mobility */
#define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* Objects are reclaimable */
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index d65159d..547777e 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -200,4 +202,20 @@ static __always_inline void *kmalloc_nod
}
#endif
+struct slub_notify_struct {
+ struct kmem_cache *cachep;
+ void *objp;
+ gfp_t gfp;
+};
+
+enum {
+ SLUB_ALLOC,
+ SLUB_FREE,
+ SLUB_NEWPAGE,
+ SLUB_FREEPAGE,
+};
+
+int slub_register_notifier(struct notifier_block *nb);
+void slub_unregister_notifier(struct notifier_block *nb);
+
#endif /* _LINUX_SLUB_DEF_H */
diff --git a/mm/slub.c b/mm/slub.c
index 1802645..bfb7c21 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1013,6 +1013,91 @@ static inline void add_full(struct kmem_
static inline void kmem_cache_open_debug_check(struct kmem_cache *s) {}
#define slub_debug 0
#endif
+
+/*
+ * notifiers
+ */
+
+static struct srcu_notifier_head slub_nb;
+
+static noinline
+int __slub_alloc_notify(int cmd_alloc, int cmd_free, struct kmem_cache *cachep,
+ void *obj, gfp_t gfp)
+{
+ int ret, called;
+ struct slub_notify_struct arg;
+
+ arg.cachep = cachep;
+ arg.objp = obj;
+ arg.gfp = gfp;
+
+ ret = __srcu_notifier_call_chain(&slub_nb, cmd_alloc, &arg,
+ -1, &called);
+ ret = notifier_to_errno(ret);
+
+ if (ret < 0)
+ __srcu_notifier_call_chain(&slub_nb, cmd_free, &arg,
+ called, NULL);
+
+ return ret;
+}
+
+static noinline
+void __slub_free_notify(int cmd, struct kmem_cache *cachep, void *obj)
+{
+ struct slub_notify_struct arg;
+
+ arg.cachep = cachep;
+ arg.objp = obj;
+ arg.gfp = 0;
+
+ srcu_notifier_call_chain(&slub_nb, cmd, &arg);
+}
+
+int slub_register_notifier(struct notifier_block *nb)
+{
+ return srcu_notifier_chain_register(&slub_nb, nb);
+}
+
+void slub_unregister_notifier(struct notifier_block *nb)
+{
+ srcu_notifier_chain_unregister(&slub_nb, nb);
+}
+
+/*
+ * fastpath hooks
+ */
+
+static inline
+int slub_alloc_notify(struct kmem_cache *cachep, void *obj, gfp_t gfp)
+{
+ return (unlikely(cachep->flags & SLAB_NOTIFY)) ?
+ __slub_alloc_notify(SLUB_ALLOC, SLUB_FREE,
+ cachep, obj, gfp) : 0;
+}
+
+static inline
+void slub_free_notify(struct kmem_cache *cachep, void *obj)
+{
+ if (unlikely(cachep->flags & SLAB_NOTIFY))
+ __slub_free_notify(SLUB_FREE, cachep, obj);
+}
+
+static inline
+int slub_newpage_notify(struct kmem_cache *cachep, struct page *pg, gfp_t gfp)
+{
+ return (unlikely(cachep->flags & SLAB_NOTIFY)) ?
+ __slub_alloc_notify(SLUB_NEWPAGE, SLUB_FREEPAGE,
+ cachep, pg, gfp) : 0;
+}
+
+static inline
+void slub_freepage_notify(struct kmem_cache *cachep, struct page *pg)
+{
+ if (unlikely(cachep->flags & SLAB_NOTIFY))
+ __slub_free_notify(SLUB_FREEPAGE, cachep, pg);
+}
+
/*
* Slab allocation and freeing
*/
@@ -1036,7 +1121,10 @@ static struct page *allocate_slab(struct
page = alloc_pages_node(node, flags, s->order);
if (!page)
- return NULL;
+ goto out;
+
+ if (slub_newpage_notify(s, page, flags) < 0)
+ goto out_free;
mod_zone_page_state(page_zone(page),
(s->flags & SLAB_RECLAIM_ACCOUNT) ?
@@ -1044,6 +1132,11 @@ static struct page *allocate_slab(struct
pages);
return page;
+
+out_free:
+ __free_pages(page, s->order);
+out:
+ return NULL;
}
static void setup_object(struct kmem_cache *s, struct page *page,
@@ -1136,6 +1229,8 @@ static void rcu_free_slab(struct rcu_hea
static void free_slab(struct kmem_cache *s, struct page *page)
{
+ slub_freepage_notify(s, page);
+
if (unlikely(s->flags & SLAB_DESTROY_BY_RCU)) {
/*
* RCU free overloads the RCU head over the LRU
@@ -1555,6 +1650,11 @@ static void __always_inline *slab_alloc(
}
local_irq_restore(flags);
+ if (object && slub_alloc_notify(s, object, gfpflags) < 0) {
+ kmem_cache_free(s, object);
+ return NULL;
+ }
+
if (unlikely((gfpflags & __GFP_ZERO) && object))
memset(object, 0, c->objsize);
@@ -1651,6 +1751,8 @@ static void __always_inline slab_free(st
unsigned long flags;
struct kmem_cache_cpu *c;
+ slub_free_notify(s, x);
+
local_irq_save(flags);
debug_check_no_locks_freed(object, s->objsize);
c = get_cpu_slab(s, smp_processor_id());
@@ -2764,6 +2874,7 @@ void __init kmem_cache_init(void)
kmem_size = sizeof(struct kmem_cache);
#endif
+ srcu_init_notifier_head(&slub_nb);
printk(KERN_INFO "SLUB: Genslabs=%d, HWalign=%d, Order=%d-%d, MinObjects=%d,"
" CPUs=%d, Nodes=%d\n",
next prev parent reply other threads:[~2007-09-17 12:26 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-17 12:19 [PATCH 0/4] Kernel memory accounting container (v3) Pavel Emelyanov
[not found] ` <46EE70B4.6060902-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-09-17 12:26 ` Pavel Emelyanov [this message]
[not found] ` <46EE726F.1010707-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-09-17 18:25 ` [PATCH 1/4] Add notification about some major slab events Christoph Lameter
[not found] ` <Pine.LNX.4.64.0709171122150.27057-RYO/mD75kfhx2SFC9UQUAuF7EQX82lMiAL8bYrjMMd8@public.gmane.org>
2007-09-18 8:03 ` Pavel Emelyanov
[not found] ` <46EF865F.4050409-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-09-18 19:35 ` Christoph Lameter
2007-09-19 10:08 ` Pavel Emelyanov
[not found] ` <46F0F520.1010804-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-09-19 17:45 ` Christoph Lameter
2007-09-17 12:30 ` [PATCH 2/4] Switch caches notification dynamically Pavel Emelyanov
[not found] ` <46EE7375.3040902-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-09-17 18:29 ` Christoph Lameter
[not found] ` <Pine.LNX.4.64.0709171128380.27057-RYO/mD75kfhx2SFC9UQUAuF7EQX82lMiAL8bYrjMMd8@public.gmane.org>
2007-09-18 6:51 ` Pavel Emelyanov
2007-09-17 18:32 ` Christoph Lameter
[not found] ` <Pine.LNX.4.64.0709171130470.27057-RYO/mD75kfhx2SFC9UQUAuF7EQX82lMiAL8bYrjMMd8@public.gmane.org>
2007-09-18 6:54 ` Pavel Emelyanov
[not found] ` <46EF7610.1060302-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-09-18 19:36 ` Christoph Lameter
2007-09-17 12:33 ` [PATCH 3/4] Setup the container Pavel Emelyanov
2007-09-17 12:35 ` [PATCH 4/4] Account for the slub objects Pavel Emelyanov
[not found] ` <46EE74AF.70105-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-09-17 16:08 ` Dave Hansen
2007-09-18 6:27 ` Pavel Emelyanov
2007-09-17 16:09 ` Dave Hansen
2007-09-18 6:28 ` Pavel Emelyanov
2007-09-17 18:27 ` [PATCH 0/4] Kernel memory accounting container (v3) Christoph Lameter
[not found] ` <Pine.LNX.4.64.0709171126330.27057-RYO/mD75kfhx2SFC9UQUAuF7EQX82lMiAL8bYrjMMd8@public.gmane.org>
2007-09-17 20:51 ` Balbir Singh
[not found] ` <46EEE8B7.2070805-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2007-09-17 21:19 ` Christoph Lameter
[not found] ` <Pine.LNX.4.64.0709171417330.28926-RYO/mD75kfhx2SFC9UQUAuF7EQX82lMiAL8bYrjMMd8@public.gmane.org>
2007-09-18 6:56 ` Pavel Emelyanov
2007-09-18 6:25 ` Pavel Emelyanov
[not found] ` <46EF6F6C.60702-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-09-18 19:37 ` Christoph Lameter
-- strict thread matches above, loose matches on Subject: below --
2007-09-21 9:14 [PATCH 0/5] Kernel memory accounting container (v4) Pavel Emelyanov
[not found] ` <46F38B67.3020609-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-09-21 9:17 ` [PATCH 1/4] Add notification about some major slab events Pavel Emelyanov
[not found] ` <46F38C1D.2080902-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-09-24 21:05 ` Christoph Lameter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=46EE726F.1010707@openvz.org \
--to=xemul-gefaqzzx7r8dnm+yrofe0a@public.gmane.org \
--cc=clameter-sJ/iWh9BUns@public.gmane.org \
--cc=containers-qjLDD68F18O7TbgM5vRIOg@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.