Skip to contentSkip to conversation

virtio: Add specification for virtio-gpio

PATCH Superseded Viresh Kumar 4 participants 26 messages Jul 20, 2021 – Jul 27, 2021

v6 of 9 Superseded Latest is v9 →

lore
Share & tools
lore
#0 lore raw

v6 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, a different 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 everything apart from number of gpios and size of the gpio_names_field.

- Supports freeing of a GPIO line after use, we call them activate/deactivate now, which suits their purpose better.

- Interrupt implementation handled with feature bit 0. Either the interrupts are fully supported or not at all.

- All non-interrupt traffic happens on a single virtqueue, requestq. Interrupt traffic goes over eventq.

- 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:

V5 -> V6:
- All non-interrupt traffic happens on a single virtqueue, requestq. Interrupt traffic goes over eventq now.
- Many fields dropped from the config structure.
- Separate message type to get gpio-names, added more description about how the names should be.
- Much clearer message flows, both non-irq messages and irq-messages.
- Parallelism supported for all type of messages, for different GPIO pins.
- All references to POSIX errors dropped, just reply pass or fail.
- request/free renamed to activate/deactivate, as that's what we will end up doing there, activate or deactivate a GPIO line.
- General purpose IO as I/O or Input/Output instead.
- Hopefully I didn't miss any review comments.

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 |  30 ++-
 content.tex     |   1 +
 virtio-gpio.tex | 608 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 635 insertions(+), 4 deletions(-)
 create mode 100644 virtio-gpio.tex
Signature · 1 line
2.31.1.272.g89b43f80a514
#1 lore raw

PATCH v6 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 |  28 +++-
 content.tex     |   1 +
 virtio-gpio.tex | 369 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 394 insertions(+), 4 deletions(-)
 create mode 100644 virtio-gpio.tex
conformance.tex +24 -4
index 94d7a06db899..c52f1a40be2d 100644
@@ -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 / GPIO 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 / GPIO Device Conformance}.
 
     \item Clause \ref{sec:Conformance / Legacy Interface: Transitional Device and Transitional Driver Conformance}.
   \end{itemize}
@@ -301,6 +303,15 @@ \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}{GPIO Driver Conformance}\label{sec:Conformance / Driver Conformance / GPIO Driver Conformance}
+
+A General Purpose Input/Output (GPIO) driver MUST conform to the following
+normative statements:
+
+\begin{itemize}
+\item \ref{drivernormative:Device Types / GPIO Device / requestq Operation}
+\end{itemize}
+
 \conformance{\section}{Device Conformance}\label{sec:Conformance / Device Conformance}
 
 A device MUST conform to the following normative statements:
@@ -550,6 +561,15 @@ \section{Conformance Targets}\label{sec:Conformance / Conformance Targets}
 \item \ref{devicenormative:Device Types / SCMI Device / Device Operation / Shared Memory Operation}
 \end{itemize}
 
+\conformance{\subsection}{GPIO Device Conformance}\label{sec:Conformance / Device Conformance / GPIO Device Conformance}
+
+A General Purpose Input/Output (GPIO) device MUST conform to the following
+normative statements:
+
+\begin{itemize}
+\item \ref{devicenormative:Device Types / GPIO Device / requestq 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 +1 -0
index 5c70a3c415a3..511f2071959d 100644
@@ -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 +369 -0

369 lines not on this page · raw message

Signature · 1 line
2.31.1.272.g89b43f80a514
#2 lore raw

[virtio-dev] Re: [PATCH V6 1/2] virtio-gpio: Add the device specification

Quoted 12 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]>.

---

virtio-gpio.tex line 42

Quoted 6 lines
virtio-gpio.tex new file +6 -0
+
+\item[\field{gpio_names_size}] is the size of the gpio-names memory block in
+    bytes, which can be fetched by the driver using the
+    \field{VIRTIO_GPIO_MSG_GET_NAMES} message. The device MUST set this to 0 if
+    it doesn't support names for the GPIO lines.
+\end{description}

I would be more comfortable with leaving out this field, and making the name lookup fixed-length and per line.

Quoted 7 lines

+\subsubsection{requestq Operation: Get Names}\label{sec:Device Types / GPIO Device / requestq Operation / Get Names}

virtio-gpio.tex new file +6 -0
+
+The driver sends this message to receive a stream of 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 an empty string.
+

virtio-gpio.tex line 132

Quoted 10 lines
virtio-gpio.tex new file +10 -0
+These names of the GPIO lines should be most meaningful producer names for the
+system, such as name indicating the usage. For example "MMC-CD", "Red LED Vdd"
+and "ethernet reset" are reasonable line names as they describe what the line is
+used for, while "GPIO0" is not a good name to give to a GPIO line.
+
+The device MUST set the \field{gpio_names_size} to a non-zero value if this
+message is supported by the device, else it must be set to zero.
+
+The driver must allocate the \field{value[N]} buffer in the \field{struct
+virtio_gpio_response} for N bytes, where N = \field{gpio_names_size}.

Making this a per-line request also has the advantage that the device can have names associated with some of the lines, but leave some other lines unnamed, which I think is something that happens in practice.

Not sure what a good upper limit for the length of the name is, but making this fixed-length would seem simpler to me.

virtio-gpio.tex line 153

Quoted 4 lines

+\subsubsection{requestq Operation: Activate}\label{sec:Device Types / GPIO Device / requestq Operation / Activate}

virtio-gpio.tex new file +3 -0
+
+The driver sends this message to notify the device that one of its lines has
+been assigned for use.

Maybe expand this description a little more according to our previous discussion.
In particular, I would expect this to describe

- what the controller hardware is expected to do as a result
- which of the other calls are allowed on lines that have been requested or have not been requested. This information could be duplicated in the respective descriptions. In particular, it is not obvious whether you should set the direction before or after 'request', and I assume only one of the two possibilities is allowed.

virtio-gpio.tex line 345

Quoted 4 lines
virtio-gpio.tex new file +4 -0
+
+\item The driver MUST NOT send another message, of any type, for a GPIO line
+    before receiving a response from the device for the previously sent message
+    for the same GPIO line.

I have a question here, not sure if this needs to be answered in the spec: why can't the driver send activate, set-direction and set-value all at once for a line?
Clearly if one request fails, the later ones would fail as well in this example, but
I don't see this as a problem for either side.

Quoted 2 lines

+\item The device MAY process messages out of order and in parallel and MAY send
+ message's response to the driver out of order.

Here I have the opposite question: what is the benefit of allowing the requests to be processed out of order? Should these not all be instantaneous, and easier to handle by making the request queue serialized?

Arnd

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]

#3 lore raw

Re: [PATCH V6 1/2] virtio-gpio: Add the device specification

Quoted 2 lines · Arnd Bergmann

I would be more comfortable with leaving out this field, and making the name lookup fixed-length and per line.

I can leave it from configuration, sure.

Doing it per-line seems to be too much overhead, since we are going to call this for every line anyway (at least in Linux implementation). I haven't tried it, but I somehow feel that probe() will take a significant time to finish with that, lets say for 256 GPIO lines.

Quoted 7 lines

Making this a per-line request also has the advantage that the device can have names associated with some of the lines, but leave some other lines unnamed, which I think is something that happens in practice.

