mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Petr Mladek <pmladek@suse.com>
To: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Jiri Kosina <jikos@kernel.org>, Miroslav Benes <mbenes@suse.cz>,
	Jason Baron <jbaron@akamai.com>,
	Joe Lawrence <joe.lawrence@redhat.com>,
	Jessica Yu <jeyu@kernel.org>,
	Evgenii Shatokhin <eshatokhin@virtuozzo.com>,
	live-patching@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v10 05/10] livepatch: Support separate list for replaced patches.
Date: Mon, 19 Mar 2018 16:02:07 +0100	[thread overview]
Message-ID: <20180319150207.iz5ecbsogg5lpwac@pathway.suse.cz> (raw)
In-Reply-To: <20180313224613.sdkdkcvhpqv54s6c@treble>

On Tue 2018-03-13 17:46:13, Josh Poimboeuf wrote:
> On Wed, Mar 07, 2018 at 09:20:34AM +0100, Petr Mladek wrote:
> > From: Jason Baron <jbaron@akamai.com>
> > 
> > We are going to add a feature called atomic replace. It will allow to
> > create a patch that would replace all already registered patches.
> > 
> > The replaced patches will stay registered because they are typically
> > unregistered by some package uninstall scripts. But we will remove
> > these patches from @klp_patches list to keep the enabled patch
> > on the bottom of the stack. Otherwise, we would need to implement
> > rather complex logic for moving the patches on the stack. Also
> > it would complicate implementation of the atomic replace feature.
> > It is not worth it.
> > 
> > As a result, we will have patches that are registered but that
> > are no longer usable. Let's get prepared for this and use
> > a better descriptive name for klp_is_patch_registered() function.
> > 
> > Also create separate list for the replaced patches and allow to
> > unregister them. Alternative solution would be to add a flag
> > into struct klp_patch. Note that patch->kobj.state_initialized
> > is not safe because it can be cleared outside klp_mutex.
> > ---
> >  kernel/livepatch/core.c | 30 ++++++++++++++++++++++++------
> >  1 file changed, 24 insertions(+), 6 deletions(-)
> > 
> > diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
> > index ab1f6a371fc8..fd0296859ff4 100644
> > --- a/kernel/livepatch/core.c
> > +++ b/kernel/livepatch/core.c
> > @@ -47,6 +47,13 @@ DEFINE_MUTEX(klp_mutex);
> >  
> >  static LIST_HEAD(klp_patches);
> >  
> > +/*
> > + * List of 'replaced' patches that have been replaced by a patch that has the
> > + * 'replace' bit set. When they are added to this list, they are disabled and
> > + * can not be re-enabled, but they can be unregistered().
> > + */
> > +static LIST_HEAD(klp_replaced_patches);
> 
> Can someone remind me why we're permanently disabling replaced patches?
> I seem to remember being involved in that decision, but at least with
> this latest version of the patches, it seems like it would be simpler to
> just let 'replace' patches be rolled back to the previous state when
> they're unpatched.  Then we don't need two lists of patches, the nops
> can become more permanent, the replaced patches remain "enabled" but
> inert, and the unpatching behavior is less surprising to the user, more
> like a normal rollback.

Yes, keeping the patches might make some things easier. But it might
also bring some problems and it would make the feature less useful.
The following arguments come to my mind:

1. The feature should help to keep the system in a consistent and
   well defined state. It should not depend on what patches were
   installed before.

   We do not want to force people to install every single livepatch
   before. It should be enough to install the last one. But then
   we might get different amount of NOPs depending on what was
   installed before.


2. The feature should allow to unpatch some functions while keeping
   the others patched.

   The ftrace handler might cause some unwanted slowdown or other
   problems. The performance might get restored only when we remove
   the NOPs when they are not longer necessary.


3. The handling of callbacks is already problematic. We run only
   the ones from the last patch to make things easier.

   We would need to come with something more complicated if we
   want to support rollback to "random" patches on the stack.
   And support for random patches is fundamental at least
   from my point of view.


> Along those lines, I'd also propose that we constrain our existing patch
> stacking even further.  Right now we allow a new patch to be registered
> on top of a disabled patch, though we don't allow the new patch to be
> enabled until the previous patch gets enabled.  I'd propose we no longer
> allow that condition.  We should instead enforce that all existing
> patches are *enabled* before allowing a new patch to be registered on
> top.  That way the patch stacking is even more sane, and there are less
> "unusual" conditions to worry about.  We have enough of those already.
> Each additional bit of flexibility has a maintenance cost, and this one
> isn't worth it IMO.

Again, this might make some things easier but it might also bring
problems.

For example, we would need to solve the situation when the last
patch is disabled and cannot be removed because the transition
was forced. This might be more common after removing the immediate
feature.

Also it might be less user friendly. White the atomic replace could
make things easier for both developers and users.


> The downside of the above proposals is that now you can't remove an old
> patch after it's been replaced, but IMO that's a small price to pay for
> code sanity.  Every additional bit of flexibility has a maintenance
> cost, and this one isn't worth it IMO.  Just force the user to leave the
> old inert patches loaded.  They shouldn't take up much memory anyway,
> and they might come in handy should a revert be needed.

I actually think about exactly the opposite way. IMHO, the atomic replace
and cumulative patches allow to handle livepatches more securely.
Also most situations might be solved by just going forward. If we support
only replace mode, we could get rid of the stack, disable feature,
and possibly make the code more straightforward.

To make it clear. I do not have any plans to work on this. It is
just an idea.


> > +
> >  static struct kobject *klp_root_kobj;
> >  
> >  static void klp_init_func_list(struct klp_object *obj, struct klp_func *func)

[...]

