[Devel] [PATCH RH9 08/10] drivers/vhost: add API to queue work at virtqueue worker

Andrey Zhadchenko andrey.zhadchenko at virtuozzo.com
Wed Sep 7 16:40:11 MSK 2022



On 9/3/22 00:48, Konstantin Khorenko wrote:
> On 16.08.2022 09:44, Andrey Zhadchenko wrote:
>> Add routines to queue works on virtqueue assigned workers
>>
>> https://jira.sw.ru/browse/PSBM-139414
>> Signed-off-by: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
>> ---
>>   drivers/vhost/vhost.c | 22 ++++++++++++++++++++++
>>   drivers/vhost/vhost.h |  5 +++++
>>   2 files changed, 27 insertions(+)
>>
>> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
>> index 965299b0c0a3..5cf3d8eccfff 100644
>> --- a/drivers/vhost/vhost.c
>> +++ b/drivers/vhost/vhost.c
>> @@ -274,6 +274,17 @@ static void vhost_worker_flush(struct 
>> vhost_worker *w)
>>       wait_for_completion(&flush.wait_event);
>>   }
>> +void vhost_work_flush_vq(struct vhost_virtqueue *vq)
>> +{
>> +    struct vhost_worker *w = READ_ONCE(vq->worker);
>> +
>> +    if (!w)
>> +        return;
>> +
>> +    vhost_worker_flush(w);
>> +}
>> +EXPORT_SYMBOL_GPL(vhost_work_flush_vq);
>> +
>>   /* Flush any work that has been scheduled. When calling this, don't 
>> hold any
>>    * locks that are also used by the callback. */
>>   void vhost_poll_flush(struct vhost_poll *poll)
>> @@ -293,6 +304,17 @@ void vhost_work_queue(struct vhost_dev *dev, 
>> struct vhost_work *work)
>>   }
>>   EXPORT_SYMBOL_GPL(vhost_work_queue);
>> +void vhost_work_queue_vq(struct vhost_virtqueue *vq, struct 
>> vhost_work *work)
>> +{
>> +    struct vhost_worker *w = READ_ONCE(vq->worker);
>> +
>> +    if (!w)
>> +        return;
> 
> Why if we try to queue a work and fail because of no worker - there is 
> nothing to worry about?

Probably it is time to worry about.
However this is a behavior of original vhost_work_queue(), so it is 
preserved in a derivative function.

Also generally you either requested workers from vhost or not. In the 
former case after vhost_dev_set_owner() all queues have a worker 
assigned (and before VHOST_SET_OWNER and several other ioctl's it is 
impossible to actually receive requests). In the latter case you should 
never call vhost_work_queue() and alike anyways as you manage workers 
yourself.

> 
>> +
>> +    vhost_work_queue_at_worker(w, work);
>> +}
>> +EXPORT_SYMBOL_GPL(vhost_work_queue_vq);
>> +
>>   /* A lockless hint for busy polling code to exit the loop */
>>   bool vhost_has_work(struct vhost_dev *dev)
>>   {
>> diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
>> index 9632f6501617..dc7428c26cbe 100644
>> --- a/drivers/vhost/vhost.h
>> +++ b/drivers/vhost/vhost.h
>> @@ -142,6 +142,11 @@ struct vhost_virtqueue {
>>       struct vhost_worker *worker;
>>   };
>> +/* Queue the work on virtqueue assigned worker */
>> +void vhost_work_queue_vq(struct vhost_virtqueue *vq, struct 
>> vhost_work *work);
>> +/* Flush virtqueue assigned worker */
>> +void vhost_work_flush_vq(struct vhost_virtqueue *vq);
>> +
>>   struct vhost_msg_node {
>>     union {
>>         struct vhost_msg msg;


More information about the Devel mailing list