Not sure what a good upper limit for the length of the name is, but making this fixed-length would seem simpler to me.

Or allocate 20-25 bytes for each string and allocate a buffer of size

25 * ngpios

The device can write 0 (null) for some of the GPIOs, where it doesn't want to provide a name, or set it to a null terminated string with length <= 25.

Quoted 9 lines

virtio-gpio.tex line 153

Quoted 4 lines

+\subsubsection{requestq Operation: Activate}\label{sec:Device Types / GPIO Device / requestq Operation / Activate}

virtio-gpio.tex new file +3 -0
+
+The driver sends this message to notify the device that one of its lines has
+been assigned for use.

Maybe expand this description a little more according to our previous discussion.
In particular, I would expect this to describe

Quoted 6 lines

- what the controller hardware is expected to do as a result
- which of the other calls are allowed on lines that have been requested or have not been requested. This information could be duplicated in the respective descriptions. In particular, it is not obvious whether you should set the direction before or after 'request', and I assume only one of the two possibilities is allowed.

Right.

Quoted 10 lines

virtio-gpio.tex line 345

Quoted 3 lines

+\item The driver MUST NOT send another message, of any type, for a GPIO line

virtio-gpio.tex new file +2 -0
+    before receiving a response from the device for the previously sent message
+    for the same GPIO line.

I have a question here, not sure if this needs to be answered in the spec: why can't the driver send activate, set-direction and set-value all at once for a line?
Clearly if one request fails, the later ones would fail as well in this example, but
I don't see this as a problem for either side.

The driver can already do set-direction and value at once. Merging activate along with that would mean, that the host needs to keep a reference count at its end to activate the line on the first call to set-value, but not on others.

We would still need to keep the deactivate request, as the host wouldn't know when the guest is done using a line. And for that reason it looked better to have an explicit call to activate here.

Quoted 6 lines
Quoted 2 lines

+\item The device MAY process messages out of order and in parallel and MAY send
+ message's response to the driver out of order.

Here I have the opposite question: what is the benefit of allowing the requests to be processed out of order? Should these not all be instantaneous, and easier to handle by making the request queue serialized?

Lets say the guest sends two requests, almost at the same time to the host and they are queued on the vq in this order only:

- set direction-out-with-value-1 for line 5.
- set direction-in for line 11.

Now, if the host is able to process them in parallel, then the second request for line 11 may finish before the requests for line 5 (as it has lesser amount of work to do).

I don't see why the host should wait for the first request to finish before queuing up the buffers for the second request, while it has already finished.

To be most efficient, the queue should be thought of as a series of buffers which are present in any order, based on what finishes first. It doesn't increase the complexity on any side to be honest. The code remains straight forward with it.

Signature · 1 line
viresh
#4 lore raw

Re: [PATCH V6 1/2] virtio-gpio: Add the device specification

Quoted 11 lines · Viresh Kumar
Quoted 2 lines · Arnd Bergmann

I would be more comfortable with leaving out this field, and making the name lookup fixed-length and per line.

I can leave it from configuration, sure.

Doing it per-line seems to be too much overhead, since we are going to call this for every line anyway (at least in Linux implementation). I haven't tried it, but I somehow feel that probe() will take a significant time to finish with that, lets say for 256 GPIO lines.

My guess is that this would not cause any notable overhead, but we will know for sure if you can measure it.

Quoted 8 lines
Quoted 7 lines

Making this a per-line request also has the advantage that the device can have names associated with some of the lines, but leave some other lines unnamed, which I think is something that happens in practice.

Not sure what a good upper limit for the length of the name is, but making this fixed-length would seem simpler to me.

Quoted 7 lines

Or allocate 20-25 bytes for each string and allocate a buffer of size

25 * ngpios

The device can write 0 (null) for some of the GPIOs, where it doesn't want to provide a name, or set it to a null terminated string with length <= 25.

I was thinking of a name limit in the context of doing the operation per line. If you keep the list of nul-terminated strings, then I think I would also not limit the length per line.

Quoted 4 lines
Quoted 4 lines
Quoted 3 lines

+\item The driver MUST NOT send another message, of any type, for a GPIO line

virtio-gpio.tex new file +2 -0
+    before receiving a response from the device for the previously sent message
+    for the same GPIO line.
Quoted 8 lines
Quoted 6 lines

I have a question here, not sure if this needs to be answered in the spec: why can't the driver send activate, set-direction and set-value all at once for a line?
Clearly if one request fails, the later ones would fail as well in this example, but
I don't see this as a problem for either side.

The driver can already do set-direction and value at once.

Ah, I completely missed that.

Quoted 3 lines

Merging activate along with that would mean, that the host needs to keep a reference count at its end to activate the line on the first call to set-value, but not on others.

My question here was about something else, to rephrase: Can't we allow the driver to queue multiple requests for one line and then have the device process them in order (regardless of whether it processes requests for other lines in parallel). The sequence I had in mind here was

driver:
1. queue enable
2. queue set-direction
3. queue set-value
4. notify device
device:
5. process enable
6. queue enable-response
7. process set-direction
8. queue set-direction response
9. process set-value
10. queue set-value response
11. notify driver
driver:
12. mark all requests as done

Quoted 3 lines

We would still need to keep the deactivate request, as the host wouldn't know when the guest is done using a line. And for that reason it looked better to have an explicit call to activate here.

Folding the activate/deactivate is also an interesting option, as discussed before. I don't think we actually need to do reference counting, just making the direction a tristate. I think this would work fine here:

- default direction is VIRTIO_GPIO_MSG_SET_DIRECTION_NONE"
- as long as the direction is not set, nothing else is allowed on the line
- changing the direction from "none" to "in" or "out" implies "activate"
- changing the direction from "in" or "out" back to "none" implies "deactivate"

This is similar to folding the irq type into the direction command, and I would slightly prefer it that way, but I'd like to hear what others think about it.

Quoted 17 lines
Quoted 6 lines
Quoted 2 lines

+\item The device MAY process messages out of order and in parallel and MAY send
+ message's response to the driver out of order.

Here I have the opposite question: what is the benefit of allowing the requests to be processed out of order? Should these not all be instantaneous, and easier to handle by making the request queue serialized?

Lets say the guest sends two requests, almost at the same time to the host and they are queued on the vq in this order only:

- set direction-out-with-value-1 for line 5.
- set direction-in for line 11.

Now, if the host is able to process them in parallel, then the second request for line 11 may finish before the requests for line 5 (as it has lesser amount of work to do).

Quoted 8 lines

I don't see why the host should wait for the first request to finish before queuing up the buffers for the second request, while it has already finished.

To be most efficient, the queue should be thought of as a series of buffers which are present in any order, based on what finishes first. It doesn't increase the complexity on any side to be honest. The code remains straight forward with it.

I expected the host side to be atomic here. Under which circumstance would the 'set direction out with value' call in your example block?

Arnd

#5 lore raw

Re: [PATCH V6 1/2] virtio-gpio: Add the device specification

Quoted 8 lines · Arnd Bergmann
Quoted 4 lines · Viresh Kumar

Doing it per-line seems to be too much overhead, since we are going to call this for every line anyway (at least in Linux implementation). I haven't tried it, but I somehow feel that probe() will take a significant time to finish with that, lets say for 256 GPIO lines.

