Skip to content

Commit a648c9c

Browse files
mikechristieksacilotto
authored andcommitted
vhost scsi: fix cmd completion race
BugLink: https://bugs.launchpad.net/bugs/1908562 [ Upstream commit 47a3565 ] We might not do the final se_cmd put from vhost_scsi_complete_cmd_work. When the last put happens a little later then we could race where vhost_scsi_complete_cmd_work does vhost_signal, the guest runs and sends more IO, and vhost_scsi_handle_vq runs but does not find any free cmds. This patch has us delay completing the cmd until the last lio core ref is dropped. We then know that once we signal to the guest that the cmd is completed that if it queues a new command it will find a free cmd. Signed-off-by: Mike Christie <[email protected]> Reviewed-by: Maurizio Lombardi <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Michael S. Tsirkin <[email protected]> Acked-by: Stefan Hajnoczi <[email protected]> Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Kamal Mostafa <[email protected]> Signed-off-by: Ian May <[email protected]>
1 parent 6482040 commit a648c9c

File tree

1 file changed

+15
-27
lines changed

1 file changed

+15
-27
lines changed

drivers/vhost/scsi.c

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ static u32 vhost_scsi_tpg_get_inst_index(struct se_portal_group *se_tpg)
320320
return 1;
321321
}
322322

323-
static void vhost_scsi_release_cmd(struct se_cmd *se_cmd)
323+
static void vhost_scsi_release_cmd_res(struct se_cmd *se_cmd)
324324
{
325325
struct vhost_scsi_cmd *tv_cmd = container_of(se_cmd,
326326
struct vhost_scsi_cmd, tvc_se_cmd);
@@ -340,6 +340,16 @@ static void vhost_scsi_release_cmd(struct se_cmd *se_cmd)
340340
target_free_tag(se_sess, se_cmd);
341341
}
342342

343+
static void vhost_scsi_release_cmd(struct se_cmd *se_cmd)
344+
{
345+
struct vhost_scsi_cmd *cmd = container_of(se_cmd,
346+
struct vhost_scsi_cmd, tvc_se_cmd);
347+
struct vhost_scsi *vs = cmd->tvc_vhost;
348+
349+
llist_add(&cmd->tvc_completion_list, &vs->vs_completion_list);
350+
vhost_work_queue(&vs->dev, &vs->vs_completion_work);
351+
}
352+
343353
static u32 vhost_scsi_sess_get_index(struct se_session *se_sess)
344354
{
345355
return 0;
@@ -362,28 +372,15 @@ static int vhost_scsi_get_cmd_state(struct se_cmd *se_cmd)
362372
return 0;
363373
}
364374

365-
static void vhost_scsi_complete_cmd(struct vhost_scsi_cmd *cmd)
366-
{
367-
struct vhost_scsi *vs = cmd->tvc_vhost;
368-
369-
llist_add(&cmd->tvc_completion_list, &vs->vs_completion_list);
370-
371-
vhost_work_queue(&vs->dev, &vs->vs_completion_work);
372-
}
373-
374375
static int vhost_scsi_queue_data_in(struct se_cmd *se_cmd)
375376
{
376-
struct vhost_scsi_cmd *cmd = container_of(se_cmd,
377-
struct vhost_scsi_cmd, tvc_se_cmd);
378-
vhost_scsi_complete_cmd(cmd);
377+
transport_generic_free_cmd(se_cmd, 0);
379378
return 0;
380379
}
381380

382381
static int vhost_scsi_queue_status(struct se_cmd *se_cmd)
383382
{
384-
struct vhost_scsi_cmd *cmd = container_of(se_cmd,
385-
struct vhost_scsi_cmd, tvc_se_cmd);
386-
vhost_scsi_complete_cmd(cmd);
383+
transport_generic_free_cmd(se_cmd, 0);
387384
return 0;
388385
}
389386

@@ -429,15 +426,6 @@ vhost_scsi_allocate_evt(struct vhost_scsi *vs,
429426
return evt;
430427
}
431428

432-
static void vhost_scsi_free_cmd(struct vhost_scsi_cmd *cmd)
433-
{
434-
struct se_cmd *se_cmd = &cmd->tvc_se_cmd;
435-
436-
/* TODO locking against target/backend threads? */
437-
transport_generic_free_cmd(se_cmd, 0);
438-
439-
}
440-
441429
static int vhost_scsi_check_stop_free(struct se_cmd *se_cmd)
442430
{
443431
return target_put_sess_cmd(se_cmd);
@@ -556,7 +544,7 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work)
556544
} else
557545
pr_err("Faulted on virtio_scsi_cmd_resp\n");
558546

559-
vhost_scsi_free_cmd(cmd);
547+
vhost_scsi_release_cmd_res(se_cmd);
560548
}
561549

562550
vq = -1;
@@ -1088,7 +1076,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
10881076
&prot_iter, exp_data_len,
10891077
&data_iter))) {
10901078
vq_err(vq, "Failed to map iov to sgl\n");
1091-
vhost_scsi_release_cmd(&cmd->tvc_se_cmd);
1079+
vhost_scsi_release_cmd_res(&cmd->tvc_se_cmd);
10921080
goto err;
10931081
}
10941082
}

0 commit comments

Comments
 (0)