On Thu, May 22, 2025 at 12:39 PM Akihiko Odaki <akihiko.od...@daynix.com> wrote: > > On 2025/05/22 10:50, 'Jason Wang' via devel wrote: > > On Wed, May 21, 2025 at 11:51 AM Akihiko Odaki <akihiko.od...@daynix.com> > > wrote: > >> > >> On 2025/05/21 9:51, Jason Wang wrote: > >>> On Fri, May 16, 2025 at 11:29 AM Akihiko Odaki <akihiko.od...@daynix.com> > >>> wrote: > >>>> > >>>> On 2025/05/16 10:44, Jason Wang wrote: > >>>>> On Wed, May 14, 2025 at 2:58 PM Akihiko Odaki > >>>>> <akihiko.od...@daynix.com> wrote: > >>>>>> > >>>>>> On 2025/05/14 14:05, 'Jason Wang' via devel wrote: > >>>>>>> On Sat, May 10, 2025 at 3:24 PM Akihiko Odaki > >>>>>>> <akihiko.od...@daynix.com> wrote: > >>>>>>>> > >>>>>>>> virtio_net_pre_load_queues() inspects vdev->guest_features to tell if > >>>>>>>> VIRTIO_NET_F_RSS or VIRTIO_NET_F_MQ is enabled to infer the required > >>>>>>>> number of queues. This works for VIRTIO_NET_F_MQ but it doesn't for > >>>>>>>> VIRTIO_NET_F_RSS because only the lowest 32 bits of > >>>>>>>> vdev->guest_features > >>>>>>>> is set at the point and VIRTIO_NET_F_RSS uses bit 60 while > >>>>>>>> VIRTIO_NET_F_MQ uses bit 22. > >>>>>>>> > >>>>>>>> Instead of inferring the required number of queues from > >>>>>>>> vdev->guest_features, use the number loaded from the vm state. > >>>>>>>> > >>>>>>>> Fixes: 8c49756825da ("virtio-net: Add only one queue pair when > >>>>>>>> realizing") > >>>>>>>> Signed-off-by: Akihiko Odaki <akihiko.od...@daynix.com> > >>>>>>>> --- > >>>>>>>> include/hw/virtio/virtio.h | 2 +- > >>>>>>>> hw/net/virtio-net.c | 11 ++++------- > >>>>>>>> hw/virtio/virtio.c | 14 +++++++------- > >>>>>>>> 3 files changed, 12 insertions(+), 15 deletions(-) > >>>>>>>> > >>>>>>>> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h > >>>>>>>> index 638691028050..af52580c1e63 100644 > >>>>>>>> --- a/include/hw/virtio/virtio.h > >>>>>>>> +++ b/include/hw/virtio/virtio.h > >>>>>>>> @@ -211,7 +211,7 @@ struct VirtioDeviceClass { > >>>>>>>> int (*start_ioeventfd)(VirtIODevice *vdev); > >>>>>>>> void (*stop_ioeventfd)(VirtIODevice *vdev); > >>>>>>>> /* Called before loading queues. Useful to add queues > >>>>>>>> before loading. */ > >>>>>>>> - int (*pre_load_queues)(VirtIODevice *vdev); > >>>>>>>> + int (*pre_load_queues)(VirtIODevice *vdev, uint32_t n); > >>>>>>> > >>>>>>> This turns out to be tricky as it has a lot of assumptions as > >>>>>>> described in the changelog (e.g only lower 32bit of guest_features is > >>>>>>> correct etc when calling this function). > >>>>>> > >>>>>> The problem is that I missed the following comment in > >>>>>> hw/virtio/virtio.c: > >>>>>> /* > >>>>>> * Temporarily set guest_features low bits - needed by > >>>>>> * virtio net load code testing for > >>>>>> VIRTIO_NET_F_CTRL_GUEST_OFFLOADS > >>>>>> * VIRTIO_NET_F_GUEST_ANNOUNCE and VIRTIO_NET_F_CTRL_VQ. > >>>>>> * > >>>>>> * Note: devices should always test host features in future - > >>>>>> don't > >>>>>> create > >>>>>> * new dependencies like this. > >>>>>> */ > >>>>>> vdev->guest_features = features; > >>>>>> > >>>>>> This problem is specific to guest_features so avoiding it should give > >>>>>> us > >>>>>> a reliable solution. > >>>>> > >>>>> I meant not all the states were fully loaded for pre_load_queues(), > >>>>> this seems another trick besides the above one. We should seek a way > >>>>> to do it in post_load() or at least document the assumptions. > >>>> > >>>> The name of the function already clarifies the state is not fully > >>>> loaded. An implementation of the function can make no assumption on the > >>>> state except that you can add queues here, which is already documented. > >>> > >>> Where? I can only see this: > >>> > >>> /* Called before loading queues. Useful to add queues before > >>> loading. */ > >> > >> I meant it is documented that it can add queues. There is nothing else > >> to document as an implementation of the function can make no assumption > >> else. > >> > >>> > >>>> > >>>>> > >>>>>> > >>>>>>> > >>>>>>> Looking at the commit that introduces this which is 9379ea9db3c that > >>>>>>> says: > >>>>>>> > >>>>>>> """ > >>>>>>> Otherwise the loaded queues will not have handlers and elements > >>>>>>> in them will not be processed. > >>>>>>> """ > >>>>>>> > >>>>>>> I fail to remember what it means or what happens if we don't do > >>>>>>> 9379ea9db3c. > >>>>>> > >>>>>> The packets and control commands in the queues except the first queue > >>>>>> will not be processed because they do not have handle_output set. > >>>>> > >>>>> I don't understand here, the VM is not resumed in this case. Or what > >>>>> issue did you see here? > >>>> > >>>> Below is the order of relevant events that happen when loading and > >>>> resuming a VM for migration: > >>>> > >>>> 1) vdc->realize() gets called. virtio-net adds one RX queue, one TX > >>>> queue, and one control queue. > >>>> 2) vdc->pre_load_queues() gets called. virtio-net adds more queues if > >>>> the "n" parameter requires that. > >>>> 3) The state of queues are loaded. > >>>> 4) The VM gets resumed. > >>>> > >>>> If we skip 2), 3) will load states of queues that are not added yet, > >>>> which breaks these queues and packets and leave control packets on them > >>>> unprocessed. > >>> > >>> Ok, let's document this and > >>> > >>> 1) explain why only virtio-net requires the pre_load_queues (due to > >>> the fact that the index of ctrl vq could be changed according to > >>> #queue_paris) > >> > >> We would need this logic even if the index of ctrl vq didn't change. We > >> need it because virtio-net have varying number of queues, which needs to > >> be added before loading. > > > > Well, if the ctrl vq index doesn't change we don't need a dynamic > > virtio_add_queue() we can do them all in realize just like other > > multiqueue devices. > > The number of virtqueues also affects the behavior visible to the guest > so we shouldn't add them all in realize anyway. In particular, struct > virtio_pci_common_cfg contains fields related virtqueus, and most (if > not all) of them are affected by the number of virtqueues.
I don't understand here, is this requested by the spec for example? Thanks > > Regards, > Akihiko Odaki >