My guess is that this would not cause any notable overhead, but we will know for sure if you can measure it.

I will surely try it to get the number out, but sending a request 256 times instead of just once looks inefficient from the face of it :)

Quoted 10 lines
Quoted 7 lines

Or allocate 20-25 bytes for each string and allocate a buffer of size

25 * ngpios

The device can write 0 (null) for some of the GPIOs, where it doesn't want to provide a name, or set it to a null terminated string with length <= 25.

I was thinking of a name limit in the context of doing the operation per line.

I really don't want to do it, since in kernel at least we would run that function for all lines right at probe().

Quoted 2 lines

If you keep the list of nul-terminated strings, then I think I would also not limit the length per line.

The problem at hand is knowing the (maximum) size of the buffer to pre-allocate at the driver. And here are the options:

- Keep gpio_names_size in the config structure (like this commit, which is kind of fine since we won't need this multiple times).

- Add a new message type for that, i.e. getting size of the gpio_names_block, but I don't like it since this will be used only once.

- Fix size for each GPIO pin's name to X characters and the driver allocates a buffer of size X * ngpio. This provides good boundaries between line names, more straightforward, less confusing, but more data (unnecessarily) to be sent.

Which one do you like ?

Quoted 16 lines
Quoted 10 lines
Quoted 6 lines

I have a question here, not sure if this needs to be answered in the spec: why can't the driver send activate, set-direction and set-value all at once for a line?
Clearly if one request fails, the later ones would fail as well in this example, but
I don't see this as a problem for either side.

Merging activate along with that would mean, that the host needs to keep a reference count at its end to activate the line on the first call to set-value, but not on others.

My question here was about something else, to rephrase: Can't we allow the driver to queue multiple requests for one line and then have the device process them in order (regardless of whether it processes requests for other lines in parallel). The sequence I had in mind here was

Quoted 15 lines

driver:
1. queue enable
2. queue set-direction
3. queue set-value
4. notify device
device:
5. process enable
6. queue enable-response
7. process set-direction
8. queue set-direction response
9. process set-value
10. queue set-value response
11. notify driver
driver:
12. mark all requests as done

Hmm, we can do that in principle by saying all requests for a particular line must be served in order. But right now I have rather limited the number of requests per line to 1 for a reason, i.e. there will always be a single user of a GPIO line at any point of time. And so the operations will always be sequential.

If you look at users of GPIO, lets say in kernel for now, they all use generic APIs like request, set-direction, set-value, etc. There is no fixed order of how the different callbacks will be called by the user, and so we will never get the requests in bulk or groups (like you mentioned above). Each operation has its own significance, and it won't be right to return from, lets say gpio_set_value(), without getting the result of the operation.

So when can something like this, what you showed above, can be useful ?

Quoted 4 lines
Quoted 3 lines

We would still need to keep the deactivate request, as the host wouldn't know when the guest is done using a line. And for that reason it looked better to have an explicit call to activate here.

Quoted 8 lines

Folding the activate/deactivate is also an interesting option, as discussed before. I don't think we actually need to do reference counting, just making the direction a tristate. I think this would work fine here:

- default direction is VIRTIO_GPIO_MSG_SET_DIRECTION_NONE"
- as long as the direction is not set, nothing else is allowed on the line
- changing the direction from "none" to "in" or "out" implies "activate"
- changing the direction from "in" or "out" back to "none" implies "deactivate"

I am not able to see anything which can break with this, so this looks okay. We can get away with activate/deactivate and use direction-none for that.

Quoted 3 lines

This is similar to folding the irq type into the direction command, and I would slightly prefer it that way, but I'd like to hear what others think about it.

I would really like to keep the irq stuff separate from rest of the basic APIs. This would also be less confusing because the irq stuff is handled separately using a feature flag here.

Over that the users won't club these either, like in Linux the user will do gpio-request, then direction-input, and then request irq.

So these are all required to be sent at different times.

Quoted 18 lines
Quoted 18 lines
Quoted 3 lines

Here I have the opposite question: what is the benefit of allowing the requests to be processed out of order? Should these not all be instantaneous, and easier to handle by making the request queue serialized?

Lets say the guest sends two requests, almost at the same time to the host and they are queued on the vq in this order only:

- set direction-out-with-value-1 for line 5.
- set direction-in for line 11.

Now, if the host is able to process them in parallel, then the second request for line 11 may finish before the requests for line 5 (as it has lesser amount of work to do).

I don't see why the host should wait for the first request to finish before queuing up the buffers for the second request, while it has already finished.

Quoted 7 lines
Quoted 4 lines

To be most efficient, the queue should be thought of as a series of buffers which are present in any order, based on what finishes first. It doesn't increase the complexity on any side to be honest. The code remains straight forward with it.

I expected the host side to be atomic here. Under which circumstance would the 'set direction out with value' call in your example block?

Yes it will block, but another thread can initiate another request for a different GPIO line.

Signature · 1 line
viresh
#6 lore raw

Re: [PATCH V6 1/2] virtio-gpio: Add the device specification

Quoted 7 lines · Viresh Kumar
Quoted 6 lines · Arnd Bergmann
Quoted 4 lines · Viresh Kumar

Doing it per-line seems to be too much overhead, since we are going to call this for every line anyway (at least in Linux implementation). I haven't tried it, but I somehow feel that probe() will take a significant time to finish with that, lets say for 256 GPIO lines.

Quoted 5 lines
Quoted 2 lines

My guess is that this would not cause any notable overhead, but we will know for sure if you can measure it.

I will surely try it to get the number out, but sending a request 256 times instead of just once looks inefficient from the face of it :)

It could still be only one notification though, just a lot of requests with a pair of buffers each, that you send all at once.

Quoted 13 lines
Quoted 2 lines

If you keep the list of nul-terminated strings, then I think I would also not limit the length per line.

The problem at hand is knowing the (maximum) size of the buffer to pre-allocate at the driver. And here are the options:

- Keep gpio_names_size in the config structure (like this commit, which is kind of fine since we won't need this multiple times).

- Add a new message type for that, i.e. getting size of the gpio_names_block, but I don't like it since this will be used only once.

Quoted 6 lines

- Fix size for each GPIO pin's name to X characters and the driver allocates a buffer of size X * ngpio. This provides good boundaries between line names, more straightforward, less confusing, but more data (unnecessarily) to be sent.

Which one do you like ?

If we stay with a single message to get all the names, I'd probably also stay with having the buffer length in config space as you do in the current version.

Quoted 46 lines
Quoted 16 lines
Quoted 10 lines
Quoted 6 lines

I have a question here, not sure if this needs to be answered in the spec: why can't the driver send activate, set-direction and set-value all at once for a line?
Clearly if one request fails, the later ones would fail as well in this example, but
I don't see this as a problem for either side.

Merging activate along with that would mean, that the host needs to keep a reference count at its end to activate the line on the first call to set-value, but not on others.

My question here was about something else, to rephrase: Can't we allow the driver to queue multiple requests for one line and then have the device process them in order (regardless of whether it processes requests for other lines in parallel). The sequence I had in mind here was

Quoted 15 lines

driver:
1. queue enable
2. queue set-direction
3. queue set-value
4. notify device
device:
5. process enable
6. queue enable-response
7. process set-direction
8. queue set-direction response
9. process set-value
10. queue set-value response
11. notify driver
driver:
12. mark all requests as done

Hmm, we can do that in principle by saying all requests for a particular line must be served in order. But right now I have rather limited the number of requests per line to 1 for a reason, i.e. there will always be a single user of a GPIO line at any point of time. And so the operations will always be sequential.

If you look at users of GPIO, lets say in kernel for now, they all use generic APIs like request, set-direction, set-value, etc. There is no fixed order of how the different callbacks will be called by the user, and so we will never get the requests in bulk or groups (like you mentioned above). Each operation has its own significance, and it won't be right to return from, lets say gpio_set_value(), without getting the result of the operation.

Quoted 2 lines

So when can something like this, what you showed above, can be useful ?

Maybe this is something we can get advice for from the virtio maintainers. It was just a feeling on my side that slightly relaxing the requirement makes this more like other virtio drivers.

Functionally, I think there is no difference between mandating that the driver only queues one request per gpio line over requiring that the device processes all requests on a gpio line in sequence, but the latter can be slightly more efficient.

Quoted 4 lines
Quoted 3 lines

This is similar to folding the irq type into the direction command, and I would slightly prefer it that way, but I'd like to hear what others think about it.

Quoted 8 lines

I would really like to keep the irq stuff separate from rest of the basic APIs. This would also be less confusing because the irq stuff is handled separately using a feature flag here.

Over that the users won't club these either, like in Linux the user will do gpio-request, then direction-input, and then request irq.

So these are all required to be sent at different times.

ok

Quoted 10 lines
Quoted 7 lines
Quoted 4 lines

To be most efficient, the queue should be thought of as a series of buffers which are present in any order, based on what finishes first. It doesn't increase the complexity on any side to be honest. The code remains straight forward with it.

I expected the host side to be atomic here. Under which circumstance would the 'set direction out with value' call in your example block?

Yes it will block, but another thread can initiate another request for a different GPIO line.

Ok, I was hoping that the gpiolib interfaces would all end up being non-blocking, but I agree that if the guest has to wait for a notification it can be useful to have more than one going on at once. Especially if the host implementation is in a separate process there is not even a theoretical upper bound on how long it takes to process a request.

Arnd

#7 lore raw

Re: [PATCH V6 1/2] virtio-gpio: Add the device specification

Quoted 8 lines · Arnd Bergmann
Quoted 7 lines · Viresh Kumar
Quoted 6 lines · Arnd Bergmann
Quoted 4 lines · Viresh Kumar

Doing it per-line seems to be too much overhead, since we are going to call this for every line anyway (at least in Linux implementation). I haven't tried it, but I somehow feel that probe() will take a significant time to finish with that, lets say for 256 GPIO lines.

Quoted 5 lines
Quoted 5 lines
Quoted 2 lines

My guess is that this would not cause any notable overhead, but we will know for sure if you can measure it.

I will surely try it to get the number out, but sending a request 256 times instead of just once looks inefficient from the face of it :)

I created a small setup with qemu-arm64 over x86:
- Without any memcpy() of data or buffers in the GPIO drivers on both ends.
- i.e. essentially taking into consideration only the time to send receive requests, the virtio core may be copying packets in between though, not sure.

Quoted 2 lines

It could still be only one notification though, just a lot of requests with a pair of buffers each, that you send all at once.

If we send only one notification at the end, it takes ~ 1ms for 256 GPIO pins, pretty much like a single request only. The downside here is that the device (host) also needs to prepare the queue for equal number (to ngpio) of elements. This is something the spec hasn't touched until now, i.e. how many buffers must be queued for the virtqueues. The max allowed in qemu is 1024 right now.

Even if I send them sequentially, with separate notification for each request, it takes ~15-20 ms to finish 256 lines and ~80 for 1024 lines.

Though a single request still sounds tempting to me :)

Quoted 38 lines
Quoted 35 lines
Quoted 5 lines

My question here was about something else, to rephrase: Can't we allow the driver to queue multiple requests for one line and then have the device process them in order (regardless of whether it processes requests for other lines in parallel). The sequence I had in mind here was

Quoted 15 lines

driver:
1. queue enable
2. queue set-direction
3. queue set-value
4. notify device
device:
5. process enable
6. queue enable-response
7. process set-direction
8. queue set-direction response
9. process set-value
10. queue set-value response
11. notify driver
driver:
12. mark all requests as done

Hmm, we can do that in principle by saying all requests for a particular line must be served in order. But right now I have rather limited the number of requests per line to 1 for a reason, i.e. there will always be a single user of a GPIO line at any point of time. And so the operations will always be sequential.

If you look at users of GPIO, lets say in kernel for now, they all use generic APIs like request, set-direction, set-value, etc. There is no fixed order of how the different callbacks will be called by the user, and so we will never get the requests in bulk or groups (like you mentioned above). Each operation has its own significance, and it won't be right to return from, lets say gpio_set_value(), without getting the result of the operation.

Quoted 2 lines

So when can something like this, what you showed above, can be useful ?

Quoted 8 lines

Maybe this is something we can get advice for from the virtio maintainers. It was just a feeling on my side that slightly relaxing the requirement makes this more like other virtio drivers.

Functionally, I think there is no difference between mandating that the driver only queues one request per gpio line over requiring that the device processes all requests on a gpio line in sequence, but the latter can be slightly more efficient.

Yes, it can be efficient but I don't see when this can be used in practice. Specially in kernel, the way GPIO users handle stuff.

But anyway, I don't have any issue specifically with allowing multiple requests per GPIO line in the spec itself. Spec can be kept open for such an option.

Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines

To be most efficient, the queue should be thought of as a series of buffers which are present in any order, based on what finishes first. It doesn't increase the complexity on any side to be honest. The code remains straight forward with it.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

I expected the host side to be atomic here. Under which circumstance would the 'set direction out with value' call in your example block?

Yes it will block, but another thread can initiate another request for a different GPIO line.

Ok, I was hoping that the gpiolib interfaces would all end up being non-blocking,

I am not sure how we can do that :(

Quoted 4 lines

but I agree that if the guest has to wait for a notification it can be useful to have more than one going on at once. Especially if the host implementation is in a separate process there is not even a theoretical upper bound on how long it takes to process a request.

Right.

Signature · 1 line
viresh
#8 lore raw

Re: [PATCH V6 1/2] virtio-gpio: Add the device specification

Quoted 18 lines · Viresh Kumar
Quoted 6 lines · Arnd Bergmann
Quoted 5 lines · Viresh Kumar
Quoted 2 lines

My guess is that this would not cause any notable overhead, but we will know for sure if you can measure it.

I will surely try it to get the number out, but sending a request 256 times instead of just once looks inefficient from the face of it :)

I created a small setup with qemu-arm64 over x86:
- Without any memcpy() of data or buffers in the GPIO drivers on both ends.
- i.e. essentially taking into consideration only the time to send receive requests, the virtio core may be copying packets in between though, not sure.

Quoted 2 lines

It could still be only one notification though, just a lot of requests with a pair of buffers each, that you send all at once.

Quoted 6 lines

