#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/notifier.h>
#include <linux/kmemprof.h>

MODULE_LICENSE("GPL");

#define OBJFILTER_SIZE 128

static char * objfilter[OBJFILTER_SIZE];
MODULE_PARM(objfilter, "1-" __MODULE_STRING(OBJFILTER_SIZE) "s");

static int through_objfilter (const char * objname)
{
	int i;
	for (i = 0; i < OBJFILTER_SIZE && objfilter[i]; i++) {
		if (!strcmp(objname, objfilter[i]))
			return 1;
	}
	return 0;
}

static int kmemprof_objfilter (struct notifier_block * self, unsigned long val,
				void * arg)
{
	struct kmemprof_event * event = (struct kmemprof_event *) arg;
	int ret = NOTIFY_OK;

	if (!through_objfilter(kmem_cache_name(event->cache))) {
		ret |= NOTIFY_STOP_MASK;
	}

	return ret;
}

static struct notifier_block objfilter_nb = {
	.notifier_call = &kmemprof_objfilter,
	.priority = 10
};

static int __init mymodule_init(void)
{
	int i;

	for (i = 0; i < OBJFILTER_SIZE && objfilter[i]; i++) {
		printk("objfilter: %s\n", objfilter[i]);
	}
	kmemprof_notifier_chain_register(&objfilter_nb);

	return 0;
}

static void __exit mymodule_exit(void)
{
	kmemprof_notifier_chain_unregister(&objfilter_nb);
}

module_init(mymodule_init);
module_exit(mymodule_exit);

