diff mbox

[RFC,4/4] vhost-user: Add new option to specify vhost-user backend supports

Message ID 1432538908-26298-5-git-send-email-mukawa@igel.co.jp
State Superseded
Headers show

Commit Message

Tetsuya Mukawa May 25, 2015, 7:28 a.m. UTC
This patch adds 'backend_features' option for vhost-user backends.
If this option is specified, QEMU assumes vhost-user backends support
the features specified by user, and QEMU can start without vhost-user
backend.

Here are examples.
* QEMU is configured as vhost-user client.
 -chardev socket,id=chr0,path=/tmp/sock,reconnect=3 \
 -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_features=0x68000 \
 -device virtio-net-pci,netdev=net0 \

* QEMU is configured as vhost-user server.
 -chardev socket,id=chr0,path=/tmp/sock,server,nowait \
 -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_features=0x68000 \
 -device virtio-net-pci,netdev=net0 \

To know vhost-user backend features that the backend expects, please
specify 0xffffffff as backend_features, then invoke QEMU and check error log
like below.

  Lack of backend features. Expected 0xffffffff, but receives 0x68000

Above log indicates the backend features QEMU should be passed.

Signed-off-by: Tetsuya Mukawa <mukawa@igel.co.jp>
---
 hw/net/vhost_net.c             |  9 ++++++++-
 hw/net/virtio-net.c            | 24 ++++++++++++++++++++++++
 hw/scsi/vhost-scsi.c           |  2 +-
 hw/virtio/vhost-user.c         |  9 +++++++++
 hw/virtio/vhost.c              |  8 ++++++--
 include/hw/virtio/vhost.h      |  5 ++++-
 include/hw/virtio/virtio-net.h |  2 ++
 include/net/net.h              |  6 ++++++
 include/net/vhost_net.h        |  2 ++
 net/net.c                      | 18 ++++++++++++++++++
 net/tap.c                      |  5 ++++-
 net/vhost-user.c               | 42 ++++++++++++++++++++++++++++++++++++++++--
 qapi-schema.json               | 10 ++++++++--
 qemu-options.hx                |  3 ++-
 14 files changed, 134 insertions(+), 11 deletions(-)

Comments

Eric Blake May 25, 2015, 10:11 p.m. UTC | #1
On 05/25/2015 01:28 AM, Tetsuya Mukawa wrote:
> This patch adds 'backend_features' option for vhost-user backends.
> If this option is specified, QEMU assumes vhost-user backends support
> the features specified by user, and QEMU can start without vhost-user
> backend.
> 
> Here are examples.
> * QEMU is configured as vhost-user client.
>  -chardev socket,id=chr0,path=/tmp/sock,reconnect=3 \
>  -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_features=0x68000 \
>  -device virtio-net-pci,netdev=net0 \
> 
> * QEMU is configured as vhost-user server.
>  -chardev socket,id=chr0,path=/tmp/sock,server,nowait \
>  -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_features=0x68000 \
>  -device virtio-net-pci,netdev=net0 \
> 
> To know vhost-user backend features that the backend expects, please
> specify 0xffffffff as backend_features, then invoke QEMU and check error log
> like below.
> 
>   Lack of backend features. Expected 0xffffffff, but receives 0x68000
> 
> Above log indicates the backend features QEMU should be passed.
> 
> Signed-off-by: Tetsuya Mukawa <mukawa@igel.co.jp>
> ---

> +++ b/qapi-schema.json
> @@ -2243,6 +2243,8 @@
>  #
>  # @queues: #optional number of queues to be created for multiqueue capable tap
>  #
> +# @backend_features: #optional feature flag to support vhost user backend

Missing a (since 2.4) designation.

New interfaces should prefer - over _, but I see that you are consistent
with vnet_hder already in this struct so it is okay.

> +#
>  # Since 1.2
>  ##
>  { 'struct': 'NetdevTapOptions',
> @@ -2259,7 +2261,8 @@
>      '*vhostfd':    'str',
>      '*vhostfds':   'str',
>      '*vhostforce': 'bool',
> -    '*queues':     'uint32'} }
> +    '*queues':     'uint32',
> +    '*backend_features':'uint64'} }

Ewww. Making users figure out what integers to pass is NOT user
friendly.  Better would be an enum type, and make the parameter an
optional array of enum values.

>  
>  ##
>  # @NetdevSocketOptions
> @@ -2444,12 +2447,15 @@
>  #
>  # @vhostforce: #optional vhost on for non-MSIX virtio guests (default: false).
>  #
> +# @backend_features: #optional feature flag to support vhost user backend (default: 0).
> +#

Long line. Please wrap to fit within 80 columns.  Missing (since 2.4)
deisgnation.  Again, I don't like making users know a raw integer; an
enum type would be better.

>  # Since 2.1
>  ##
>  { 'struct': 'NetdevVhostUserOptions',
>    'data': {
>      'chardev':        'str',
> -    '*vhostforce':    'bool' } }
> +    '*vhostforce':    'bool',
> +    '*backend_features':    'uint64' } }

This struct has no pre-existing _, so the name 'backend-features' is nicer.
Tetsuya Mukawa May 26, 2015, 2:46 a.m. UTC | #2
Hi Eric,

On 月, 2015-05-25 at 16:11 -0600, Eric Blake wrote:
> On 05/25/2015 01:28 AM, Tetsuya Mukawa wrote:
> > This patch adds 'backend_features' option for vhost-user backends.
> > If this option is specified, QEMU assumes vhost-user backends support
> > the features specified by user, and QEMU can start without vhost-user
> > backend.
> > 
> > Here are examples.
> > * QEMU is configured as vhost-user client.
> >  -chardev socket,id=chr0,path=/tmp/sock,reconnect=3 \
> >  -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_features=0x68000 \
> >  -device virtio-net-pci,netdev=net0 \
> > 
> > * QEMU is configured as vhost-user server.
> >  -chardev socket,id=chr0,path=/tmp/sock,server,nowait \
> >  -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_features=0x68000 \
> >  -device virtio-net-pci,netdev=net0 \
> > 
> > To know vhost-user backend features that the backend expects, please
> > specify 0xffffffff as backend_features, then invoke QEMU and check error log
> > like below.
> > 
> >   Lack of backend features. Expected 0xffffffff, but receives 0x68000
> > 
> > Above log indicates the backend features QEMU should be passed.
> > 
> > Signed-off-by: Tetsuya Mukawa <mukawa@igel.co.jp>
> > ---
> 
> > +++ b/qapi-schema.json
> > @@ -2243,6 +2243,8 @@
> >  #
> >  # @queues: #optional number of queues to be created for multiqueue capable tap
> >  #
> > +# @backend_features: #optional feature flag to support vhost user backend
> 
> Missing a (since 2.4) designation.
> 
> New interfaces should prefer - over _, but I see that you are consistent
> with vnet_hder already in this struct so it is okay.
> 
> > +#
> >  # Since 1.2
> >  ##
> >  { 'struct': 'NetdevTapOptions',
> > @@ -2259,7 +2261,8 @@
> >      '*vhostfd':    'str',
> >      '*vhostfds':   'str',
> >      '*vhostforce': 'bool',
> > -    '*queues':     'uint32'} }
> > +    '*queues':     'uint32',
> > +    '*backend_features':'uint64'} }
> 
> Ewww. Making users figure out what integers to pass is NOT user
> friendly.  Better would be an enum type, and make the parameter an
> optional array of enum values.

