From: Petr Mladek <pmladek@suse.com>
To: Seth Forshee <sforshee@kernel.org>
Cc: Jason Wang <jasowang@redhat.com>,
"Michael S. Tsirkin" <mst@redhat.com>,
Jiri Kosina <jikos@kernel.org>, Miroslav Benes <mbenes@suse.cz>,
Joe Lawrence <joe.lawrence@redhat.com>,
Josh Poimboeuf <jpoimboe@kernel.org>,
virtualization@lists.linux-foundation.org, kvm@vger.kernel.org,
netdev@vger.kernel.org, live-patching@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/2] vhost: check for pending livepatches from vhost worker kthreads
Date: Thu, 26 Jan 2023 12:49:24 +0100 [thread overview]
Message-ID: <Y9JoxAHLplZoVPea@alley> (raw)
In-Reply-To: <Y9JhEJXFRDZjONAH@alley>
On Thu 2023-01-26 12:16:36, Petr Mladek wrote:
> On Wed 2023-01-25 10:57:30, Seth Forshee wrote:
> > On Wed, Jan 25, 2023 at 12:34:26PM +0100, Petr Mladek wrote:
> > > On Tue 2023-01-24 11:21:39, Seth Forshee wrote:
> > > > On Tue, Jan 24, 2023 at 03:17:43PM +0100, Petr Mladek wrote:
> > > > > On Fri 2023-01-20 16:12:22, Seth Forshee (DigitalOcean) wrote:
> > > > > > Livepatch relies on stack checking of sleeping tasks to switch kthreads,
> > > > > > so a busy kthread can block a livepatch transition indefinitely. We've
> > > > > > seen this happen fairly often with busy vhost kthreads.
> > > > >
> > > > > > --- a/drivers/vhost/vhost.c
> > > > > > +++ b/drivers/vhost/vhost.c
> > > > > > @@ -366,6 +367,9 @@ static int vhost_worker(void *data)
> > > > > > if (need_resched())
> > > > > > schedule();
> > > > > > }
> > > > > > +
> > > > > > + if (unlikely(klp_patch_pending(current)))
> > > > > > + klp_switch_current();
> > > > >
> > > > > I suggest to use the following intead:
> > > > >
> > > > > if (unlikely(klp_patch_pending(current)))
> > > > > klp_update_patch_state(current);
> > > > >
> > > > > We already use this in do_idle(). The reason is basically the same.
> > > > > It is almost impossible to livepatch the idle task when a CPU is
> > > > > very idle.
> > > > >
> > > > Let's say that a livepatch is loaded which replaces vhost_worker(). New
> > > > vhost worker threads are started which use the replacement function. Now
> > > > if the patch is disabled, these new worker threads would be switched
> > > > despite still running the code from the patch module, correct? Could the
> > > > module then be unloaded, freeing the memory containing the code these
> > > > kthreads are executing?
> > >
> > > Hmm, the same problem might be when we livepatch a function that calls
> > > another function that calls klp_update_patch_state(). But in this case
> > > it would be kthread() from kernel/kthread.c. It would affect any
> > > running kthread. I doubt that anyone would seriously think about
> > > livepatching this function.
And I missed something. klp_update_patch_state_safe(), proposed below,
would not cover the above scenario.
It might be possible to add something similar to kthread()
function. I think that it is the only "livepatchable" function
that might call vhost_worker(). We could block
klp_update_patch_state() for the entire kthread when the kthread()
function is called from a livepatch.
Well, it is all just the best effort. The reference counting in
the ftrace handler would be more reliable. But it would require
adding the trampoline on the return.
> /**
> * klp_update_patch_state_safe() - do not update the path state when
> * called from a livepatch.
> * @task: task_struct to be updated
> * @calller_addr: address of the function which calls this one
> *
> * Do not update the patch set when called from a livepatch.
> * It would allow to remove the livepatch module even when
> * the code still might be in use.
> */
> void klp_update_patch_state_safe(struct task_struct *task, void *caller_addr)
> {
> static bool checked;
> static bool safe;
>
> if (unlikely(!checked)) {
> struct module *mod;
>
> preempt_disable();
> mod = __module_address(caller_addr);
> if (!mod || !is_livepatch_module(mod))
> safe = true;
> checked = true;
> preempt_enable();
> }
>
> if (safe)
> klp_update_patch_state(task);
> }
>
> and use in vhost_worker()
>
> if (unlikely(klp_patch_pending(current)))
> klp_update_patch_state_safe(current, vhost_worker);
>
> Even better might be to get the caller address using some compiler
> macro. I guess that it should be possible.
>
> And even better would be to detect this at the compile time. But
> I do not know how to do so.
>
> > Okay, I can send a v2 which does this, so long as it's okay to export
> > klp_update_patch_state() to modules.
>
> It would be acceptable for me if we added a warning above the function
> definition and into the livepatch documentation.
I would probably go this way after all. Still thinking...
Best Regards,
Petr
WARNING: multiple messages have this Message-ID (diff)
From: Petr Mladek via Virtualization <virtualization@lists.linux-foundation.org>
To: Seth Forshee <sforshee@kernel.org>
Cc: Joe Lawrence <joe.lawrence@redhat.com>,
kvm@vger.kernel.org, "Michael S. Tsirkin" <mst@redhat.com>,
netdev@vger.kernel.org, Jiri Kosina <jikos@kernel.org>,
linux-kernel@vger.kernel.org,
virtualization@lists.linux-foundation.org,
live-patching@vger.kernel.org, Miroslav Benes <mbenes@suse.cz>,
Josh Poimboeuf <jpoimboe@kernel.org>
Subject: Re: [PATCH 2/2] vhost: check for pending livepatches from vhost worker kthreads
Date: Thu, 26 Jan 2023 12:49:24 +0100 [thread overview]
Message-ID: <Y9JoxAHLplZoVPea@alley> (raw)
In-Reply-To: <Y9JhEJXFRDZjONAH@alley>
On Thu 2023-01-26 12:16:36, Petr Mladek wrote:
> On Wed 2023-01-25 10:57:30, Seth Forshee wrote:
> > On Wed, Jan 25, 2023 at 12:34:26PM +0100, Petr Mladek wrote:
> > > On Tue 2023-01-24 11:21:39, Seth Forshee wrote:
> > > > On Tue, Jan 24, 2023 at 03:17:43PM +0100, Petr Mladek wrote:
> > > > > On Fri 2023-01-20 16:12:22, Seth Forshee (DigitalOcean) wrote:
> > > > > > Livepatch relies on stack checking of sleeping tasks to switch kthreads,
> > > > > > so a busy kthread can block a livepatch transition indefinitely. We've
> > > > > > seen this happen fairly often with busy vhost kthreads.
> > > > >
> > > > > > --- a/drivers/vhost/vhost.c
> > > > > > +++ b/drivers/vhost/vhost.c
> > > > > > @@ -366,6 +367,9 @@ static int vhost_worker(void *data)
> > > > > > if (need_resched())
> > > > > > schedule();
> > > > > > }
> > > > > > +
> > > > > > + if (unlikely(klp_patch_pending(current)))
> > > > > > + klp_switch_current();
> > > > >
> > > > > I suggest to use the following intead:
> > > > >
> > > > > if (unlikely(klp_patch_pending(current)))
> > > > > klp_update_patch_state(current);
> > > > >
> > > > > We already use this in do_idle(). The reason is basically the same.
> > > > > It is almost impossible to livepatch the idle task when a CPU is
> > > > > very idle.
> > > > >
> > > > Let's say that a livepatch is loaded which replaces vhost_worker(). New
> > > > vhost worker threads are started which use the replacement function. Now
> > > > if the patch is disabled, these new worker threads would be switched
> > > > despite still running the code from the patch module, correct? Could the
> > > > module then be unloaded, freeing the memory containing the code these
> > > > kthreads are executing?
> > >
> > > Hmm, the same problem might be when we livepatch a function that calls
> > > another function that calls klp_update_patch_state(). But in this case
> > > it would be kthread() from kernel/kthread.c. It would affect any
> > > running kthread. I doubt that anyone would seriously think about
> > > livepatching this function.
And I missed something. klp_update_patch_state_safe(), proposed below,
would not cover the above scenario.
It might be possible to add something similar to kthread()
function. I think that it is the only "livepatchable" function
that might call vhost_worker(). We could block
klp_update_patch_state() for the entire kthread when the kthread()
function is called from a livepatch.
Well, it is all just the best effort. The reference counting in
the ftrace handler would be more reliable. But it would require
adding the trampoline on the return.
> /**
> * klp_update_patch_state_safe() - do not update the path state when
> * called from a livepatch.
> * @task: task_struct to be updated
> * @calller_addr: address of the function which calls this one
> *
> * Do not update the patch set when called from a livepatch.
> * It would allow to remove the livepatch module even when
> * the code still might be in use.
> */
> void klp_update_patch_state_safe(struct task_struct *task, void *caller_addr)
> {
> static bool checked;
> static bool safe;
>
> if (unlikely(!checked)) {
> struct module *mod;
>
> preempt_disable();
> mod = __module_address(caller_addr);
> if (!mod || !is_livepatch_module(mod))
> safe = true;
> checked = true;
> preempt_enable();
> }
>
> if (safe)
> klp_update_patch_state(task);
> }
>
> and use in vhost_worker()
>
> if (unlikely(klp_patch_pending(current)))
> klp_update_patch_state_safe(current, vhost_worker);
>
> Even better might be to get the caller address using some compiler
> macro. I guess that it should be possible.
>
> And even better would be to detect this at the compile time. But
> I do not know how to do so.
>
> > Okay, I can send a v2 which does this, so long as it's okay to export
> > klp_update_patch_state() to modules.
>
> It would be acceptable for me if we added a warning above the function
> definition and into the livepatch documentation.
I would probably go this way after all. Still thinking...
Best Regards,
Petr
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
next prev parent reply other threads:[~2023-01-26 11:49 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-20 22:12 [PATCH 0/2] vhost: improve livepatch switching for heavily loaded vhost worker kthreads Seth Forshee (DigitalOcean)
2023-01-20 22:12 ` [PATCH 1/2] livepatch: add an interface for safely switching kthreads Seth Forshee (DigitalOcean)
2023-01-20 22:12 ` [PATCH 2/2] vhost: check for pending livepatches from vhost worker kthreads Seth Forshee (DigitalOcean)
2023-01-24 14:17 ` Petr Mladek
2023-01-24 14:17 ` Petr Mladek via Virtualization
2023-01-24 17:21 ` Seth Forshee
2023-01-25 11:34 ` Petr Mladek
2023-01-25 11:34 ` Petr Mladek via Virtualization
2023-01-25 16:57 ` Seth Forshee
2023-01-26 11:16 ` Petr Mladek
2023-01-26 11:16 ` Petr Mladek via Virtualization
2023-01-26 11:49 ` Petr Mladek [this message]
2023-01-26 11:49 ` Petr Mladek via Virtualization
2023-01-22 8:34 ` [PATCH 0/2] vhost: improve livepatch switching for heavily loaded " Michael S. Tsirkin
2023-01-22 8:34 ` Michael S. Tsirkin
2023-01-26 17:03 ` Petr Mladek
2023-01-26 17:03 ` Petr Mladek via Virtualization
2023-01-26 21:12 ` Seth Forshee (DigitalOcean)
2023-01-27 4:43 ` Josh Poimboeuf
2023-01-27 10:37 ` Peter Zijlstra
2023-01-27 10:37 ` Peter Zijlstra
2023-01-27 12:09 ` Petr Mladek
2023-01-27 12:09 ` Petr Mladek via Virtualization
2023-01-27 14:37 ` Seth Forshee
2023-01-27 16:52 ` Josh Poimboeuf
2023-01-27 17:09 ` Josh Poimboeuf
2023-01-27 22:11 ` Josh Poimboeuf
2023-01-30 12:40 ` Peter Zijlstra
2023-01-30 12:40 ` Peter Zijlstra
2023-01-30 17:50 ` Seth Forshee
2023-01-30 18:18 ` Josh Poimboeuf
2023-01-30 18:36 ` Mark Rutland
2023-01-30 18:36 ` Mark Rutland
2023-01-30 19:48 ` Josh Poimboeuf
2023-01-31 1:53 ` Song Liu
2023-01-31 10:22 ` Mark Rutland
2023-01-31 10:22 ` Mark Rutland
2023-01-31 16:38 ` Josh Poimboeuf
2023-02-01 11:10 ` Mark Rutland
2023-02-01 11:10 ` Mark Rutland
2023-02-01 16:57 ` Josh Poimboeuf
2023-02-01 17:11 ` Mark Rutland
2023-02-01 17:11 ` Mark Rutland
2023-01-30 19:59 ` Josh Poimboeuf
2023-01-31 10:02 ` Peter Zijlstra
2023-01-31 10:02 ` Peter Zijlstra
2023-01-27 20:02 ` Seth Forshee
2023-01-27 11:19 ` Petr Mladek
2023-01-27 11:19 ` Petr Mladek via Virtualization
2023-01-27 14:57 ` Seth Forshee
2023-01-30 9:55 ` Petr Mladek
2023-01-30 9:55 ` Petr Mladek via Virtualization
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=Y9JoxAHLplZoVPea@alley \
--to=pmladek@suse.com \
--cc=jasowang@redhat.com \
--cc=jikos@kernel.org \
--cc=joe.lawrence@redhat.com \
--cc=jpoimboe@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=live-patching@vger.kernel.org \
--cc=mbenes@suse.cz \
--cc=mst@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=sforshee@kernel.org \
--cc=virtualization@lists.linux-foundation.org \
/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.