Re: [PATCH] vhost-user-scsi: support reconnect to backend

2023-07-31 Thread Li Feng


> 2023年7月31日 06:09,Raphael Norwitz  写道:
> 
> 
> 
>> On Jul 28, 2023, at 3:48 AM, Li Feng  wrote:
>> 
>> Thanks for your reply.
>> 
>>> 2023年7月28日 上午5:21,Raphael Norwitz  写道:
>>> 
>>> 
>>> 
 On Jul 25, 2023, at 6:19 AM, Li Feng  wrote:
 
 Thanks for your comments.
 
> 2023年7月25日 上午1:21,Raphael Norwitz  写道:
> 
> Very excited to see this. High level looks good modulo a few small things.
> 
> My major concern is around existing vhost-user-scsi backends which don’t 
> support VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD. IMO we should hide the 
> reconnect behavior behind a VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD check. 
> We may want to do the same for vhost-user-blk.
> 
> The question is then what happens if the check is false. IIUC without an 
> inflight FD, if a device processes requests out of order, it’s not safe 
> to continue execution on reconnect, as there’s no way for the backend to 
> know how to replay IO. Should we permanently wedge the device or have 
> QEMU fail out? May be nice to have a toggle for this.
 
 Based on what MST said, is there anything else I need to do?
>>> 
>>> I don’t think so.
>>> 
> 
>> On Jul 21, 2023, at 6:51 AM, Li Feng  wrote:
>> 
>> If the backend crashes and restarts, the device is broken.
>> This patch adds reconnect for vhost-user-scsi.
>> 
>> Tested with spdk backend.
>> 
>> Signed-off-by: Li Feng 
>> ---
>> hw/block/vhost-user-blk.c   |   2 -
>> hw/scsi/vhost-scsi-common.c |  27 ++---
>> hw/scsi/vhost-user-scsi.c   | 163 +---
>> include/hw/virtio/vhost-user-scsi.h |   3 +
>> include/hw/virtio/vhost.h   |   2 +
>> 5 files changed, 165 insertions(+), 32 deletions(-)
>> 
>> diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
>> index eecf3f7a81..f250c740b5 100644
>> --- a/hw/block/vhost-user-blk.c
>> +++ b/hw/block/vhost-user-blk.c
>> @@ -32,8 +32,6 @@
>> #include "sysemu/sysemu.h"
>> #include "sysemu/runstate.h"
>> 
>> -#define REALIZE_CONNECTION_RETRIES 3
>> -
>> static const int user_feature_bits[] = {
>>  VIRTIO_BLK_F_SIZE_MAX,
>>  VIRTIO_BLK_F_SEG_MAX,
>> diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c
> 
> Why can’t all the vhost-scsi-common stuff be moved to a separate change?
 
 I will move this code to separate patch.
> 
> Especially the stuff introduced for vhost-user-blk in 
> 1b0063b3048af65dfaae6422a572c87db8575a92 should be moved out.
 OK.
 
> 
>> index a06f01af26..08801886b8 100644
>> --- a/hw/scsi/vhost-scsi-common.c
>> +++ b/hw/scsi/vhost-scsi-common.c
>> @@ -52,16 +52,22 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
>> 
>>  vsc->dev.acked_features = vdev->guest_features;
>> 
>> -assert(vsc->inflight == NULL);
>> -vsc->inflight = g_new0(struct vhost_inflight, 1);
>> -ret = vhost_dev_get_inflight(&vsc->dev,
>> - vs->conf.virtqueue_size,
>> - vsc->inflight);
>> +ret = vhost_dev_prepare_inflight(&vsc->dev, vdev);
>>  if (ret < 0) {
>> -error_report("Error get inflight: %d", -ret);
>> +error_report("Error setting inflight format: %d", -ret);
>>  goto err_guest_notifiers;
>>  }
>> 
>> +if (!vsc->inflight->addr) {
>> +ret = vhost_dev_get_inflight(&vsc->dev,
>> +vs->conf.virtqueue_size,
>> +vsc->inflight);
>> +if (ret < 0) {
>> +error_report("Error get inflight: %d", -ret);
>> +goto err_guest_notifiers;
>> +}
>> +}
>> +
>>  ret = vhost_dev_set_inflight(&vsc->dev, vsc->inflight);
>>  if (ret < 0) {
>>  error_report("Error set inflight: %d", -ret);
>> @@ -85,9 +91,6 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
>>  return ret;
>> 
>> err_guest_notifiers:
>> -g_free(vsc->inflight);
>> -vsc->inflight = NULL;
>> -
>>  k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
>> err_host_notifiers:
>>  vhost_dev_disable_notifiers(&vsc->dev, vdev);
>> @@ -111,12 +114,6 @@ void vhost_scsi_common_stop(VHostSCSICommon *vsc)
>>  }
>>  assert(ret >= 0);
>> 
> 
> In the vhost-scsi (kernel backend) path, what will cleanup vsc->inflight 
> now?
 OK, we should check the vsc->inflight if it is null, the vhost-scsi 
 doesn’t allocate the
 inflight object memory.
>>> 
>>> Are you saying vhost-scsi never allocates inflight so we don’t need to 
>>> check for it?
>> We have checked the vsc->inflight, and only if allocated, we send the 
>> get/set_inflight_fd.
>> This works with vhost-user-scsi/vhost-scsi

Re: [PATCH] vhost-user-scsi: support reconnect to backend

2023-07-30 Thread Raphael Norwitz


> On Jul 28, 2023, at 3:48 AM, Li Feng  wrote:
> 
> Thanks for your reply.
> 
>> 2023年7月28日 上午5:21,Raphael Norwitz  写道:
>> 
>> 
>> 
>>> On Jul 25, 2023, at 6:19 AM, Li Feng  wrote:
>>> 
>>> Thanks for your comments.
>>> 
 2023年7月25日 上午1:21,Raphael Norwitz  写道:
 
 Very excited to see this. High level looks good modulo a few small things.
 
 My major concern is around existing vhost-user-scsi backends which don’t 
 support VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD. IMO we should hide the 
 reconnect behavior behind a VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD check. We 
 may want to do the same for vhost-user-blk.
 
 The question is then what happens if the check is false. IIUC without an 
 inflight FD, if a device processes requests out of order, it’s not safe to 
 continue execution on reconnect, as there’s no way for the backend to know 
 how to replay IO. Should we permanently wedge the device or have QEMU fail 
 out? May be nice to have a toggle for this.
>>> 
>>> Based on what MST said, is there anything else I need to do?
>> 
>> I don’t think so.
>> 
 
> On Jul 21, 2023, at 6:51 AM, Li Feng  wrote:
> 
> If the backend crashes and restarts, the device is broken.
> This patch adds reconnect for vhost-user-scsi.
> 
> Tested with spdk backend.
> 
> Signed-off-by: Li Feng 
> ---
> hw/block/vhost-user-blk.c   |   2 -
> hw/scsi/vhost-scsi-common.c |  27 ++---
> hw/scsi/vhost-user-scsi.c   | 163 +---
> include/hw/virtio/vhost-user-scsi.h |   3 +
> include/hw/virtio/vhost.h   |   2 +
> 5 files changed, 165 insertions(+), 32 deletions(-)
> 
> diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
> index eecf3f7a81..f250c740b5 100644
> --- a/hw/block/vhost-user-blk.c
> +++ b/hw/block/vhost-user-blk.c
> @@ -32,8 +32,6 @@
> #include "sysemu/sysemu.h"
> #include "sysemu/runstate.h"
> 
> -#define REALIZE_CONNECTION_RETRIES 3
> -
> static const int user_feature_bits[] = {
>   VIRTIO_BLK_F_SIZE_MAX,
>   VIRTIO_BLK_F_SEG_MAX,
> diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c
 
 Why can’t all the vhost-scsi-common stuff be moved to a separate change?
>>> 
>>> I will move this code to separate patch.
 
 Especially the stuff introduced for vhost-user-blk in 
 1b0063b3048af65dfaae6422a572c87db8575a92 should be moved out.
>>> OK.
>>> 
 
> index a06f01af26..08801886b8 100644
> --- a/hw/scsi/vhost-scsi-common.c
> +++ b/hw/scsi/vhost-scsi-common.c
> @@ -52,16 +52,22 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
> 
>   vsc->dev.acked_features = vdev->guest_features;
> 
> -assert(vsc->inflight == NULL);
> -vsc->inflight = g_new0(struct vhost_inflight, 1);
> -ret = vhost_dev_get_inflight(&vsc->dev,
> - vs->conf.virtqueue_size,
> - vsc->inflight);
> +ret = vhost_dev_prepare_inflight(&vsc->dev, vdev);
>   if (ret < 0) {
> -error_report("Error get inflight: %d", -ret);
> +error_report("Error setting inflight format: %d", -ret);
>   goto err_guest_notifiers;
>   }
> 
> +if (!vsc->inflight->addr) {
> +ret = vhost_dev_get_inflight(&vsc->dev,
> +vs->conf.virtqueue_size,
> +vsc->inflight);
> +if (ret < 0) {
> +error_report("Error get inflight: %d", -ret);
> +goto err_guest_notifiers;
> +}
> +}
> +
>   ret = vhost_dev_set_inflight(&vsc->dev, vsc->inflight);
>   if (ret < 0) {
>   error_report("Error set inflight: %d", -ret);
> @@ -85,9 +91,6 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
>   return ret;
> 
> err_guest_notifiers:
> -g_free(vsc->inflight);
> -vsc->inflight = NULL;
> -
>   k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
> err_host_notifiers:
>   vhost_dev_disable_notifiers(&vsc->dev, vdev);
> @@ -111,12 +114,6 @@ void vhost_scsi_common_stop(VHostSCSICommon *vsc)
>   }
>   assert(ret >= 0);
> 
 
 In the vhost-scsi (kernel backend) path, what will cleanup vsc->inflight 
 now?
>>> OK, we should check the vsc->inflight if it is null, the vhost-scsi doesn’t 
>>> allocate the
>>> inflight object memory.
>> 
>> Are you saying vhost-scsi never allocates inflight so we don’t need to check 
>> for it?
> We have checked the vsc->inflight, and only if allocated, we send the 
> get/set_inflight_fd.
> This works with vhost-user-scsi/vhost-scsi both.

So then it sounds like this code introduces a resource leak. 
g_free(vsc->inflight) should be added to the vhost-scsi code in 
vhost_scsi_stop().

>> 
>>> 
>

Re: [PATCH] vhost-user-scsi: support reconnect to backend

2023-07-28 Thread Li Feng
Thanks for your reply.

> 2023年7月28日 上午5:21,Raphael Norwitz  写道:
> 
> 
> 
>> On Jul 25, 2023, at 6:19 AM, Li Feng  wrote:
>> 
>> Thanks for your comments.
>> 
>>> 2023年7月25日 上午1:21,Raphael Norwitz  写道:
>>> 
>>> Very excited to see this. High level looks good modulo a few small things.
>>> 
>>> My major concern is around existing vhost-user-scsi backends which don’t 
>>> support VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD. IMO we should hide the 
>>> reconnect behavior behind a VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD check. We 
>>> may want to do the same for vhost-user-blk.
>>> 
>>> The question is then what happens if the check is false. IIUC without an 
>>> inflight FD, if a device processes requests out of order, it’s not safe to 
>>> continue execution on reconnect, as there’s no way for the backend to know 
>>> how to replay IO. Should we permanently wedge the device or have QEMU fail 
>>> out? May be nice to have a toggle for this.
>> 
>> Based on what MST said, is there anything else I need to do?
> 
> I don’t think so.
> 
>>> 
 On Jul 21, 2023, at 6:51 AM, Li Feng  wrote:
 
 If the backend crashes and restarts, the device is broken.
 This patch adds reconnect for vhost-user-scsi.
 
 Tested with spdk backend.
 
 Signed-off-by: Li Feng 
 ---
 hw/block/vhost-user-blk.c   |   2 -
 hw/scsi/vhost-scsi-common.c |  27 ++---
 hw/scsi/vhost-user-scsi.c   | 163 +---
 include/hw/virtio/vhost-user-scsi.h |   3 +
 include/hw/virtio/vhost.h   |   2 +
 5 files changed, 165 insertions(+), 32 deletions(-)
 
 diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
 index eecf3f7a81..f250c740b5 100644
 --- a/hw/block/vhost-user-blk.c
 +++ b/hw/block/vhost-user-blk.c
 @@ -32,8 +32,6 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/runstate.h"
 
 -#define REALIZE_CONNECTION_RETRIES 3
 -
 static const int user_feature_bits[] = {
   VIRTIO_BLK_F_SIZE_MAX,
   VIRTIO_BLK_F_SEG_MAX,
 diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c
>>> 
>>> Why can’t all the vhost-scsi-common stuff be moved to a separate change?
>> 
>> I will move this code to separate patch.
>>> 
>>> Especially the stuff introduced for vhost-user-blk in 
>>> 1b0063b3048af65dfaae6422a572c87db8575a92 should be moved out.
>> OK.
>> 
>>> 
 index a06f01af26..08801886b8 100644
 --- a/hw/scsi/vhost-scsi-common.c
 +++ b/hw/scsi/vhost-scsi-common.c
 @@ -52,16 +52,22 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
 
   vsc->dev.acked_features = vdev->guest_features;
 
 -assert(vsc->inflight == NULL);
 -vsc->inflight = g_new0(struct vhost_inflight, 1);
 -ret = vhost_dev_get_inflight(&vsc->dev,
 - vs->conf.virtqueue_size,
 - vsc->inflight);
 +ret = vhost_dev_prepare_inflight(&vsc->dev, vdev);
   if (ret < 0) {
 -error_report("Error get inflight: %d", -ret);
 +error_report("Error setting inflight format: %d", -ret);
   goto err_guest_notifiers;
   }
 
 +if (!vsc->inflight->addr) {
 +ret = vhost_dev_get_inflight(&vsc->dev,
 +vs->conf.virtqueue_size,
 +vsc->inflight);
 +if (ret < 0) {
 +error_report("Error get inflight: %d", -ret);
 +goto err_guest_notifiers;
 +}
 +}
 +
   ret = vhost_dev_set_inflight(&vsc->dev, vsc->inflight);
   if (ret < 0) {
   error_report("Error set inflight: %d", -ret);
 @@ -85,9 +91,6 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
   return ret;
 
 err_guest_notifiers:
 -g_free(vsc->inflight);
 -vsc->inflight = NULL;
 -
   k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
 err_host_notifiers:
   vhost_dev_disable_notifiers(&vsc->dev, vdev);
 @@ -111,12 +114,6 @@ void vhost_scsi_common_stop(VHostSCSICommon *vsc)
   }
   assert(ret >= 0);
 
>>> 
>>> In the vhost-scsi (kernel backend) path, what will cleanup vsc->inflight 
>>> now?
>> OK, we should check the vsc->inflight if it is null, the vhost-scsi doesn’t 
>> allocate the
>> inflight object memory.
> 
> Are you saying vhost-scsi never allocates inflight so we don’t need to check 
> for it?
We have checked the vsc->inflight, and only if allocated, we send the 
get/set_inflight_fd.
This works with vhost-user-scsi/vhost-scsi both.
> 
>> 
>>> 
 -if (vsc->inflight) {
 -vhost_dev_free_inflight(vsc->inflight);
 -g_free(vsc->inflight);
 -vsc->inflight = NULL;
 -}
 -
   vhost_dev_disable_notifiers(&vsc->dev, vdev);
 }
 
 diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
 index ee99b

Re: [PATCH] vhost-user-scsi: support reconnect to backend

2023-07-27 Thread Raphael Norwitz


> On Jul 25, 2023, at 6:19 AM, Li Feng  wrote:
> 
> Thanks for your comments.
> 
>> 2023年7月25日 上午1:21,Raphael Norwitz  写道:
>> 
>> Very excited to see this. High level looks good modulo a few small things.
>> 
>> My major concern is around existing vhost-user-scsi backends which don’t 
>> support VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD. IMO we should hide the 
>> reconnect behavior behind a VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD check. We 
>> may want to do the same for vhost-user-blk.
>> 
>> The question is then what happens if the check is false. IIUC without an 
>> inflight FD, if a device processes requests out of order, it’s not safe to 
>> continue execution on reconnect, as there’s no way for the backend to know 
>> how to replay IO. Should we permanently wedge the device or have QEMU fail 
>> out? May be nice to have a toggle for this.
> 
> Based on what MST said, is there anything else I need to do?

I don’t think so.

>> 
>>> On Jul 21, 2023, at 6:51 AM, Li Feng  wrote:
>>> 
>>> If the backend crashes and restarts, the device is broken.
>>> This patch adds reconnect for vhost-user-scsi.
>>> 
>>> Tested with spdk backend.
>>> 
>>> Signed-off-by: Li Feng 
>>> ---
>>> hw/block/vhost-user-blk.c   |   2 -
>>> hw/scsi/vhost-scsi-common.c |  27 ++---
>>> hw/scsi/vhost-user-scsi.c   | 163 +---
>>> include/hw/virtio/vhost-user-scsi.h |   3 +
>>> include/hw/virtio/vhost.h   |   2 +
>>> 5 files changed, 165 insertions(+), 32 deletions(-)
>>> 
>>> diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
>>> index eecf3f7a81..f250c740b5 100644
>>> --- a/hw/block/vhost-user-blk.c
>>> +++ b/hw/block/vhost-user-blk.c
>>> @@ -32,8 +32,6 @@
>>> #include "sysemu/sysemu.h"
>>> #include "sysemu/runstate.h"
>>> 
>>> -#define REALIZE_CONNECTION_RETRIES 3
>>> -
>>> static const int user_feature_bits[] = {
>>>VIRTIO_BLK_F_SIZE_MAX,
>>>VIRTIO_BLK_F_SEG_MAX,
>>> diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c
>> 
>> Why can’t all the vhost-scsi-common stuff be moved to a separate change?
> 
> I will move this code to separate patch.
>> 
>> Especially the stuff introduced for vhost-user-blk in 
>> 1b0063b3048af65dfaae6422a572c87db8575a92 should be moved out.
> OK.
> 
>> 
>>> index a06f01af26..08801886b8 100644
>>> --- a/hw/scsi/vhost-scsi-common.c
>>> +++ b/hw/scsi/vhost-scsi-common.c
>>> @@ -52,16 +52,22 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
>>> 
>>>vsc->dev.acked_features = vdev->guest_features;
>>> 
>>> -assert(vsc->inflight == NULL);
>>> -vsc->inflight = g_new0(struct vhost_inflight, 1);
>>> -ret = vhost_dev_get_inflight(&vsc->dev,
>>> - vs->conf.virtqueue_size,
>>> - vsc->inflight);
>>> +ret = vhost_dev_prepare_inflight(&vsc->dev, vdev);
>>>if (ret < 0) {
>>> -error_report("Error get inflight: %d", -ret);
>>> +error_report("Error setting inflight format: %d", -ret);
>>>goto err_guest_notifiers;
>>>}
>>> 
>>> +if (!vsc->inflight->addr) {
>>> +ret = vhost_dev_get_inflight(&vsc->dev,
>>> +vs->conf.virtqueue_size,
>>> +vsc->inflight);
>>> +if (ret < 0) {
>>> +error_report("Error get inflight: %d", -ret);
>>> +goto err_guest_notifiers;
>>> +}
>>> +}
>>> +
>>>ret = vhost_dev_set_inflight(&vsc->dev, vsc->inflight);
>>>if (ret < 0) {
>>>error_report("Error set inflight: %d", -ret);
>>> @@ -85,9 +91,6 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
>>>return ret;
>>> 
>>> err_guest_notifiers:
>>> -g_free(vsc->inflight);
>>> -vsc->inflight = NULL;
>>> -
>>>k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
>>> err_host_notifiers:
>>>vhost_dev_disable_notifiers(&vsc->dev, vdev);
>>> @@ -111,12 +114,6 @@ void vhost_scsi_common_stop(VHostSCSICommon *vsc)
>>>}
>>>assert(ret >= 0);
>>> 
>> 
>> In the vhost-scsi (kernel backend) path, what will cleanup vsc->inflight now?
> OK, we should check the vsc->inflight if it is null, the vhost-scsi doesn’t 
> allocate the
> inflight object memory.

Are you saying vhost-scsi never allocates inflight so we don’t need to check 
for it?

> 
>> 
>>> -if (vsc->inflight) {
>>> -vhost_dev_free_inflight(vsc->inflight);
>>> -g_free(vsc->inflight);
>>> -vsc->inflight = NULL;
>>> -}
>>> -
>>>vhost_dev_disable_notifiers(&vsc->dev, vdev);
>>> }
>>> 
>>> diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
>>> index ee99b19e7a..e0e88b0c42 100644
>>> --- a/hw/scsi/vhost-user-scsi.c
>>> +++ b/hw/scsi/vhost-user-scsi.c
>>> @@ -89,14 +89,126 @@ static void vhost_dummy_handle_output(VirtIODevice 
>>> *vdev, VirtQueue *vq)
>>> {
>>> }
>>> 
>>> +static int vhost_user_scsi_connect(DeviceState *dev, Error **errp)
>>> +{
>>> +VirtIODevice *vdev = VIRTIO_DEVICE(de

Re: [PATCH] vhost-user-scsi: support reconnect to backend

2023-07-25 Thread Li Feng
Thanks for your comments.

> 2023年7月25日 上午1:21,Raphael Norwitz  写道:
> 
> Very excited to see this. High level looks good modulo a few small things.
> 
> My major concern is around existing vhost-user-scsi backends which don’t 
> support VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD. IMO we should hide the 
> reconnect behavior behind a VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD check. We 
> may want to do the same for vhost-user-blk.
> 
> The question is then what happens if the check is false. IIUC without an 
> inflight FD, if a device processes requests out of order, it’s not safe to 
> continue execution on reconnect, as there’s no way for the backend to know 
> how to replay IO. Should we permanently wedge the device or have QEMU fail 
> out? May be nice to have a toggle for this.

Based on what MST said, is there anything else I need to do?
> 
>> On Jul 21, 2023, at 6:51 AM, Li Feng  wrote:
>> 
>> If the backend crashes and restarts, the device is broken.
>> This patch adds reconnect for vhost-user-scsi.
>> 
>> Tested with spdk backend.
>> 
>> Signed-off-by: Li Feng 
>> ---
>> hw/block/vhost-user-blk.c   |   2 -
>> hw/scsi/vhost-scsi-common.c |  27 ++---
>> hw/scsi/vhost-user-scsi.c   | 163 +---
>> include/hw/virtio/vhost-user-scsi.h |   3 +
>> include/hw/virtio/vhost.h   |   2 +
>> 5 files changed, 165 insertions(+), 32 deletions(-)
>> 
>> diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
>> index eecf3f7a81..f250c740b5 100644
>> --- a/hw/block/vhost-user-blk.c
>> +++ b/hw/block/vhost-user-blk.c
>> @@ -32,8 +32,6 @@
>> #include "sysemu/sysemu.h"
>> #include "sysemu/runstate.h"
>> 
>> -#define REALIZE_CONNECTION_RETRIES 3
>> -
>> static const int user_feature_bits[] = {
>>VIRTIO_BLK_F_SIZE_MAX,
>>VIRTIO_BLK_F_SEG_MAX,
>> diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c
> 
> Why can’t all the vhost-scsi-common stuff be moved to a separate change?

I will move this code to separate patch.
> 
> Especially the stuff introduced for vhost-user-blk in 
> 1b0063b3048af65dfaae6422a572c87db8575a92 should be moved out.
OK.

> 
>> index a06f01af26..08801886b8 100644
>> --- a/hw/scsi/vhost-scsi-common.c
>> +++ b/hw/scsi/vhost-scsi-common.c
>> @@ -52,16 +52,22 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
>> 
>>vsc->dev.acked_features = vdev->guest_features;
>> 
>> -assert(vsc->inflight == NULL);
>> -vsc->inflight = g_new0(struct vhost_inflight, 1);
>> -ret = vhost_dev_get_inflight(&vsc->dev,
>> - vs->conf.virtqueue_size,
>> - vsc->inflight);
>> +ret = vhost_dev_prepare_inflight(&vsc->dev, vdev);
>>if (ret < 0) {
>> -error_report("Error get inflight: %d", -ret);
>> +error_report("Error setting inflight format: %d", -ret);
>>goto err_guest_notifiers;
>>}
>> 
>> +if (!vsc->inflight->addr) {
>> +ret = vhost_dev_get_inflight(&vsc->dev,
>> +vs->conf.virtqueue_size,
>> +vsc->inflight);
>> +if (ret < 0) {
>> +error_report("Error get inflight: %d", -ret);
>> +goto err_guest_notifiers;
>> +}
>> +}
>> +
>>ret = vhost_dev_set_inflight(&vsc->dev, vsc->inflight);
>>if (ret < 0) {
>>error_report("Error set inflight: %d", -ret);
>> @@ -85,9 +91,6 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
>>return ret;
>> 
>> err_guest_notifiers:
>> -g_free(vsc->inflight);
>> -vsc->inflight = NULL;
>> -
>>k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
>> err_host_notifiers:
>>vhost_dev_disable_notifiers(&vsc->dev, vdev);
>> @@ -111,12 +114,6 @@ void vhost_scsi_common_stop(VHostSCSICommon *vsc)
>>}
>>assert(ret >= 0);
>> 
> 
> In the vhost-scsi (kernel backend) path, what will cleanup vsc->inflight now?
OK, we should check the vsc->inflight if it is null, the vhost-scsi doesn’t 
allocate the
inflight object memory.

> 
>> -if (vsc->inflight) {
>> -vhost_dev_free_inflight(vsc->inflight);
>> -g_free(vsc->inflight);
>> -vsc->inflight = NULL;
>> -}
>> -
>>vhost_dev_disable_notifiers(&vsc->dev, vdev);
>> }
>> 
>> diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
>> index ee99b19e7a..e0e88b0c42 100644
>> --- a/hw/scsi/vhost-user-scsi.c
>> +++ b/hw/scsi/vhost-user-scsi.c
>> @@ -89,14 +89,126 @@ static void vhost_dummy_handle_output(VirtIODevice 
>> *vdev, VirtQueue *vq)
>> {
>> }
>> 
>> +static int vhost_user_scsi_connect(DeviceState *dev, Error **errp)
>> +{
>> +VirtIODevice *vdev = VIRTIO_DEVICE(dev);
>> +VHostUserSCSI *s = VHOST_USER_SCSI(vdev);
>> +VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
>> +VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
>> +int ret = 0;
>> +
>> +if (s->connected) {
>> +return 0;
>> +}
>> +s->connected = true;
>> +
>> +vsc->dev.num_q

Re: [PATCH] vhost-user-scsi: support reconnect to backend

2023-07-24 Thread Michael S. Tsirkin
On Mon, Jul 24, 2023 at 05:21:37PM +, Raphael Norwitz wrote:
> Very excited to see this. High level looks good modulo a few small things.
> 
> My major concern is around existing vhost-user-scsi backends which don’t 
> support VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD. IMO we should hide the 
> reconnect behavior behind a VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD check. We 
> may want to do the same for vhost-user-blk.
> 
> The question is then what happens if the check is false. IIUC without an 
> inflight FD, if a device processes requests out of order, it’s not safe to 
> continue execution on reconnect, as there’s no way for the backend to know 
> how to replay IO. Should we permanently wedge the device or have QEMU fail 
> out? May be nice to have a toggle for this.

No, device itself can store the state somewhere. And if it wants to,
it can check VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD and fail reconnect.

-- 
MST




Re: [PATCH] vhost-user-scsi: support reconnect to backend

2023-07-24 Thread Raphael Norwitz
Very excited to see this. High level looks good modulo a few small things.

My major concern is around existing vhost-user-scsi backends which don’t 
support VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD. IMO we should hide the reconnect 
behavior behind a VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD check. We may want to do 
the same for vhost-user-blk.

The question is then what happens if the check is false. IIUC without an 
inflight FD, if a device processes requests out of order, it’s not safe to 
continue execution on reconnect, as there’s no way for the backend to know how 
to replay IO. Should we permanently wedge the device or have QEMU fail out? May 
be nice to have a toggle for this.

> On Jul 21, 2023, at 6:51 AM, Li Feng  wrote:
> 
> If the backend crashes and restarts, the device is broken.
> This patch adds reconnect for vhost-user-scsi.
> 
> Tested with spdk backend.
> 
> Signed-off-by: Li Feng 
> ---
> hw/block/vhost-user-blk.c   |   2 -
> hw/scsi/vhost-scsi-common.c |  27 ++---
> hw/scsi/vhost-user-scsi.c   | 163 +---
> include/hw/virtio/vhost-user-scsi.h |   3 +
> include/hw/virtio/vhost.h   |   2 +
> 5 files changed, 165 insertions(+), 32 deletions(-)
> 
> diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
> index eecf3f7a81..f250c740b5 100644
> --- a/hw/block/vhost-user-blk.c
> +++ b/hw/block/vhost-user-blk.c
> @@ -32,8 +32,6 @@
> #include "sysemu/sysemu.h"
> #include "sysemu/runstate.h"
> 
> -#define REALIZE_CONNECTION_RETRIES 3
> -
> static const int user_feature_bits[] = {
> VIRTIO_BLK_F_SIZE_MAX,
> VIRTIO_BLK_F_SEG_MAX,
> diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c

Why can’t all the vhost-scsi-common stuff be moved to a separate change?

Especially the stuff introduced for vhost-user-blk in 
1b0063b3048af65dfaae6422a572c87db8575a92 should be moved out.

> index a06f01af26..08801886b8 100644
> --- a/hw/scsi/vhost-scsi-common.c
> +++ b/hw/scsi/vhost-scsi-common.c
> @@ -52,16 +52,22 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
> 
> vsc->dev.acked_features = vdev->guest_features;
> 
> -assert(vsc->inflight == NULL);
> -vsc->inflight = g_new0(struct vhost_inflight, 1);
> -ret = vhost_dev_get_inflight(&vsc->dev,
> - vs->conf.virtqueue_size,
> - vsc->inflight);
> +ret = vhost_dev_prepare_inflight(&vsc->dev, vdev);
> if (ret < 0) {
> -error_report("Error get inflight: %d", -ret);
> +error_report("Error setting inflight format: %d", -ret);
> goto err_guest_notifiers;
> }
> 
> +if (!vsc->inflight->addr) {
> +ret = vhost_dev_get_inflight(&vsc->dev,
> +vs->conf.virtqueue_size,
> +vsc->inflight);
> +if (ret < 0) {
> +error_report("Error get inflight: %d", -ret);
> +goto err_guest_notifiers;
> +}
> +}
> +
> ret = vhost_dev_set_inflight(&vsc->dev, vsc->inflight);
> if (ret < 0) {
> error_report("Error set inflight: %d", -ret);
> @@ -85,9 +91,6 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
> return ret;
> 
> err_guest_notifiers:
> -g_free(vsc->inflight);
> -vsc->inflight = NULL;
> -
> k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
> err_host_notifiers:
> vhost_dev_disable_notifiers(&vsc->dev, vdev);
> @@ -111,12 +114,6 @@ void vhost_scsi_common_stop(VHostSCSICommon *vsc)
> }
> assert(ret >= 0);
> 

In the vhost-scsi (kernel backend) path, what will cleanup vsc->inflight now?

> -if (vsc->inflight) {
> -vhost_dev_free_inflight(vsc->inflight);
> -g_free(vsc->inflight);
> -vsc->inflight = NULL;
> -}
> -
> vhost_dev_disable_notifiers(&vsc->dev, vdev);
> }
> 
> diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
> index ee99b19e7a..e0e88b0c42 100644
> --- a/hw/scsi/vhost-user-scsi.c
> +++ b/hw/scsi/vhost-user-scsi.c
> @@ -89,14 +89,126 @@ static void vhost_dummy_handle_output(VirtIODevice 
> *vdev, VirtQueue *vq)
> {
> }
> 
> +static int vhost_user_scsi_connect(DeviceState *dev, Error **errp)
> +{
> +VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> +VHostUserSCSI *s = VHOST_USER_SCSI(vdev);
> +VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
> +VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
> +int ret = 0;
> +
> +if (s->connected) {
> +return 0;
> +}
> +s->connected = true;
> +
> +vsc->dev.num_queues = vs->conf.num_queues;
> +vsc->dev.nvqs = VIRTIO_SCSI_VQ_NUM_FIXED + vs->conf.num_queues;
> +vsc->dev.vqs = s->vhost_vqs;
> +vsc->dev.vq_index = 0;
> +vsc->dev.backend_features = 0;
> +
> +ret = vhost_dev_init(&vsc->dev, &s->vhost_user, VHOST_BACKEND_TYPE_USER, 
> 0,
> + errp);
> +if (ret < 0) {
> +return ret;
> +}
> +
> +/* restore vhost state */

Should this

[PATCH] vhost-user-scsi: support reconnect to backend

2023-07-21 Thread Li Feng
If the backend crashes and restarts, the device is broken.
This patch adds reconnect for vhost-user-scsi.

Tested with spdk backend.

Signed-off-by: Li Feng 
---
 hw/block/vhost-user-blk.c   |   2 -
 hw/scsi/vhost-scsi-common.c |  27 ++---
 hw/scsi/vhost-user-scsi.c   | 163 +---
 include/hw/virtio/vhost-user-scsi.h |   3 +
 include/hw/virtio/vhost.h   |   2 +
 5 files changed, 165 insertions(+), 32 deletions(-)

diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index eecf3f7a81..f250c740b5 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -32,8 +32,6 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/runstate.h"
 
-#define REALIZE_CONNECTION_RETRIES 3
-
 static const int user_feature_bits[] = {
 VIRTIO_BLK_F_SIZE_MAX,
 VIRTIO_BLK_F_SEG_MAX,
diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c
index a06f01af26..08801886b8 100644
--- a/hw/scsi/vhost-scsi-common.c
+++ b/hw/scsi/vhost-scsi-common.c
@@ -52,16 +52,22 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
 
 vsc->dev.acked_features = vdev->guest_features;
 
-assert(vsc->inflight == NULL);
-vsc->inflight = g_new0(struct vhost_inflight, 1);
-ret = vhost_dev_get_inflight(&vsc->dev,
- vs->conf.virtqueue_size,
- vsc->inflight);
+ret = vhost_dev_prepare_inflight(&vsc->dev, vdev);
 if (ret < 0) {
-error_report("Error get inflight: %d", -ret);
+error_report("Error setting inflight format: %d", -ret);
 goto err_guest_notifiers;
 }
 
+if (!vsc->inflight->addr) {
+ret = vhost_dev_get_inflight(&vsc->dev,
+vs->conf.virtqueue_size,
+vsc->inflight);
+if (ret < 0) {
+error_report("Error get inflight: %d", -ret);
+goto err_guest_notifiers;
+}
+}
+
 ret = vhost_dev_set_inflight(&vsc->dev, vsc->inflight);
 if (ret < 0) {
 error_report("Error set inflight: %d", -ret);
@@ -85,9 +91,6 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
 return ret;
 
 err_guest_notifiers:
-g_free(vsc->inflight);
-vsc->inflight = NULL;
-
 k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
 err_host_notifiers:
 vhost_dev_disable_notifiers(&vsc->dev, vdev);
@@ -111,12 +114,6 @@ void vhost_scsi_common_stop(VHostSCSICommon *vsc)
 }
 assert(ret >= 0);
 
-if (vsc->inflight) {
-vhost_dev_free_inflight(vsc->inflight);
-g_free(vsc->inflight);
-vsc->inflight = NULL;
-}
-
 vhost_dev_disable_notifiers(&vsc->dev, vdev);
 }
 
diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index ee99b19e7a..e0e88b0c42 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -89,14 +89,126 @@ static void vhost_dummy_handle_output(VirtIODevice *vdev, 
VirtQueue *vq)
 {
 }
 
+static int vhost_user_scsi_connect(DeviceState *dev, Error **errp)
+{
+VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+VHostUserSCSI *s = VHOST_USER_SCSI(vdev);
+VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
+VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
+int ret = 0;
+
+if (s->connected) {
+return 0;
+}
+s->connected = true;
+
+vsc->dev.num_queues = vs->conf.num_queues;
+vsc->dev.nvqs = VIRTIO_SCSI_VQ_NUM_FIXED + vs->conf.num_queues;
+vsc->dev.vqs = s->vhost_vqs;
+vsc->dev.vq_index = 0;
+vsc->dev.backend_features = 0;
+
+ret = vhost_dev_init(&vsc->dev, &s->vhost_user, VHOST_BACKEND_TYPE_USER, 0,
+ errp);
+if (ret < 0) {
+return ret;
+}
+
+/* restore vhost state */
+if (virtio_device_started(vdev, vdev->status)) {
+ret = vhost_scsi_common_start(vsc);
+if (ret < 0) {
+return ret;
+}
+}
+
+return 0;
+}
+
+static void vhost_user_scsi_event(void *opaque, QEMUChrEvent event);
+
+static void vhost_user_scsi_disconnect(DeviceState *dev)
+{
+VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+VHostUserSCSI *s = VHOST_USER_SCSI(vdev);
+VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
+VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
+
+if (!s->connected) {
+return;
+}
+s->connected = false;
+
+vhost_scsi_common_stop(vsc);
+
+vhost_dev_cleanup(&vsc->dev);
+
+/* Re-instate the event handler for new connections */
+qemu_chr_fe_set_handlers(&vs->conf.chardev, NULL, NULL,
+ vhost_user_scsi_event, NULL, dev, NULL, true);
+}
+
+static void vhost_user_scsi_event(void *opaque, QEMUChrEvent event)
+{
+DeviceState *dev = opaque;
+VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+VHostUserSCSI *s = VHOST_USER_SCSI(vdev);
+VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
+VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
+Error *local_err = NULL;
+
+switch (event)