public inbox for live-patching@vger.kernel.org
 help / color / mirror / Atom feed
From: Josh Poimboeuf <jpoimboe@kernel.org>
To: Petr Mladek <pmladek@suse.com>
Cc: Nicolai Stange <nstange@suse.de>,
	Marcos Paulo de Souza <mpdesouza@suse.com>,
	linux-kernel@vger.kernel.org, live-patching@vger.kernel.org,
	jpoimboe@redhat.com, joe.lawrence@redhat.com
Subject: Re: [PATCH v2 4/4] livepatch/shadow: Add garbage collection of shadow variables
Date: Sat, 4 Feb 2023 15:59:10 -0800	[thread overview]
Message-ID: <20230204235910.4j4ame5ntqogqi7m@treble> (raw)
In-Reply-To: <Y2u659H1tZQfG0uQ@alley>

On Wed, Nov 09, 2022 at 03:36:23PM +0100, Petr Mladek wrote:
> > Right.  Though, thinking about it more, this isn't even needed.  Each
> > klp_shadow would have a pointer to its owning module.  We already have a
> > global hash of klp_shadows which can be iterated when the module gets
> > unloaded or replaced.
> >
> > Assuming atomic replace, the new patch is almost always a superset of
> > the old patch.  We can optimize for that case.
> 
> I see. But I do not agree with this assumption. The new livepatch
> might also remove code that caused problems.
> 
> Also we allow downgrades. I mean that there is no versioning
> of livepatches. Older livepatches might replace new ones.
> 
> We really want to support downgrades or upgrades that remove
> problematic code. Or upgrades that start fixing the problem
> a better way using another shadow variable.

So I've been thinking about this too...

I think it's good to support downgrades.  But even with this patch set,
they still aren't properly supported because of the callback design.

Unpatch callbacks aren't called for the replaced patch.  Any cleanup it
needs to do (e.g., for a downgrade) is skipped.  That can cause all
kinds of problems including leaks and conflicts with future patches.

And actually, that seems directly related to shadow variable garbage
collection.

Typically you would call 'klp_shadow_free_all(id, dtor)' in the
post_unpatch callback, *unless* that data is going to be used by the
replacement patch.

That "unless" is the problem.  Without that problem, garbage collection
of shadow variables would be trivial.

Thing is, that "unless" exists not only for the freeing of shadow
variables, but also for the allocation of some shadow variables in
pre/post-patch callbacks, and many other types of initializations and
cleanups done by patch/unpatch callbacks.

Correct me if I'm wrong, but it seems like downgrades (and similar
scenarios like upgrades with partial revert) are the primary real-world
motivation for this patch set.

These patches feel like a partial solution to a bigger problem.  If we
really want to support downgrade use cases, the callbacks will need to
be improved.

The main issue is that callbacks aren't called at the right times, and
they're not granular enough to support different levels of
upgrade/downgrade so that we can arbitrarily replace any patch with any
other version of the patch without consequence.

If the callbacks were split up and called only when they're needed, it
would be trivial to free the shadow variables in a post_unpatch
callback.


To support this we could have some kind of callback versioning, where a
klp_object can have an array of klp_callbacks, and each set of callbacks
has a version associated with it.

For example, consider a sequence of patches P1-P4, each of which is an
upgrade from the last.

(Note: I'm assuming only one klp_object here to keep it simple.)

- P1 has [ callbacks.version=1 ]
- P2 has [ callbacks.version=1 ]
- P3 has [ callbacks.version=1, callbacks.version=2 ]
- P4 has [ callbacks.version=1, callbacks.version=3 ]

Usually a patch will have the same callbacks (with same versions) as its
predecessor.  P1 and P2 have the same callbacks (v1).

If needed, a patch can then add an additional set of callbacks (with
bumped version) like P3.  Or it can remove its predecessor's callbacks.
Or it can do both, like P4.

When deciding which callbacks to call for a replace operation, it's
basically an XOR.  If a callback version exists in one patch but not the
other, its callbacks should be called.

For example, if P3 gets upgraded to P4, call P4's v3 patch callbacks and
P3's v2 unpatch callbacks.

If P4 gets downgraded to P1, call P4's v3 unpatch callbacks.

BTW, "version" may not be the right name, as there's no concept of newer
or older: any patch can be arbitrarily replaced by any other patch.  The
version is just a unique ID for a set of callbacks.

-- 
Josh

  reply	other threads:[~2023-02-04 23:59 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-26 19:41 [PATCH v2 0/4] livepatch: Add garbage collection for shadow variables Marcos Paulo de Souza
2022-10-26 19:41 ` [PATCH v2 1/4] livepatch/shadow: Separate code to get or use pre-allocated shadow variable Marcos Paulo de Souza
2022-10-31 15:44   ` Petr Mladek
2022-10-26 19:41 ` [PATCH v2 2/4] livepatch/shadow: Separate code removing all shadow variables for a given id Marcos Paulo de Souza
2022-10-26 19:41 ` [PATCH v2 3/4] livepatch/shadow: Introduce klp_shadow_type structure Marcos Paulo de Souza
2022-10-31 16:02   ` Petr Mladek
2023-01-31  4:36   ` Josh Poimboeuf
2022-10-26 19:41 ` [PATCH v2 4/4] livepatch/shadow: Add garbage collection of shadow variables Marcos Paulo de Souza
2022-11-04  1:03   ` Josh Poimboeuf
2022-11-04 10:25     ` Petr Mladek
2022-11-08  1:32       ` Josh Poimboeuf
2022-11-08  9:14         ` Petr Mladek
2022-11-08 18:44           ` Josh Poimboeuf
2022-11-09 14:36             ` Petr Mladek
2023-02-04 23:59               ` Josh Poimboeuf [this message]
2023-02-17 16:22                 ` Petr Mladek
2022-11-11  9:20       ` Nicolai Stange
2022-11-11  9:55         ` Petr Mladek
2022-11-13 18:51           ` Josh Poimboeuf
2023-01-17 15:01             ` Petr Mladek
2023-01-25 23:22               ` Josh Poimboeuf
2023-01-26  9:36                 ` Petr Mladek
2023-02-04 19:34                 ` Josh Poimboeuf
2023-01-31  4:40   ` Josh Poimboeuf
2023-01-31 14:23     ` Petr Mladek
2023-01-31 21:17       ` Josh Poimboeuf
2023-02-02 13:58         ` Petr Mladek
2023-02-01  0:18   ` Josh Poimboeuf
2023-02-02 10:14     ` Petr Mladek
2023-02-04 17:37       ` Josh Poimboeuf
2022-11-01 10:43 ` [PATCH v2 0/4] livepatch: Add garbage collection for " Petr Mladek
2023-01-23 17:33   ` Marcos Paulo de Souza
2023-01-24 15:51     ` Petr Mladek
2023-01-26 16:35       ` Petr Mladek
2023-01-26 17:05         ` Joe Lawrence
2023-01-26 18:30           ` Josh Poimboeuf
2023-01-27 10:51             ` Petr Mladek
2023-01-27 11:08           ` Marcos Paulo de Souza

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=20230204235910.4j4ame5ntqogqi7m@treble \
    --to=jpoimboe@kernel.org \
    --cc=joe.lawrence@redhat.com \
    --cc=jpoimboe@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=live-patching@vger.kernel.org \
    --cc=mpdesouza@suse.com \
    --cc=nstange@suse.de \
    --cc=pmladek@suse.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox