Re: [virtio-dev][PATCH v1 1/2] virtio-mmio: Add MSI and different notification address support
From: Stefan Hajnoczi
Date: Fri Jan 10 2020 - 04:52:41 EST
On Thu, Jan 09, 2020 at 01:13:09PM +0800, Liu, Jing2 wrote:
>
> On 1/7/2020 12:18 AM, Stefan Hajnoczi wrote:
> > On Fri, Dec 20, 2019 at 11:25:03PM +0800, Jing Liu wrote:
> > > Upgrade virtio-mmio to version 3, with the abilities to support
> > > MSI interrupt and notification features.
> > >
> > > The details of version 2 will be appended as part of legacy interface
> > > in next patch.
> > Cool, MSI is useful. Not a full review, but some comments below...
>
> Hi Stefan,
>
> Thanks for reviewing patches! Glad to see that MSI is welcome.
>
> > > Signed-off-by: Jing Liu<jing2.liu@xxxxxxxxxxxxxxx>
> > > Signed-off-by: Chao Peng<chao.p.peng@xxxxxxxxxxxxxxx>
> > > Signed-off-by: Zha Bin<zhabin@xxxxxxxxxxxxxxxxx>
> > > Signed-off-by: Liu Jiang<gerry@xxxxxxxxxxxxxxxxx>
> > > ---
> > > content.tex | 191 ++++++++++++++++++++++++++++++++++++++++++++++++-----------
> > > msi-status.c | 5 ++
> > > 2 files changed, 163 insertions(+), 33 deletions(-)
> > > create mode 100644 msi-status.c
> > >
> > > diff --git a/content.tex b/content.tex
> > > index d68cfaf..eaaffec 100644
> > > --- a/content.tex
> > > +++ b/content.tex
> > > @@ -1597,9 +1597,9 @@ \subsection{MMIO Device Register Layout}\label{sec:Virtio Transport Options / Vi
> > > }
> > > \hline
> > > \mmioreg{Version}{Device version number}{0x004}{R}{%
> > > - 0x2.
> > > + 0x3.
> > > \begin{note}
> > > - Legacy devices (see \ref{sec:Virtio Transport Options / Virtio Over MMIO / Legacy interface}~\nameref{sec:Virtio Transport Options / Virtio Over MMIO / Legacy interface}) used 0x1.
> > > + Legacy devices (see \ref{sec:Virtio Transport Options / Virtio Over MMIO / Legacy interface}~\nameref{sec:Virtio Transport Options / Virtio Over MMIO / Legacy interface}) used 0x1 or 0x2.
> > "Legacy devices" refers to pre-VIRTIO 1.0 devices. 0x2 is VIRTIO 1.0
> > and therefore not "Legacy". I suggest the following wording:
> >
> > Legacy devices (see \ref{sec:Virtio Transport Options / Virtio Over MMIO / Legacy interface}~\nameref{sec:Virtio Transport Options / Virtio Over MMIO / Legacy interface}) used 0x1.
> > + VIRTIO 1.0 and 1.1 used 0x2.
> Thanks for the guide.
> > Did you consider using a transport feature bit instead of changing the
> > device version number? Feature bits allow more graceful compatibility:
> > old drivers will continue to work with new devices and new drivers will
> > continue to work with old devices.
>
> Yes, we considered using a feature bit from 24~37 or above, while a concern
> is that,
>
> the device which uses such bit only represents the behavior of mmio
> transport layer but not common behavior
>
> of virtio device. Or am I missing some "transport" feature bit range?
https://docs.oasis-open.org/virtio/virtio/v1.1/cs01/virtio-v1.1-cs01.html#x1-4100006
Feature bit 39 is reserved and can be used.
This is similar to when the SR_IOV (37) feature bit was added for
virtio-pci.
> > > \end{note}
> > > }
> > > \hline
> > > @@ -1671,25 +1671,23 @@ \subsection{MMIO Device Register Layout}\label{sec:Virtio Transport Options / Vi
> > > accesses apply to the queue selected by writing to \field{QueueSel}.
> > > }
> > > \hline
> > > - \mmioreg{QueueNotify}{Queue notifier}{0x050}{W}{%
> > > - Writing a value to this register notifies the device that
> > > - there are new buffers to process in a queue.
> > > + \mmioreg{QueueNotify}{Queue notifier}{0x050}{RW}{%
> > > + Reading from the register returns the virtqueue notification configuration.
> > > - When VIRTIO_F_NOTIFICATION_DATA has not been negotiated,
> > > - the value written is the queue index.
> > > + See \ref{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Notification Address}
> > > + for the configuration format.
> > > - When VIRTIO_F_NOTIFICATION_DATA has been negotiated,
> > > - the \field{Notification data} value has the following format:
> > > + Writing when the notification address calculated by the notification configuration
> > > + is just located at this register.
> > I don't understand this sentence. What happens when the driver writes
> > to this register?
>
> We're trying to define the notification mechanism that, driver MUST read
> 0x50 to get the notification configuration
>
> and calculate the notify address. The writing case here is that, the notify
> address is just located here e.g. notify_base=0x50, notify_mul=0.
I still don't understand what this means. It's just an English issue
and it will become clear if you can rephrase what you're saying.
> > > - \lstinputlisting{notifications-le.c}
> > > -
> > > - See \ref{sec:Virtqueues / Driver notifications}~\nameref{sec:Virtqueues / Driver notifications}
> > > - for the definition of the components.
> > > + See \ref{sec:Virtio Transport Options / Virtio Over MMIO / MMIO-specific Initialization And Device Operation / Available Buffer Notifications}
> > > + to see the notification data format.
> > > }
> > > \hline
> > > \mmioreg{InterruptStatus}{Interrupt status}{0x60}{R}{%
> > > Reading from this register returns a bit mask of events that
> > > - caused the device interrupt to be asserted.
> > > + caused the device interrupt to be asserted. This is only used
> > > + when MSI is not enabled.
> > > The following events are possible:
> > > \begin{description}
> > > \item[Used Buffer Notification] - bit 0 - the interrupt was asserted
> > > @@ -1703,7 +1701,7 @@ \subsection{MMIO Device Register Layout}\label{sec:Virtio Transport Options / Vi
> > > \mmioreg{InterruptACK}{Interrupt acknowledge}{0x064}{W}{%
> > > Writing a value with bits set as defined in \field{InterruptStatus}
> > > to this register notifies the device that events causing
> > > - the interrupt have been handled.
> > > + the interrupt have been handled. This is only used when MSI is not enabled.
> > > }
> > > \hline
> > > \mmioreg{Status}{Device status}{0x070}{RW}{%
> > > @@ -1762,6 +1760,31 @@ \subsection{MMIO Device Register Layout}\label{sec:Virtio Transport Options / Vi
> > > \field{SHMSel} is unused) results in a base address of
> > > 0xffffffffffffffff.
> > > }
> > > + \hline
> > > + \mmioreg{MsiStatus}{MSI status}{0x0c0}{R}{%
> > > + Reading from this register returns the global MSI enable/disable status and maximum
> > > + number of virtqueues that device supports.
> > > + \lstinputlisting{msi-status.c}
> > > + }
> > Why is it necessary to combine the number of virtqueues and global
> > MSI enable/disable into a single 16-bit field?
>
> Originally, we want this 16-bit Read-Only, so we put some RO things together
> and separate
>
> enable setting command to next register.
>
> > virtio-mmio uses 32-bit registers. It doesn't try hard to save register
> > space so it's strange to do it here (11-bit number of virtqueue field
> > but 32-bit QueueSel field).
>
> In order to improve performance/save register space, we combine some data
> together.
>
> For example, combine MSI cmd operator (e.g. enable/disable, vector setup)
> with argument (e.g. 1/0, queue index).
>
> But it seems we miss the consistency with QueueSel. So do you think if the
> max queue number should be 32-bit,
>
> which means it must be the same with QueueSel? If so, I guess we need some
> re-organization. :)
I suggest following the 32-bit register size convention unless there is
a specific reason why using other register sizes is absolutely necessary.
> >
> > > + \hline
> > > + \mmioreg{MsiCmd}{MSI command}{0x0c2}{W}{%
> > > + The driver writes to this register with appropriate operators and arguments to
> > > + execute MSI command to device.
> > > + Operators supported is setting global MSI enable/disable status
> > > + and updating MSI configuration to device.
> > If the global MSI enable/disable state is written in this register,
> > consider making this register readable too so the global MSI
> > enable/disable state can be read from it.
>
> Read enable/disable state is in 0x0c0.
The read-only 0xc0 register combines two pieces of information:
1. Global MSI enable/disable state
2. Number of virtqueues (or is "number of MSI vectors" a more accurate
term?)
A simpler way of organizing the registers is:
MsiMaxVectors R
MsiState RW
This is simpler because drivers can read the MsiMaxVectors field and
treat the value as an integer (no masking required). And a person
reading the specification instantly knows how to fetch the MSI
enable/disable state when they read the MsiState register description.
They don't need to look through all the other registers to find the one
that allows them to read the state.
Stefan
Attachment:
signature.asc
Description: PGP signature