Thanks for your comments. 
I guess below may be good example. Is this same as your suggestion?

 virtio-net-pci,netdev=hostnet3,id=net3,gso=off,guest_tso4=off,guest_tso6=off

So I will improve 'backend-features' like below.

 backend-features=gso=off,guest_tso4=off,guest_tso6=off

Also I will fix 'qapi-schema.json' to work like above.

> 
> >  
> >  ##
> >  # @NetdevSocketOptions
> > @@ -2444,12 +2447,15 @@
> >  #
> >  # @vhostforce: #optional vhost on for non-MSIX virtio guests (default: false).
> >  #
> > +# @backend_features: #optional feature flag to support vhost user backend (default: 0).
> > +#
> 
> Long line. Please wrap to fit within 80 columns.  Missing (since 2.4)
> deisgnation.  

I will fix it in v2 patch.

> Again, I don't like making users know a raw integer; an
> enum type would be better.
> 
> >  # Since 2.1
> >  ##
> >  { 'struct': 'NetdevVhostUserOptions',
> >    'data': {
> >      'chardev':        'str',
> > -    '*vhostforce':    'bool' } }
> > +    '*vhostforce':    'bool',
> > +    '*backend_features':    'uint64' } }
> 
> This struct has no pre-existing _, so the name 'backend-features' is nicer.
> 

Also I will fix it.

Regards,
Tetsuya
Tetsuya Mukawa May 26, 2015, 4:29 a.m. UTC | #3
On 2015/05/26 11:46, Tetsuya Mukawa wrote:
> Hi Eric,
>
> On 月, 2015-05-25 at 16:11 -0600, Eric Blake wrote:
>> On 05/25/2015 01:28 AM, Tetsuya Mukawa wrote:
>>> This patch adds 'backend_features' option for vhost-user backends.
>>> If this option is specified, QEMU assumes vhost-user backends support
>>> the features specified by user, and QEMU can start without vhost-user
>>> backend.
>>>
>>> Here are examples.
>>> * QEMU is configured as vhost-user client.
>>>  -chardev socket,id=chr0,path=/tmp/sock,reconnect=3 \
>>>  -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_features=0x68000 \
>>>  -device virtio-net-pci,netdev=net0 \
>>>
>>> * QEMU is configured as vhost-user server.
>>>  -chardev socket,id=chr0,path=/tmp/sock,server,nowait \
>>>  -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_features=0x68000 \
>>>  -device virtio-net-pci,netdev=net0 \
>>>
>>> To know vhost-user backend features that the backend expects, please
>>> specify 0xffffffff as backend_features, then invoke QEMU and check error log
>>> like below.
>>>
>>>   Lack of backend features. Expected 0xffffffff, but receives 0x68000
>>>
>>> Above log indicates the backend features QEMU should be passed.
>>>
>>> Signed-off-by: Tetsuya Mukawa <mukawa@igel.co.jp>
>>> ---
>>> +++ b/qapi-schema.json
>>> @@ -2243,6 +2243,8 @@
>>>  #
>>>  # @queues: #optional number of queues to be created for multiqueue capable tap
>>>  #
>>> +# @backend_features: #optional feature flag to support vhost user backend
>> Missing a (since 2.4) designation.
>>
>> New interfaces should prefer - over _, but I see that you are consistent
>> with vnet_hder already in this struct so it is okay.
>>
>>> +#
>>>  # Since 1.2
>>>  ##
>>>  { 'struct': 'NetdevTapOptions',
>>> @@ -2259,7 +2261,8 @@
>>>      '*vhostfd':    'str',
>>>      '*vhostfds':   'str',
>>>      '*vhostforce': 'bool',
>>> -    '*queues':     'uint32'} }
>>> +    '*queues':     'uint32',
>>> +    '*backend_features':'uint64'} }
>> Ewww. Making users figure out what integers to pass is NOT user
>> friendly.  Better would be an enum type, and make the parameter an
>> optional array of enum values.
> Thanks for your comments. 
> I guess below may be good example. Is this same as your suggestion?
>
>  virtio-net-pci,netdev=hostnet3,id=net3,gso=off,guest_tso4=off,guest_tso6=off
>
> So I will improve 'backend-features' like below.
>
>  backend-features=gso=off,guest_tso4=off,guest_tso6=off
>
> Also I will fix 'qapi-schema.json' to work like above.

I seems it's impossible to implement like above.
I may need to implement like below.

virtio-net-pci,netdev=hostnet3,id=net3,backend_gso=on,backend_guest_tso4=on,backend_guest_tso6=on


Tetsuya

>>>  
>>>  ##
>>>  # @NetdevSocketOptions
>>> @@ -2444,12 +2447,15 @@
>>>  #
>>>  # @vhostforce: #optional vhost on for non-MSIX virtio guests (default: false).
>>>  #
>>> +# @backend_features: #optional feature flag to support vhost user backend (default: 0).
>>> +#
>> Long line. Please wrap to fit within 80 columns.  Missing (since 2.4)
>> deisgnation.  
> I will fix it in v2 patch.
>
>> Again, I don't like making users know a raw integer; an
>> enum type would be better.
>>
>>>  # Since 2.1
>>>  ##
>>>  { 'struct': 'NetdevVhostUserOptions',
>>>    'data': {
>>>      'chardev':        'str',
>>> -    '*vhostforce':    'bool' } }
>>> +    '*vhostforce':    'bool',
>>> +    '*backend_features':    'uint64' } }
>> This struct has no pre-existing _, so the name 'backend-features' is nicer.
>>
> Also I will fix it.
>
> Regards,
> Tetsuya
>
>
Eric Blake May 26, 2015, 12:52 p.m. UTC | #4
On 05/25/2015 10:29 PM, Tetsuya Mukawa wrote:

