OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

virtio-dev message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: Re: [PATCH V8 2/2] virtio-gpio: Add support for interrupts


On Fri, Jul 30, 2021 at 10:52 AM Marc Zyngier <maz@kernel.org> wrote:
> On Fri, 30 Jul 2021 07:45:03 +0100, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> > +
> > +\item If the GPIO line is configured for level interrupts, the device MUST
> > +    ignore an active interrupt signaled on this GPIO line, until the time the
> > +    buffers are made available again by the driver. Once the buffers are
> > +    available again, and the interrupt on the line is still active, the device
> > +    MUST notify the driver again of an interrupt event.
>
> It feels like there is a problem here. A virtio device signals
> interrupts by using edge triggered signalling. Nothing wrong with
> that. However, signalling a level over a an edge signalling is much
> more tricky.
>
> For example, let's assume that the irqchip driver handles a level
> interrupt: it gets the message from the device indicating that a GPIO
> level interrupt is pending. During the handling, the interrupt is made
> pending again, without having ever transitioned via an inactive state.
> If you don't have a mechanism to retrigger the level, you have lost an
> interrupt.
>
> I can't see anything in this document that hints at a way to
> resample/retrigger a level interrupt, which is what you would normally
> do on EOI for an interrupt controller that implements level-over-edge
> signalling.

Thanks a lot for taking a closer look. I still hope this is just a problem
that needs to be clarified in the description, not something wrong with
the design, as I don't see the problem yet. As far as I can tell, this is
different from an edge interrupt, since the eventq communication is
really a two-way message.

The EOI for the level interrupt is the message being enqueued after
the guest is done processing the interrupt. I can see four ways this
could go:

1. If the interrupt has not been made pending again yet, nothing happens
  until it eventually becomes pending again (this is the obvious case)

2. If it is already pending, chip->irq_eoi() causes the new event descriptor
  to be queued on the eventq, and it signals the host about new buffers
  being available. The /host/ samples the level of the line, notices it is
  pending and puts the resulting buffer back on the 'used' queue even
  before returning from the guest 'notify' function.
  The guest virtio core code keeps processing the 'used' buffers and
  gets back into the interrupt handler.

3. Same as 2., but the host handles the virtqueue ->notify asynchronously,
  and the guest has already checked the 'used' queue before the host
  adds back the buffer to tell it that the line is still active. Now the guest
  gets notified again after it returns from the virtqueue interrupt, in order
  to process the new 'used' buffer.

4. The gpio line actually goes into inactive state until after the new event
   is queued in chip->irq_eoi(), but becomes active immediately afterwards.
   Now the host gets interrupted and handles this by queuing the event
   reply but cannot interrupt the guest because it is still processing the
   original virtqueue event. However, since the event is queued, it will be
   processed the same way as 2. or 3. by the virtio core.

Do  you see a problem with scenarios 2, 3 or 4, or with another case
that I may have missed?

[This all assumes that the host is able to atomically enable interrupts and
check the current level when processing the new buffer. If the host uses the
Linux gpiolib ioctl interface, this means it has to register for an edge event
on the line first, and then read the current value before adding the file
descriptor to its poll table. I feel this is out of the scope of the virtio spec
though.]

       Arnd


[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]