Scalable statistics counters with /proc reporting
Subsystems (2)
RFC PATCH 1/1 Scalable statistics counters with /proc reporting
Hello,
Here is another go towards cache friendly scalable statistics counters. This version incorporates /proc reporting, and applies cleanly on 2.5.6.
Recap:
Global shared memory locations are usually used to gather statistics of various events in the kernel. This would typically cause bouncing of cachelines along with serialization overheads for such counters in a SMP scenario. The following patch provides interfaces to gather statistics in a cache friendly manner by using per-cpu data for counters. The patch sits on top of a per-cpu dynamic word allocator, hence these interfaces can be used in dynamically allocated structures, modules etc. Also note that serialization mechanisms for these counters can be done away with if your application can tolerate slightly stale values during reads.
Usage:
Typical usage would be something like this:
struct foo {
char *data;
statctr_t a;
....
....
} foovar;static int __init blah_init_module(void)
{
....
foovar = kmalloc(sizeof (struct foo), GFP_KERNEL);
if(statctr_init(&foovar->a, 0, NULL, "procentryfora")) {
/* could not init .. so cleanup */
blah_cleanup(foovar)
return -ENOMEM;
}
....
}static void __exit blah_exit_module(void)
{
....
statctr_cleanup(&foovar->a);
....
} static void blah_somefunc(void)
{
....
statctr_inc(&foovar->a);
....
}The statctr_init routine takes struct proc_dir_entry *parent as 3rd arg and const char *procname as fourth. If procname is NULL, no proc entry is created, if parent is null, entry if need to be created will be made under /proc/stats. There is also a statctr_ninit routine to initialise an array/ contiguous counters part of packed structures. But they donot provide /proc functionality as yet.
Perfromance studies for such counters have been put up on
http://lse.sf.net/counters/statctr.html
Comments welcome.
Regards,
Kiran.
fs/proc/root.c +2 -0
@@ -19,6 +19,7 @@#include <linux/smp_lock.h> struct proc_dir_entry *proc_net, *proc_bus, *proc_root_fs, *proc_root_driver; +struct proc_dir_entry *proc_stats;#ifdef CONFIG_SYSCTL struct proc_dir_entry *proc_sys_root;
@@ -76,6 +77,7 @@proc_rtas_init ();#endif proc_bus =proc_mkdir ("bus" ,0 ); + proc_stats =proc_mkdir ("stats" ,0 ); }static struct dentry *proc_root_lookup (struct inode * dir,struct dentry * dentry)
include/linux/pcpu_alloc.h +75 -0
75 lines not on this page · raw message
include/linux/statctr.h +186 -0
186 lines not on this page · raw message
init/main.c +2 -0
@@ -27,6 +27,7 @@#include <linux/iobuf.h> #include <linux/bootmem.h> #include <linux/tty.h> +#include <linux/pcpu_alloc.h> #include <asm/io.h> #include <asm/bugs.h>
@@ -412,6 +413,7 @@* make syscalls (and thus be locked). */ smp_init (); +pcpu_ctr_sys_init ();/* Do the rest non-__init'ed, we're now alive */ rest_init ();
kernel/Makefile +2 -2
@@ -10,12 +10,12 @@ O_TARGET := kernel.o export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o \ - printk.o + printk.o statctr.o obj-y = sched.o dma.o fork.o exec_domain.o panic.o printk.o \ module.o exit.o itimer.o info.o time.o softirq.o resource.o \ sysctl.o acct.o capability.o ptrace.o timer.o user.o \ - signal.o sys.o kmod.o context.o + signal.o sys.o kmod.o context.o statctr.o obj-$(CONFIG_UID16) += uid16.o obj-$(CONFIG_MODULES) += ksyms.o
kernel/statctr.c +166 -0
166 lines not on this page · raw message
mm/Makefile +2 -1
@@ -9,11 +9,12 @@ O_TARGET := mm.o -export-objs := shmem.o filemap.o mempool.o page_alloc.o +export-objs := shmem.o filemap.o mempool.o page_alloc.o pcpu_alloc.o obj-y := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \ vmalloc.o slab.o bootmem.o swap.o vmscan.o page_io.o \ page_alloc.o swap_state.o swapfile.o numa.o oom_kill.o \ shmem.o highmem.o mempool.o +obj-$(CONFIG_SMP) += pcpu_alloc.o include $(TOPDIR)/Rules.make
mm/pcpu_alloc.c +346 -0
346 lines not on this page · raw message