>>>>  { 'struct': 'NetdevTapOptions',
>>>> @@ -2259,7 +2261,8 @@
>>>>      '*vhostfd':    'str',
>>>>      '*vhostfds':   'str',
>>>>      '*vhostforce': 'bool',
>>>> -    '*queues':     'uint32'} }
>>>> +    '*queues':     'uint32',
>>>> +    '*backend_features':'uint64'} }
>>> Ewww. Making users figure out what integers to pass is NOT user
>>> friendly.  Better would be an enum type, and make the parameter an
>>> optional array of enum values.
>> Thanks for your comments. 
>> I guess below may be good example. Is this same as your suggestion?
>>
>>  virtio-net-pci,netdev=hostnet3,id=net3,gso=off,guest_tso4=off,guest_tso6=off
>>
>> So I will improve 'backend-features' like below.
>>
>>  backend-features=gso=off,guest_tso4=off,guest_tso6=off
>>
>> Also I will fix 'qapi-schema.json' to work like above.
> 
> I seems it's impossible to implement like above.
> I may need to implement like below.
> 
> virtio-net-pci,netdev=hostnet3,id=net3,backend_gso=on,backend_guest_tso4=on,backend_guest_tso6=on

Or even:

virtio-net-pci,netdev=hostnet3,id=net3,backend.gso=on,backend.guest_tso4=on,backend.guest_tso6=on

Look at -device for how to set up nested structs using '.' for a nice
hierarchy of options all belonging to a common substruct.
Tetsuya Mukawa May 28, 2015, 1:25 a.m. UTC | #5
On 2015/05/26 21:52, Eric Blake wrote:
> On 05/25/2015 10:29 PM, Tetsuya Mukawa wrote:
>
>>>>>  { 'struct': 'NetdevTapOptions',
>>>>> @@ -2259,7 +2261,8 @@
>>>>>      '*vhostfd':    'str',
>>>>>      '*vhostfds':   'str',
>>>>>      '*vhostforce': 'bool',
>>>>> -    '*queues':     'uint32'} }
>>>>> +    '*queues':     'uint32',
>>>>> +    '*backend_features':'uint64'} }
>>>> Ewww. Making users figure out what integers to pass is NOT user
>>>> friendly.  Better would be an enum type, and make the parameter an
>>>> optional array of enum values.
>>> Thanks for your comments. 
>>> I guess below may be good example. Is this same as your suggestion?
>>>
>>>  virtio-net-pci,netdev=hostnet3,id=net3,gso=off,guest_tso4=off,guest_tso6=off
>>>
>>> So I will improve 'backend-features' like below.
>>>
>>>  backend-features=gso=off,guest_tso4=off,guest_tso6=off
>>>
>>> Also I will fix 'qapi-schema.json' to work like above.
>> I seems it's impossible to implement like above.
>> I may need to implement like below.
>>
>> virtio-net-pci,netdev=hostnet3,id=net3,backend_gso=on,backend_guest_tso4=on,backend_guest_tso6=on
> Or even:
>
> virtio-net-pci,netdev=hostnet3,id=net3,backend.gso=on,backend.guest_tso4=on,backend.guest_tso6=on
>
> Look at -device for how to set up nested structs using '.' for a nice
> hierarchy of options all belonging to a common substruct.
>

I appreciate for your suggestion.
I will check '-device' option, and implement like above in v2 patch.

Tetsuya
Tetsuya Mukawa May 29, 2015, 4:42 a.m. UTC | #6
On 2015/05/28 10:25, Tetsuya Mukawa wrote:
> On 2015/05/26 21:52, Eric Blake wrote:
>> On 05/25/2015 10:29 PM, Tetsuya Mukawa wrote:
>>
>>>>>>  { 'struct': 'NetdevTapOptions',
>>>>>> @@ -2259,7 +2261,8 @@
>>>>>>      '*vhostfd':    'str',
>>>>>>      '*vhostfds':   'str',
>>>>>>      '*vhostforce': 'bool',
>>>>>> -    '*queues':     'uint32'} }
>>>>>> +    '*queues':     'uint32',
>>>>>> +    '*backend_features':'uint64'} }
>>>>> Ewww. Making users figure out what integers to pass is NOT user
>>>>> friendly.  Better would be an enum type, and make the parameter an
>>>>> optional array of enum values.
>>>> Thanks for your comments. 
>>>> I guess below may be good example. Is this same as your suggestion?
>>>>
>>>>  virtio-net-pci,netdev=hostnet3,id=net3,gso=off,guest_tso4=off,guest_tso6=off
>>>>
>>>> So I will improve 'backend-features' like below.
>>>>
>>>>  backend-features=gso=off,guest_tso4=off,guest_tso6=off
>>>>
>>>> Also I will fix 'qapi-schema.json' to work like above.
>>> I seems it's impossible to implement like above.
>>> I may need to implement like below.
>>>
>>> virtio-net-pci,netdev=hostnet3,id=net3,backend_gso=on,backend_guest_tso4=on,backend_guest_tso6=on
>> Or even:
>>
>> virtio-net-pci,netdev=hostnet3,id=net3,backend.gso=on,backend.guest_tso4=on,backend.guest_tso6=on
>>
>> Look at -device for how to set up nested structs using '.' for a nice
>> hierarchy of options all belonging to a common substruct.
>>
> I appreciate for your suggestion.
> I will check '-device' option, and implement like above in v2 patch.

I've checked '-device' option and DeviceClass, and found I may not be
able to use above nice hierarchy with '-net' option.
Probably it is because '-net' option isn't for describing device itself,
so there is no DeviceClass.
And without DeviceClass I guess I cannot use '.' infrastructure.

I may be able to describe vhost-user backend features in '-device
virtio-net-pci,.....', but I guess it's not good.
Probably describing in '-net vhost-user,....' will be good.

As described above, I implemented like below in next patch.

-chardev socket,id=chr0,path=/tmp/sock,reconnect=3 \
-device virtio-net-pci,netdev=net0 \
-netdev
vhost-user,id=net0,chardev=chr0,vhostforce,backend_gso=on,backend_guest_ecn=on

BTW, '-device' option has already had options like below.
 - guest_csum
 - guest_tso4
 .....

So I used '_' like below
 - backend_guest_csum
 - backend_guest_tso4
 ......

Regards,
Tetsuya
Tetsuya Mukawa May 29, 2015, 4:42 a.m. UTC | #7
Hi guys,

