From: David Woodhouse <dwmw2@infradead.org>
To: Juergen Gross <jgross@suse.com>,
xen-devel <xen-devel@lists.xenproject.org>
Cc: Stefano Stabellini <sstabellini@kernel.org>,
Paul Durrant <paul@xen.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org,
linux-serial@vger.kernel.org, Dawei Li <set_pte_at@outlook.com>,
Jiri Slaby <jirislaby@kernel.org>,
Roger Pau Monne <roger.pau@citrix.com>
Subject: Re: [PATCH] hvc/xen: fix event channel handling for secondary consoles
Date: Fri, 20 Oct 2023 16:20:20 +0100 [thread overview]
Message-ID: <55b87d75e13f1b888d90b03ea4bebe044b305e6a.camel@infradead.org> (raw)
In-Reply-To: <36c9298d-2052-42de-9ef4-135c120a2417@suse.com>
[-- Attachment #1: Type: text/plain, Size: 3455 bytes --]
On Fri, 2023-10-20 at 10:51 +0200, Juergen Gross wrote:
>
> > (qemu) device_del con1
> > [ 32.050919] ------------[ cut here ]------------
> > [ 32.050942] Trying to free already-free IRQ 33
> > [ 32.050990] WARNING: CPU: 0 PID: 51 at kernel/irq/manage.c:1895 __free_irq+0x1d4/0x330
> >
> > Fix that by calling notifier_del_irq() first, which only calls
> > free_irq() if the irq was requested in the first place. Then use
>
> I don't think the "if the irq was requested in the first place" is the correct
> reasoning.
>
> I think the problem is that notifier_del_irq() will be called another time
> through the .notifier_del hook. Two calls of notifier_del_irq() are fine, but
> one call of it and another call of free_irq() via unbind_from_irqhandler() is
> a problem.
Er... yes, the HVC tty device still exists, can still be open and in
use by userspace during the time that xencons_disconnect_backend() is
running.
Why does xencons_disconnect_backend() do all the evtchn and gnttab
teardown *first* and then only call hvc_remove() at the end. That seems
weird.
So if I do 'dd if=/dev/zero of=/dev/hvc1' while I remove the device
from qemu... yep, that seems to have filled the ring after the evtchn
was torn down, and it's waiting for ever in domU_write_console().
In fact, that isn't *even* because of the race within
xencons_disconnect_backend(). In xencons_backend_changed() when the
backend goes into state XenbusStateClos{ing,ed} for the disconnect, we
just set the frontend state directly to XenbusStateClosed without even
*calling* xencons_disconnect_backend().
So we were *told* of the impending unplug. We fail to actually stop
using the device, but we tell the backend that it's OK to go away.
Oops :)
The incremental patch below makes it work if I unplug a console while
writing /dev/zero to it.
But I suspect instead of calling xencons_disconnect_backend() when the
backend changes to XenbusStateClos{ing,ed}, it should actually *just*
do the hvc_close() part? The evtchn and gnttab cleanup should wait
until the backend has actually finished closing?
And what locking is there around xencons_disconnect_backend() anyway?
Do we rely on the fact that it can all only happen from the xenstore
watch thread?
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
index f0376612b267..0806078835f6 100644
--- a/drivers/tty/hvc/hvc_xen.c
+++ b/drivers/tty/hvc/hvc_xen.c
@@ -377,8 +377,10 @@ void xen_console_resume(void)
#ifdef CONFIG_HVC_XEN_FRONTEND
static void xencons_disconnect_backend(struct xencons_info *info)
{
+ if (info->hvc != NULL)
+ hvc_remove(info->hvc);
+ info->hvc = NULL;
if (info->irq > 0) {
- notifier_del_irq(info->hvc, info->irq);
evtchn_put(info->evtchn);
info->irq = 0;
info->evtchn = 0;
@@ -390,9 +392,6 @@ static void xencons_disconnect_backend(struct xencons_info *info)
if (info->gntref > 0)
gnttab_free_grant_references(info->gntref);
info->gntref = 0;
- if (info->hvc != NULL)
- hvc_remove(info->hvc);
- info->hvc = NULL;
}
static void xencons_free(struct xencons_info *info)
@@ -558,6 +557,7 @@ static void xencons_backend_changed(struct xenbus_device *dev,
break;
fallthrough; /* Missed the backend's CLOSING state */
case XenbusStateClosing:
+ xencons_disconnect_backend(dev_get_drvdata(&dev->dev));
xenbus_frontend_closed(dev);
break;
}
[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 5965 bytes --]
prev parent reply other threads:[~2023-10-20 15:21 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-17 23:46 [PATCH] hvc/xen: fix event channel handling for secondary consoles David Woodhouse
2023-10-20 8:51 ` Juergen Gross
2023-10-20 15:20 ` David Woodhouse [this message]
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=55b87d75e13f1b888d90b03ea4bebe044b305e6a.camel@infradead.org \
--to=dwmw2@infradead.org \
--cc=gregkh@linuxfoundation.org \
--cc=jgross@suse.com \
--cc=jirislaby@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=paul@xen.org \
--cc=roger.pau@citrix.com \
--cc=set_pte_at@outlook.com \
--cc=sstabellini@kernel.org \
--cc=xen-devel@lists.xenproject.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).