If we send only one notification at the end, it takes ~ 1ms for 256 GPIO pins, pretty much like a single request only. The downside here is that the device (host) also needs to prepare the queue for equal number (to ngpio) of elements. This is something the spec hasn't touched until now, i.e. how many buffers must be queued for the virtqueues. The max allowed in qemu is 1024 right now.

1ms is borderline I guess, it's close to the range of things that gets annoying for boot-time optimization.

Quoted 5 lines

Even if I send them sequentially, with separate notification for each request, it takes ~15-20 ms to finish 256 lines and ~80 for 1024 lines.

Though a single request still sounds tempting to me :)

Right, 80ms is definitely noticeable, this can easily make the difference between an instant guest boot and a perceived delay.

Quoted 10 lines
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

I expected the host side to be atomic here. Under which circumstance would the 'set direction out with value' call in your example block?

Yes it will block, but another thread can initiate another request for a different GPIO line.

Ok, I was hoping that the gpiolib interfaces would all end up being non-blocking,

I am not sure how we can do that :(

I suppose not without a complete redesign from scratch.

Arnd

#9 lore raw

Re: [PATCH V6 1/2] virtio-gpio: Add the device specification

Quoted 12 lines · Arnd Bergmann
Quoted 6 lines · Viresh Kumar

If we send only one notification at the end, it takes ~ 1ms for 256 GPIO pins, pretty much like a single request only. The downside here is that the device (host) also needs to prepare the queue for equal number (to ngpio) of elements. This is something the spec hasn't touched until now, i.e. how many buffers must be queued for the virtqueues. The max allowed in qemu is 1024 right now.

1ms is borderline I guess, it's close to the range of things that gets annoying for boot-time optimization.

Quoted 8 lines
Quoted 5 lines

Even if I send them sequentially, with separate notification for each request, it takes ~15-20 ms to finish 256 lines and ~80 for 1024 lines.

Though a single request still sounds tempting to me :)

Right, 80ms is definitely noticeable, this can easily make the difference between an instant guest boot and a perceived delay.

It is also important to mention here that in my current example, there was no copy
of the gpio line name string made anywhere.

If we choose this message to be per-line, then there will be at least one memcpy at the host of the string for each GPIO line, there may be another copy somewhere
in between at guest or host, not sure. Though in case of a single request, this will
be a single memcpy operation at the guest (and others in between as mentioned earlier),
but not per line and maybe more efficient.

So even in the best possible scenario, this will be several ms, at least for separate
message for each GPIO line.

Anyway, how do you suggest I define this call now. Per-line or entire block (fixed size or
from config structure) ? I will do it the way you suggest to cut short the discussion :)

Quoted 3 lines
Quoted 1 line

I am not sure how we can do that :(

I suppose not without a complete redesign from scratch.

Yeah, I am not doing it then :)

--
viresh

#10 lore raw

Re: [PATCH V6 1/2] virtio-gpio: Add the device specification

Quoted 13 lines · Viresh Kumar

It is also important to mention here that in my current example, there was no copy
of the gpio line name string made anywhere.

If we choose this message to be per-line, then there will be at least one memcpy at the host of the string for each GPIO line, there may be another copy somewhere
in between at guest or host, not sure. Though in case of a single request, this will
be a single memcpy operation at the guest (and others in between as mentioned earlier),
but not per line and maybe more efficient.

Quoted 8 lines

So even in the best possible scenario, this will be several ms, at least for separate
message for each GPIO line.

Anyway, how do you suggest I define this call now. Per-line or entire block (fixed size or
from config structure) ? I will do it the way you suggest to cut short the discussion :)

Also to mention that this request will always be called (at least for Linux) only once for all the GPIO lines, at probe time only. And never after that.

So making it per-line doesn't give us any flexibility that we may be looking for.

--
Viresh

#11 lore raw

Re: [PATCH V6 1/2] virtio-gpio: Add the device specification

Quoted 3 lines · Viresh Kumar

So making it per-line doesn't give us any flexibility that we may be looking for.

I was not really looking for extra flexibility here, only for a simpler and more consistent interface definition. But if the simpler interface comes at the cost of more complexity and time overhead in the driver, it's probably not worth it.

Arnd

#12 lore raw

[virtio-dev] Re: [PATCH V6 1/2] virtio-gpio: Add the device specification

In reply to Arnd Bergmann
Quoted 4 lines · Arnd Bergmann
Quoted 2 lines · Viresh Kumar
Quoted 1 line · Arnd Bergmann

On Mon, Jul 26, 2021 at 12:16 PM Viresh Kumar <[email protected]> wrote:

[Disclaimer: I basically don't know anything about gpio]

Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
Quoted 10 lines
Quoted 6 lines

I have a question here, not sure if this needs to be answered in the spec: why can't the driver send activate, set-direction and set-value all at once for a line?
Clearly if one request fails, the later ones would fail as well in this example, but
I don't see this as a problem for either side.

Merging activate along with that would mean, that the host needs to keep a reference count at its end to activate the line on the first call to set-value, but not on others.

My question here was about something else, to rephrase: Can't we allow the driver to queue multiple requests for one line and then have the device process them in order (regardless of whether it processes requests for other lines in parallel). The sequence I had in mind here was

Quoted 15 lines
Quoted 7 lines
Quoted 7 lines

driver:
1. queue enable
2. queue set-direction
3. queue set-value
4. notify device
device:
5. process enable

Quoted 8 lines
Quoted 8 lines

6. queue enable-response
7. process set-direction
8. queue set-direction response
9. process set-value
10. queue set-value response
11. notify driver
driver:
12. mark all requests as done

What are the ordering/sequence requirements here? E.g., are enable/set-direction or enable/set-value/set-direction valid sequences?

If we consider the sequence 1-4 above as a command chain, what about adding a chaining field that can point to the next command in the chain? The driver would build the chain in one go, the device would process the chain one after another, and stop if it encounters an error. The driver would be free to submit chains for other lines, but not another one for the same line as long as the current chain is not yet finished.

[Yes, I realize that this looks a lot like channel I/O...]

Quoted 7 lines
Quoted 7 lines

Hmm, we can do that in principle by saying all requests for a particular line must be served in order. But right now I have rather limited the number of requests per line to 1 for a reason, i.e. there will always be a single user of a GPIO line at any point of time. And so the operations will always be sequential.

Quoted 7 lines
Quoted 7 lines

If you look at users of GPIO, lets say in kernel for now, they all use generic APIs like request, set-direction, set-value, etc. There is no fixed order of how the different callbacks will be called by the user, and so we will never get the requests in bulk or groups (like you mentioned above). Each operation has its own significance, and it won't be right to return from, lets say gpio_set_value(), without getting the result of the operation.

You could match this to individual chains of length one, where you cannot submit another request for a line before the current one is finished.

Quoted 4 lines
Quoted 3 lines

So when can something like this, what you showed above, can be useful ?

Quoted 8 lines

Maybe this is something we can get advice for from the virtio maintainers. It was just a feeling on my side that slightly relaxing the requirement makes this more like other virtio drivers.

Functionally, I think there is no difference between mandating that the driver only queues one request per gpio line over requiring that the device processes all requests on a gpio line in sequence, but the latter can be slightly more efficient.

It might be worth considering for future drivers, or non-Linux drivers.

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]

#13 lore raw

Re: [virtio-dev] Re: [PATCH V6 1/2] virtio-gpio: Add the device specification