Here are patches to add feature to start QEMU without vhost-user backend.
Currently, if we want to use vhost-user backend, the backend must start before
QEMU. Also, if QEMU or the backend is closed unexpectedly, there is no way to
recover without restarting both applications. Practically, it's not useful.

This patch series adds following features.
 - QEMU can start before the backend.
 - QEMU or the backend can restart anytime.
   connectivity will be recovered automatically, when app starts again.
   (if QEMU is server, QEMU just wait reconnection)
   while lost connection, link status of virtio-net device is down,
   so virtio-net driver on the guest can know it

To work like above, the patch introduces flags to specify features vhost-user
backend will support.

Here are examples.
('backend_mrg_rxbuf' is an one of new flags. To know all, check the last patch)

    * QEMU is configured as vhost-user client.
     -chardev socket,id=chr0,path=/tmp/sock,reconnect=3 \
     -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_mrg_rxbuf \
     -device virtio-net-pci,netdev=net0 \

    * QEMU is configured as vhost-user server.
     -chardev socket,id=chr0,path=/tmp/sock,server,nowait \
     -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_mrg_rxbuf \
     -device virtio-net-pci,netdev=net0 \

When virtio-net device is configured by virtio-net driver, QEMU should know
vhost-user backend features. But if QEMU starts without the backend, QEMU cannot
know it. So above the feature values specified by user will be used as features
the backend will support.

When connection between QEMU and the backend is established, QEMU checkes feature
values of the backend to make sure the expected features are provided.
If it doesn't, the connection will be closed by QEMU.

Regards,
Tetsuya

----------
Changes
----------
- Changes from RFC patch
  The last patch of this series was changed like below.
   - Rebase to latest master.
   - Remove needless has_backend_feature variable.
   - Change user interface to be able to specify each feature by name.
   - Add (Since 2.4) to schema file.
   - Fix commit title and body.


Tetsuya Mukawa (4):
  vhost-user: Add ability to know vhost-user backend disconnection
  vhost-user: Shutdown vhost-user connection when wrong messages are
    passed
  vhost-user: Enable 'nowait' and 'reconnect' option
  vhost-user: Add new option to specify vhost-user backend features

 hw/net/vhost_net.c             |   6 ++-
 hw/net/virtio-net.c            |  13 +++++
 hw/scsi/vhost-scsi.c           |   2 +-
 hw/virtio/vhost-user.c         |  24 ++++++---
 hw/virtio/vhost.c              |   7 ++-
 include/hw/virtio/vhost.h      |   3 +-
 include/hw/virtio/virtio-net.h |   1 +
 include/net/net.h              |   3 ++
 include/net/vhost_net.h        |   1 +
 include/sysemu/char.h          |   7 +++
 net/net.c                      |   9 ++++
 net/tap.c                      |   1 +
 net/vhost-user.c               |  69 ++++++++++++++++++++++++-
 qapi-schema.json               | 114 +++++++++++++++++++++++++++++++++++------
 qemu-char.c                    |  15 ++++++
 qemu-options.hx                |  10 ++++
 16 files changed, 256 insertions(+), 29 deletions(-)
Tetsuya Mukawa June 11, 2015, 1:56 a.m. UTC | #8
On 2015/05/29 13:42, Tetsuya Mukawa wrote:
> Hi guys,
>
> Here are patches to add feature to start QEMU without vhost-user backend.
> Currently, if we want to use vhost-user backend, the backend must start before
> QEMU. Also, if QEMU or the backend is closed unexpectedly, there is no way to
> recover without restarting both applications. Practically, it's not useful.
>
> This patch series adds following features.
>  - QEMU can start before the backend.
>  - QEMU or the backend can restart anytime.
>    connectivity will be recovered automatically, when app starts again.
>    (if QEMU is server, QEMU just wait reconnection)
>    while lost connection, link status of virtio-net device is down,
>    so virtio-net driver on the guest can know it
>
> To work like above, the patch introduces flags to specify features vhost-user
> backend will support.
>
> Here are examples.
> ('backend_mrg_rxbuf' is an one of new flags. To know all, check the last patch)
>
>     * QEMU is configured as vhost-user client.
>      -chardev socket,id=chr0,path=/tmp/sock,reconnect=3 \
>      -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_mrg_rxbuf \
>      -device virtio-net-pci,netdev=net0 \
>
>     * QEMU is configured as vhost-user server.
>      -chardev socket,id=chr0,path=/tmp/sock,server,nowait \
>      -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_mrg_rxbuf \
>      -device virtio-net-pci,netdev=net0 \
>
> When virtio-net device is configured by virtio-net driver, QEMU should know
> vhost-user backend features. But if QEMU starts without the backend, QEMU cannot
> know it. So above the feature values specified by user will be used as features
> the backend will support.
>
> When connection between QEMU and the backend is established, QEMU checkes feature
> values of the backend to make sure the expected features are provided.
> If it doesn't, the connection will be closed by QEMU.
>
> Regards,
> Tetsuya
>
> ----------
> Changes
> ----------
> - Changes from RFC patch
>   The last patch of this series was changed like below.
>    - Rebase to latest master.
>    - Remove needless has_backend_feature variable.
>    - Change user interface to be able to specify each feature by name.
>    - Add (Since 2.4) to schema file.
>    - Fix commit title and body.
>
>
> Tetsuya Mukawa (4):
>   vhost-user: Add ability to know vhost-user backend disconnection
>   vhost-user: Shutdown vhost-user connection when wrong messages are
>     passed
>   vhost-user: Enable 'nowait' and 'reconnect' option
>   vhost-user: Add new option to specify vhost-user backend features
>
>  hw/net/vhost_net.c             |   6 ++-
>  hw/net/virtio-net.c            |  13 +++++
>  hw/scsi/vhost-scsi.c           |   2 +-
>  hw/virtio/vhost-user.c         |  24 ++++++---
>  hw/virtio/vhost.c              |   7 ++-
>  include/hw/virtio/vhost.h      |   3 +-
>  include/hw/virtio/virtio-net.h |   1 +
>  include/net/net.h              |   3 ++
>  include/net/vhost_net.h        |   1 +
>  include/sysemu/char.h          |   7 +++
>  net/net.c                      |   9 ++++
>  net/tap.c                      |   1 +
>  net/vhost-user.c               |  69 ++++++++++++++++++++++++-
>  qapi-schema.json               | 114 +++++++++++++++++++++++++++++++++++------
>  qemu-char.c                    |  15 ++++++
>  qemu-options.hx                |  10 ++++
>  16 files changed, 256 insertions(+), 29 deletions(-)
>

