[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Intention to work on GSoC project
From: |
Sahil |
Subject: |
Re: Intention to work on GSoC project |
Date: |
Mon, 25 Mar 2024 18:50:32 +0530 |
Hi,
Thank you for your reply.
On Wednesday, March 20, 2024 9:27:00 PM IST Eugenio Perez Martin wrote:
> [...]
> > Q1.
> > Regarding the "Deep dive into Virtio-networking and vhost-net"
> > article [3], the "Introduction" subsection of the "Vhost protocol"
> > section mentions that sending the available buffer notification
> > involves a vCPU interrupt (4th bullet point).
>
> Now I realize we used a very misleading term there :). Without
> ioeventfd, when the guest writes to the PCI notification area the
> guest vCPU is totally paused there, and the control is handed to
> host's KVM first and QEMU after it. The same physical CPU of the
> machine needs to switch context because of that.
>
> Is an interruption of the execution and a context switch. Maybe
> "paused" is a better term.
>
> > But in figure 2, the arrow for the "available buffer notification"
> > indicates a PCI interrupt. Initially I thought they were two different
> > interrupts but I am a little confused about this now.
>
> They are different, but at that part of the blog is just the direction
> of who interrupts / notifies who :).
Thank you for the clarification. This makes sense now.
On Wednesday, March 20, 2024 9:59:30 PM IST Eugenio Perez Martin wrote:
> [...]
> > Q1.
> > Step 2 in the "Process to make a buffer available" diagram depicts
> > how the virtio driver writes the descriptor index in the avail ring.
> > In the example, the descriptor index #0 is written in the first entry.
> > But in figure 2, the number 0 is in the 4th position in the avail ring.
> > Is the avail ring queue an array of "struct virtq_avail" which maintains
> > metadata such as the number of descriptor indexes in the header?
>
> struct virtq_avail has two members: uint16_t idx and ring[]. To be in
> the first position of the avail ring means to be in ring[0] there.
>
> Idx and ring[] are just headers in the figure, not actual positions.
> Same as Avail. Now that you mention maybe there is a better way to
> represent that, yes.
>
> Let me know if I didn't explain it well.
>
> > Also, in the second position, the number changes from 0 (figure 1) to
> > 1 (figure 2). I haven't understood what idx, 0 (later 1) and ring[]
> > represent in the figures. Does this number represent the number of
> > descriptors that are currently in the avail ring?
>
> It is the position in ring[] where the device needs to stop looking
> for descriptors. It starts at 0, and when the device sees 1 it means
> ring[0] has a descriptor to process.
>
> Now you need to apply a "modulo virtqueue size" to that index. So if
> the virtqueue is 256, avail_idx 257 means the last valid descriptor is
> at 0. This happens naturally when the driver keeps adding descriptors
> and wraps the queue.
>
> The authoritative source of this is the VirtQueues section of the
> virtio standard [1], feel free to check it in case it clarifies
> something better.
I have understood this as well. Reading the virtio specification was
definitely helpful.
> > Q2.
> >
> > There's this paragraph in the article right below the above mentioned
> > diagram:
> > > The avail ring must be able to hold the same number of descriptors
> > > as the descriptor area, and the descriptor area must have a size power
> > > of two, so idx wraps naturally at some point. For example, if the ring
> > > size is 256 entries, idx 1 references the same descriptor as idx 257,
> > > 513... And it will wrap at a 16 bit boundary. This way, neither side
> > > needs to worry about processing an invalid idx: They are all valid.
> >
> > I haven't really understood this. I have understood that idx is calculated
> > as idx mod queue_length. But I haven't understood the "16 bit boundary"
> > part.
>
> avail_idx is an uin16_t, so ((uint16_t)-1) + 1 == 0.
> > I am also not very clear on how a queue length that is not a power of 2
> > might cause trouble. Could you please expand on this?
>
> That's a limitation in the standard, but I'm not sure where it comes
> from beyond being computationally easier to calculate ring position
> with a mask than with a remainder of a random non-power-of-two number.
Understood.
> Packed virtqueue removes that limitation.
Right, I noticed that "queue_size" does not have to be a power of 2 for
packed virtqueues.
> > Q3.
> > I have started going through the source code in
> > "drivers/virtio/virtio_ring.c". I have understood that the virtio driver
> > runs in the guest's kernel. Does that mean the drivers in
> > "drivers/virtio/*" are enabled when linux is being run in a guest VM?
>
> For PCI devices, as long as it detects a device with vendor == Red
> Hat, Inc. (0x1AF4) and device ID 0x1000 through 0x107F inclusive, yes.
> You can also load and unload manually with modprobe as other drivers.
Got it. The linux documentation in "documentation/driver-api/virtio/virtio.rst"
covers this as well. I must have missed this before sending the email.
> Let me know if you have more doubts. Thanks!
I have also read through the "Packed virtqueue: How to reduce overhead
with virtio" article [1] and the relevant section from the virtio specification
[2].
This has been slightly difficult to grasp. Going through the source in
"drivers/virtio/virtio_ring.c" is helping a bit but I am still confused about
a few things.
Q1.
Section 2.7.4 of the virtio spec [3] states that in an available descriptor, the
"Element Length" stores the length of the buffer element. In the next few lines,
it also states that the "Element Length" is reserved for used descriptors and is
ignored by drivers. This sounds a little contradictory given that drivers write
available desciptors in the descriptor ring.
Q2.
In the Red Hat article, just below the first listing ("Memory layout of a packed
virtqueue descriptor"), there's the following line referring to the buffer id in
"virtq_desc":
> This time, the id field is not an index for the device to look for the
> buffer: it is
> an opaque value for it, only has meaning for the driver.
But the device returns the buffer id when it writes the used descriptor to the
descriptor ring. The "only has meaning for the driver" part has got me a little
confused. Which buffer id is this that the device returns? Is it related to the
buffer id in the available descriptor?
Thanks,
Sahil
[1] https://www.redhat.com/en/blog/packed-virtqueue-how-reduce-overhead-virtio
[2]
https://docs.oasis-open.org/virtio/virtio/v1.1/csprd01/virtio-v1.1-csprd01.html#x1-610007
[3]
https://docs.oasis-open.org/virtio/virtio/v1.1/csprd01/virtio-v1.1-csprd01.html#x1-650004
- Re: Intention to work on GSoC project, Eugenio Perez Martin, 2024/03/01
- Re: Intention to work on GSoC project, Sahil, 2024/03/01
- Re: Intention to work on GSoC project, Eugenio Perez Martin, 2024/03/14
- Re: Intention to work on GSoC project, Sahil, 2024/03/15
- Re: Intention to work on GSoC project, Eugenio Perez Martin, 2024/03/15
- Re: Intention to work on GSoC project, Sahil, 2024/03/16
- Re: Intention to work on GSoC project, Sahil, 2024/03/18
- Re: Intention to work on GSoC project, Eugenio Perez Martin, 2024/03/20
- Re: Intention to work on GSoC project,
Sahil <=
- Re: Intention to work on GSoC project, Eugenio Perez Martin, 2024/03/20