Quoted 17 lines · Cornelia Huck
Quoted 7 lines · Arnd Bergmann
Quoted 7 lines
Quoted 7 lines

driver:
1. queue enable
2. queue set-direction
3. queue set-value
4. notify device
device:
5. process enable

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

6. queue enable-response
7. process set-direction
8. queue set-direction response
9. process set-value
10. queue set-value response
11. notify driver
driver:
12. mark all requests as done

Quoted 2 lines

What are the ordering/sequence requirements here? E.g., are enable/set-direction or enable/set-value/set-direction valid sequences?

Yes, these are valid sequences. But there is not real hardfixed way of doing things here, the users can call them most likely in any order.

Quoted 6 lines

If we consider the sequence 1-4 above as a command chain, what about adding a chaining field that can point to the next command in the chain? The driver would build the chain in one go, the device would process the chain one after another, and stop if it encounters an error. The driver would be free to submit chains for other lines, but not another one for the same line as long as the current chain is not yet finished.

These commands aren't related necessarily and so this kind of linking between them is not right. Each operation is really independent from each other, though the user may not want to initiate the second operation if the first one fails. This isn't something like I2C messages, where the first one gives the address and second one gives something else (like size) and is incomplete without the first one.

Here all instructions is actually independent of each other.

I think Arnd was just thinking of this to make it possible to send notification only once, if that can give some improvement. But I am quite sure that Linux today will most likely not end up using it that way.

Quoted 10 lines
Quoted 8 lines

Maybe this is something we can get advice for from the virtio maintainers. It was just a feeling on my side that slightly relaxing the requirement makes this more like other virtio drivers.

Functionally, I think there is no difference between mandating that the driver only queues one request per gpio line over requiring that the device processes all requests on a gpio line in sequence, but the latter can be slightly more efficient.

It might be worth considering for future drivers, or non-Linux drivers.

Right, as I said in the other email just now, I am fine with allowing this in spec at least (someone may want to use it later), i.e. queuing of multiple request for the same GPIO line and them being processed in the same order.

Signature · 1 line
viresh
#14 lore raw

Re: [PATCH V6 1/2] virtio-gpio: Add the device specification

In reply to Viresh Kumar

Hi Viresh,

Quoted 8 lines · Viresh Kumar
Quoted 3 lines · Arnd Bergmann

Here I have the opposite question: what is the benefit of allowing the requests to be processed out of order? Should these not all be instantaneous, and easier to handle by making the request queue serialized?

Lets say the guest sends two requests, almost at the same time to the host and they are queued on the vq in this order only:

Quoted 6 lines

- set direction-out-with-value-1 for line 5.
- set direction-in for line 11.

Now, if the host is able to process them in parallel, then the second request for line 11 may finish before the requests for line 5 (as it has lesser amount of work to do).

Speaking about parallel processing, have you already envisioned support for .[sg]et_multiple()?

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
#15 lore raw

Re: [PATCH V6 1/2] virtio-gpio: Add the device specification

Quoted 14 lines · Geert Uytterhoeven

Hi Viresh,

Quoted 11 lines · Viresh Kumar
Quoted 3 lines · Arnd Bergmann

Here I have the opposite question: what is the benefit of allowing the requests to be processed out of order? Should these not all be instantaneous, and easier to handle by making the request queue serialized?

Lets say the guest sends two requests, almost at the same time to the host and they are queued on the vq in this order only:

- set direction-out-with-value-1 for line 5.
- set direction-in for line 11.

Quoted 6 lines
Quoted 3 lines

Now, if the host is able to process them in parallel, then the second request for line 11 may finish before the requests for line 5 (as it has lesser amount of work to do).

Speaking about parallel processing, have you already envisioned support for .[sg]et_multiple()?

Not yet, but we can surely do that once someone needs it. Same goes for lots of other gpio pinwise operations.

Signature · 1 line
viresh
#16 lore raw

PATCH v6 2/2 virtio-gpio: Add support for interrupts

In reply to Viresh Kumar

This patch adds support for interrupts to the virtio-gpio specification. This uses the feature bit 0 for the same.

---
 conformance.tex |   2 +
 virtio-gpio.tex | 241 +++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 242 insertions(+), 1 deletion(-)
conformance.tex +2 -0
index c52f1a40be2d..64bcc12d1199 100644
@@ -310,6 +310,7 @@ \section{Conformance Targets}\label{sec:Conformance / Conformance Targets}
 
 \begin{itemize}
 \item \ref{drivernormative:Device Types / GPIO Device / requestq Operation}
+\item \ref{drivernormative:Device Types / GPIO Device / eventq Operation}
 \end{itemize}
 
 \conformance{\section}{Device Conformance}\label{sec:Conformance / Device Conformance}
@@ -568,6 +569,7 @@ \section{Conformance Targets}\label{sec:Conformance / Conformance Targets}
 
 \begin{itemize}
 \item \ref{devicenormative:Device Types / GPIO Device / requestq Operation}
+\item \ref{devicenormative:Device Types / GPIO Device / eventq Operation}
 \end{itemize}
 
 \conformance{\section}{Legacy Interface: Transitional Device and Transitional Driver Conformance}\label{sec:Conformance / Legacy Interface: Transitional Device and Transitional Driver Conformance}
virtio-gpio.tex +240 -1

278 lines not on this page · raw message

Signature · 6 lines
2.31.1.272.g89b43f80a514


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
#17 lore raw

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

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.

I think the flow of event messages already looks great with this version, and I like the level of detail in the explanations.

The only part I don't like is that it seems overly redundant to have three ways to enable/disable irq delivery. More on that below.

