From: Maxime Coquelin: > On 6/22/20 3:43 PM, Matan Azrad wrote: > > > > > > From: Maxime Coquelin: > >> Sent: Monday, June 22, 2020 3:33 PM > >> To: Matan Azrad <ma...@mellanox.com>; Xiao Wang > >> <xiao.w.w...@intel.com> > >> Cc: dev@dpdk.org > >> Subject: Re: [PATCH v1 3/4] vhost: improve device ready definition > >> > >> > >> > >> On 6/22/20 12:06 PM, Matan Azrad wrote: > >>> > >>> Hi Maxime > >>> > >>> From: Maxime Coquelin <maxime.coque...@redhat.com> > >>>> Sent: Monday, June 22, 2020 11:56 AM > >>>> To: Matan Azrad <ma...@mellanox.com>; Xiao Wang > >>>> <xiao.w.w...@intel.com> > >>>> Cc: dev@dpdk.org > >>>> Subject: Re: [PATCH v1 3/4] vhost: improve device ready definition > >>>> > >>>> > >>>> > >>>> On 6/22/20 10:41 AM, Matan Azrad wrote: > >>>>>> The issue is if you only check ready state only before and after > >>>>>> the message affecting the ring is handled, it can be ready at > >>>>>> both stages, while the rings have changed and state change > >>>>>> callback should > >>>> have been called. > >>>>> But in this version I checked twice, before message handler and > >>>>> after > >>>> message handler, so it should catch any update. > >>>> > >>>> No, this is not enough, we have to check also during some handlers, > >>>> so that the ready state is invalidated because sometimes it will be > >>>> ready before and after the message handler but with different values. > >>>> > >>>> That's what I did in my example patch: > >>>> @@ -1847,15 +1892,16 @@ vhost_user_set_vring_kick(struct > virtio_net > >>>> **pdev, struct VhostUserMsg *msg, > >>>> > >>>> ... > >>>> > >>>> if (vq->kickfd >= 0) > >>>> close(vq->kickfd); > >>>> + > >>>> + vq->kickfd = VIRTIO_UNINITIALIZED_EVENTFD; > >>>> + > >>>> + vhost_user_update_vring_state(dev, file.index); > >>>> + > >>>> vq->kickfd = file.fd; > >>>> > >>>> > >>>> Without that, the ready check will return ready before and after > >>>> the kickfd changed and the driver won't be notified. > >>> > >>> The driver will be notified in the next VHOST_USER_SET_VRING_ENABLE > >> message according to v1. > >>> > >>> One of our assumption we agreed on in the design mail is that it > >>> doesn't > >> make sense that QEMU will change queue configuration without enabling > >> the queue again. > >>> Because of that we decided to force calling state callback again > >>> when > >> QEMU send VHOST_USER_SET_VRING_ENABLE(1) message even if the > queue is > >> already ready. > >>> So when driver/app see state enable->enable, it should take into > >>> account > >> that the queue configuration was probably changed. > >>> > >>> I think that this assumption is correct according to the QEMU code. > >> > >> Yes, this was our initial assumption. > >> But now looking into the details of the implementation, I find it is > >> even cleaner & clearer not to do this assumption. > >> > >>> That's why I prefer to collect all the ready checks callbacks (queue > >>> state and > >> device new\conf) to one function that will be called after the > >> message > >> handler: > >>> Pseudo: > >>> vhost_user_update_ready_statuses() { > >>> switch (msg): > >>> case enable: > >>> if(enable is 1) > >>> force queue state =1. > >>> case callfd > >>> case kickfd > >>> ..... > >>> Check queue and device ready + call callbacks if needed.. > >>> Default > >>> Return; > >>> } > >> > >> I find it more natural to "invalidate" ready state where it is > >> handled (after vring_invalidate(), before setting new FD for call & > >> kick, ...) > > > > I think that if you go with this direction, if the first queue pair is > > invalidated, > you need to notify app\driver also about device ready change. > > Also it will cause 2 notifications to the driver instead of one in case of > > FD > change. > > You'll always end-up with two notifications, either Qemu has sent the disable > and so you'll have one notification for the disable and one for the enable, or > it didn't sent the disable and it will happen at old value invalidation time > and > after new value is taken into account. >
I don't see it in current QEMU behavior. When working MQ I see that some virtqs get configuration message while they are in enabled state. Then, enable message is sent again later. > > Why not to take this correct assumption and update ready state only in one > point in the code instead of doing it in all the configuration handlers > around? > > IMO, It is correct, less intrusive, simpler, clearer and cleaner. > > I just looked closer at the Vhost-user spec, and I'm no more so sure this is a > correct assumption: > > "While processing the rings (whether they are enabled or not), client must > support changing some configuration aspects on the fly." Ok, this doesn't explain how configuration is changed on the fly. As I mentioned, QEMU sends enable message always after configuration message. > > In addition it saves the style that already used in this function in: > > - vhost_user_check_and_alloc_queue_pair > > - switch (request) { > > case VHOST_USER_SET_FEATURES: > > case VHOST_USER_SET_PROTOCOL_FEATURES: > > case VHOST_USER_SET_OWNER: > > case VHOST_USER_SET_MEM_TABLE: > > case VHOST_USER_SET_LOG_BASE: > > case VHOST_USER_SET_LOG_FD: > > case VHOST_USER_SET_VRING_NUM: > > case VHOST_USER_SET_VRING_ADDR: > > case VHOST_USER_SET_VRING_BASE: > > case VHOST_USER_SET_VRING_KICK: > > case VHOST_USER_SET_VRING_CALL: > > case VHOST_USER_SET_VRING_ERR: > > case VHOST_USER_SET_VRING_ENABLE: > > case VHOST_USER_SEND_RARP: > > case VHOST_USER_NET_SET_MTU: > > case VHOST_USER_SET_SLAVE_REQ_FD: > > vhost_user_lock_all_queue_pairs(dev); > > > > Matan > > > > > > > >