Ping.

Could someone please review this patches?
http://patchwork.ozlabs.org/project/qemu-devel/list/?submitter=66139

Regards,
Tetsuya
Stefan Hajnoczi June 15, 2015, 2:08 p.m. UTC | #9
On Fri, May 29, 2015 at 01:42:26PM +0900, Tetsuya Mukawa wrote:
>    - Change user interface to be able to specify each feature by name.

I disagree with this change, the uint64_t backend_features option was
better because:

The text options will just result in a very long command-line that is
hard to read for humans.  Instead of checking a bit in a single hex
number, you have to scan over long comma-separated text options which
can be in any arbitrary order to find the feature bit you were looking
for.

This option needs to be scripted or generated by a management tool
anyway since it depends on the vhost-user backend program that is being
paired with QEMU.  The number of human users constructing these option
is extremely low - if they use it they'll copy-paste it from their
vhost-user program's documentation so the contents don't matter much
(shorter is better though).

The text options must be updated when new feature bits are added to
virtio-net.

For these reasons I find the numeric backend_features option better.
Stefan Hajnoczi June 15, 2015, 2:12 p.m. UTC | #10
On Thu, Jun 11, 2015 at 10:56:06AM +0900, Tetsuya Mukawa wrote:
> On 2015/05/29 13:42, Tetsuya Mukawa wrote:
> > Hi guys,
> >
> > Here are patches to add feature to start QEMU without vhost-user backend.
> > Currently, if we want to use vhost-user backend, the backend must start before
> > QEMU. Also, if QEMU or the backend is closed unexpectedly, there is no way to
> > recover without restarting both applications. Practically, it's not useful.
> >
> > This patch series adds following features.
> >  - QEMU can start before the backend.
> >  - QEMU or the backend can restart anytime.
> >    connectivity will be recovered automatically, when app starts again.
> >    (if QEMU is server, QEMU just wait reconnection)
> >    while lost connection, link status of virtio-net device is down,
> >    so virtio-net driver on the guest can know it
> >
> > To work like above, the patch introduces flags to specify features vhost-user
> > backend will support.
> >
> > Here are examples.
> > ('backend_mrg_rxbuf' is an one of new flags. To know all, check the last patch)
> >
> >     * QEMU is configured as vhost-user client.
> >      -chardev socket,id=chr0,path=/tmp/sock,reconnect=3 \
> >      -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_mrg_rxbuf \
> >      -device virtio-net-pci,netdev=net0 \
> >
> >     * QEMU is configured as vhost-user server.
> >      -chardev socket,id=chr0,path=/tmp/sock,server,nowait \
> >      -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_mrg_rxbuf \
> >      -device virtio-net-pci,netdev=net0 \
> >
> > When virtio-net device is configured by virtio-net driver, QEMU should know
> > vhost-user backend features. But if QEMU starts without the backend, QEMU cannot
> > know it. So above the feature values specified by user will be used as features
> > the backend will support.
> >
> > When connection between QEMU and the backend is established, QEMU checkes feature
> > values of the backend to make sure the expected features are provided.
> > If it doesn't, the connection will be closed by QEMU.
> >
> > Regards,
> > Tetsuya
> >
> > ----------
> > Changes
> > ----------
> > - Changes from RFC patch
> >   The last patch of this series was changed like below.
> >    - Rebase to latest master.
> >    - Remove needless has_backend_feature variable.
> >    - Change user interface to be able to specify each feature by name.
> >    - Add (Since 2.4) to schema file.
> >    - Fix commit title and body.
> >
> >
> > Tetsuya Mukawa (4):
> >   vhost-user: Add ability to know vhost-user backend disconnection
> >   vhost-user: Shutdown vhost-user connection when wrong messages are
> >     passed
> >   vhost-user: Enable 'nowait' and 'reconnect' option
> >   vhost-user: Add new option to specify vhost-user backend features
> >
> >  hw/net/vhost_net.c             |   6 ++-
> >  hw/net/virtio-net.c            |  13 +++++
> >  hw/scsi/vhost-scsi.c           |   2 +-
> >  hw/virtio/vhost-user.c         |  24 ++++++---
> >  hw/virtio/vhost.c              |   7 ++-
> >  include/hw/virtio/vhost.h      |   3 +-
> >  include/hw/virtio/virtio-net.h |   1 +
> >  include/net/net.h              |   3 ++
> >  include/net/vhost_net.h        |   1 +
> >  include/sysemu/char.h          |   7 +++
> >  net/net.c                      |   9 ++++
> >  net/tap.c                      |   1 +
> >  net/vhost-user.c               |  69 ++++++++++++++++++++++++-
> >  qapi-schema.json               | 114 +++++++++++++++++++++++++++++++++++------
> >  qemu-char.c                    |  15 ++++++
> >  qemu-options.hx                |  10 ++++
> >  16 files changed, 256 insertions(+), 29 deletions(-)
> >
> 
> Ping.
> 
> Could someone please review this patches?
> http://patchwork.ozlabs.org/project/qemu-devel/list/?submitter=66139

Nikolay, Jason, or Michael:
Can one of you please step up to become maintainer of net/vhost-user.c.

I don't follow vhost-user development much and can't give good review
feedback about the vhost-user specific aspects.

Please send a patch that adds you to the MAINTAINERS file for
net/vhost-user.c.  Then either include merged patches in Michael's pull
requests or ask me (and in the future, Jason) to include them in net
pull requests.