virtio-gpio.tex \subsubsection{requestq Operation: Message Flow}\label{sec:Device Types / GPIO D · line 556

Quoted 3 lines

+\item If the GPIO line is configured for Level interrupts, the device MUST

virtio-gpio.tex +2 -0
+    ignore any further interrupts for the line, until the time the buffers are
+    made available again by the driver.

This wording sounds odd, since there are not technically any interrupt events on the level triggered line, but instead the level is active. I would describe this
as "the device MUST mask the interrupt line, until the time ...", though that conflicts with the terminology for the mask/unmask request.

I would still hope that we can combine the irq_type, mask and request steps into either one or two steps. I think the minimalistic approach would be to expand the message to include both the "mask" and "set-type" operations, and this should work, as long as we define sensible semantics.

Another option would be to fold the "set irq type" operation into "set direction",
so an input can be configured as any of the five irq types, with "IRQ_TYPE_NONE" implying that interrupts are disabled for this line. This would still provide an extra way of masking the interrupt, so we just need "set-direction" and "request event". In this case, setting the interrupt type to "none" should probably cancel any pending irq and force the message to be returned.

You could actually take that further and fold the "set value" into "set direction", which also simplifies the output direction and avoids the case where can you set a gpio to output before setting the value first.

Arnd

#18 lore raw

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

Quoted 6 lines · Arnd Bergmann
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.

I think the flow of event messages already looks great with this version, and I like the level of detail in the explanations.

Thanks.

Quoted 7 lines

The only part I don't like is that it seems overly redundant to have three ways to enable/disable irq delivery. More on that below.

virtio-gpio.tex \subsubsection{requestq Operation: Message Flow}\label{sec:Device Types / GPIO D · line 556

Quoted 3 lines

+\item If the GPIO line is configured for Level interrupts, the device MUST

virtio-gpio.tex +2 -0
+    ignore any further interrupts for the line, until the time the buffers are
+    made available again by the driver.
Quoted 5 lines

This wording sounds odd, since there are not technically any interrupt events on the level triggered line, but instead the level is active. I would describe this
as "the device MUST mask the interrupt line, until the time ...", though that conflicts with the terminology for the mask/unmask request.

Right.

Quoted 1 line

I would still hope that we can combine the irq_type, mask and request

request ? you wanted to say "unmask" ?

Quoted 3 lines

steps into either one or two steps. I think the minimalistic approach would be to expand the message to include both the "mask" and "set-type" operations, and this should work, as long as we define sensible semantics.

I think we can easily merge unmask and set-type into a single message, since that will fit within the request structure used for most of the requests on the requestq. i.e. a single byte of data.

mask() doesn't require irq-type, so it can live separately.

Quoted 2 lines

Another option would be to fold the "set irq type" operation into "set direction",

Yeah, I would like to keep them separate and not mix irq-type with directions in general, as you can set direction to input with or without setting its interrupt type.

Over that interrupt support is enabled with a feature, so better keep it separate.

Quoted 9 lines

so an input can be configured as any of the five irq types, with "IRQ_TYPE_NONE" implying that interrupts are disabled for this line. This would still provide an extra way of masking the interrupt, so we just need "set-direction" and "request event". In this case, setting the interrupt type to "none" should probably cancel any pending irq and force the message to be returned.

You could actually take that further and fold the "set value" into "set direction",

At least gpio-direction-out already takes a value with it.

Quoted 2 lines

which also simplifies the output direction and avoids the case where can you set a gpio to output before setting the value first.

Yeah, that is already done.

Signature · 1 line
viresh
#19 lore raw

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

Quoted 5 lines · Viresh Kumar
Quoted 1 line · Arnd Bergmann

I would still hope that we can combine the irq_type, mask and request

request ? you wanted to say "unmask" ?

No, I meant VIRTIO_GPIO_MSG_IRQ_TYPE, VIRTIO_GPIO_MSG_IRQ_{UN,}MASK and virtio_gpio_irq_request messages.

All three can change the state between 'can interrupt' and 'can not interrupt', so you only get notified if all three are in the active state (irq type != none, mask disabled, request queued).

Quoted 9 lines
Quoted 3 lines

steps into either one or two steps. I think the minimalistic approach would be to expand the message to include both the "mask" and "set-type" operations, and this should work, as long as we define sensible semantics.

I think we can easily merge unmask and set-type into a single message, since that will fit within the request structure used for most of the requests on the requestq. i.e. a single byte of data.

mask() doesn't require irq-type, so it can live separately.

The question is whether it adds any value though. As far as I can tell, it is completely redundant, duplicating either what is implied by irq type==none, or what is implied by the request not being queued.

Quoted 11 lines
Quoted 9 lines

so an input can be configured as any of the five irq types, with "IRQ_TYPE_NONE" implying that interrupts are disabled for this line. This would still provide an extra way of masking the interrupt, so we just need "set-direction" and "request event". In this case, setting the interrupt type to "none" should probably cancel any pending irq and force the message to be returned.

You could actually take that further and fold the "set value" into "set direction",

At least gpio-direction-out already takes a value with it.

Ok.

Arnd

#20 lore raw

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

Quoted 8 lines · Arnd Bergmann
Quoted 5 lines · Viresh Kumar
Quoted 1 line · Arnd Bergmann

I would still hope that we can combine the irq_type, mask and request

request ? you wanted to say "unmask" ?

No, I meant VIRTIO_GPIO_MSG_IRQ_TYPE,

Ah, I was confused since this request type isn't there anymore.

Quoted 14 lines

VIRTIO_GPIO_MSG_IRQ_{UN,}MASK and virtio_gpio_irq_request messages.

All three can change the state between 'can interrupt' and 'can not interrupt', so you only get notified if all three are in the active state (irq type != none, mask disabled, request queued).

Quoted 8 lines
Quoted 3 lines

steps into either one or two steps. I think the minimalistic approach would be to expand the message to include both the "mask" and "set-type" operations, and this should work, as long as we define sensible semantics.

I think we can easily merge unmask and set-type into a single message, since that will fit within the request structure used for most of the requests on the requestq. i.e. a single byte of data.

Quoted 5 lines
Quoted 1 line

mask() doesn't require irq-type, so it can live separately.

The question is whether it adds any value though. As far as I can tell, it is completely redundant, duplicating either what is implied by irq type==none, or what is implied by the request not being queued.

Right, we shouldn't have redundant stuff in here.

Though, binding of all interrupt operations to the eventq can be trick IMO.

- How will the driver mask an interrupt for which the buffer is already sent over the eventq? There is no API available to recall a buffer. So we would need an API over the requestq for that.

- Latching of edge interrupt between the buffer is returned by the device and requeued by the driver. How will the device know if the user has simply requeued the eventq buffer (where the latched value is meaningful) or it has done something like free_irq() followed by request_irq() in the kernel (where the latched value must be discarded).

Signature · 1 line
viresh
#21 lore raw

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

Quoted 5 lines · Viresh Kumar
Quoted 3 lines · Arnd Bergmann

The question is whether it adds any value though. As far as I can tell, it is completely redundant, duplicating either what is implied by irq type==none, or what is implied by the request not being queued.

Quoted 8 lines

Right, we shouldn't have redundant stuff in here.

Though, binding of all interrupt operations to the eventq can be trick IMO.

- How will the driver mask an interrupt for which the buffer is already sent over the eventq? There is no API available to recall a buffer. So we would need an API over the requestq for that.

Agreed, there needs to be some way to cancel the request. I don't think this would have to be a fast or common operation, so setting the line back to IRQ_TYPE_NONE would be one way.

Another option would be to make the mask software-only and just ignore an incoming event for a line that is configured as masked, and then not requeue the request.

Quoted 6 lines

- Latching of edge interrupt between the buffer is returned by the device and requeued by the driver. How will the device know if the user has simply requeued the eventq buffer (where the latched value is meaningful) or it has done something like free_irq() followed by request_irq() in the kernel (where the latched value must be discarded).

I was expecting a 'mask' to not discard the latched event but simply not deliver it until it gets unmasked. Either way, we can define that a new set-irq-type request discards all latched edge interrupts.

Arnd

#22 lore raw

Re: [virtio-dev] Re: [PATCH V6 2/2] virtio-gpio: Add support for interrupts

Quoted 11 lines · Arnd Bergmann
Quoted 10 lines · Viresh Kumar
Quoted 3 lines · Arnd Bergmann

The question is whether it adds any value though. As far as I can tell, it is completely redundant, duplicating either what is implied by irq type==none, or what is implied by the request not being queued.

Right, we shouldn't have redundant stuff in here.

Though, binding of all interrupt operations to the eventq can be trick IMO.

Quoted 7 lines
Quoted 3 lines

- How will the driver mask an interrupt for which the buffer is already sent over the eventq? There is no API available to recall a buffer. So we would need an API over the requestq for that.

Agreed, there needs to be some way to cancel the request. I don't think this would have to be a fast or common operation, so setting the line back to IRQ_TYPE_NONE would be one way.

Hmm, how would that work ? I thought you were talking about inferring all irq operations from the presence of the buffer in the eventq itself. So once the buffer is sent to the host, we can't send it again to change the irq-type.

Quoted 3 lines

Another option would be to make the mask software-only and just ignore an incoming event for a line that is configured as masked, and then not requeue the request.

Hmm, I wonder what will happen if the driver gets removed/probed again after sending the buffer :)

Quoted 9 lines
Quoted 6 lines

- Latching of edge interrupt between the buffer is returned by the device and requeued by the driver. How will the device know if the user has simply requeued the eventq buffer (where the latched value is meaningful) or it has done something like free_irq() followed by request_irq() in the kernel (where the latched value must be discarded).

I was expecting a 'mask' to not discard the latched event but simply not deliver it until it gets unmasked.

Right, we are aligned on that. Masked == buffer is owned by driver here.

Quoted 2 lines

Either way, we can define that
a new set-irq-type request discards all latched edge interrupts.

Hmm, so you proposing to keep a separate (single) request for irq handling over the controlq ?

Signature · 1 line
viresh
#23 lore raw

Re: [virtio-dev] Re: [PATCH V6 2/2] virtio-gpio: Add support for interrupts

Quoted 16 lines · Viresh Kumar
Quoted 15 lines · Arnd Bergmann
Quoted 13 lines · Viresh Kumar
Quoted 3 lines · Arnd Bergmann

The question is whether it adds any value though. As far as I can tell, it is completely redundant, duplicating either what is implied by irq type==none, or what is implied by the request not being queued.

Right, we shouldn't have redundant stuff in here.

Though, binding of all interrupt operations to the eventq can be trick IMO.

- How will the driver mask an interrupt for which the buffer is already sent over the eventq? There is no API available to recall a buffer. So we would need an API over the requestq for that.

Quoted 8 lines
Quoted 3 lines

Agreed, there needs to be some way to cancel the request. I don't think this would have to be a fast or common operation, so setting the line back to IRQ_TYPE_NONE would be one way.

Hmm, how would that work ? I thought you were talking about inferring all irq operations from the presence of the buffer in the eventq itself. So once the buffer is sent to the host, we can't send it again to change the irq-type.

You are right, I was getting ahead of myself here: we could do this if the set-irq-type oepration gets folded into set-direction as I hinted as one of many options, but it does not work if the set-irq-type and ack operations are both folded into queuing a request on the event queue.

Quoted 6 lines
Quoted 3 lines

Another option would be to make the mask software-only and just ignore an incoming event for a line that is configured as masked, and then not requeue the request.

Hmm, I wonder what will happen if the driver gets removed/probed again after sending the buffer :)