> > @@ -375,7 +393,7 @@ int klp_disable_patch(struct klp_patch *patch)
> >  
> >  	mutex_lock(&klp_mutex);
> >  
> > -	if (!klp_is_patch_registered(patch)) {
> > +	if (!klp_is_patch_usable(patch)) {
> 
> This is another case where a wrapper function hurts readability.  What
> does "usable" even mean to the reader of this code?  Every time I see
> it, I have to do a double take.  I think getting rid of the wrapper in
> favor of just doing
>
> 	if (!klp_is_patch_in_list(patch, &klp_patches))

IMHO, this is only a matter of taste. In the long term, the name
"is_patch_usable" might be more descriptive than the information that
the patch is on some  list.

Anyway, I reworked this for v11. I removed klp_replaced_patches list.
Instead, I added "bool registered" into struct klp_patch. Also
I renamed klp_is_patch_registered() to klp_is_patch_on_stack().

Then you could check is_patch_on_stack() in the enable/disable
functions. And you could check patch->registered in
klp_unregister_patch(). I believe that it is more clear.


Best Regards,
Petr

  reply	other threads:[~2018-03-19 15:02 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-07  8:20 [PATCH v10 00/10] livepatch: Atomic replace feature Petr Mladek
2018-03-07  8:20 ` [PATCH v10 01/10] livepatch: Use lists to manage patches, objects and functions Petr Mladek
2018-03-13 22:38   ` Josh Poimboeuf
2018-03-07  8:20 ` [PATCH v10 02/10] livepatch: Free only structures with initialized kobject Petr Mladek
2018-03-13 22:38   ` Josh Poimboeuf
2018-03-14 15:50     ` Petr Mladek
2018-03-07  8:20 ` [PATCH v10 03/10] livepatch: Initial support for dynamic structures Petr Mladek
2018-03-13 22:44   ` Josh Poimboeuf
2018-03-19 13:10     ` Petr Mladek
2018-03-07  8:20 ` [PATCH v10 04/10] livepatch: Allow to unpatch only functions of the given type Petr Mladek
2018-03-07  8:20 ` [PATCH v10 05/10] livepatch: Support separate list for replaced patches Petr Mladek
2018-03-13 22:46   ` Josh Poimboeuf
2018-03-19 15:02     ` Petr Mladek [this message]
2018-03-19 21:43       ` Josh Poimboeuf
2018-03-20 12:25         ` Petr Mladek
2018-03-20 12:48           ` Evgenii Shatokhin
2018-03-20 13:30           ` Miroslav Benes
2018-03-20 20:15           ` Josh Poimboeuf
2018-03-23  9:45             ` Petr Mladek
2018-03-23 22:44               ` Josh Poimboeuf
2018-03-26 10:11                 ` Petr Mladek
2018-04-06 19:50                   ` Josh Poimboeuf
2018-04-10  8:34                     ` Petr Mladek
2018-04-10 13:21                       ` Miroslav Benes
2018-04-10 13:56                         ` Evgenii Shatokhin
2018-04-10 17:47                           ` Josh Poimboeuf
2018-04-11  7:56                             ` Miroslav Benes
2018-04-10 17:42                       ` Josh Poimboeuf
2018-04-11  8:07                         ` Miroslav Benes
2018-04-11 12:32                           ` Josh Poimboeuf
2018-04-11 13:39                             ` Miroslav Benes
2018-04-11 14:17                             ` Petr Mladek
2018-04-11 15:48                               ` Josh Poimboeuf
2018-04-16 14:58                                 ` Petr Mladek
2018-04-16 19:04                                   ` Josh Poimboeuf
2018-04-17  8:23                                     ` Miroslav Benes
2018-04-17 15:37                                     ` Petr Mladek
2018-04-17 17:57                                       ` Josh Poimboeuf
2018-03-07  8:20 ` [PATCH v10 06/10] livepatch: Add atomic replace Petr Mladek
2018-03-13 22:48   ` Josh Poimboeuf
2018-03-20 14:35     ` Petr Mladek
2018-03-20 21:26       ` Josh Poimboeuf
2018-03-22 15:43         ` Petr Mladek
2018-03-07  8:20 ` [PATCH v10 07/10] livepatch: Correctly handle atomic replace for not yet loaded modules Petr Mladek
2018-03-13 14:55   ` Petr Mladek
2018-03-07  8:20 ` [PATCH v10 08/10] livepatch: Improve dynamic struct klp_object detection and manipulation Petr Mladek
2018-03-07  8:20 ` [PATCH v10 09/10] livepatch: Allow to replace even disabled patches Petr Mladek
2018-03-07  8:20 ` [PATCH v10 10/10] livepatch: Atomic replace and cumulative patches documentation Petr Mladek
2018-03-07 21:55 ` [PATCH v10 00/10] livepatch: Atomic replace feature Joe Lawrence
2018-03-08 15:01   ` Petr Mladek
2018-03-08 15:09     ` Joe Lawrence
2018-03-12 18:57       ` Joe Lawrence
2018-03-20 13:16         ` Miroslav Benes
2018-03-26 10:56         ` Petr Mladek
2018-03-26 18:12           ` Joe Lawrence
2018-03-27  8:22             ` Petr Mladek
2018-08-17 10:17 ` Evgenii Shatokhin
2018-08-17 14:53   ` Petr Mladek
2018-08-17 15:33     ` Evgenii Shatokhin

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=20180319150207.iz5ecbsogg5lpwac@pathway.suse.cz \
    --to=pmladek@suse.com \
    --cc=eshatokhin@virtuozzo.com \
    --cc=jbaron@akamai.com \
    --cc=jeyu@kernel.org \
    --cc=jikos@kernel.org \
    --cc=joe.lawrence@redhat.com \
    --cc=jpoimboe@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=live-patching@vger.kernel.org \
    --cc=mbenes@suse.cz \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®