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 2/5] Generic notifiers for SLUB events
Date: Fri, 21 Sep 2007 13:19:58 +0400 [thread overview]
Message-ID: <46F38CBE.8050601@openvz.org> (raw)
In-Reply-To: <46F38B67.3020609-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
If the user wants more than one listener for SLUB event,
it can register them all as notifier_block-s so all of
them will be notified.
This costs us about 10% of performance loss, in comparison
with static linking.
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 the
handlers can sleep. Neither regular nor atomic notifiers
provide such facilities.
Signed-off-by: Pavel Emelyanov <xemul-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
---
diff --git a/init/Kconfig b/init/Kconfig
index 0bb211a..326fd55 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -593,6 +599,16 @@ config SLUB_DEBUG
SLUB sysfs support. /sys/slab will not exist and there will be
no support for cache validation etc.
+config SLUB_NOTIFY
+ default y
+ bool "Enable SLUB events generic notification"
+ depends on SLUB
+ help
+ When Y, this option enables generic notifications of some major
+ slub events. However, if you do know that there will be the
+ only listener for them, you may say N here, so that callbacks
+ will be called directly.
+
choice
prompt "Choose SLAB allocator"
default SLUB
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index 40801e7..fd9a3d4 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 ac4f157..b5af598 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1040,6 +1040,81 @@ static inline unsigned long kmem_cache_f
#define slub_debug 0
#endif
+/*
+ * notifiers
+ */
+
+#ifdef CONFIG_SLUB_NOTIFY
+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);
+}
+
+static inline
+int slub_alloc_notify(struct kmem_cache *cachep, void *obj, gfp_t gfp)
+{
+ return __slub_alloc_notify(SLUB_ALLOC, SLUB_FREE, cachep, obj, gfp);
+}
+
+static inline
+void slub_free_notify(struct kmem_cache *cachep, void *obj)
+{
+ __slub_free_notify(SLUB_FREE, cachep, obj);
+}
+
+static inline
+int slub_newpage_notify(struct kmem_cache *cachep, struct page *pg, gfp_t gfp)
+{
+ return __slub_alloc_notify(SLUB_NEWPAGE, SLUB_FREEPAGE, cachep, pg, gfp);
+}
+
+static inline
+void slub_freepage_notify(struct kmem_cache *cachep, struct page *pg)
+{
+ __slub_free_notify(SLUB_FREEPAGE, cachep, pg);
+}
+#else
int __attribute__ ((weak))
slub_alloc_notify(struct kmem_cache *cachep, void *obj, gfp_t gfp)
{
@@ -1060,6 +1040,7 @@ static inline unsigned long kmem_cache_f
slub_freepage_notify(struct kmem_cache *cachep, struct page *pg)
{
}
+#endif
/*
* Slab allocation and freeing
@@ -2785,8 +2916,9 @@ void __init kmem_cache_init(void)
#else
kmem_size = sizeof(struct kmem_cache);
#endif
-
-
+#ifdef CONFIG_SLUB_NOTIFY
+ srcu_init_notifier_head(&slub_nb);
+#endif
printk(KERN_INFO "SLUB: Genslabs=%d, HWalign=%d, Order=%d-%d, MinObjects=%d,"
" CPUs=%d, Nodes=%d\n",
caches, cache_line_size(),
next prev parent reply other threads:[~2007-09-21 9:19 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
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
2007-09-21 9:19 ` Pavel Emelyanov [this message]
2007-09-21 9:22 ` [PATCH 3/5] Switch caches notification dynamically Pavel Emelyanov
[not found] ` <46F38D3B.2050608-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-09-24 21:07 ` Christoph Lameter
[not found] ` <Pine.LNX.4.64.0709241406280.30982-RYO/mD75kfhx2SFC9UQUAuF7EQX82lMiAL8bYrjMMd8@public.gmane.org>
2007-09-25 7:46 ` Pavel Emelyanov
2007-09-21 9:23 ` [PATCH 4/5] Setup the container Pavel Emelyanov
2007-09-21 9:24 ` [PATCH 5/5] Account for the slub objects Pavel Emelyanov
2007-09-21 12:23 ` [PATCH 0/5] Kernel memory accounting container (v4) Balbir Singh
-- strict thread matches above, loose matches on Subject: below --
2007-09-25 14:16 [PATCH 0/5] Kernel memory accounting container (v5) Pavel Emelyanov
[not found] ` <46F91841.9070708-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-09-25 14:19 ` [PATCH 2/5] Generic notifiers for SLUB events Pavel Emelyanov
[not found] ` <46F918D9.3020406-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-10-01 13:05 ` Balbir Singh
[not found] ` <4700F083.1070706-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2007-10-01 13:07 ` Pavel Emelyanov
[not found] ` <4700F120.2070302-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-10-01 20:39 ` 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=46F38CBE.8050601@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.