Stefan
Michael S. Tsirkin June 15, 2015, 2:21 p.m. UTC | #11
On Mon, Jun 15, 2015 at 03:12:28PM +0100, Stefan Hajnoczi wrote:
> On Thu, Jun 11, 2015 at 10:56:06AM +0900, Tetsuya Mukawa wrote:
> > On 2015/05/29 13:42, Tetsuya Mukawa wrote:
> > > Hi guys,
> > >
> > > Here are patches to add feature to start QEMU without vhost-user backend.
> > > Currently, if we want to use vhost-user backend, the backend must start before
> > > QEMU. Also, if QEMU or the backend is closed unexpectedly, there is no way to
> > > recover without restarting both applications. Practically, it's not useful.
> > >
> > > This patch series adds following features.
> > >  - QEMU can start before the backend.
> > >  - QEMU or the backend can restart anytime.
> > >    connectivity will be recovered automatically, when app starts again.
> > >    (if QEMU is server, QEMU just wait reconnection)
> > >    while lost connection, link status of virtio-net device is down,
> > >    so virtio-net driver on the guest can know it
> > >
> > > To work like above, the patch introduces flags to specify features vhost-user
> > > backend will support.
> > >
> > > Here are examples.
> > > ('backend_mrg_rxbuf' is an one of new flags. To know all, check the last patch)
> > >
> > >     * QEMU is configured as vhost-user client.
> > >      -chardev socket,id=chr0,path=/tmp/sock,reconnect=3 \
> > >      -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_mrg_rxbuf \
> > >      -device virtio-net-pci,netdev=net0 \
> > >
> > >     * QEMU is configured as vhost-user server.
> > >      -chardev socket,id=chr0,path=/tmp/sock,server,nowait \
> > >      -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_mrg_rxbuf \
> > >      -device virtio-net-pci,netdev=net0 \
> > >
> > > When virtio-net device is configured by virtio-net driver, QEMU should know
> > > vhost-user backend features. But if QEMU starts without the backend, QEMU cannot
> > > know it. So above the feature values specified by user will be used as features
> > > the backend will support.
> > >
> > > When connection between QEMU and the backend is established, QEMU checkes feature
> > > values of the backend to make sure the expected features are provided.
> > > If it doesn't, the connection will be closed by QEMU.
> > >
> > > Regards,
> > > Tetsuya
> > >
> > > ----------
> > > Changes
> > > ----------
> > > - Changes from RFC patch
> > >   The last patch of this series was changed like below.
> > >    - Rebase to latest master.
> > >    - Remove needless has_backend_feature variable.
> > >    - Change user interface to be able to specify each feature by name.
> > >    - Add (Since 2.4) to schema file.
> > >    - Fix commit title and body.
> > >
> > >
> > > Tetsuya Mukawa (4):
> > >   vhost-user: Add ability to know vhost-user backend disconnection
> > >   vhost-user: Shutdown vhost-user connection when wrong messages are
> > >     passed
> > >   vhost-user: Enable 'nowait' and 'reconnect' option
> > >   vhost-user: Add new option to specify vhost-user backend features
> > >
> > >  hw/net/vhost_net.c             |   6 ++-
> > >  hw/net/virtio-net.c            |  13 +++++
> > >  hw/scsi/vhost-scsi.c           |   2 +-
> > >  hw/virtio/vhost-user.c         |  24 ++++++---
> > >  hw/virtio/vhost.c              |   7 ++-
> > >  include/hw/virtio/vhost.h      |   3 +-
> > >  include/hw/virtio/virtio-net.h |   1 +
> > >  include/net/net.h              |   3 ++
> > >  include/net/vhost_net.h        |   1 +
> > >  include/sysemu/char.h          |   7 +++
> > >  net/net.c                      |   9 ++++
> > >  net/tap.c                      |   1 +
> > >  net/vhost-user.c               |  69 ++++++++++++++++++++++++-
> > >  qapi-schema.json               | 114 +++++++++++++++++++++++++++++++++++------
> > >  qemu-char.c                    |  15 ++++++
> > >  qemu-options.hx                |  10 ++++
> > >  16 files changed, 256 insertions(+), 29 deletions(-)
> > >
> > 
> > Ping.
> > 
> > Could someone please review this patches?
> > http://patchwork.ozlabs.org/project/qemu-devel/list/?submitter=66139
> 
> Nikolay, Jason, or Michael:
> Can one of you please step up to become maintainer of net/vhost-user.c.
> 
> I don't follow vhost-user development much and can't give good review
> feedback about the vhost-user specific aspects.
> 
> Please send a patch that adds you to the MAINTAINERS file for
> net/vhost-user.c.  Then either include merged patches in Michael's pull
> requests or ask me (and in the future, Jason) to include them in net
> pull requests.
> 
> Stefan

Done.
Tetsuya Mukawa June 16, 2015, 5:09 a.m. UTC | #12
On 2015/06/15 23:08, Stefan Hajnoczi wrote:
> On Fri, May 29, 2015 at 01:42:26PM +0900, Tetsuya Mukawa wrote:
>>    - Change user interface to be able to specify each feature by name.
> I disagree with this change, the uint64_t backend_features option was
> better because:
>
> The text options will just result in a very long command-line that is
> hard to read for humans.  Instead of checking a bit in a single hex
> number, you have to scan over long comma-separated text options which
> can be in any arbitrary order to find the feature bit you were looking
> for.
>
> This option needs to be scripted or generated by a management tool
> anyway since it depends on the vhost-user backend program that is being
> paired with QEMU.  The number of human users constructing these option
> is extremely low - if they use it they'll copy-paste it from their
> vhost-user program's documentation so the contents don't matter much
> (shorter is better though).
>
> The text options must be updated when new feature bits are added to
> virtio-net.
>
> For these reasons I find the numeric backend_features option better.

Thanks for comments.
I guess it's reasonable, so I will revert it in next patches.

Regards,
Tetsuya
diff mbox

Patch

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 47f8b89..f974d09 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -158,8 +158,15 @@  struct vhost_net *vhost_net_init(VhostNetOptions *options)
     net->dev.nvqs = 2;
     net->dev.vqs = net->vqs;
 
+    if (options->has_backend_features) {
+        net->dev.has_backend_features = options->has_backend_features;
+        net->dev.backend_features = options->backend_features;
+    }
+
     r = vhost_dev_init(&net->dev, options->opaque,
-                       options->backend_type, options->force);
+                       options->backend_type, options->force,
+                       options->has_backend_features,
+                       options->backend_features);
     if (r < 0) {
         goto fail;
     }
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 3af6faf..ebe5422 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -366,6 +366,28 @@  static int peer_has_ufo(VirtIONet *n)
     return n->has_ufo;
 }
 
+static int peer_has_backend_features(VirtIONet *n)
+{
+    if (!peer_has_vnet_hdr(n))
+        return 0;
+
+    n->has_backend_features =
+            qemu_has_backend_features(qemu_get_queue(n->nic)->peer);
+
+    return n->has_backend_features;
+}
+
+static uint64_t peer_backend_features(VirtIONet *n)
+{
+    if (!peer_has_vnet_hdr(n))
+        return 0;
+
+    n->backend_features =
+            qemu_backend_features(qemu_get_queue(n->nic)->peer);
+
+    return n->backend_features;
+}
+
 static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs)
 {
     int i;
@@ -463,6 +485,8 @@  static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
     }
 
     if (!get_vhost_net(nc->peer)) {
+        if (peer_has_backend_features(n))
+            features = peer_backend_features(n);
         return features;
     }
     return vhost_net_get_features(get_vhost_net(nc->peer), features);
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 335f442..4998a95 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -246,7 +246,7 @@  static void vhost_scsi_realize(DeviceState *dev, Error **errp)
     s->dev.backend_features = 0;
 
     ret = vhost_dev_init(&s->dev, (void *)(uintptr_t)vhostfd,
-                         VHOST_BACKEND_TYPE_KERNEL, true);
+                         VHOST_BACKEND_TYPE_KERNEL, true, false, 0);
     if (ret < 0) {
         error_setg(errp, "vhost-scsi: vhost initialization failed: %s",
                    strerror(-ret));
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 4d7e3ba..f0dcb97 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -307,6 +307,15 @@  static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
                 error_report("Received bad msg size.");
                 goto close;
             }
