virtio: Add specification for virtio-gpio
v5 cover virtio: Add specification for virtio-gpio
Hello,
This patchset adds virtio specification for GPIO devices. It supports basic GPIO line operations, along with optional interrupts on them (in a separate patch).
This is an *alternative implementation* of the virtio-gpio specification, another version of it was earlier posted by Enrico [1].
I took back V4 of the specification I posted earlier (on June 17th), to allow Enrico to come up with something that is robust and works for everyone (as he started this thing last year), but it didn't go as expected. I couldn't see any of my review comments being incorporated (or any intentions of them getting in ever) in the two versions Enrico posted and a month passed since then.
And so I am trying to present an alternative approach here to solve the problem, which I believe is more clear and robust. I am open to suggestions to improve it further.
I will let the virtio/gpio maintainers decide on its fate.
Key differences from Enrico's approach [1]:
- config structure is rearranged to remove unnecessary fields/padding, and place gpio_names block in such a way that we can expand the structure easily going forward, if required.
- Supports freeing of a GPIO line after use.
- Interrupt implementation handled with feature bit 0. Either the interrupts are fully supported or not at all.
- Doesn't add any ordering restrictions on the device, it can respond earlier to the second request, while still processing the first one.
- Clearly state that two requests can't be initiated for the same line by device or driver.
Version history of the specification I sent:
V4 -> V5:
- Split into two patches, irq stuff in patch 2.
- Use separate virtqueue for sending data from device/driver.
- Allow parallel processing of requests for different GPIOs, only one request at a time for the same GPIO line.
- Same goes for interrupt side, only one interrupt request per GPIO line.
- Improved formatting in general.
- Add new sections explaining message flow sequence.
V3 -> V4:
- The GPIO line names must be unique within a device.
- The gpio_names[0] field is dropped and gpio_names_offset field is added in place of the 2 bytes of padding.
- New interrupts must not be initiated by the device, without a response for the previous one.
V2 -> V3:
- Unused char in name string should be marked 0 now.
- s/host/device/ and s/guest/driver/
- Added a new feature for IRQ mode, VIRTIO_GPIO_F_IRQ.
- A new feature should be added for Version information if required later on.
V1 -> V2:
- gpio_names_size is 32 bit.
- gpio field is 16 bit.
- padding added 16 bit.
- Added packed attribute to few structures
- Add the missing 'type' field to the request
- Dropped to _nodata request/responses to simplify a bit, updated related text.
--
Viresh
[1] https://lists.oasis-open.org/archives/virtio-dev/202106/msg00030.html
Viresh Kumar (2):
virtio-gpio: Add the device specification
virtio-gpio: Add support for interrupts
conformance.tex | 26 ++- content.tex | 3 +- virtio-gpio.tex | 464 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 488 insertions(+), 5 deletions(-) create mode 100644 virtio-gpio.tex
Signature · 1 line
2.31.1.272.g89b43f80a514
PATCH v5 1/2 virtio-gpio: Add the device specification
virtio-gpio is a virtual GPIO controller. It provides a way to flexibly communicate with the host GPIO controllers from the guest.
This patch adds the specification for it.
Based on the initial work posted by:
"Enrico Weigelt, metux IT consult" <[email protected]>.
--- conformance.tex | 26 +++- content.tex | 3 +- virtio-gpio.tex | 317 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 341 insertions(+), 5 deletions(-) create mode 100644 virtio-gpio.tex
conformance.tex +22 -4
@@ -30,8 +30,9 @@ \section{Conformance Targets}\label{sec:Conformance / Conformance Targets} \ref{sec:Conformance / Driver Conformance / IOMMU Driver Conformance}, \ref{sec:Conformance / Driver Conformance / Sound Driver Conformance}, \ref{sec:Conformance / Driver Conformance / Memory Driver Conformance}, -\ref{sec:Conformance / Driver Conformance / I2C Adapter Driver Conformance} or -\ref{sec:Conformance / Driver Conformance / SCMI Driver Conformance}. +\ref{sec:Conformance / Driver Conformance / I2C Adapter Driver Conformance}, +\ref{sec:Conformance / Driver Conformance / SCMI Driver Conformance} or +\ref{sec:Conformance / Driver Conformance / General Purpose IO Driver Conformance}. \item Clause \ref{sec:Conformance / Legacy Interface: Transitional Device and Transitional Driver Conformance}. \end{itemize}
@@ -54,8 +55,9 @@ \section{Conformance Targets}\label{sec:Conformance / Conformance Targets} \ref{sec:Conformance / Device Conformance / IOMMU Device Conformance}, \ref{sec:Conformance / Device Conformance / Sound Device Conformance}, \ref{sec:Conformance / Device Conformance / Memory Device Conformance}, -\ref{sec:Conformance / Device Conformance / I2C Adapter Device Conformance} or -\ref{sec:Conformance / Device Conformance / SCMI Device Conformance}. +\ref{sec:Conformance / Device Conformance / I2C Adapter Device Conformance}, +\ref{sec:Conformance / Device Conformance / SCMI Device Conformance} or +\ref{sec:Conformance / Device Conformance / General Purpose IO Device Conformance}. \item Clause \ref{sec:Conformance / Legacy Interface: Transitional Device and Transitional Driver Conformance}. \end{itemize}
@@ -301,6 +303,14 @@ \section{Conformance Targets}\label{sec:Conformance / Conformance Targets} \item \ref{drivernormative:Device Types / SCMI Device / Device Operation / Setting Up eventq Buffers} \end{itemize} +\conformance{\subsection}{General Purpose IO Driver Conformance}\label{sec:Conformance / Driver Conformance / General Purpose IO Driver Conformance} + +An General Purpose IO driver MUST conform to the following normative statements: + +\begin{itemize} +\item \ref{drivernormative:Device Types / GPIO Device / Device Operation} +\end{itemize} + \conformance{\section}{Device Conformance}\label{sec:Conformance / Device Conformance} A device MUST conform to the following normative statements:
@@ -550,6 +560,14 @@ \section{Conformance Targets}\label{sec:Conformance / Conformance Targets} \item \ref{devicenormative:Device Types / SCMI Device / Device Operation / Shared Memory Operation} \end{itemize} +\conformance{\subsection}{General Purpose IO Device Conformance}\label{sec:Conformance / Device Conformance / General Purpose IO Device Conformance} + +An General Purpose IO device MUST conform to the following normative statements: + +\begin{itemize} +\item \ref{devicenormative:Device Types / GPIO Device / Device Operation} +\end{itemize} + \conformance{\section}{Legacy Interface: Transitional Device and Transitional Driver Conformance}\label{sec:Conformance / Legacy Interface: Transitional Device and Transitional Driver Conformance} A conformant implementation MUST be either transitional or non-transitional, see \ref{intro:Legacy
content.tex +2 -1
@@ -2876,7 +2876,7 @@ \chapter{Device Types}\label{sec:Device Types} \hline 40 & Bluetooth device \\ \hline -41 & GPIO device \\ +41 & General Purpose IO (GPIO) device \\ \hline \end{tabular}
@@ -6583,6 +6583,7 @@ \subsubsection{Legacy Interface: Framing Requirements}\label{sec:Device \input{virtio-mem.tex} \input{virtio-i2c.tex} \input{virtio-scmi.tex} +\input{virtio-gpio.tex} \chapter{Reserved Feature Bits}\label{sec:Reserved Feature Bits}
virtio-gpio.tex new file +317 -0
317 lines not on this page · raw message
Signature · 1 line
2.31.1.272.g89b43f80a514
Re: [PATCH V5 1/2] virtio-gpio: Add the device specification
Quoted 10 lines
virtio-gpio is a virtual GPIO controller. It provides a way to flexibly communicate with the host GPIO controllers from the guest.
This patch adds the specification for it.
Based on the initial work posted by:
"Enrico Weigelt, metux IT consult" <[email protected]>.
I'm not too familiar with either virtio specification or gpio, but there are a few things
that stuck out to me anyway, so I'll comment here anyway on the things that surprised me the most.
Quoted 1 line
+\section{General Purpose IO Device}\label{sec:Device Types / GPIO Device}
Nitpicking: If you expand GPIO, I would write it as "General Purpose Input/Output"
or maybe "General Purpose I/O", but not just "General Purpose IO".
Quoted 13 lines
+\subsection{Device configuration layout}\label{sec:Device Types / GPIO Device / Device configuration layout}
virtio-gpio.tex new file +12
-0+ +GPIO device uses the following structure layout for configuration: + +\begin{lstlisting} +struct virtio_gpio_config { + u8 name[32]; + le16 ngpio; + le16 names_offset; + le32 names_size; + + /* at offset defined by names_offset field */ + u8 gpio_names[];
virtio-gpio.tex line 47
Quoted 10 lines
virtio-gpio.tex new file +10
-0+}; +\end{lstlisting} + +All fields of this structure, except \field{gpio_names}, must always be set by +the device and all fields are read-only for the driver. + +\begin{description} +\item[\field{name}] is a zero-terminated string that represents the name of the + GPIO device. The unused bytes in the string must be initialized to zero by + the device.
I'm a bit confused about why you have both a combined "name" field and separate "gpio_names" fields. I not too familiar with the internals of the gpio subsystem, but I see that in the devicetree bindings, we have only optional per gpio line names, but no name for the device itself.
Even if we decide that this is needed after all, it would be helpful to explain some background here about what this name is used for, as others may have the same question.
virtio-gpio.tex line 68
Quoted 7 lines
+\item[\field{gpio_names}] field is optional for a device to implement. If this
virtio-gpio.tex new file +6
-0+ field isn't implemented by the device, then the device must set the + \field{names_size} field to zero. If this field is implemented by the + device, then it must contain a stream of \field{ngpio} zero-terminated + strings, where each string represents the name of a GPIO line, present in + increasing order of the GPIO line numbers. The GPIO line names must + be unique within a GPIO Device and must not be empty string.
Also here, maybe add a sentence to explain what the gpio names are used for and what they are not used for.
virtio-gpio.tex line 112
Quoted 9 lines
virtio-gpio.tex new file +9
-0+A request is initiated by the sender by adding a buffer of type \field{struct +virtio_gpio_msg} to its respective virtqueue, after setting all fields of the +message and \field{type} field with one of the message types from +\field{VIRTIO_GPIO_MSG_*}. + +In response, the receiver adds a copy of the same buffer on its respective +virtqueue, after performing a logical OR operation to the \field{type} field +with VIRTIO_GPIO_MSG_RESPONSE mask and updating the \field{value} field based on +message type.
So you have one virtqueue for a request and another virtqueue for the reply? As they are always treated as a transaction, wouldn't it be easier to have a single virtqueue and make each transaction have both an input and an output buffer?
Quoted 4 lines
virtio-gpio.tex new file +4
-0+#define VIRTIO_GPIO_MSG_GET_DIRECTION 0x0003 +#define VIRTIO_GPIO_MSG_SET_DIRECTION_IN 0x0004 +#define VIRTIO_GPIO_MSG_SET_DIRECTION_OUT 0x0005 +#define VIRTIO_GPIO_MSG_GET_VALUE 0x0006
virtio-gpio.tex line 134
Quoted 10 lines
virtio-gpio.tex new file +10
-0+#define VIRTIO_GPIO_MSG_SET_VALUE 0x0007 + +/* GPIO response mask, to be Or'ed with one of the above */ +#define VIRTIO_GPIO_MSG_RESPONSE 0x8000 +\end{lstlisting} + +The response messages may contain error codes (in the \field{value} field) on +failures, they must be read as negative POSIX errno codes, unless stated +otherwise, i.e. 0 as success, and negative value as POSIX error code, positive +values as invalid, unless stated otherwise.
I don't understand how POSIX errno codes are meant to be used here, as I'm not aware of any generic definition of binary values. If you mean the Linux errno values, those cannot be used here as they are certainly architecture specific. You have to enumerate the possible response codes that the device is allowed to return, and what the meaning behind those is.
Quoted 9 lines
+\subsubsection{Device Operation: Request}\label{sec:Device Types / GPIO Device / Device Operation / Request }
virtio-gpio.tex new file +8
-0+ +The driver initiates this message to notify the device that one of its lines has +been assigned for use. + +\begin{tabular}{ |l||l|l|l| } +\hline +Fields & \field{type} & \field{gpio} & \field{value} \\ +\hline
virtio-gpio.tex line 154
Quoted 10 lines
virtio-gpio.tex new file +10
-0+Message & \field{VIRTIO_GPIO_MSG_REQUEST} & line number & 0 \\ +\hline +Response & \field{VIRTIO_GPIO_MSG_REQUEST} \newline | \field{VIRTIO_GPIO_MSG_RESPONSE} & line number & 0 = success, \newline or -errno = failure \\ +\hline +\end{tabular} + +\subsubsection{Device Operation: Free}\label{sec:Device Types / GPIO Device / Device Operation / Free } + +The driver initiates this message to notify the device that a previously +requested line has been unassigned and can be deactivated.
How is this intended to be used? Why is this not up to the guest kernel to keep track
of? I would expect that if a gpio line is listed in the information that the driver is free
to use it at any time without having to request it first.
While we do have the notion of gpiod_get/gpiod_put in the in-kernel interface, this is only used for arbitration between drivers (or driver vs user space) normally,
but not communicated with gpio controllers as far as I know.
virtio-gpio.tex line 283
Quoted 3 lines
+\subsection{Message flow}\label{sec:Device Types / GPIO Device / Message Flow}
virtio-gpio.tex new file +2
-0+ +This section describe how the messages flow between device and driver.
describes
Arnd
Re: [PATCH V5 1/2] virtio-gpio: Add the device specification
Quoted 5 lines · Arnd Bergmann
Quoted 1 line
+\section{General Purpose IO Device}\label{sec:Device Types / GPIO Device}
Nitpicking: If you expand GPIO, I would write it as "General Purpose Input/Output"
or maybe "General Purpose I/O", but not just "General Purpose IO".
Right.
Quoted 20 lines
Quoted 20 lines
+\subsection{Device configuration layout}\label{sec:Device Types / GPIO Device / Device configuration layout}
virtio-gpio.tex new file +19
-0+ +GPIO device uses the following structure layout for configuration: + +\begin{lstlisting} +struct virtio_gpio_config { + u8 name[32]; + le16 ngpio; + le16 names_offset; + le32 names_size; + + /* at offset defined by names_offset field */ + u8 gpio_names[]; +}; +\end{lstlisting} + +All fields of this structure, except \field{gpio_names}, must always be set by +the device and all fields are read-only for the driver. + +\begin{description}
Quoted 8 lines
virtio-gpio.tex line 47
Quoted 3 lines
+\item[\field{name}] is a zero-terminated string that represents the name of the
virtio-gpio.tex new file +2
-0+ GPIO device. The unused bytes in the string must be initialized to zero by + the device.I'm a bit confused about why you have both a combined "name" field and separate "
gpio_names" fields. I not too familiar with the internals of the gpio subsystem, but I see that in the devicetree bindings, we have only optional per gpio line names, but no name for the device itself.
The combined name is for distinguishing the GPIO controller at the guest, which is normally done in the kernel by assigning value from dev_name(dev).
With virtio-mmio nodes assigned randomly by hypervisors (like Qemu), those names may not be very useful. And so I thought that this name can be useful.
This eventually would get into gpio_chip->label field at kernel.
Quoted 3 lines
Even if we decide that this is needed after all, it would be helpful to explain some background here about what this name is used for, as others may have the same question.
Okay, I will add some details on it.
Quoted 10 lines
virtio-gpio.tex line 68
Quoted 7 lines
+\item[\field{gpio_names}] field is optional for a device to implement. If this
virtio-gpio.tex new file +6
-0+ field isn't implemented by the device, then the device must set the + \field{names_size} field to zero. If this field is implemented by the + device, then it must contain a stream of \field{ngpio} zero-terminated + strings, where each string represents the name of a GPIO line, present in + increasing order of the GPIO line numbers. The GPIO line names must + be unique within a GPIO Device and must not be empty string.Also here, maybe add a sentence to explain what the gpio names are used for and what they are not used for.
Okay, will do. Though this field is going away now (after Michael's feedback) and
a request will take its place.
Quoted 11 lines
virtio-gpio.tex line 112
Quoted 9 lines
virtio-gpio.tex new file +9
-0+A request is initiated by the sender by adding a buffer of type \field{struct +virtio_gpio_msg} to its respective virtqueue, after setting all fields of the +message and \field{type} field with one of the message types from +\field{VIRTIO_GPIO_MSG_*}. + +In response, the receiver adds a copy of the same buffer on its respective +virtqueue, after performing a logical OR operation to the \field{type} field +with VIRTIO_GPIO_MSG_RESPONSE mask and updating the \field{value} field based on +message type.So you have one virtqueue for a request and another virtqueue for the reply?
Yes, or I will say one for device to send message/response and one for driver.
Quoted 3 lines
As they are always treated as a transaction, wouldn't it be easier to have a single virtqueue and make each transaction have both an input and an output buffer?
parallel
That's what I did initially (and that's we did in I2C as well), but then I realised
that it may not work well with transactions done in parallel.
For example, we want to allow setting direction to input for pins 5 and 8 in parallel. I at that time thought that with using a single virtqueue for both request/response messages may block the virtqueue for further usage. But now that I think about it a bit more, it may not.
We should still be able to identify different response messages based on the address of the buffer (for example) and so what you are suggesting may actually work and won't be a bottleneck as I thought of it earlier.
If this works fine, I will move back to one virtqueue for all non-irq stuff, like I
had until V4 and one virtqueue only for interrupt processing.
Quoted 12 lines
Quoted 12 lines
virtio-gpio.tex new file +12
-0+#define VIRTIO_GPIO_MSG_GET_DIRECTION 0x0003 +#define VIRTIO_GPIO_MSG_SET_DIRECTION_IN 0x0004 +#define VIRTIO_GPIO_MSG_SET_DIRECTION_OUT 0x0005 +#define VIRTIO_GPIO_MSG_GET_VALUE 0x0006 +#define VIRTIO_GPIO_MSG_SET_VALUE 0x0007 + +/* GPIO response mask, to be Or'ed with one of the above */ +#define VIRTIO_GPIO_MSG_RESPONSE 0x8000 +\end{lstlisting} + +The response messages may contain error codes (in the \field{value} field) on +failures, they must be read as negative POSIX errno codes, unless stated
Quoted 8 lines
virtio-gpio.tex line 134
Quoted 2 lines
virtio-gpio.tex new file +2
-0+otherwise, i.e. 0 as success, and negative value as POSIX error code, positive +values as invalid, unless stated otherwise.I don't understand how POSIX errno codes are meant to be used here, as I'm not aware of any generic definition of binary values. If you mean the Linux errno values, those cannot be used here as they are certainly architecture specific. You have to enumerate the possible response codes that the device is allowed to return, and what the meaning behind those is.
That's what I thought earlier and had my own error types, but then Enrico suggested
using these and I thought, why not ?
Now that I looked at
https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
POSIX only defines meaning of various error names and don't attach a numerical value to them. So, we can't use them as is.
Quoted 11 lines
virtio-gpio.tex line 154
Quoted 4 lines
+\subsubsection{Device Operation: Free}\label{sec:Device Types / GPIO Device / Device Operation / Free }
virtio-gpio.tex new file +3
-0+ +The driver initiates this message to notify the device that a previously +requested line has been unassigned and can be deactivated.How is this intended to be used? Why is this not up to the guest kernel to keep track
of? I would expect that if a gpio line is listed in the information that the driver is free
to use it at any time without having to request it first.
Quoted 4 lines
While we do have the notion of gpiod_get/gpiod_put in the in-kernel interface, this is only used for arbitration between drivers (or driver vs user space) normally,
but not communicated with gpio controllers as far as I know.
I looked at kernel implementation of GPIO drivers and few of them have implemented request/free callbacks and they do read/write to hardware registers to do some controller specific stuff.
Moreover, the host may want to arbitrate GPIO pins between guests for example and would need something like this to make it work.
And so I thought the specification should always allow it.
--
Viresh
Re: [PATCH V5 1/2] virtio-gpio: Add the device specification
Quoted 15 lines · Viresh Kumar
Quoted 5 lines · Arnd Bergmann
Quoted 5 lines
virtio-gpio.tex new file +5
-0+ +All fields of this structure, except \field{gpio_names}, must always be set by +the device and all fields are read-only for the driver. + +\begin{description}Quoted 8 lines
virtio-gpio.tex line 47
Quoted 3 lines
+\item[\field{name}] is a zero-terminated string that represents the name of the
virtio-gpio.tex new file +2
-0+ GPIO device. The unused bytes in the string must be initialized to zero by + the device.I'm a bit confused about why you have both a combined "name" field and separate "
gpio_names" fields. I not too familiar with the internals of the gpio subsystem, but I see that in the devicetree bindings, we have only optional per gpio line names, but no name for the device itself.
Quoted 7 lines
The combined name is for distinguishing the GPIO controller at the guest, which is normally done in the kernel by assigning value from
dev_name(dev).With virtio-mmio nodes assigned randomly by hypervisors (like Qemu), those names may not be very useful. And so I thought that this name can be useful.
This eventually would get into
gpio_chip->labelfield at kernel.
I still don't quite get it. Why would the guest care about a stable name?
Shouldn't all users of the gpio node be handled through phandle references and similar?
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
+\item[\field{gpio_names}] field is optional for a device to implement. If this
virtio-gpio.tex new file +6
-0+ field isn't implemented by the device, then the device must set the + \field{names_size} field to zero. If this field is implemented by the + device, then it must contain a stream of \field{ngpio} zero-terminated + strings, where each string represents the name of a GPIO line, present in + increasing order of the GPIO line numbers. The GPIO line names must + be unique within a GPIO Device and must not be empty string.
Quoted 5 lines
Quoted 2 lines
Also here, maybe add a sentence to explain what the gpio names are used for and what they are not used for.
Okay, will do. Though this field is going away now (after Michael's feedback) and a request will take its place.
Right. Any thoughts about just having the names be part of the metadata in the DT? I think that sounds easier than the request, though both methods are fairly straightforward really.
Quoted 12 lines
Quoted 11 lines
virtio-gpio.tex line 112
Quoted 9 lines
virtio-gpio.tex new file +9
-0+A request is initiated by the sender by adding a buffer of type \field{struct +virtio_gpio_msg} to its respective virtqueue, after setting all fields of the +message and \field{type} field with one of the message types from +\field{VIRTIO_GPIO_MSG_*}. + +In response, the receiver adds a copy of the same buffer on its respective +virtqueue, after performing a logical OR operation to the \field{type} field +with VIRTIO_GPIO_MSG_RESPONSE mask and updating the \field{value} field based on +message type.So you have one virtqueue for a request and another virtqueue for the reply?
Quoted 1 line
Yes, or I will say one for device to send message/response and one for driver.
Ah, so maybe it's more like what I was looking for then after all, rather than what I understood you do.
To clarify: the flow as I now understand it is
- driver wants something (configuration, gpio read, gpio write, irq ack, ...):
driver sends a message with transmit and receive buffer on the first queue and gets a reply back immediately
- device wants something (only an irq):
driver sets up a message to receive a buffer for a line, device fills it when the event happens.
Quoted 5 lines
Quoted 3 lines
As they are always treated as a transaction, wouldn't it be easier to have a single virtqueue and make each transaction have both an input and an output buffer?
parallel
Quoted 8 lines
That's what I did initially (and that's we did in I2C as well), but then I realised
that it may not work well with transactions done in parallel.For example, we want to allow setting direction to input for pins 5 and 8 in parallel. I at that time thought that with using a single virtqueue for both request/response messages may block the virtqueue for further usage. But now that I think about it a bit more, it may not.
That should not be an issue. I think the reply would always be instantaneous here, and the requests can just be processed in order.
Quoted 3 lines
We should still be able to identify different response messages based on the address of the buffer (for example) and so what you are suggesting may actually work and won't be a bottleneck as I thought of it earlier.
Yes, I think that is rather normal operation for a virtqueue.
Quoted 2 lines
If this works fine, I will move back to one virtqueue for all non-irq stuff, like I had until V4 and one virtqueue only for interrupt processing.
ok, great.
Quoted 16 lines
Quoted 11 lines
virtio-gpio.tex line 154
Quoted 4 lines
+\subsubsection{Device Operation: Free}\label{sec:Device Types / GPIO Device / Device Operation / Free }
virtio-gpio.tex new file +3
-0+ +The driver initiates this message to notify the device that a previously +requested line has been unassigned and can be deactivated.How is this intended to be used? Why is this not up to the guest kernel to keep track
of? I would expect that if a gpio line is listed in the information that the driver is free
to use it at any time without having to request it first.Quoted 4 lines
While we do have the notion of gpiod_get/gpiod_put in the in-kernel interface, this is only used for arbitration between drivers (or driver vs user space) normally,
but not communicated with gpio controllers as far as I know.
Quoted 8 lines
I looked at kernel implementation of GPIO drivers and few of them have implemented request/free callbacks and they do read/write to hardware registers to do some controller specific stuff.
Moreover, the host may want to arbitrate GPIO pins between guests for example and would need something like this to make it work.
And so I thought the specification should always allow it.
Do you have an example for what the hardware driver would do here? Maybe LinusW can clarify whether he thinks it is needed.
Even if the hardware requires the request/free style calls in case of passing through a line to a guest, I would expect that can be handled in host user space, i.e. the virtio device code calls 'request' before it passes down a gpio line to a guest.
Arnd
Re: [PATCH V5 1/2] virtio-gpio: Add the device specification
Quoted 1 line · Arnd Bergmann
I still don't quite get it. Why would the guest care about a stable name?
For Linux userspace, debugging mostly, at guest userspace. Like what you get out of /sys/class/gpio/gpiochipN/label or in debugfs.
i.e. to easily identify the chip there since device names aren't fixed otherwise.
Though this was initially added by Enrico and I never though of removing it. If you still think it is a waste, will get rid of it.
Quoted 2 lines
Shouldn't all users of the gpio node be handled through phandle references and similar?
Yeah, users should be using that.
Quoted 3 lines
Right. Any thoughts about just having the names be part of the metadata in the DT? I think that sounds easier than the request, though both methods are fairly straightforward really.
I think we shouldn't divide stuff in between spec and DT as the spec can be used without DT as well. And so keeping them entirely in the spec may be better. The same holds true otherwise for number of gpio lines as well, or the entire config structure.
Quoted 2 lines
Ah, so maybe it's more like what I was looking for then after all, rather than what I understood you do.
Naah, you understood it correctly earlier.
Quoted 9 lines
To clarify: the flow as I now understand it is
- driver wants something (configuration, gpio read, gpio write, irq ack, ...):
driver sends a message with transmit and receive buffer on the first queue and gets a reply back immediately- device wants something (only an irq):
driver sets up a message to receive a buffer for a line, device fills it when the event happens.
And this is what I am going to do now :)
In the irq case, the driver must send a response message as well, to inform that interrupt is processed and it is ready for the next one.
Quoted 2 lines
That should not be an issue. I think the reply would always be instantaneous here, and the requests can just be processed in order.
They aren't required to be in order after all. Lets say 3 different requests are added by 3 different threads in guest, they can all reach in random order at the host and the host can send response to them in any order. At least in Linux, you can attach a void *data with each transfer and we can easily use that to identify the transfer which completed.
Quoted 1 line
Do you have an example for what the hardware driver would do here?
Activate functioning of a pin ?
I see many drivers in Linux who do some reg read/write in request, not exactly sure what's going on but something on the lines of activating/deactivating a line. Examples: gpio-cadence.c, gpio-din2.c, gpio-cs5535.c, gpio-mb86s7x.c, etc.
Quoted 1 line
Maybe LinusW can clarify whether he thinks it is needed.
+1
Quoted 4 lines
Even if the hardware requires the request/free style calls in case of passing through a line to a guest, I would expect that can be handled in host user space, i.e. the virtio device code calls 'request' before it passes down a gpio line to a guest.
That may not always work and this count of refcounting at the backend daemon may not be correct.
So, the guest calls set-direction-out-with-val-1, the backend activates the GPIO pin, sets direction/value and then deactivates it ? That won't work, right ?
On those lines, I think these operations must be renamed to ACTIVATE/DEACTIVATE instead of REQUEST/FREE, that is what we want to do here.
Signature · 1 line
viresh
[virtio-dev] Re: [PATCH V5 1/2] virtio-gpio: Add the device specification
Quoted 4 lines · Viresh Kumar
Quoted 1 line · Arnd Bergmann
I still don't quite get it. Why would the guest care about a stable name?
Quoted 8 lines
For Linux userspace, debugging mostly, at guest userspace. Like what you get out of
/sys/class/gpio/gpiochipN/labelor in debugfs.i.e. to easily identify the chip there since device names aren't fixed otherwise.
Though this was initially added by Enrico and I never though of removing it. If you still think it is a waste, will get rid of it.
I still don't see it as an important enough part of the interface to be encoded in the virtio spec. In the most likely use cases I can think of, you would never need more than one gpio controller in a virtio machine, since you can have an arbitrary number of lines connected to it already.
This also simplifies the host side, as it avoids requiring the host to configure a name that ends up being the same almost always.
If Linus or Bartosz think we should have the name, leave it in there, otherwise I'd remove it.
Quoted 8 lines
Quoted 3 lines
Right. Any thoughts about just having the names be part of the metadata in the DT? I think that sounds easier than the request, though both methods are fairly straightforward really.
I think we shouldn't divide stuff in between spec and DT as the spec can be used without DT as well. And so keeping them entirely in the spec may be better. The same holds true otherwise for number of gpio lines as well, or the entire config structure.
Encoding the number of gpio lines in the config registers makes sense to me, but I don't see how you can sensibly get away without some other structure to describe what the lines are. It doesn't have to be DT, but that's what we use in practice.
Quoted 8 lines
Quoted 2 lines
That should not be an issue. I think the reply would always be instantaneous here, and the requests can just be processed in order.
They aren't required to be in order after all. Lets say 3 different requests are added by 3 different threads in guest, they can all reach in random order at the host and the host can send response to them in any order. At least in Linux, you can attach a void *data with each transfer and we can easily use that to identify the transfer which completed.
Ok, good.
Quoted 5 lines
Quoted 4 lines
Even if the hardware requires the request/free style calls in case of passing through a line to a guest, I would expect that can be handled in host user space, i.e. the virtio device code calls 'request' before it passes down a gpio line to a guest.
Quoted 8 lines
That may not always work and this count of refcounting at the backend daemon may not be correct.
So, the guest calls set-direction-out-with-val-1, the backend activates the GPIO pin, sets direction/value and then deactivates it ? That won't work, right ?
On those lines, I think these operations must be renamed to ACTIVATE/DEACTIVATE instead of REQUEST/FREE, that is what we want to do here.
From the drivers you pointed to, it seems to be something like a 'disconnected' state where the pin is neither input nor output, so this could perhaps get reflected
in the interface as well, by having each pin be one of IN/OUT/NONE. Not sure if that is any better.
Arnd
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
Re: [PATCH V5 1/2] virtio-gpio: Add the device specification
Quoted 10 lines · Arnd Bergmann
I still don't see it as an important enough part of the interface to be encoded in the virtio spec. In the most likely use cases I can think of, you would never need more than one gpio controller in a virtio machine, since you can have an arbitrary number of lines connected to it already.
This also simplifies the host side, as it avoids requiring the host to configure a name that ends up being the same almost always.
If Linus or Bartosz think we should have the name, leave it in there, otherwise I'd remove it.
I don't have a really good argument for keeping it, dropping it for now unless someone thinks it is important. :)
Quoted 4 lines
Encoding the number of gpio lines in the config registers makes sense to me, but I don't see how you can sensibly get away without some other structure to describe what the lines are. It doesn't have to be DT, but that's what we use in practice.
Yes, we normally end up defining them in DT via "gpio-line-names" binding, but I think it would be better to get them over the protocol instead here as this should be self sufficient. Something like DT will still be required to link users to the GPIO device, and that's outside of the scope of the protocol, so DT works well there.
Quoted 10 lines
Quoted 8 lines
That may not always work and this count of refcounting at the backend daemon may not be correct.
So, the guest calls set-direction-out-with-val-1, the backend activates the GPIO pin, sets direction/value and then deactivates it ? That won't work, right ?
On those lines, I think these operations must be renamed to ACTIVATE/DEACTIVATE instead of REQUEST/FREE, that is what we want to do here.
From the drivers you pointed to,
There were more, I just didn't get to them :)
Quoted 5 lines
it seems to be something like a 'disconnected'
state where the pin is neither input nor output, so this could perhaps get reflected
in the interface as well, by having each pin be one of IN/OUT/NONE. Not sure if that is any better.
I think keeping APIs like ACTIVATE/DEACTIVATE makes it cleaner, than adding another state of the PIN itself.
Signature · 1 line
viresh
Re: [PATCH V5 1/2] virtio-gpio: Add the device specification
In reply to Arnd BergmannHi Arnd,
Quoted 13 lines · Arnd Bergmann
Quoted 11 lines · Viresh Kumar
Quoted 1 line · Arnd Bergmann
I still don't quite get it. Why would the guest care about a stable name?
For Linux userspace, debugging mostly, at guest userspace. Like what you get out of
/sys/class/gpio/gpiochipN/labelor in debugfs.i.e. to easily identify the chip there since device names aren't fixed otherwise.
Though this was initially added by Enrico and I never though of removing it. If you still think it is a waste, will get rid of it.
Quoted 7 lines
I still don't see it as an important enough part of the interface to be encoded in the virtio spec. In the most likely use cases I can think of, you would never need more than one gpio controller in a virtio machine, since you can have an arbitrary number of lines connected to it already.
This also simplifies the host side, as it avoids requiring the host to configure a name that ends up being the same almost always.
Exactly, using the GPIO aggregator you can aggregate all GPIOs you want to export to a specific guest, followed by adjusting the permissions on the newly created /dev/gpiochip*.
Note to $self: look into interrupt support for the GPIO Aggregator.
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH V5 1/2] virtio-gpio: Add the device specification
In reply to Viresh KumarQuoted 16 lines · Viresh Kumar
Quoted 3 lines · Arnd Bergmann
As they are always treated as a transaction, wouldn't it be easier to have a single virtqueue and make each transaction have both an input and an output buffer?
parallel
That's what I did initially (and that's we did in I2C as well), but then I realised
that it may not work well with transactions done in parallel.For example, we want to allow setting direction to input for pins 5 and 8 in parallel. I at that time thought that with using a single virtqueue for both request/response messages may block the virtqueue for further usage. But now that I think about it a bit more, it may not.
Quoted 7 lines
We should still be able to identify different response messages based on the address of the buffer (for example) and so what you are suggesting may actually work and won't be a bottleneck as I thought of it earlier.
If this works fine, I will move back to one virtqueue for all non-irq stuff, like I
had until V4 and one virtqueue only for interrupt processing.
Okay, I tested this and it works. I was able to send multiple requests in parallel and it worked out fine.
So I am going to switch back to what I had earlier, i.e. one virtqueue for all requests originating from driver and its response from device.
And a different virtqueue for interrupts.
Signature · 1 line
viresh
Re: [PATCH V5 1/2] virtio-gpio: Add the device specification
In reply to Viresh KumarHi Viresh,
Quoted 10 lines · Viresh Kumar
virtio-gpio is a virtual GPIO controller. It provides a way to flexibly communicate with the host GPIO controllers from the guest.
This patch adds the specification for it.
Based on the initial work posted by:
"Enrico Weigelt, metux IT consult" <[email protected]>.
Thanks for your patch!
Disclaimer: IANAVP (not a virtio person here ;-)
Quoted 30 lines
virtio-gpio.tex new file +27
-0@@ -0,0 +1,317 @@ +\section{General Purpose IO Device}\label{sec:Device Types / GPIO Device} + +The Virtio GPIO device is a virtual general purpose IO device that supports a +variable number of named IO lines, which can be configured in input mode or in +output mode with logical level low (0) or high (1). + +\subsection{Device ID}\label{sec:Device Types / GPIO Device / Device ID} +41 + +\subsection{Virtqueues}\label{sec:Device Types / GPIO Device / Virtqueues} + +\begin{description} +\item[0] txq (driver to device) +\item[1] rxq (device to driver) +\end{description} + +The \field{txq} virtqueue is used by the driver to send messages to the device +and the \field{rxq} virtqueue is used by the device to send messages to the +driver. + +\subsection{Feature bits}\label{sec:Device Types / GPIO Device / Feature bits} + +None currently defined. + +\subsection{Device configuration layout}\label{sec:Device Types / GPIO Device / Device configuration layout} + +GPIO device uses the following structure layout for configuration:
virtio-gpio.tex line 37
Quoted 10 lines
virtio-gpio.tex new file +10
-0+ +\begin{lstlisting} +struct virtio_gpio_config { + u8 name[32]; + le16 ngpio; + le16 names_offset; + le32 names_size; + + /* at offset defined by names_offset field */ + u8 gpio_names[];
Is this the standard (virtio) way to define fields like this? Personally, I would write "__gpio_names[]", to make it more obvious if some code tries to access the field directly.
Of course the real implementation should provide a macro/function to access the names in a safe way.
Quoted 23 lines
virtio-gpio.tex new file +23
-0+}; +\end{lstlisting} + +All fields of this structure, except \field{gpio_names}, must always be set by +the device and all fields are read-only for the driver. + +\begin{description} +\item[\field{name}] is a zero-terminated string that represents the name of the + GPIO device. The unused bytes in the string must be initialized to zero by + the device. + +\item[\field{ngpio}] is the total number of GPIO lines supported by the device. + +\item[\field{names_offset}] is the offset of the \field{gpio_names} field from + the base address of the \field{struct virtio_gpio_config}. The device must + set its value to 40 for current version of the specification. In future this + value may change if the \field {struct virtio_gpio_config} is expanded by + adding more fields to it. + +\item[\field{names_size}] is the size of the \field{gpio_names} memory block. + The device must set it to the size, in bytes, of the \field{gpio_names} + field. The device must set this to zero, if the \field{gpio_names} field + isn't implemented by the device.
virtio-gpio.tex line 70
Quoted 10 lines
virtio-gpio.tex new file +10
-0+ +\item[\field{gpio_names}] field is optional for a device to implement. If this + field isn't implemented by the device, then the device must set the + \field{names_size} field to zero. If this field is implemented by the + device, then it must contain a stream of \field{ngpio} zero-terminated + strings, where each string represents the name of a GPIO line, present in + increasing order of the GPIO line numbers. The GPIO line names must + be unique within a GPIO Device and must not be empty string. + +\end{description}
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH V5 1/2] virtio-gpio: Add the device specification
Quoted 5 lines · Geert Uytterhoeven
Is this the standard (virtio) way to define fields like this? Personally, I would write "__gpio_names[]", to make it more obvious if some code tries to access the field directly.
Of course the real implementation should provide a macro/function to access the names in a safe way.
Looks like this field is going away and we need a separate request for this.
Thanks for taking time to look at this.
--
viresh
Re: [PATCH V5 1/2] virtio-gpio: Add the device specification
In reply to Viresh KumarQuoted 11 lines · Viresh Kumar
+\begin{lstlisting}
virtio-gpio.tex new file +10
-0+struct virtio_gpio_config { + u8 name[32]; + le16 ngpio; + le16 names_offset; + le32 names_size; + + /* at offset defined by names_offset field */ + u8 gpio_names[]; +}; +\end{lstlisting}
...
virtio-gpio.tex line 70
Quoted 10 lines
virtio-gpio.tex new file +10
-0+ +\item[\field{gpio_names}] field is optional for a device to implement. If this + field isn't implemented by the device, then the device must set the + \field{names_size} field to zero. If this field is implemented by the + device, then it must contain a stream of \field{ngpio} zero-terminated + strings, where each string represents the name of a GPIO line, present in + increasing order of the GPIO line numbers. The GPIO line names must + be unique within a GPIO Device and must not be empty string. + +\end{description}
There's a problem with this approach: config space size is actually pretty limited since it might be in the IO space when using PCI. That is turn is recommended not to exceed 256 bytes. Is it important to have the names accessible before driver is fully initialized? If not I would just create a VQ
and use that to retrieve this data.
Note: the competing virtio-gpio proposal on list shares the issue.
Signature · 1 line
MST
Re: [PATCH V5 1/2] virtio-gpio: Add the device specification
Quoted 18 lines · Michael S. Tsirkin
Quoted 17 lines · Viresh Kumar
+\begin{lstlisting}
virtio-gpio.tex new file +16
-0+struct virtio_gpio_config { + u8 name[32]; + le16 ngpio; + le16 names_offset; + le32 names_size; + + /* at offset defined by names_offset field */ + u8 gpio_names[]; +}; +\end{lstlisting} + +\item[\field{gpio_names}] field is optional for a device to implement. If this + field isn't implemented by the device, then the device must set the + \field{names_size} field to zero. If this field is implemented by the + device, then it must contain a stream of \field{ngpio} zero-terminated + strings, where each string represents the name of a GPIO line, present in
Quoted 8 lines
virtio-gpio.tex line 70
Quoted 4 lines
virtio-gpio.tex new file +4
-0+ increasing order of the GPIO line numbers. The GPIO line names must + be unique within a GPIO Device and must not be empty string. + +\end{description}There's a problem with this approach: config space size is actually pretty limited since it might be in the IO space when using PCI. That is turn is recommended not to exceed 256 bytes.
Hmm, interesting. This block of data, for gpio names, can be really large as well,
lets say if we have 256 GPIOs with each requiring 10 bytes for name, its over 2KB.
Yeah, that can't go with the config structure then.
Quoted 2 lines
Is it important to have the names accessible before driver is fully initialized?
Not really.
Quoted 1 line
If not I would just create a VQ and use that to retrieve this data.
For example in Linux we need this information before the GPIO device is registered with the framework and we can fetch data over virtio there.
Quoted 1 line
Note: the competing virtio-gpio proposal on list shares the issue.
Right.
Thanks Michael for your feedback.
--
viresh
PATCH v5 2/2 virtio-gpio: Add support for interrupts
In reply to Viresh KumarThis patch adds support for interrupts to the virtio-gpio specification. This uses the feature bit 0 for the same.
--- virtio-gpio.tex | 153 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 150 insertions(+), 3 deletions(-)
virtio-gpio.tex +150 -3
@@ -20,7 +20,9 @@ \subsection{Virtqueues}\label{sec:Device Types / GPIO Device / Virtqueues} \subsection{Feature bits}\label{sec:Device Types / GPIO Device / Feature bits} -None currently defined. +\begin{description} +\item[VIRTIO_GPIO_F_IRQ (0)] The device supports interrupts on GPIO lines. +\end{description} \subsection{Device configuration layout}\label{sec:Device Types / GPIO Device / Device configuration layout}
@@ -79,6 +81,12 @@ \subsection{Device Initialization}\label{sec:Device Types / GPIO Device / Device \item The driver MUST populate the \field{rxq} virtqueue with \field{struct virtio_gpio_msg} buffer. + +\item The driver MUST check the presence of \field{VIRTIO_GPIO_F_IRQ} feature + before initiating any IRQ messages. + +\item The device MUST mask interrupts on all the GPIO lines, if the + \field{VIRTIO_GPIO_F_IRQ} feature is supported. \end{itemize} \subsection{Device Operation}\label{sec:Device Types / GPIO Device / Device Operation}
@@ -111,8 +119,12 @@ \subsection{Device Operation}\label{sec:Device Types / GPIO Device / Device Oper with VIRTIO_GPIO_MSG_RESPONSE mask and updating the \field{value} field based on message type. -For the current version of the specification, the sender is always the driver -and receiver is always the device. +The device is the sender only for the messages of type +\field{VIRTIO_GPIO_MSG_IRQ_EVENT} and the device sends it over the \field{rxq} +virtqueue. + +The driver is the sender for all other message types and send them over +\field{txq} virtqueue. \begin{lstlisting} /* GPIO message types: driver -> device */
@@ -123,11 +135,27 @@ \subsection{Device Operation}\label{sec:Device Types / GPIO Device / Device Oper #define VIRTIO_GPIO_MSG_SET_DIRECTION_OUT 0x0005 #define VIRTIO_GPIO_MSG_GET_VALUE 0x0006 #define VIRTIO_GPIO_MSG_SET_VALUE 0x0007 +#define VIRTIO_GPIO_MSG_IRQ_TYPE 0x0008 +#define VIRTIO_GPIO_MSG_IRQ_MASK 0x0009 +#define VIRTIO_GPIO_MSG_IRQ_UNMASK 0x000a + +/* GPIO message type: from device -> driver */ +#define VIRTIO_GPIO_MSG_IRQ_EVENT 0x000b /* GPIO response mask, to be Or'ed with one of the above */ #define VIRTIO_GPIO_MSG_RESPONSE 0x8000 \end{lstlisting} +\begin{lstlisting} +/* GPIO interrupt type */ +#define VIRTIO_GPIO_IRQ_TYPE_NONE 0x00 +#define VIRTIO_GPIO_IRQ_TYPE_EDGE_RISING 0x01 +#define VIRTIO_GPIO_IRQ_TYPE_EDGE_FALLING 0x02 +#define VIRTIO_GPIO_IRQ_TYPE_EDGE_BOTH 0x03 +#define VIRTIO_GPIO_IRQ_TYPE_LEVEL_HIGH 0x04 +#define VIRTIO_GPIO_IRQ_TYPE_LEVEL_LOW 0x08 +\end{lstlisting} + The response messages may contain error codes (in the \field{value} field) on failures, they must be read as negative POSIX errno codes, unless stated otherwise, i.e. 0 as success, and negative value as POSIX error code, positive
@@ -238,6 +266,81 @@ \subsubsection{Device Operation: Set Value}\label{sec:Device Types / GPIO Device \hline \end{tabular} +\subsubsection{Device Operation: IRQ Type}\label{sec:Device Types / GPIO Device / Device Operation / IRQ Type } + +The driver initiates this message to request the device to set the IRQ trigger +type to one of the \field{VIRTIO_GPIO_IRQ_TYPE_*} values, for a line configured +for input. + +This request is only allowed if the \field{VIRTIO_GPIO_F_IRQ} feature is +supported by the device. + +\begin{tabular}{ |l||l|l|l| } +\hline +Fields & \field{type} & \field{gpio} & \field{value} \\ +\hline +Message & \field{VIRTIO_GPIO_MSG_IRQ_TYPE} & line number & one of \field{VIRTIO_GPIO_IRQ_TYPE_*} \\ +\hline +Response & \field{VIRTIO_GPIO_MSG_IRQ_TYPE} \newline | \field{VIRTIO_GPIO_MSG_RESPONSE} & line number & 0 = success, \newline or -errno = failure \\ +\hline +\end{tabular} + +\subsubsection{Device Operation: IRQ Mask}\label{sec:Device Types / GPIO Device / Device Operation / IRQ Mask } + +The driver initiates this message to request the device to mask IRQ on a GPIO +line configured for input. + +This request is only allowed if the \field{VIRTIO_GPIO_F_IRQ} feature is +supported by the device. + +\begin{tabular}{ |l||l|l|l| } +\hline +Fields & \field{type} & \field{gpio} & \field{value} \\ +\hline +Message & \field{VIRTIO_GPIO_MSG_IRQ_MASK} & line number & 0 \\ +\hline +Response & \field{VIRTIO_GPIO_MSG_IRQ_MASK} \newline | \field{VIRTIO_GPIO_MSG_RESPONSE} & line number & 0 = success, \newline or -errno = failure \\ +\hline +\end{tabular} + +\subsubsection{Device Operation: IRQ Unmask}\label{sec:Device Types / GPIO Device / Device Operation / IRQ Unmask } + +The driver initiates this message to request the device to unmask IRQ on a GPIO +line configured for input. + +This request is only allowed if the \field{VIRTIO_GPIO_F_IRQ} feature is +supported by the device. + +\begin{tabular}{ |l||l|l|l| } +\hline +Fields & \field{type} & \field{gpio} & \field{value} \\ +\hline +Message & \field{VIRTIO_GPIO_MSG_IRQ_UNMASK} & line number & 0 \\ +\hline +Response & \field{VIRTIO_GPIO_MSG_IRQ_UNMASK} \newline | \field{VIRTIO_GPIO_MSG_RESPONSE} & line number & 0 = success, \newline or -errno = failure \\ +\hline +\end{tabular} + +\subsubsection{Device Operation: IRQ Event}\label{sec:Device Types / GPIO Device / Device Operation / IRQ Event } + +The device initiates this message to notify the driver of an IRQ event on a line +previously configured for interrupt. + +This request is only allowed if the \field{VIRTIO_GPIO_F_IRQ} feature is +supported by the device. + +This is the only message which is initiated by the device and not the driver. + +\begin{tabular}{ |l||l|l|l| } +\hline +Fields & \field{type} & \field{gpio} & \field{value} \\ +\hline +Message & \field{VIRTIO_GPIO_MSG_IRQ_EVENT} & line number & 0 \\ +\hline +Response & \field{VIRTIO_GPIO_MSG_IRQ_EVENT} \newline | \field{VIRTIO_GPIO_MSG_RESPONSE} & line number & 0 = success, \newline or -errno = failure \\ +\hline +\end{tabular} + \drivernormative{\subsubsection}{Device Operation}{Device Types / GPIO Device / Device Operation} \begin{itemize}
@@ -252,6 +355,11 @@ \subsubsection{Device Operation: Set Value}\label{sec:Device Types / GPIO Device \item The driver MUST NOT initiate another message for a GPIO line, before response to the previously sent message is received for the same line. + +\item The driver MUST NOT send IRQ messages for a GPIO line configured for output. + +\item The driver MUST NOT initiate IRQ messages if the \field{VIRTIO_GPIO_F_IRQ} + feature is not supported by the device. \end{itemize} \devicenormative{\subsubsection}{Device Operation}{Device Types / GPIO Device / Device Operation}
@@ -315,3 +423,42 @@ \subsubsection{Driver Requests}\label{sec:Device Types / GPIO Device / Message F \item The driver can initiate an request for a different GPIO line before receiving response for a previous request for another line. \end{itemize} + +\subsubsection{Device Interrupts}\label{sec:Device Types / GPIO Device / Message Flow / Interrupts} + +The \field{VIRTIO_GPIO_MSG_IRQ_EVENT} message type can only be initiated by the +device and sent to the driver over the \field{rxq} virtqueue. + +\begin{itemize} +\item The device, on sensing an interrupt for a GPIO line, prepares a buffer of + type \field{struct virtio_gpio_msg} and sets its \field{type} to + \field{VIRTIO_GPIO_MSG_IRQ_EVENT}, \field{gpio} field with a GPIO line + number, and \field{value} field to 0. + +\item The device sends the buffer to the driver over the \field{rxq} virtqueue. + +\item The device MUST NOT initiate another interrupt request for the same GPIO + line before receiving a response from the driver. + +\item The driver, after receiving the buffer from the driver, handles the + interrupt. + +\item The driver at this point may initiate a new request (like masking of the + IRQ line) and send it over to the device over the \field{txq} virtqueue. + The device must respond to them, without waiting for a response to the + IRQ itself. + +\item The driver prepares a buffer of type \field{struct virtio_gpio_msg} and + sets its \field{type} field to (\field{VIRTIO_GPIO_MSG_IRQ_EVENT} | + \field{VIRTIO_GPIO_MSG_RESPONSE}), \field{gpio} field with \field{gpio} of + the received buffer, and \field{value} to message defined value. + +\item The driver sends the buffer to the device over the \field{txq} virtqueue. + +\item The device receives and processes the buffer. + +\item The device can initiate another IRQ request for the same GPIO line now. + +\item The driver can initiate an IRQ request for a different GPIO line before + receiving response for a previous IRQ request for another line. +\end{itemize}
Signature · 6 lines
2.31.1.272.g89b43f80a514 --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
virtio-gpio.tex \subsubsection{Device Operation: Set Value}\label{sec:Device Types / GPIO Device · line 276
Quoted 9 lines · Viresh Kumar
+\subsubsection{Device Operation: IRQ Type}\label{sec:Device Types / GPIO Device / Device Operation / IRQ Type }
virtio-gpio.tex +7
-0+ +The driver initiates this message to request the device to set the IRQ trigger +type to one of the \field{VIRTIO_GPIO_IRQ_TYPE_*} values, for a line configured +for input. + +This request is only allowed if the \field{VIRTIO_GPIO_F_IRQ} feature is +supported by the device.
Is there a way for the driver to know which trigger types are supported on a given line? If not, would that be useful, or do we assume that this knowledge exists in the place that sets the trigger type based on e.g. device tree data?
Quoted 9 lines
+\subsubsection{Device Operation: IRQ Event}\label{sec:Device Types / GPIO Device / Device Operation / IRQ Event }
virtio-gpio.tex +8
-0+ +The device initiates this message to notify the driver of an IRQ event on a line +previously configured for interrupt. + +This request is only allowed if the \field{VIRTIO_GPIO_F_IRQ} feature is +supported by the device. + +This is the only message which is initiated by the device and not the driver.
virtio-gpio.tex \subsubsection{Device Operation: Set Value}\label{sec:Device Types / GPIO Device · line 342
Quoted 10 lines
virtio-gpio.tex +10
-0+ +\begin{tabular}{ |l||l|l|l| } +\hline +Fields & \field{type} & \field{gpio} & \field{value} \\ +\hline +Message & \field{VIRTIO_GPIO_MSG_IRQ_EVENT} & line number & 0 \\ +\hline +Response & \field{VIRTIO_GPIO_MSG_IRQ_EVENT} \newline | \field{VIRTIO_GPIO_MSG_RESPONSE} & line number & 0 = success, \newline or -errno = failure \\ +\hline +\end{tabular}
Can you clarify what "initiated by the device" means here? Do you mean the driver has to pre-fill the rxq with message buffers and the device picks one of them? In this case I would not call it "initiated by the device", unless that terminology is what the virtio spec calls the same thing elsewhere.
For the 'errno' value, see my comments on patch 1/2.
Quoted 18 lines
+\subsubsection{Device Interrupts}\label{sec:Device Types / GPIO Device / Message Flow / Interrupts}
virtio-gpio.tex +17
-0+ +The \field{VIRTIO_GPIO_MSG_IRQ_EVENT} message type can only be initiated by the +device and sent to the driver over the \field{rxq} virtqueue. + +\begin{itemize} +\item The device, on sensing an interrupt for a GPIO line, prepares a buffer of + type \field{struct virtio_gpio_msg} and sets its \field{type} to + \field{VIRTIO_GPIO_MSG_IRQ_EVENT}, \field{gpio} field with a GPIO line + number, and \field{value} field to 0. + +\item The device sends the buffer to the driver over the \field{rxq} virtqueue. + +\item The device MUST NOT initiate another interrupt request for the same GPIO + line before receiving a response from the driver. + +\item The driver, after receiving the buffer from the driver, handles the + interrupt.
virtio-gpio.tex \subsubsection{Driver Requests}\label{sec:Device Types / GPIO Device / Message F · line 454
Quoted 10 lines
virtio-gpio.tex +10
-0+ +\item The driver at this point may initiate a new request (like masking of the + IRQ line) and send it over to the device over the \field{txq} virtqueue. + The device must respond to them, without waiting for a response to the + IRQ itself. + +\item The driver prepares a buffer of type \field{struct virtio_gpio_msg} and + sets its \field{type} field to (\field{VIRTIO_GPIO_MSG_IRQ_EVENT} | + \field{VIRTIO_GPIO_MSG_RESPONSE}), \field{gpio} field with \field{gpio} of + the received buffer, and \field{value} to message defined value.
Ah, ok. So the driver does have to fill in a request for an irq event on this particular line first for the rxq, not just a generic "send me something" request.
I think that makes sense, but I find the way you describe it confusing, so this should be explained a little better in the "Device Operation: IRQ Event" subsubsection, even if you end up repeating yourself here.
I'm missing a bit here to explain how edge vs level interrupts are handled. In particular:
- for an edge interrupt, what happens when a new event comes between the VIRTIO_GPIO_MSG_IRQ_EVENT message and the new buffer getting queued? Will the device send another irq-event message, does it not send one, or is this implementation defined?
- for level triggered interrupts, how does the driver know that the event response has been received by the device? Does this not require a more complicated handshake?
Arnd
Re: [virtio-dev] Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
Quoted 14 lines · Arnd Bergmann
virtio-gpio.tex \subsubsection{Device Operation: Set Value}\label{sec:Device Types / GPIO Device · line 276
Quoted 8 lines · Viresh Kumar
+\subsubsection{Device Operation: IRQ Type}\label{sec:Device Types / GPIO Device / Device Operation / IRQ Type }
virtio-gpio.tex +7
-0+ +The driver initiates this message to request the device to set the IRQ trigger +type to one of the \field{VIRTIO_GPIO_IRQ_TYPE_*} values, for a line configured +for input. + +This request is only allowed if the \field{VIRTIO_GPIO_F_IRQ} feature is +supported by the device.Is there a way for the driver to know which trigger types are supported on a given line? If not, would that be useful, or do we assume that this knowledge exists in the place that sets the trigger type based on e.g. device tree data?
I think it would be better to not send data partially via DT, as it may not be available for all the use cases.
So, if something is needed, then it should be made available over the protocol itself.
I assumed that we can take it for granted that all trigger types are supported, but maybe not.
FWIW, I also took reference from another GPIO protocol developed for greybus:
https://github.com/projectara/greybus-spec/blob/master/source/bridged_phy.rst#gpio-protocol
and it also assumed all interrupt types would be supported.
I am fine with adding a field for that in the configuration structure, if you think it
would make sense.
Quoted 13 lines
Quoted 13 lines
+\subsubsection{Device Operation: IRQ Event}\label{sec:Device Types / GPIO Device / Device Operation / IRQ Event }
virtio-gpio.tex +12
-0+ +The device initiates this message to notify the driver of an IRQ event on a line +previously configured for interrupt. + +This request is only allowed if the \field{VIRTIO_GPIO_F_IRQ} feature is +supported by the device. + +This is the only message which is initiated by the device and not the driver. + +\begin{tabular}{ |l||l|l|l| } +\hline +Fields & \field{type} & \field{gpio} & \field{value} \\
Quoted 8 lines
virtio-gpio.tex \subsubsection{Device Operation: Set Value}\label{sec:Device Types / GPIO Device · line 342
Quoted 6 lines
+\hline
virtio-gpio.tex +5
-0+Message & \field{VIRTIO_GPIO_MSG_IRQ_EVENT} & line number & 0 \\ +\hline +Response & \field{VIRTIO_GPIO_MSG_IRQ_EVENT} \newline | \field{VIRTIO_GPIO_MSG_RESPONSE} & line number & 0 = success, \newline or -errno = failure \\ +\hline +\end{tabular}Can you clarify what "initiated by the device" means here?
I meant the initial message is sent by the device (host) and the driver (guest) responds with success/failure.
Quoted 3 lines
Do you mean
the driver has to pre-fill the rxq with message buffers and the device picks one of them?
This is how it works technically I think. AFAIU, the driver needs to keep the buffers filled (even for the responses to the messages initiated at the driver).
Quoted 3 lines
In this case I would not call it "initiated by
the device", unless that terminology is what the virtio spec calls the same thing elsewhere.
I am not sure what that should be called as either, maybe virtio-spec maintainers
can share the preferred way.
Cornelia, Michael?
Quoted 4 lines
virtio-gpio.tex \subsubsection{Driver Requests}\label{sec:Device Types / GPIO Device / Message F · line 454
Quoted 4 lines
+\item The driver prepares a buffer of type \field{struct
virtio_gpio_msg} andvirtio-gpio.tex +3
-0+ sets its \field{type} field to (\field{VIRTIO_GPIO_MSG_IRQ_EVENT} | + \field{VIRTIO_GPIO_MSG_RESPONSE}), \field{gpio} field with \field{gpio} of + the received buffer, and \field{value} to message defined value.
This is the response message that the driver sends on receiving an interrupt, this
isn't pre-filled and is sent on txq instead of rxq.
Quoted 3 lines
Ah, ok. So the driver does have to fill in a request for an irq event on this particular line first for the rxq, not just a generic "send me something" request.
Yes, and the driver also needs to add buffers here for receiving response to the messages initiated by the driver.
Quoted 3 lines
I think that makes sense, but I find the way you describe it confusing, so this should be explained a little better in the "Device Operation: IRQ Event" subsubsection, even if you end up repeating yourself here.
Okay.
Quoted 7 lines
I'm missing a bit here to explain how edge vs level interrupts are handled. In particular:
- for an edge interrupt, what happens when a new event comes between the
VIRTIO_GPIO_MSG_IRQ_EVENTmessage and the new buffer getting queued? Will the device send another irq-event message, does it not send one, or is this implementation defined?
The device MUST not send another irq request for the same GPIO line, until the time it has received a response from the driver. Once the response has arrived at the device, it can raise the interrupt again if the level interrupt is
still active.
We should see it like how interrupts are handled in kernel, once an interrupt comes we disable it until the time the handler has got a chance to run, and the handler here is at the driver.
Quoted 3 lines
- for level triggered interrupts, how does the driver know that the event response has been received by the device? Does this not require a more complicated handshake?
Okay, maybe there is something I need to improve here if this isn't clear..
Every virtio-gpio transfer has two parts, a message is sent (maybe I should call it Request instead as I did earlier) by the sender, and receiver sends a response
after processing the message.
The device (host) is sender for the irq-message, and it will wait until a response
is received from the driver (guest) for the same. That can be seen as returning from an irq-handler in kernel for example, at which point interrupt gets enabled again.
Was I able to clarify it ?
--
viresh
Re: [virtio-dev] Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
Quoted 16 lines · Viresh Kumar
Quoted 14 lines · Arnd Bergmann
virtio-gpio.tex \subsubsection{Device Operation: Set Value}\label{sec:Device Types / GPIO Device · line 276
Quoted 8 lines · Viresh Kumar
+\subsubsection{Device Operation: IRQ Type}\label{sec:Device Types / GPIO Device / Device Operation / IRQ Type }
virtio-gpio.tex +7
-0+ +The driver initiates this message to request the device to set the IRQ trigger +type to one of the \field{VIRTIO_GPIO_IRQ_TYPE_*} values, for a line configured +for input. + +This request is only allowed if the \field{VIRTIO_GPIO_F_IRQ} feature is +supported by the device.Is there a way for the driver to know which trigger types are supported on a given line? If not, would that be useful, or do we assume that this knowledge exists in the place that sets the trigger type based on e.g. device tree data?
Quoted 8 lines
I think it would be better to not send data partially via DT, as it may not be available for all the use cases.
So, if something is needed, then it should be made available over the protocol itself.
I assumed that we can take it for granted that all trigger types are supported, but maybe not.
What I meant is that the guest OS kernel would only ever set a trigger type that makes sense based on what the device on the other end of the GPIO line needs, and this would be encoded in the interrupt-cells.
Quoted 8 lines
FWIW, I also took reference from another GPIO protocol developed for greybus:
https://github.com/projectara/greybus-spec/blob/master/source/bridged_phy.rst#gpio-protocol
and it also assumed all interrupt types would be supported.
I am fine with adding a field for that in the configuration structure, if you think it would make sense.
Let's see what the gpio maintainers think
Quoted 33 lines
Quoted 13 lines
Quoted 13 lines
+\subsubsection{Device Operation: IRQ Event}\label{sec:Device Types / GPIO Device / Device Operation / IRQ Event }
virtio-gpio.tex +12
-0+ +The device initiates this message to notify the driver of an IRQ event on a line +previously configured for interrupt. + +This request is only allowed if the \field{VIRTIO_GPIO_F_IRQ} feature is +supported by the device. + +This is the only message which is initiated by the device and not the driver. + +\begin{tabular}{ |l||l|l|l| } +\hline +Fields & \field{type} & \field{gpio} & \field{value} \\Quoted 8 lines
virtio-gpio.tex \subsubsection{Device Operation: Set Value}\label{sec:Device Types / GPIO Device · line 342
Quoted 6 lines
+\hline
virtio-gpio.tex +5
-0+Message & \field{VIRTIO_GPIO_MSG_IRQ_EVENT} & line number & 0 \\ +\hline +Response & \field{VIRTIO_GPIO_MSG_IRQ_EVENT} \newline | \field{VIRTIO_GPIO_MSG_RESPONSE} & line number & 0 = success, \newline or -errno = failure \\ +\hline +\end{tabular}Can you clarify what "initiated by the device" means here?
I meant the initial message is sent by the device (host) and the driver (guest) responds with success/failure.
Quoted 3 lines
Do you mean
the driver has to pre-fill the rxq with message buffers and the device picks one of them?This is how it works technically I think. AFAIU, the driver needs to keep the buffers filled (even for the responses to the messages initiated at the driver).
Quoted 8 lines
Quoted 3 lines
In this case I would not call it "initiated by
the device", unless that terminology is what the virtio spec calls the same thing elsewhere.I am not sure what that should be called as either, maybe virtio-spec maintainers can share the preferred way.
Cornelia, Michael?
Ok, let's see what they think. I would have found this less confusing if you just describe what message the driver sends and how the device responds to it.
Quoted 8 lines
Quoted 4 lines
virtio-gpio.tex \subsubsection{Driver Requests}\label{sec:Device Types / GPIO Device / Message F · line 454
Quoted 4 lines
+\item The driver prepares a buffer of type \field{struct
virtio_gpio_msg} andvirtio-gpio.tex +3
-0+ sets its \field{type} field to (\field{VIRTIO_GPIO_MSG_IRQ_EVENT} | + \field{VIRTIO_GPIO_MSG_RESPONSE}), \field{gpio} field with \field{gpio} of + the received buffer, and \field{value} to message defined value.This is the response message that the driver sends on receiving an interrupt, this isn't pre-filled and is sent on txq instead of rxq.
Quoted 6 lines
Quoted 3 lines
Ah, ok. So the driver does have to fill in a request for an irq event on this particular line first for the rxq, not just a generic "send me something" request.
Yes, and the driver also needs to add buffers here for receiving response to the messages initiated by the driver.
Ok, I think that needs to be made clearer here. I'm still not sure I have understood exactly what messages you
Quoted 8 lines
Quoted 7 lines
I'm missing a bit here to explain how edge vs level interrupts are handled. In particular:
- for an edge interrupt, what happens when a new event comes between the
VIRTIO_GPIO_MSG_IRQ_EVENTmessage and the new buffer getting queued? Will the device send another irq-event message, does it not send one, or is this implementation defined?
Quoted 4 lines
The device MUST not send another irq request for the same GPIO line, until the time it has received a response from the driver. Once the response has arrived at the device, it can raise the interrupt again if the level interrupt is still active.
The part about not sending another interrupt is the easy part. What I mean is what happens if another edge event comes into the gpio controller before the driver responds. Does the device immediately send another interrupt message or does it skip that?
Quoted 14 lines
We should see it like how interrupts are handled in kernel, once an interrupt comes we disable it until the time the handler has got a chance to run, and the handler here is at the driver.
Quoted 3 lines
- for level triggered interrupts, how does the driver know that the event response has been received by the device? Does this not require a more complicated handshake?
Okay, maybe there is something I need to improve here if this isn't clear..
Every virtio-gpio transfer has two parts, a message is sent (maybe I should call it Request instead as I did earlier) by the sender, and receiver sends a response after processing the message.
Quoted 7 lines
The device (host) is sender for the irq-message, and it will wait until a response
is received from the driver (guest) for the same. That can be seen as returning from an irq-handler in kernel for example, at which point interrupt gets enabled again.Was I able to clarify it ?
I'm not sure it's helpful to describe the protocol as symmetric when neither the virtqueue below it nor the idea of a gpio controller is symmetric.
I think a better way to describe it would be request/response pairs where the driver asks for something to be done and it gets an immediate response, as opposed to long-running event notifications where the driver queues up a descriptor and it only completes when an interrupt happens.
Arnd
Re: [virtio-dev] Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
Quoted 7 lines · Arnd Bergmann
Quoted 6 lines · Viresh Kumar
Quoted 4 lines · Arnd Bergmann
Is there a way for the driver to know which trigger types are supported on a given line? If not, would that be useful, or do we assume that this knowledge exists in the place that sets the trigger type based on e.g. device tree data?
And I understood it now only :(
I am not sure if this kind of per-line info would be really useful, and I now doubt
if we should have a config structure field for the entire GPIO block or not. i.e.
something that conveys the trigger types for entire GPIO device.
Quoted 3 lines
What I meant is that the guest OS kernel would only ever set a trigger type that makes sense based on what the device on the other end of the GPIO line needs, and this would be encoded in the interrupt-cells.
Thanks for explaining again.
Quoted 3 lines
Ok, let's see what they think. I would have found this less confusing if you just describe what message the driver sends and how the device responds to it.
I did add that kind of information in the tables for each of the message types, maybe they weren't that readable in the text version.
Here is an example of it:
+\begin{tabular}{ |l||l|l|l| }
+\hline
+Fields & \field{type} & \field{gpio} & \field{value} \\
+\hline
+Message & \field{VIRTIO_GPIO_MSG_GET_DIRECTION} & line number & 0 \\
+\hline
+Response & \field{VIRTIO_GPIO_MSG_GET_DIRECTION} \newline | \field{VIRTIO_GPIO_MSG_RESPONSE} & line number & 0 = output, 1 = input, \newline or -errno = failure \\
+\hline
+\end{tabular}
The driver sends a message with "type" VIRTIO_GPIO_MSG_GET_DIRECTION and the device responds with a buffer with "type" field set to VIRTIO_GPIO_MSG_GET_DIRECTION | VIRTIO_GPIO_MSG_RESPONSE and the direction set in the "value" field.
Quoted 5 lines
Quoted 2 lines
Yes, and the driver also needs to add buffers here for receiving response to the messages initiated by the driver.
Ok, I think that needs to be made clearer here. I'm still not sure I have understood exactly what messages you
Will work on that.
Quoted 9 lines
Quoted 4 lines
The device MUST not send another irq request for the same GPIO line, until the time it has received a response from the driver. Once the response has arrived at the device, it can raise the interrupt again if the level interrupt is still active.
The part about not sending another interrupt is the easy part. What I mean is what happens if another edge event comes into the gpio controller before the driver responds. Does the device immediately send another interrupt message or does it skip that?
Hmm, what should it do in that case ? What do we do in kernel for this ? I think maybe we should accumulate the interrupts in that period of time and send only the last one ?
Also will it make sense to send the trigger-type information to the driver on an interrupt? For example a user may have programmed a line for both edge trigger interrupts. Should we send info about which edge it is, rising or falling ?
Quoted 7 lines
I'm not sure it's helpful to describe the protocol as symmetric when neither the virtqueue below it nor the idea of a gpio controller is symmetric.
I think a better way to describe it would be request/response pairs where the driver asks for something to be done and it gets an immediate response, as opposed to long-running event notifications where the driver queues up a descriptor and it only completes when an interrupt happens.
Yes, I think it would be better to bind the request/response messages together. I will see if that will work fine or not before confirming.
--
Viresh
Re: [virtio-dev] Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
Quoted 11 lines · Viresh Kumar
Quoted 9 lines · Arnd Bergmann
Quoted 4 lines
The device MUST not send another irq request for the same GPIO line, until the time it has received a response from the driver. Once the response has arrived at the device, it can raise the interrupt again if the level interrupt is still active.
The part about not sending another interrupt is the easy part. What I mean is what happens if another edge event comes into the gpio controller before the driver responds. Does the device immediately send another interrupt message or does it skip that?
Quoted 7 lines
Hmm, what should it do in that case ? What do we do in kernel for this ? I think maybe we should accumulate the interrupts in that period of time and send only the last one ?
Also will it make sense to send the trigger-type information to the driver on an interrupt? For example a user may have programmed a line for both edge trigger interrupts. Should we send info about which edge it is, rising or falling ?
It's important to get the order correct here, and there are a lot of variations in hardware, so we need to pick the one that works best. Unfortunately I can never quite remember what they are either ;-)
Looking at the two ways of handling irqs that we care about
1. edge interrupts:
void handle_edge_irq(struct irq_desc *desc)
{
...
desc->irq_data.chip->irq_ack(&desc->irq_data);
do {
...
handle_irq_event(desc);
} while ((desc->istate & IRQS_PENDING) &&
!irqd_irq_disabled(&desc->irq_data));
...
}Here the irq gets rearmed first and then we call into the driver that has requested it. That driver processes all information that is associated with the event, or possibly multiple events that have happened since the handler waslast called. If another irq arrives after the driver is done looking for them, we will receive another event from the virtio device and all is good.
Ideally the 'irq_ack' would simply involve queuing another request for an event on the second virtqueue. However I don't know if there is a way for the virtio-gpio driver to know whether this request has been observed by the virtio-gpio device. If not, the irq_ack may arrive at the device only after the handle_irq_event() function is complete and we miss an interrupt.
2. level interrupts:
void handle_level_irq(struct irq_desc *desc)
{
mask_ack_irq(desc);
...
handle_irq_event(desc);
...
cond_unmask_irq(desc);
}Going through this the literal way would mean sending a mask, ack, and unmask request through virtio and waiting for a reply each time, but that does seem excessive.
As long as the interrupt is masked initially (since there is no event request pending immediately after the irq event reply), I would hope that we can get away with simply enqueuing the request in the 'cond_unmask_irq' step. In this case, we would call all handlers for this the level irq with the line pending and masked. After the handlers are complete, it should no longer be pending and we can unmask it. If another event comes in after the handler, it gets pending again, and we get sent a new irq event reply after the Ack.
Quoted 10 lines
Quoted 7 lines
I'm not sure it's helpful to describe the protocol as symmetric when neither the virtqueue below it nor the idea of a gpio controller is symmetric.
I think a better way to describe it would be request/response pairs where the driver asks for something to be done and it gets an immediate response, as opposed to long-running event notifications where the driver queues up a descriptor and it only completes when an interrupt happens.
Yes, I think it would be better to bind the request/response messages together. I will see if that will work fine or not before confirming.
Ok.
Arnd
Re: [virtio-dev] Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
Quoted 27 lines · Arnd Bergmann
It's important to get the order correct here, and there are a lot of variations in hardware, so we need to pick the one that works best. Unfortunately I can never quite remember what they are either ;-)
Looking at the two ways of handling irqs that we care about
1. edge interrupts:
void
handle_edge_irq(struct irq_desc *desc)
{
...desc->irq_data.chip->irq_ack(&desc->irq_data); do { ... handle_irq_event(desc); } while ((desc->istate & IRQS_PENDING) && !irqd_irq_disabled(&desc->irq_data)); ... }Here the irq gets rearmed first and then we call into the driver that has requested it. That driver processes all information that is associated with the event, or possibly multiple events that have happened since the handler waslast called. If another irq arrives after the driver is done looking for them, we will receive another event from the virtio device and all is good.
Quoted 4 lines
Ideally the '
irq_ack' would simply involve queuing another request for an event on the second virtqueue. However I don't know if there is a way for the virtio-gpio driver to know whether this request has been observed by the virtio-gpio device.
The driver will send an event (virtqueue_kick()) after the buffer is queued, so we can just assume that device has been notified and it has seen it.
Quoted 14 lines
If not, the
irq_ackmay arrive at the device only after thehandle_irq_event()function is complete and we miss an interrupt.2. level interrupts:
void
handle_level_irq(struct irq_desc *desc){ mask_ack_irq(desc); ... handle_irq_event(desc); ... cond_unmask_irq(desc); }
Quoted 1 line
Going through this the literal way would mean sending a mask,
One important think worth mentioning here is that the mask/unmask work here will be done when irq_bus_sync_unlock() is called as this is a slow bus and we can't do virtio-messages on mask/unmask, irq-context I believe.
Quoted 5 lines
ack, and unmask request through virtio and waiting for a reply each time, but that does seem excessive.
As long as the interrupt is masked initially (since there is no event request pending immediately after the irq event reply),
What irq event reply ?
Quoted 7 lines
I would hope that we can get away with simply enqueuing the request in the '
cond_unmask_irq' step. In this case, we would call all handlers for this the level irq with the line pending and masked. After the handlers are complete, it should no longer be pending and we can unmask it. If another event comes in after the handler, it gets pending again, and we get sent a new irq event reply after the Ack.
Okay..
Signature · 1 line
viresh
Re: [virtio-dev] Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
Quoted 28 lines · Viresh Kumar
Quoted 27 lines · Arnd Bergmann
It's important to get the order correct here, and there are a lot of variations in hardware, so we need to pick the one that works best. Unfortunately I can never quite remember what they are either ;-)
Looking at the two ways of handling irqs that we care about
1. edge interrupts:
void
handle_edge_irq(struct irq_desc *desc)
{
...desc->irq_data.chip->irq_ack(&desc->irq_data); do { ... handle_irq_event(desc); } while ((desc->istate & IRQS_PENDING) && !irqd_irq_disabled(&desc->irq_data)); ... }Here the irq gets rearmed first and then we call into the driver that has requested it. That driver processes all information that is associated with the event, or possibly multiple events that have happened since the handler waslast called. If another irq arrives after the driver is done looking for them, we will receive another event from the virtio device and all is good.
Quoted 8 lines
Quoted 4 lines
Ideally the '
irq_ack' would simply involve queuing another request for an event on the second virtqueue. However I don't know if there is a way for the virtio-gpio driver to know whether this request has been observed by the virtio-gpio device.The driver will send an event (
virtqueue_kick()) after the buffer is queued, so we can just assume that device has been notified and it has seen it.
That's what I was hoping for, I'm just not sure if this is required by the virtio spec or just the usual implementation of the device side. Have you found a section in the spec that guarantees that the virtqueue_kick() serves as a sufficient barrier that the driver can rely on the information having arrived?
Quoted 14 lines
Quoted 14 lines
If not, the
irq_ackmay arrive at the device only after thehandle_irq_event()function is complete and we miss an interrupt.2. level interrupts:
void
handle_level_irq(struct irq_desc *desc){ mask_ack_irq(desc); ... handle_irq_event(desc); ... cond_unmask_irq(desc); }
Quoted 6 lines
Quoted 1 line
Going through this the literal way would mean sending a mask,
One important think worth mentioning here is that the mask/unmask work here will be done when
irq_bus_sync_unlock()is called as this is a slow bus and we can't do virtio-messages on mask/unmask, irq-context I believe.
Ok, in that case I guess the requeue has to be deferred, which may rule out everything other than the fasteoi method.
Quoted 7 lines
Quoted 5 lines
ack, and unmask request through virtio and waiting for a reply each time, but that does seem excessive.
As long as the interrupt is masked initially (since there is no event request pending immediately after the irq event reply),
What irq event reply ?
I meant the notification from device to driver that an event has happened.
Arnd
Re: [virtio-dev] Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
Quoted 5 lines · Arnd Bergmann
That's what I was hoping for, I'm just not sure if this is required by the virtio spec or just the usual implementation of the device side. Have you found a section in the spec that guarantees that the
virtqueue_kick()serves as a sufficient barrier that the driver can rely on the information having arrived?
This is what the spec say about it:
https://docs.oasis-open.org/virtio/virtio/v1.1/csprd01/virtio-v1.1-csprd01.html#x1-9000023
Quoted 2 lines
Ok, in that case I guess the requeue has to be deferred, which may rule out everything other than the fasteoi method.
True.
Quoted 2 lines
I meant the notification from device to driver that an event has happened.
Yeah, I understood it later.
Signature · 1 line
viresh
Re: [virtio-dev] Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
Quoted 11 lines · Viresh Kumar
Quoted 5 lines · Arnd Bergmann
That's what I was hoping for, I'm just not sure if this is required by the virtio spec or just the usual implementation of the device side. Have you found a section in the spec that guarantees that the
virtqueue_kick()serves as a sufficient barrier that the driver can rely on the information having arrived?This is what the spec say about it:
https://docs.oasis-open.org/virtio/virtio/v1.1/csprd01/virtio-v1.1-csprd01.html#x1-9000023
I don't see it spell out whether this acts as a barrier or not. As far as I can tell, the notification may be deferred, e.g. if the host is multi-threaded and virtqueue_kick() needs to send an IPI to another processor to look at the data.
Arnd
Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
In reply to Viresh KumarQuoted 2 lines · Viresh Kumar
This patch adds support for interrupts to the virtio-gpio specification. This uses the feature bit 0 for the same.
Michael (and other virtio experts),
I have a doubt about interrupt messages initiated by the device. There is nothing meaningful I want to return from the driver to the device on an interrupt event, but I need to make sure the device doesn't send another interrupt for the same GPIO line, before the previous one is serviced. I was thinking about sending some sort of response message for it, but am not sure how to implement it.
Another way out to implement this, is by adding to the spec that on interrupt the device MUST mask the interrupt line on the GPIO before sending the event to the driver and this irq can be re-enabled only by the driver sending another request over the primary virtqueue (and not interrupt virtqueue).
What do you suggest ?
Signature · 1 line
viresh
Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
Quoted 14 lines · Viresh Kumar
Quoted 2 lines · Viresh Kumar
This patch adds support for interrupts to the virtio-gpio specification. This uses the feature bit 0 for the same.
Michael (and other virtio experts),
I have a doubt about interrupt messages initiated by the device. There is nothing meaningful I want to return from the driver to the device on an interrupt event, but I need to make sure the device doesn't send another interrupt for the same GPIO line, before the previous one is serviced. I was thinking about sending some sort of response message for it, but am not sure how to implement it.
Quoted 6 lines
Another way out to implement this, is by adding to the spec that on interrupt the device MUST mask the interrupt line on the GPIO before sending the event to the driver and this irq can be re-enabled only by the driver sending another request over the primary virtqueue (and not interrupt virtqueue).
What do you suggest ?
I would still hope that we can simplify this to the 'Ack' being implied by requeuing the message from the gpio driver. In case of a level interrupt:
device driver
1. queue message
2. line activates
3. send reply
4. notify guest
5. call handler
6. line may activate
7. goto 1
For edge interrupts, I'm still not sure how it would work. The options that I see are:
a) fasteoi style controller: when the device sends an event, this becomes implicitly masked as there is no way to send another until the message is requeued, but the device latches any further events, so that queuing the next message after the guest handler returns immediately results in the event getting delivered. This would use the minimum number of requests and let the driver use the exact same code for edge and level mode, but it does mean the possibility of extra wakeups, and it may require more work in the host.
b) require the requeue to happen in the guest before calling the handler to prevent missed events. Not sure if this is possible without another message, as the guest must be sure that the host has observed the requeue, but it cannot have returned any data yet.
c) explicit ack at start of guest: driver starts by sending an ack to the first virtqueue and waiting for it to be complete, then calls the handler, and only then requeues the request. This would presumably add a lot of extra latency.
Arnd
Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
Quoted 2 lines · Arnd Bergmann
I would still hope that we can simplify this to the 'Ack' being implied by requeuing the message from the gpio driver.
Which would mean that we process one interrupt at a time, I was hoping to do some sort parallelization here by allowing interrupts for multiple GPIO lines to be processed together.
Another way of doing that would be sending a mask of all GPIO pins where interrupt is pending on this irq request. That would require a separate bit for each GPIO pin, i.e. 8 32-bit values for 256 GPIO pins. Which would also require to change the size of ngpio field in the config structure to u8 instead of u16. I am not sure why it should be u16 really (Enrico had it this way), it sounds really big. Will we ever need anything over 256? And why not add another device in that case.
Quoted 24 lines
In case of a level interrupt:
device driver
1. queue message
2. line activates
3. send reply
4. notify guest
5. call handler
6. line may activate
7. goto 1For edge interrupts, I'm still not sure how it would work. The options that I see are:
a) fasteoi style controller: when the device sends an event, this becomes implicitly masked as there is no way to send another until the message is requeued, but the device latches any further events, so that queuing the next message after the guest handler returns immediately results in the event getting delivered. This would use the minimum number of requests and let the driver use the exact same code for edge and level mode, but it does mean the possibility of extra wakeups, and it may require more work in the host.
Quoted 5 lines
b) require the requeue to happen in the guest before calling the handler to prevent missed events. Not sure if this is possible without another message, as the guest must be sure that the host has observed the requeue, but it cannot have returned any data yet.
The driver does call virtqueue_kick() there, so an event must go to the device. Maybe that can be seen as the device has observed the event.
Quoted 4 lines
c) explicit ack at start of guest: driver starts by sending an ack to the first virtqueue and waiting for it to be complete, then calls the handler, and only then requeues the request. This would presumably add a lot of extra latency.
I would like the interrupt handler at the guest to share same code across irq types, so re-queuing a buffer only after handling the interrupt work then. Moreover I am not sure currently when does irq_bus_sync_lock/unlock() get called in this whole sequence, where we actually mask/unmask the interrupts.
Signature · 1 line
viresh
Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
Quoted 9 lines · Viresh Kumar
Quoted 2 lines · Arnd Bergmann
I would still hope that we can simplify this to the 'Ack' being implied by requeuing the message from the gpio driver.
Which would mean that we process one interrupt at a time, I was hoping to do some sort parallelization here by allowing interrupts for multiple GPIO lines to be processed together.
Quoted 8 lines
Another way of doing that would be sending a mask of all GPIO pins where interrupt is pending on this irq request. That would require a separate bit for each GPIO pin, i.e. 8 32-bit values for 256 GPIO pins. Which would also require to change the size of ngpio field in the config structure to u8 instead of u16. I am not sure why it should be u16 really (Enrico had it this way), it sounds really big. Will we ever need anything over 256? And why not add another device in that case.
I don't think you can have a message for more than one line here, that would mess up the synchronization as then you have to keep double accounting of which gpios are already pending on each side.
The most sensible way I see this can be done is to have a message per line, and have it as a token that is either on the device or the driver side at any point. When the driver has sent the token over to the device, the irq is armed, and when the device replies, it is implicitly masked.
Ideally this could even replace the VIRTIO_GPIO_MSG_IRQ_TYPE, VIRTIO_GPIO_MSG_IRQ_MASK and VIRTIO_GPIO_MSG_IRQ_UNMASK messages with a single message type on the interrupt virtqueue:
struct virtio_gpio_irq_event {
__le16 line;
__u8 type;
__u8 status;
}When the driver wants an event on a gpio line, it enqueues this message to the virtqueue, and then the device either adds the corresponding file descriptor to its poll table, or replies immediately with one of these status words:
- request not supported
- level interrupt is still active (line remains at requested level)
- edge interrupt has happened since last reply
Quoted 9 lines
Quoted 5 lines
b) require the requeue to happen in the guest before calling the handler to prevent missed events. Not sure if this is possible without another message, as the guest must be sure that the host has observed the requeue, but it cannot have returned any data yet.
The driver does call
virtqueue_kick()there, so an event must go to the device. Maybe that can be seen as the device has observed the event.
But you said we can't enqueue the event from irq context in your other reply, so I think it wouldn't work after all.
Arnd
Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
Quoted 4 lines · Arnd Bergmann
I don't think you can have a message for more than one line here, that would mess up the synchronization as then you have to keep double accounting of which gpios are already pending on each side.
Yes.
Quoted 5 lines
The most sensible way I see this can be done is to have a message per line, and have it as a token that is either on the device or the driver side at any point. When the driver has sent the token over to the device, the irq is armed, and when the device replies, it is implicitly masked.
I like the idea in general but at this point I am not very sure how it will work. Looking at kernel (and qemu) side implementations, what really transfers between device and driver is a series of buffers (marked as in or out sgs). Now these are either device writable or driver. I am not sure if the device is required to write anything here to the buffer, it can simply return the buffer as is and so we can make it driver writable only, i.e. only 1 sg element required.
Quoted 2 lines
Ideally this could even replace the
VIRTIO_GPIO_MSG_IRQ_TYPE,VIRTIO_GPIO_MSG_IRQ_MASK
Maybe yes.
Quoted 1 line
and
VIRTIO_GPIO_MSG_IRQ_UNMASK
I think we would still require some kind of unmasking here as the driver would have already sent the buffer to the device and wants the ownership back, otherwise it may hit an interrupt later on.
Although I would like to keep the three routines separate, just to be robust here. For example what will we do if the user does this (yes it won't do it, but I am trying to handle the corner cases well):
1. irq-type-edge-falling
2. irq-unmask
3. irq-type-edge-both
Since we would have already sent the buffer at (2), we can't do (3) without getting the buffer back.
Tying everything with availability of the buffer itself makes it kind of messy.
Quoted 16 lines
messages with a single message type on the interrupt virtqueue:
struct virtio_gpio_irq_event { __le16 line; __u8 type; __u8 status; }When the driver wants an event on a gpio line, it enqueues this message to the virtqueue, and then the device either adds the corresponding file descriptor to its poll table, or replies immediately with one of these status words:
- request not supported
- level interrupt is still active (line remains at requested level)
- edge interrupt has happened since last reply
Signature · 1 line
viresh
Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
Quoted 15 lines · Viresh Kumar
Quoted 4 lines · Arnd Bergmann
I don't think you can have a message for more than one line here, that would mess up the synchronization as then you have to keep double accounting of which gpios are already pending on each side.
Yes.
Quoted 5 lines
The most sensible way I see this can be done is to have a message per line, and have it as a token that is either on the device or the driver side at any point. When the driver has sent the token over to the device, the irq is armed, and when the device replies, it is implicitly masked.
Quoted 7 lines
I like the idea in general but at this point I am not very sure how it will work. Looking at kernel (and qemu) side implementations, what really transfers between device and driver is a series of buffers (marked as in or out sgs). Now these are either device writable or driver. I am not sure if the device is required to write anything here to the buffer, it can simply return the buffer as is and so we can make it driver writable only, i.e. only 1 sg element required.
I think it can be done either way:
a) if you have two buffers, the driver asks for an irq event, and the driver replies with a filled-out event saying what happened, or that it could not do it.
b) with just one buffer, we know that something happened, but now the driver has to ensure that the event request is valid before queuing it. If the driver asks for an event on a gpio line that is not an irq source, or configured as output, or has a mode that the device cannot support, the event would either have to be returned immediately or never.
Quoted 5 lines
Quoted 1 line
and
VIRTIO_GPIO_MSG_IRQ_UNMASKI think we would still require some kind of unmasking here as the driver would have already sent the buffer to the device and wants the ownership back, otherwise it may hit an interrupt later on.
I think we can live with getting a spurious interrupt in case the driver reconfigures the line later on to no longer be an interrupt source.
Quoted 8 lines
Although I would like to keep the three routines separate, just to be robust here. For example what will we do if the user does this (yes it won't do it, but I am trying to handle the corner cases well):
1. irq-type-edge-falling
2. irq-unmask
3. irq-type-edge-both
Quoted 5 lines
Since we would have already sent the buffer at (2), we can't do (3) without getting the buffer back.
Tying everything with availability of the buffer itself makes it kind of messy.
Right, this case would be easier for the guest if we separate setting the irq polarity from the action of asking for an event, but I suspect it would make the device implementation trickier in the process (which you may not care about as much).
An easy way to deal with this scenario would be to mandate that any VIRTIO_GPIO_MSG_SET_* command forces the irq event message to trigger and have to be requeued.
Arnd
Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
Quoted 17 lines · Arnd Bergmann
I think it can be done either way:
a) if you have two buffers, the driver asks for an irq event, and the driver replies with a filled-out event saying what happened, or that it could not do it.
b) with just one buffer, we know that something happened, but now the driver has to ensure that the event request is valid before queuing it. If the driver asks for an event on a gpio line that is not an irq source, or configured as output, or has a mode that the device cannot support, the event would either have to be returned immediately or never.
I think we can live with getting a spurious interrupt in case the driver reconfigures the line later on to no longer be an interrupt source.
Quoted 8 lines
Right, this case would be easier for the guest if we separate setting the irq polarity from the action of asking for an event, but I suspect it would make the device implementation trickier in the process (which you may not care about as much).
An easy way to deal with this scenario would be to mandate that any VIRTIO_GPIO_MSG_SET_* command forces the irq event message to trigger and have to be requeued.
I will put more thought to the whole stuff and update the spec based on what I get to finally.
But I really liked the idea of the token system, with a separate message for each GPIO line. That will solve most of our problems.
Signature · 1 line
viresh
Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
In reply to Viresh KumarQuoted 41 lines · Viresh Kumar
Quoted 4 lines · Arnd Bergmann
I don't think you can have a message for more than one line here, that would mess up the synchronization as then you have to keep double accounting of which gpios are already pending on each side.
Yes.
Quoted 5 lines
The most sensible way I see this can be done is to have a message per line, and have it as a token that is either on the device or the driver side at any point. When the driver has sent the token over to the device, the irq is armed, and when the device replies, it is implicitly masked.
I like the idea in general but at this point I am not very sure how it will work. Looking at kernel (and qemu) side implementations, what really transfers between device and driver is a series of buffers (marked as in or out sgs). Now these are either device writable or driver. I am not sure if the device is required to write anything here to the buffer, it can simply return the buffer as is and so we can make it driver writable only, i.e. only 1 sg element required.
Quoted 2 lines
Ideally this could even replace the
VIRTIO_GPIO_MSG_IRQ_TYPE,VIRTIO_GPIO_MSG_IRQ_MASKMaybe yes.
Quoted 1 line
and
VIRTIO_GPIO_MSG_IRQ_UNMASKI think we would still require some kind of unmasking here as the driver would have already sent the buffer to the device and wants the ownership back, otherwise it may hit an interrupt later on.
Although I would like to keep the three routines separate, just to be robust here. For example what will we do if the user does this (yes it won't do it, but I am trying to handle the corner cases well):
1. irq-type-edge-falling
2. irq-unmask
3. irq-type-edge-both
Quoted 5 lines
Since we would have already sent the buffer at (2), we can't do (3) without getting the buffer back.
Tying everything with availability of the buffer itself makes it kind of messy.
I'm not sure about the detail but buffers can be consumed in any order. So sure you can also have an explicit unmask or cancel or whatever message on the same vq.
Quoted 19 lines
Quoted 16 lines
messages with a single message type on the interrupt virtqueue:
struct virtio_gpio_irq_event { __le16 line; __u8 type; __u8 status; }When the driver wants an event on a gpio line, it enqueues this message to the virtqueue, and then the device either adds the corresponding file descriptor to its poll table, or replies immediately with one of these status words:
- request not supported
- level interrupt is still active (line remains at requested level)
- edge interrupt has happened since last replySignature · 1 line
viresh
Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
In reply to Viresh KumarQuoted 4 lines · Viresh Kumar
Quoted 2 lines · Viresh Kumar
This patch adds support for interrupts to the virtio-gpio specification. This uses the feature bit 0 for the same.
Quoted 8 lines
Michael (and other virtio experts),
I have a doubt about interrupt messages initiated by the device. There is nothing meaningful I want to return from the driver to the device on an interrupt event, but I need to make sure the device doesn't send another interrupt for the same GPIO line, before the previous one is serviced. I was thinking about sending some sort of response message for it, but am not sure how to implement it.
My suggestion is this: driver adds a buffer to tell device it wants an interrupt. device uses the buffer to notify driver of the interrupt event.
Quoted 6 lines
Another way out to implement this, is by adding to the spec that on interrupt the device MUST mask the interrupt line on the GPIO before sending the event to the driver and this irq can be re-enabled only by the driver sending another request over the primary virtqueue (and not interrupt virtqueue).
What do you suggest ?
Well vqs fundamentally can cause spurious interrupts. First suggestion is closer to how other devices do this.
Quoted 2 lines
Signature · 1 line
viresh
Re: [PATCH V5 2/2] virtio-gpio: Add support for interrupts
Quoted 14 lines · Michael S. Tsirkin
Quoted 4 lines · Viresh Kumar
Quoted 2 lines · Viresh Kumar
This patch adds support for interrupts to the virtio-gpio specification. This uses the feature bit 0 for the same.
Quoted 8 lines
Michael (and other virtio experts),
I have a doubt about interrupt messages initiated by the device. There is nothing meaningful I want to return from the driver to the device on an interrupt event, but I need to make sure the device doesn't send another interrupt for the same GPIO line, before the previous one is serviced. I was thinking about sending some sort of response message for it, but am not sure how to implement it.
Quoted 3 lines
My suggestion is this: driver adds a buffer to tell device it wants an interrupt. device uses the buffer to notify driver of the interrupt event.
So what you are suggesting is, re-queue of the buffer would mean an acknowledgement for the interrupt from the driver.
Hmm, I was looking at parallelizing the interrupts for various GPIOs. Lets say we have X number of GPIO lines, with what you are suggesting, we will only honor 1 interrupt at a time. What I was thinking of was providing multiple buffers at the beginning itself, lets say 5-10, so we can process the interrupts in parallel in separate threads (probably running on different virtual CPUs in the guest).
Quoted 9 lines
Quoted 6 lines
Another way out to implement this, is by adding to the spec that on interrupt the device MUST mask the interrupt line on the GPIO before sending the event to the driver and this irq can be re-enabled only by the driver sending another request over the primary virtqueue (and not interrupt virtqueue).
What do you suggest ?
Well vqs fundamentally can cause spurious interrupts. First suggestion is closer to how other devices do this.
Signature · 1 line
viresh
Quoted 16 lines · Viresh Kumar
Hello,
This patchset adds virtio specification for GPIO devices. It supports basic GPIO line operations, along with optional interrupts on them (in a separate patch).
This is an *alternative implementation* of the virtio-gpio specification, another version of it was earlier posted by Enrico [1].
I took back V4 of the specification I posted earlier (on June 17th), to allow Enrico to come up with something that is robust and works for everyone (as he started this thing last year), but it didn't go as expected. I couldn't see any of my review comments being incorporated (or any intentions of them getting in ever) in the two versions Enrico posted and a month passed since then.
Quoted 3 lines
And so I am trying to present an alternative approach here to solve the problem, which I believe is more clear and robust. I am open to suggestions to improve it further.
Hi Viresh,
I've looked at the two proposals again now, and yours does look more mature, so I agree it makes sense to continue with your version.
Quoted 7 lines
I will let the virtio/gpio maintainers decide on its fate.
Key differences from Enrico's approach [1]:
- config structure is rearranged to remove unnecessary fields/padding, and place
gpio_namesblock in such a way that we can expand the structure easily going forward, if required.
Simplifying is good, maybe we can cut it down even further. I now actually wonder
if we shouldn't remove the gpio names from the virtio-gpu spec entirely.
In practice I assume this driver only makes sense to be used in combination with firmware describing how it interacts with other drivers (gpio-key, gpio-led,
mmc, i2c, ...) that require access to gpio lines for something they do, and these already rely on DT information or some equivalent.
As soon as we have a DT node for the device, the names can just be passed according ot the generic DT binding for gpio controllers.
Quoted 1 line
- Supports freeing of a GPIO line after use.
I agree it makes sense have both alloc and free as a pair if you have one of them, but as I commented I'm not convinced we do need them at all, so removing both may be better here.
Quoted 2 lines
- Interrupt implementation handled with feature bit 0. Either the interrupts are fully supported or not at all.
The interrupt definition looks better than Enrico's version, but the serialization
still looks incomplete, especially since you added level triggered mode. I always
get confused by those as well, so we'll need to have this reviewed by an irqchip person as well, but let's start with my questions for now.
Quoted 5 lines
- Doesn't add any ordering restrictions on the device, it can respond earlier to the second request, while still processing the first one.
- Clearly state that two requests can't be initiated for the same line by device or driver.
These are good.
The other comments I had regarding the use of errno values, and the split between txq/rxq messages are things you inherited from Enrico's version, so those need to be resolved regardless.
Arnd
Quoted 3 lines · Arnd Bergmann
On Fri, Jul 16, 2021 at 9:39 AM Viresh Kumar <[email protected]> wrote:
I've looked at the two proposals again now, and yours does look more mature, so I agree it makes sense to continue with your version.
Thanks for that.
Quoted 12 lines
Quoted 7 lines
I will let the virtio/gpio maintainers decide on its fate.
Key differences from Enrico's approach [1]:
- config structure is rearranged to remove unnecessary fields/padding, and place
gpio_namesblock in such a way that we can expand the structure easily going forward, if required.Simplifying is good, maybe we can cut it down even further. I now actually wonder
if we shouldn't remove the gpio names from the virtio-gpu spec entirely.
Quoted 8 lines
In practice I assume this driver only makes sense to be used in combination with firmware describing how it interacts with other drivers (gpio-key, gpio-led,
mmc, i2c, ...) that require access to gpio lines for something they do, and these already rely on DT information or some equivalent.As soon as we have a DT node for the device, the names can just be passed according ot the generic DT binding for gpio controllers.
So the Linux gpiolib implementation does use this information, not entirely sure how apart from displaying that in sysfs.
The gpio-names thing is going to be dropped anyway from the config structure and will be shared over virtqueue if really required.
Quoted 9 lines
Quoted 2 lines
- Interrupt implementation handled with feature bit 0. Either the interrupts are fully supported or not at all.
The interrupt definition looks better than Enrico's version, but the serialization
still looks incomplete, especially since you added level triggered mode. I always
get confused by those as well, so we'll need to have this reviewed by an irqchip person as well, but let's start with my questions for now.
Sure.
Quoted 3 lines
The other comments I had regarding the use of errno values, and the split between txq/rxq messages are things you inherited from Enrico's version, so those need to be resolved regardless.
Sure.
Thanks for taking time to review this Arnd.
--
Viresh