From: Josh Poimboeuf <jpoimboe@redhat.com>
To: Petr Mladek <pmladek@suse.cz>
Cc: Seth Jennings <sjenning@redhat.com>,
Jiri Kosina <jkosina@suse.cz>,
Rusty Russell <rusty@rustcorp.com.au>,
Miroslav Benes <mbenes@suse.cz>,
Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>,
mingo@kernel.org, mathieu.desnoyers@efficios.com,
oleg@redhat.com, paulmck@linux.vnet.ibm.com,
linux-kernel@vger.kernel.org, andi@firstfloor.org,
rostedt@goodmis.org, tglx@linutronix.de
Subject: Re: [RFC PATCH] livepatch/module: Do not patch modules that are not ready
Date: Tue, 3 Mar 2015 13:31:28 -0600 [thread overview]
Message-ID: <20150303193128.GA31987@treble.redhat.com> (raw)
In-Reply-To: <20150303173456.GH3703@dhcp128.suse.cz>
On Tue, Mar 03, 2015 at 06:34:57PM +0100, Petr Mladek wrote:
> Ah, I have missed the comments in the code in the first reply.
> > Why do we need two flags for this? The notifer already
> > sets/clears obj->mod, so can we rely on the value obj->mod to determine
> > if the notifier already ran?
>
> We need this for new patches. There we do not know if the module
> notifier has already been called or not, see also below.
>
> Of course, we might use more optimal storage for the two flags
> if requested. For example, two bits in an unsigned char.
>
>
> > For example:
> >
> > @@ -89,7 +89,7 @@ static bool klp_is_object_loaded(struct klp_object *obj)
> > /* sets obj->mod if object is not vmlinux and module is found */
> > static void klp_find_object_module(struct klp_object *obj)
> > {
> > - if (!klp_is_module(obj))
> > + if (!klp_is_module(obj) || obj->mod)
> > return;
> >
> > mutex_lock(&module_mutex);
> > @@ -98,7 +98,9 @@ static void klp_find_object_module(struct klp_object *obj)
> > * the klp_mutex, which is also taken by the module notifier. This
> > * prevents any module from unloading until we release the klp_mutex.
> > */
> > - obj->mod = find_module(obj->name);
> > + mod = find_module(obj->name);
> > + if (mod->state == MODULE_STATE_LIVE)
>
> The check of the MODULE_STATE_LIVE is not enough. We need to init
> modules when a new patch is registered, the module is still in
> MODULE_STATE_COMING and the module notify handler has already
> been called.
Ok, thanks for explaining. I think I got it now. But the two module
flags aren't ideal.
MODULE_STATE_COMING means that ftrace is already initialized, so I think
it doesn't _have_ to be the notifier which does the work. Instead, can
we just let it be done by whoever gets there first? Like this:
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 01ca088..05390ab 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -89,16 +89,29 @@ static bool klp_is_object_loaded(struct klp_object *obj)
/* sets obj->mod if object is not vmlinux and module is found */
static void klp_find_object_module(struct klp_object *obj)
{
- if (!klp_is_module(obj))
+ struct module *mod;
+
+ if (!klp_is_module(obj) || obj->mod)
return;
mutex_lock(&module_mutex);
+
/*
* We don't need to take a reference on the module here because we have
* the klp_mutex, which is also taken by the module notifier. This
* prevents any module from unloading until we release the klp_mutex.
*/
- obj->mod = find_module(obj->name);
+ mod = find_module(obj->name);
+
+ /*
+ * MODULE_STATE_COMING means we got to the module first before the
+ * notifier did. ftrace is already initialized, so it's fine to go
+ * ahead and start using it.
+ */
+ if (mod->state == MODULE_STATE_COMING ||
+ mod->state == MODULE_STATE_LIVE)
+ obj->mod = mod;
+
mutex_unlock(&module_mutex);
}
@@ -697,8 +710,6 @@ static void klp_free_object_loaded(struct klp_object *obj)
{
struct klp_func *func;
- obj->mod = NULL;
-
for (func = obj->funcs; func->old_name; func++)
func->old_addr = 0;
}
@@ -967,10 +978,31 @@ static int klp_module_notify(struct notifier_block *nb, unsigned long action,
continue;
if (action == MODULE_STATE_COMING) {
+
+ /*
+ * There's a small window where a register or
+ * enable call may have already done this
+ * initialization. First one there wins.
+ */
+ if (obj->mod)
+ continue;
+
obj->mod = mod;
klp_module_notify_coming(patch, obj);
- } else /* MODULE_STATE_GOING */
+ } else {
+ /* MODULE_STATE_GOING */
+
+ /*
+ * There's a small window where a register or
+ * enable call may have already done this
+ * teardown. First one there wins.
+ */
+ if (!obj->mod)
+ continue;
+
klp_module_notify_going(patch, obj);
+ obj->mod = NULL;
+ }
break;
}
next prev parent reply other threads:[~2015-03-03 19:32 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-03 11:38 [RFC PATCH] livepatch/module: Do not patch modules that are not ready Petr Mladek
2015-03-03 14:55 ` Josh Poimboeuf
2015-03-03 15:48 ` Petr Mladek
2015-03-03 16:01 ` Josh Poimboeuf
2015-03-03 17:34 ` Petr Mladek
2015-03-03 19:31 ` Josh Poimboeuf [this message]
2015-03-03 19:35 ` Josh Poimboeuf
2015-03-03 23:02 ` [PATCH 0/2] livepatch: fix patch module loading race Josh Poimboeuf
2015-03-03 23:02 ` [PATCH 1/2] livepatch: remove unnecessary call to klp_find_object_module() Josh Poimboeuf
2015-03-04 9:00 ` Petr Mladek
2015-03-04 21:48 ` Jiri Kosina
2015-03-03 23:02 ` [PATCH 2/2] livepatch: fix patched module loading race Josh Poimboeuf
2015-03-04 13:17 ` Petr Mladek
2015-03-04 14:18 ` Petr Mladek
2015-03-04 15:34 ` Josh Poimboeuf
2015-03-04 15:51 ` Jiri Kosina
2015-03-04 16:41 ` Josh Poimboeuf
2015-03-04 16:36 ` Petr Mladek
2015-03-04 17:57 ` Josh Poimboeuf
2015-03-04 22:02 ` Jiri Kosina
2015-03-04 22:45 ` Josh Poimboeuf
2015-03-05 0:52 ` Masami Hiramatsu
2015-03-05 14:18 ` Josh Poimboeuf
2015-03-06 1:24 ` Masami Hiramatsu
2015-03-06 10:51 ` Petr Mladek
2015-03-06 11:37 ` Masami Hiramatsu
2015-03-06 13:05 ` Petr Mladek
2015-03-06 14:43 ` Josh Poimboeuf
2015-03-05 14:24 ` Petr Mladek
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=20150303193128.GA31987@treble.redhat.com \
--to=jpoimboe@redhat.com \
--cc=andi@firstfloor.org \
--cc=jkosina@suse.cz \
--cc=linux-kernel@vger.kernel.org \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mathieu.desnoyers@efficios.com \
--cc=mbenes@suse.cz \
--cc=mingo@kernel.org \
--cc=oleg@redhat.com \
--cc=paulmck@linux.vnet.ibm.com \
--cc=pmladek@suse.cz \
--cc=rostedt@goodmis.org \
--cc=rusty@rustcorp.com.au \
--cc=sjenning@redhat.com \
--cc=tglx@linutronix.de \
/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.