All of lore.kernel.org
 help / color / mirror / Atom feed
From: Masami Hiramatsu <mhiramat@redhat.com>
To: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>,
	Ingo Molnar <mingo@elte.hu>, Jim Keniston <jkenisto@us.ibm.com>,
	LKML <linux-kernel@vger.kernel.org>,
	systemtap-ml <systemtap@sources.redhat.com>
Subject: Re: [RFC][PATCH -tip 8/9] kprobes: support respawn probes for	module probing
Date: Thu, 19 Mar 2009 23:48:22 -0400	[thread overview]
Message-ID: <49C31206.3060806@redhat.com> (raw)
In-Reply-To: <20090320011929.GE6895@nowhere>

Frederic Weisbecker wrote:
>> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
>> index 5016bfb..f16a54e 100644
>> --- a/kernel/kprobes.c
>> +++ b/kernel/kprobes.c
>> @@ -1416,6 +1416,256 @@ static int __kprobes debugfs_kprobe_init(void)
>>  late_initcall(debugfs_kprobe_init);
>>  #endif /* CONFIG_DEBUG_FS */
>>
>> +/* Kprobes module respawn support */
>> +enum probe_type {
>> +	PROBE_TYPE_KPROBE,
>> +	PROBE_TYPE_KRETPROBE,
>> +	PROBE_TYPE_JPROBE,
>> +};
>> +
>> +struct module_probe_client {
>> +	struct list_head list;
>> +	const char *module;	/* including symbol name */
>> +	int active;
>> +	void *data;
>> +	probe_activate_handler_t handler;
>> +	enum probe_type type;
>> +	union {
>> +		struct kprobe *kp;
>> +		struct kretprobe *rp;
>> +		struct jprobe *jp;
>> +	};
>> +};
>> +
>> +static DEFINE_MUTEX(module_probe_mutex);
>> +static LIST_HEAD(module_probe_list);
>> +
>> +static int activate_module_probe(struct module_probe_client *pc)
>> +{
>> +	int ret = 0;
>> +	if (pc->active)
>> +		return 0;
>> +	switch (pc->type) {
>> +	case PROBE_TYPE_KPROBE:
>> +		ret = register_kprobe(pc->kp);
>> +		break;
>> +	case PROBE_TYPE_KRETPROBE:
>> +		ret = register_kretprobe(pc->rp);
>> +		break;
>> +	case PROBE_TYPE_JPROBE:
>> +		ret = register_jprobe(pc->jp);
>> +		break;
>> +	default:
>> +		WARN_ON(1);
>> +		break;
>> +	}
>> +	if (!ret)
>> +		pc->active = 1;
>> +	return ret;
>> +}
>> +
>> +static void deactivate_module_probe(struct module_probe_client *pc)
>> +{
>> +	if (!pc->active)
>> +		return;
>> +	switch (pc->type) {
>> +	case PROBE_TYPE_KPROBE:
>> +		unregister_kprobe(pc->kp);
>> +		break;
>> +	case PROBE_TYPE_KRETPROBE:
>> +		unregister_kretprobe(pc->rp);
>> +		break;
>> +	case PROBE_TYPE_JPROBE:
>> +		unregister_jprobe(pc->jp);
>> +		break;
>> +	default:
>> +		WARN_ON(1);
>> +		break;
>> +	}
>> +	pc->active = 0;
>> +}
>> +
>> +static const char *probed_module_name(struct kprobe *kp)
>> +{
>> +	if ((kp->symbol_name) && strchr(kp->symbol_name, ':'))
>> +		return kp->symbol_name;
>> +	return NULL;
>> +}
>> +
>> +static int module_is_exist(const char *module)
>> +{
>> +	char buf[MODULE_NAME_LEN + 8];
>> +	snprintf(buf, MODULE_NAME_LEN + 8, "%s:__stext", module);
>> +	return module_kallsyms_lookup_name(buf) ? 1 : 0;
>> +}
>> +
>> +static int add_module_probe(const char *module, void *p, enum probe_type type,
>> +			    probe_activate_handler_t handler, void *data)
>> +{
>> +	struct module_probe_client *pc;
>> +	int ret = 0;
>> +
>> +	if (!handler)
>> +		return -EINVAL;
>> +
>> +	pc = kzalloc(sizeof(struct module_probe_client), GFP_KERNEL);
>> +	pc->kp = p;
>> +	pc->type = type;
>> +	pc->module = module;
>> +	pc->handler = handler;
>> +	pc->data = data;
>> +	INIT_LIST_HEAD(&pc->list);
>> +
>> +	mutex_lock(&module_probe_mutex);
>> +	if (module_is_exist(module))
>> +		ret = activate_module_probe(pc);
>> +	if (ret)
>> +		kfree(pc);
>> +	else
>> +		list_add_tail(&pc->list, &module_probe_list);
>> +	mutex_unlock(&module_probe_mutex);
>> +	return ret;
>> +}
>> +
>> +static void __del_module_probe(struct module_probe_client *pc)
>> +{
>> +	list_del(&pc->list);
>> +	deactivate_module_probe(pc);
>> +	kfree(pc);
>> +}
>> +
>> +static int del_module_probe(void *p)
>> +{
>> +	struct module_probe_client *pc;
>> +	int ret;
>> +
>> +	mutex_lock(&module_probe_mutex);
>> +	list_for_each_entry(pc, &module_probe_list, list)
>> +		if (pc->kp == p) {
>> +			/* don't need safe loop, we exit soon */
>> +			__del_module_probe(pc);
>> +			goto found;
>> +		}
>> +	ret = -ENOENT;
>> +found:
>> +	mutex_unlock(&module_probe_mutex);
>> +	return ret;
>> +}
>> +
>> +int __kprobes
>> +register_module_kprobe(struct kprobe *kp,
>> +		       probe_activate_handler_t handler, void *data)
>> +{
>> +	const char *module;
>> +	module = probed_module_name(kp);
>> +	if (!module)
>> +		return register_kprobe(kp);
>> +	return add_module_probe(module, kp, PROBE_TYPE_KPROBE,
>> +				handler, data);
>> +}
>> +EXPORT_SYMBOL_GPL(register_module_kprobe);
>> +
>> +int __kprobes
>> +register_module_kretprobe(struct kretprobe *rp,
>> +			  probe_activate_handler_t handler, void *data)
>> +{
>> +	const char *module;
>> +	module = probed_module_name(&rp->kp);
>> +	if (!module)
>> +		return register_kretprobe(rp);
>> +	return add_module_probe(module, rp, PROBE_TYPE_KRETPROBE,
>> +				handler, data);
>> +}
>> +EXPORT_SYMBOL_GPL(register_module_kretprobe);
>> +
>> +int __kprobes
>> +register_module_jprobe(struct jprobe *jp,
>> +		       probe_activate_handler_t handler, void *data)
>> +{
>> +	const char *module;
>> +	module = probed_module_name(&jp->kp);
>> +	if (!module)
>> +		return register_jprobe(jp);
>> +	return add_module_probe(module, jp, PROBE_TYPE_JPROBE,
>> +				handler, data);
>> +}
>> +EXPORT_SYMBOL_GPL(register_module_jprobe);
>> +
>> +void __kprobes unregister_module_kprobe(struct kprobe *kp)
>> +{
>> +	const char *module;
>> +	module = probed_module_name(kp);
>> +	if (!module)
>> +		unregister_kprobe(kp);
>> +	else
>> +		del_module_probe(kp);
>> +}
>> +EXPORT_SYMBOL_GPL(unregister_module_kprobe);
>> +
>> +void __kprobes unregister_module_kretprobe(struct kretprobe *rp)
>> +{
>> +	const char *module;
>> +	module = probed_module_name(&rp->kp);
>> +	if (!module)
>> +		unregister_kretprobe(rp);
>> +	else
>> +		del_module_probe(rp);
>> +}
>> +EXPORT_SYMBOL_GPL(unregister_module_kretprobe);
>> +
>> +void __kprobes unregister_module_jprobe(struct jprobe *jp)
>> +{
>> +	const char *module;
>> +	module = probed_module_name(&jp->kp);
>> +	if (!module)
>> +		unregister_jprobe(jp);
>> +	else
>> +		del_module_probe(jp);
>> +}
>> +EXPORT_SYMBOL_GPL(unregister_module_jprobe);
>> +
>> +static int module_is_probed(const char *mod, const char *sym)
>> +{
>> +	int len = strlen(mod);
>> +	return strncmp(mod, sym, len) == 0 && sym[len] == ':';
>> +}
>> +
>> +static int module_probe_callback(struct notifier_block *nb,
>> +				 unsigned long state, void *module)
>> +{
>> +	struct module_probe_client *pc;
>> +	struct module *mod = module;
>> +	if (state == MODULE_STATE_LIVE)
>> +		return NOTIFY_DONE;
>> +
>> +	mutex_lock(&module_probe_mutex);
>> +	list_for_each_entry(pc, &module_probe_list, list) {
>> +		if (!module_is_probed(mod->name, pc->module))
>> +			continue;
>> +		if (state == MODULE_STATE_COMING &&
>> +		    pc->handler(pc->data, module)) {
> 
> 
> I don't see a place where you check if pc->handler != NULL
> May be you could attach a stub in such cases.

Please see add_module_probe(), handler == NULL case returns -EINVAL,
and module_probe_list is internal list. So, pc->handler never be NULL.

Thank you,

-- 
Masami Hiramatsu

Software Engineer
Hitachi Computer Products (America) Inc.
Software Solutions Division

e-mail: mhiramat@redhat.com


  reply	other threads:[~2009-03-20  3:48 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-19 21:10 [RFC][PATCH -tip 8/9] kprobes: support respawn probes for module probing Masami Hiramatsu
2009-03-20  1:11 ` Frederic Weisbecker
2009-03-20  3:52   ` Masami Hiramatsu
2009-03-20  1:19 ` Frederic Weisbecker
2009-03-20  3:48   ` Masami Hiramatsu [this message]
2009-03-21  0:08     ` Frederic Weisbecker

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=49C31206.3060806@redhat.com \
    --to=mhiramat@redhat.com \
    --cc=ananth@in.ibm.com \
    --cc=fweisbec@gmail.com \
    --cc=jkenisto@us.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=systemtap@sources.redhat.com \
    /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.