+            if (dev->has_backend_features) {
+                if (dev->backend_features != (dev->backend_features & msg.u64)) {
+                    error_report("Lack of backend features. "
+                                 "Expected 0x%llx, but receives 0x%lx",
+                                 dev->backend_features, msg.u64);
+                    goto close;
+                }
+            }
+
             *((__u64 *) arg) = msg.u64;
             break;
         case VHOST_USER_GET_VRING_BASE:
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 54851b7..20cb116 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -811,7 +811,9 @@  static void vhost_virtqueue_cleanup(struct vhost_virtqueue *vq)
 }
 
 int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
-                   VhostBackendType backend_type, bool force)
+                   VhostBackendType backend_type, bool force,
+                   bool has_backend_features,
+                   unsigned long long backend_features)
 {
     uint64_t features;
     int i, r;
@@ -833,7 +835,9 @@  int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
 
     r = hdev->vhost_ops->vhost_call(hdev, VHOST_GET_FEATURES, &features);
     if (r < 0) {
-        goto fail;
+        if (!has_backend_features)
+            goto fail;
+        features = backend_features;
     }
 
     for (i = 0; i < hdev->nvqs; ++i) {
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 8f04888..60306cb 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -41,6 +41,7 @@  struct vhost_dev {
     unsigned long long features;
     unsigned long long acked_features;
     unsigned long long backend_features;
+    bool has_backend_features;
     bool started;
     bool log_enabled;
     vhost_log_chunk_t *log;
@@ -55,7 +56,9 @@  struct vhost_dev {
 };
 
 int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
-                   VhostBackendType backend_type, bool force);
+                   VhostBackendType backend_type, bool force,
+                   bool has_backend_features,
+                   unsigned long long backend_features);
 void vhost_dev_cleanup(struct vhost_dev *hdev);
 bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev);
 int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index e0dbb41..528da28 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -70,6 +70,8 @@  typedef struct VirtIONet {
     size_t guest_hdr_len;
     uint32_t host_features;
     uint8_t has_ufo;
+    uint8_t has_backend_features;
+    uint64_t backend_features;
     int mergeable_rx_bufs;
     uint8_t promisc;
     uint8_t allmulti;
diff --git a/include/net/net.h b/include/net/net.h
index e66ca03..e2eab3e 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -55,6 +55,8 @@  typedef bool (HasVnetHdrLen)(NetClientState *, int);
 typedef void (UsingVnetHdr)(NetClientState *, bool);
 typedef void (SetOffload)(NetClientState *, int, int, int, int, int);
 typedef void (SetVnetHdrLen)(NetClientState *, int);
+typedef bool (HasBackendFeatures)(NetClientState *);
+typedef unsigned long long (BackendFeatures)(NetClientState *);
 
 typedef struct NetClientInfo {
     NetClientOptionsKind type;
@@ -73,6 +75,8 @@  typedef struct NetClientInfo {
     UsingVnetHdr *using_vnet_hdr;
     SetOffload *set_offload;
     SetVnetHdrLen *set_vnet_hdr_len;
+    HasBackendFeatures *has_backend_features;
+    BackendFeatures *backend_features;
 } NetClientInfo;
 
 struct NetClientState {
@@ -136,6 +140,8 @@  bool qemu_has_ufo(NetClientState *nc);
 bool qemu_has_vnet_hdr(NetClientState *nc);
 bool qemu_has_vnet_hdr_len(NetClientState *nc, int len);
 void qemu_using_vnet_hdr(NetClientState *nc, bool enable);
+bool qemu_has_backend_features(NetClientState *nc);
+unsigned long long qemu_backend_features(NetClientState *nc);
 void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
                       int ecn, int ufo);
 void qemu_set_vnet_hdr_len(NetClientState *nc, int len);
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index b1c18a3..b4ca8e8 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -12,6 +12,8 @@  typedef struct VhostNetOptions {
     NetClientState *net_backend;
     void *opaque;
     bool force;
+    bool has_backend_features;
+    unsigned long long backend_features;
 } VhostNetOptions;
 
 struct vhost_net *vhost_net_init(VhostNetOptions *options);
diff --git a/net/net.c b/net/net.c
index 7427f6a..85e41d0 100644
--- a/net/net.c
+++ b/net/net.c
@@ -459,6 +459,24 @@  void qemu_set_vnet_hdr_len(NetClientState *nc, int len)
     nc->info->set_vnet_hdr_len(nc, len);
 }
 
+bool qemu_has_backend_features(NetClientState *nc)
+{
+    if (!nc || !nc->info->has_backend_features) {
+        return false;
+    }
+
+    return nc->info->has_backend_features(nc);
+}
+
+unsigned long long qemu_backend_features(NetClientState *nc)
+{
+    if (!nc || !nc->info->backend_features) {
+        return false;
+    }
+
+    return nc->info->backend_features(nc);
+}
+
 int qemu_can_send_packet(NetClientState *sender)
 {
     int vm_running = runstate_is_running();
diff --git a/net/tap.c b/net/tap.c
index 968df46..6d25170 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -636,12 +636,15 @@  static int net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
     }
 
     if (tap->has_vhost ? tap->vhost :
-        vhostfdname || (tap->has_vhostforce && tap->vhostforce)) {
+        vhostfdname || tap->has_backend_features ||
+                    (tap->has_vhostforce && tap->vhostforce)) {
         VhostNetOptions options;
 
         options.backend_type = VHOST_BACKEND_TYPE_KERNEL;
         options.net_backend = &s->nc;
         options.force = tap->has_vhostforce && tap->vhostforce;
+        options.has_backend_features = tap->has_backend_features;
+        options.backend_features = tap->backend_features;
 
         if (tap->has_vhostfd || tap->has_vhostfds) {
             vhostfd = monitor_fd_param(cur_mon, vhostfdname, &err);
diff --git a/net/vhost-user.c b/net/vhost-user.c
index d31fc41..2705393 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -19,6 +19,8 @@  typedef struct VhostUserState {
     NetClientState nc;
     CharDriverState *chr;
     VHostNetState *vhost_net;
+    bool has_backend_features;
+    unsigned long long backend_features;
     int watch;
 } VhostUserState;
 
@@ -54,6 +56,7 @@  static int vhost_user_start(VhostUserState *s)
     options.net_backend = &s->nc;
     options.opaque = s->chr;
     options.force = true;
+    options.backend_features = s->backend_features;
 
     s->vhost_net = vhost_net_init(&options);
 
@@ -91,12 +94,32 @@  static bool vhost_user_has_ufo(NetClientState *nc)
     return true;
 }
 
+static bool vhost_user_has_backend_features(NetClientState *nc)
+{
+    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
+
+    VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
+
+    return s->has_backend_features;
+}
+
+static unsigned long long vhost_user_backend_features(NetClientState *nc)
+{
+    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
+
+    VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
+
+    return s->backend_features;
+}
+
 static NetClientInfo net_vhost_user_info = {
         .type = NET_CLIENT_OPTIONS_KIND_VHOST_USER,
         .size = sizeof(VhostUserState),
         .cleanup = vhost_user_cleanup,
         .has_vnet_hdr = vhost_user_has_vnet_hdr,
         .has_ufo = vhost_user_has_ufo,
+        .has_backend_features = vhost_user_has_backend_features,
+        .backend_features = vhost_user_backend_features,
 };
 
 static void net_vhost_link_down(VhostUserState *s, bool link_down)
@@ -148,7 +171,9 @@  static void net_vhost_user_event(void *opaque, int event)
 }
 
 static int net_vhost_user_init(NetClientState *peer, const char *device,
-                               const char *name, CharDriverState *chr)
+                               const char *name, CharDriverState *chr,
+                               bool has_backend_features,
+                               unsigned long long backend_features)
 {
     NetClientState *nc;
     VhostUserState *s;
@@ -163,6 +188,8 @@  static int net_vhost_user_init(NetClientState *peer, const char *device,
     /* We don't provide a receive callback */
     s->nc.receive_disabled = 1;
     s->chr = chr;
+    s->has_backend_features = has_backend_features;
+    s->backend_features = backend_features;
 
     qemu_chr_add_handlers(s->chr, NULL, NULL, net_vhost_user_event, s);
 
@@ -247,6 +274,8 @@  int net_init_vhost_user(const NetClientOptions *opts, const char *name,
 {
     const NetdevVhostUserOptions *vhost_user_opts;
     CharDriverState *chr;
+    bool has_backend_features;;
+    unsigned long long backend_features;
 
     assert(opts->kind == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
     vhost_user_opts = opts->vhost_user;
@@ -263,6 +292,15 @@  int net_init_vhost_user(const NetClientOptions *opts, const char *name,
         return -1;
     }
 
+    /* backend features */
+    if (vhost_user_opts->has_backend_features) {
+        has_backend_features = true;
+        backend_features = vhost_user_opts->backend_features;
+    } else {
+        has_backend_features = false;
+        backend_features = 0;
+    }
 
-    return net_vhost_user_init(peer, "vhost_user", name, chr);
+    return net_vhost_user_init(peer, "vhost_user", name, chr,
+                                has_backend_features, backend_features);
 }
diff --git a/qapi-schema.json b/qapi-schema.json
index f97ffa1..bab4a74 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2243,6 +2243,8 @@ 
 #
 # @queues: #optional number of queues to be created for multiqueue capable tap
 #
+# @backend_features: #optional feature flag to support vhost user backend
+#
 # Since 1.2
 ##
 { 'struct': 'NetdevTapOptions',
@@ -2259,7 +2261,8 @@ 
     '*vhostfd':    'str',
     '*vhostfds':   'str',
     '*vhostforce': 'bool',
-    '*queues':     'uint32'} }
+    '*queues':     'uint32',
+    '*backend_features':'uint64'} }
 
 ##
 # @NetdevSocketOptions
@@ -2444,12 +2447,15 @@ 
 #
 # @vhostforce: #optional vhost on for non-MSIX virtio guests (default: false).
 #
+# @backend_features: #optional feature flag to support vhost user backend (default: 0).
+#
 # Since 2.1
 ##
 { 'struct': 'NetdevVhostUserOptions',
   'data': {
     'chardev':        'str',
-    '*vhostforce':    'bool' } }
+    '*vhostforce':    'bool',
+    '*backend_features':    'uint64' } }
 
 ##
 # @NetClientOptions