Removing the driver would disable the line (or set it to direction_none if we go there) and shut down the virtqueue, so both of these should lead to no event getting latched any more.

Quoted 10 lines
Quoted 9 lines
Quoted 6 lines

- Latching of edge interrupt between the buffer is returned by the device and requeued by the driver. How will the device know if the user has simply requeued the eventq buffer (where the latched value is meaningful) or it has done something like free_irq() followed by request_irq() in the kernel (where the latched value must be discarded).

I was expecting a 'mask' to not discard the latched event but simply not deliver it until it gets unmasked.

Quoted 8 lines

Right, we are aligned on that. Masked == buffer is owned by driver here.

Quoted 2 lines

Either way, we can define that
a new set-irq-type request discards all latched edge interrupts.

Hmm, so you proposing to keep a separate (single) request for irq handling over the controlq ?

This was under the assumption that we decide to still keep some controlq request that sets the irq type and just remove the 'mask' command.

If we go all the way to having only one message for interrupts, I suppose it does get a little uglier than I was hoping for, but it would still be doable: in this case, we could allow a flow like this on the eventq:

- driver requests edge interrupts
- (no event happened, so request remains pending)
- driver queues a new request asking for IRQ_TYPE_NONE notification in order to mask this line
- device replies to both requests saying no interrupt happened

Between this control flow and the version where set-type is part of set-direction, I would prefer the other option, but you already said that you don't like that one.

Arnd

#24 lore raw

Re: [virtio-dev] Re: [PATCH V6 2/2] virtio-gpio: Add support for interrupts

Quoted 3 lines · Arnd Bergmann

This was under the assumption that we decide to still keep some controlq request that sets the irq type and just remove the 'mask' command.

Right, so I think I can fold all three of irq messages, mask, unmask and type, to a single message type. Where the value of type can play the role of masking/unmasking. This should work fine, I will see if I get any more doubts on this.

Quoted 5 lines

If we go all the way to having only one message for interrupts, I suppose it does get a little uglier than I was hoping for, but it would still be doable: in this case, we could allow a flow like this on the eventq:

- driver requests edge interrupts

This over eventq and ..

Quoted 3 lines

- (no event happened, so request remains pending)
- driver queues a new request asking for IRQ_TYPE_NONE notification in order to mask this line

This over controlq. Right ?

Quoted 1 line

- device replies to both requests saying no interrupt happened

Yes, that can work.

Quoted 3 lines

Between this control flow and the version where set-type is part of set-direction, I would prefer the other option, but you already said that you don't like that one.

Yeah, I would like to keep this away from set-direction, which I am already going to use for activate/deactivate :)

Signature · 1 line
viresh
#25 lore raw

Re: [virtio-dev] Re: [PATCH V6 2/2] virtio-gpio: Add support for interrupts

Quoted 16 lines · Viresh Kumar
Quoted 3 lines · Arnd Bergmann

This was under the assumption that we decide to still keep some controlq request that sets the irq type and just remove the 'mask' command.

Right, so I think I can fold all three of irq messages, mask, unmask and type, to a single message type. Where the value of type can play the role of masking/unmasking. This should work fine, I will see if I get any more doubts on this.

Quoted 5 lines

If we go all the way to having only one message for interrupts, I suppose it does get a little uglier than I was hoping for, but it would still be doable: in this case, we could allow a flow like this on the eventq:

- driver requests edge interrupts

Quoted 7 lines

This over eventq and ..

Quoted 3 lines

- (no event happened, so request remains pending)
- driver queues a new request asking for IRQ_TYPE_NONE notification in order to mask this line

This over controlq. Right ?

Sorry for not being too clear: this was meant as the example where both messages are on the eventq. It would work just as well if the irq type setting is a message on the controlq though, so I suppose it doesn't matter what I was thinking as long as we end up with a working design ;-)

Quoted 10 lines
Quoted 1 line

- device replies to both requests saying no interrupt happened

Yes, that can work.

Quoted 3 lines

Between this control flow and the version where set-type is part of set-direction, I would prefer the other option, but you already said that you don't like that one.

Yeah, I would like to keep this away from set-direction, which I am already going to use for activate/deactivate :)

Ok, so the set of relevant messages here would be:

- controlq: set direction (includes enable, but not set-irq-type)
- controlq: set-irq-type (may cancel outstanding eventq request)
- eventq: request notification (implies unmask, reply implies mask)

This sounds like a reasonably consistent and efficient way to do it, I'm happy enough with that design for the next version.

Arnd