[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH for-4.22] char/ns16550: bound execution time of ns16550_interrupt()


  • To: Jan Beulich <jbeulich@xxxxxxxx>
  • From: Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Date: Thu, 25 Jun 2026 12:08:25 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=4LiqmLRnTzxqyK4VsYEs4YJ+niQ6u4TWLFbYGpPfmC4=; b=iXoPPKiWOvqMb4xeeCNy68Ti7xQL79ZTfJw2W5GgzZnxzz2dSTk5IU297Lu2+oRM487O13FHdbScGifGAoCf0/2GKDcRtgQsuM2k4ze1fGG2H4IUHrcfgSY1WLn5i5p46d0P6slyitClqzSnlLsJ6igOOYkmcLtqgrp49K3UrK8JEe+GX6fkvMgapH7VA/x+HHQ5CV9S2oiVD0WsYtigTbYkd0XDXBAr9l2pDUvFpJL2kxp6RSwPXL8AccAvS7Iu8ACAuV/pT26E32XC7wJ8845n7HhK5Mw/5lf1kgH05PJFvbN3Qkz77CPlJb+cyoJI13F0zHDEA7VyCStH7jtLVg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=QZXJ8o7HtCWJCt6jI5FpGHo+m6+b1PbFN125hMtDl40drZdDsQC5khRp51N1Y5leFi03NDZ2WtpsQ9JpffYJI6VFTlxK1ObgZTcUXQert4rIVBYs4HBd+iBgT1zRDY8Xv8QdVWV/0O8BAzXm9al1bzH7/Qjbt1Nii8yv12wN5S1sMqeAsIWGW1k9q7GdBTxa/WT+NjMhy6HoDszdwa7xhop7LIovmBifuZTg1z81jvaoz8CH8YblL9tlNXUmsYy072e5skOVotQVep+weo9Ce7OxQJ2bmB+d4xMvezswZQ1BmeOV3ZKleHXoDMtikdF/iay3bAGB1wSVDnLx3HVxQA==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=citrix.com header.i="@citrix.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>, Julien Grall <julien@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Thu, 25 Jun 2026 10:08:41 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On Wed, Jun 24, 2026 at 10:01:36AM +0200, Jan Beulich wrote:
> On 23.06.2026 17:54, Roger Pau Monné wrote:
> > On Tue, Jun 23, 2026 at 04:27:12PM +0200, Jan Beulich wrote:
> >> On 23.06.2026 16:16, Roger Pau Monné wrote:
> >>> On Tue, Jun 23, 2026 at 03:44:06PM +0200, Jan Beulich wrote:
> >>>> On 23.06.2026 12:31, Roger Pau Monne wrote:
> >>>>> +    if ( uart->force_polling )
> >>>>> +        return;
> >>>>
> >>>> As the IRQ was disabled, is this even possible? I.e. should this be some
> >>>> kind of assertion or alike?
> >>>
> >>> Hm, I wasn't setting IRQ_DISABLED before, and hence needed this guard.
> >>> But now with IRQ_DISABLED being set in ->status do_IRQ() should filter
> >>> any stray interrupts.  I will attempt to add an ASSERT_UNREACHABLE()
> >>> here.
> >>
> >> Simply ASSERT(!uart->force_polling) should do here? It is not wrong to
> >> run the code below in release builds in such an event. If we kept getting
> >> interrupts (perhaps at a high frequency) we'd be in trouble anyway.
> > 
> > No, I'm afraid I can't do it like that, I can't put an ASSERT there,
> > because we can still get into ns16550_interrupt() after the interrupt
> > has been disabled.  In do_IRQ() we have the following loop:
> > 
> >     while ( desc->status & IRQ_PENDING )
> >     {
> >         desc->status &= ~IRQ_PENDING;
> >         spin_unlock_irq(&desc->lock);
> > 
> >         tsc_in = tb_init_done ? get_cycles() : 0;
> >         action->handler(irq, action->dev_id);
> >         TRACE_TIME(TRC_HW_IRQ_HANDLED, irq, tsc_in, get_cycles());
> > 
> >         spin_lock_irq(&desc->lock);
> >     }
> > 
> > So if the device is generating further interrupts in the window with
> > IRQs enabled (while we execute the handler), we will keep looping
> > around this, without taking into account the setting of IRQ_DISABLED.
> 
> Ah yes.
> 
> > This is something that we might want to fix, so that the loop is bound
> > by IRQ_PENDING being set, and IRQ_DISABLED not, ie:
> > 
> >     while ( (desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING )
> 
> Or perhaps ahead of the loop
> 
>     desc->status &= ~IRQ_REPLAY;
> 
>     if ( desc->status & IRQ_DISABLED )
>         goto out;
> 
>     desc->status |= IRQ_PENDING;
> 
>     /*
>      * Since we set PENDING, if another processor is handling a different
>      * instance of this same irq, the other processor will take care of it.
>      */
>     if ( desc->status & IRQ_INPROGRESS )
>         goto out;
> 
>     desc->status |= IRQ_INPROGRESS;
> 
> thus also having the comment no longer describe only part of the conditional.

I think this is racy.  An interrupt hitting in the window with
interrupts enabled ahead of the handler having set IRQ_DISABLED will
still set IRQ_PENDING, and thus the loop would get executed a further
time, and the handler called after IRQ_DISABLED having been set.

I think we need an extra condition in the loop, I see no way this can
be solved only by dealing with the concurrent setting of IRQ_PENDING.

Thanks, Roger.



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.