diff --git a/qemu-options.hx b/qemu-options.hx
index ec356f6..3ad3486 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1466,7 +1466,7 @@  DEF("net", HAS_ARG, QEMU_OPTION_net,
     "-net tap[,vlan=n][,name=str],ifname=name\n"
     "                connect the host TAP network interface to VLAN 'n'\n"
 #else
-    "-net tap[,vlan=n][,name=str][,fd=h][,fds=x:y:...:z][,ifname=name][,script=file][,downscript=dfile][,helper=helper][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off][,vhostfd=h][,vhostfds=x:y:...:z][,vhostforce=on|off][,queues=n]\n"
+    "-net tap[,vlan=n][,name=str][,fd=h][,fds=x:y:...:z][,ifname=name][,script=file][,downscript=dfile][,helper=helper][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off][,vhostfd=h][,vhostfds=x:y:...:z][,vhostforce=on|off][,queues=n][,backend_features=n]\n"
     "                connect the host TAP network interface to VLAN 'n'\n"
     "                use network scripts 'file' (default=" DEFAULT_NETWORK_SCRIPT ")\n"
     "                to configure it and 'dfile' (default=" DEFAULT_NETWORK_DOWN_SCRIPT ")\n"
@@ -1486,6 +1486,7 @@  DEF("net", HAS_ARG, QEMU_OPTION_net,
     "                use 'vhostfd=h' to connect to an already opened vhost net device\n"
     "                use 'vhostfds=x:y:...:z to connect to multiple already opened vhost net devices\n"
     "                use 'queues=n' to specify the number of queues to be created for multiqueue TAP\n"
+    "                use 'backend_features=n' to specify the features that vhost backend supported\n"
     "-net bridge[,vlan=n][,name=str][,br=bridge][,helper=helper]\n"
     "                connects a host TAP network interface to a host bridge device 'br'\n"
     "                (default=" DEFAULT_BRIDGE_INTERFACE ") using the program 'helper'\n"