Skip to content

Commit 8faeb52

Browse files
bonziniChristoph Hellwig
authored andcommitted
virtio-scsi: fix various bad behavior on aborted requests
Even though the virtio-scsi spec guarantees that all requests related to the TMF will have been completed by the time the TMF itself completes, the request queue's callback might not have run yet. This causes requests to be completed more than once, and as a result triggers a variety of BUGs or oopses. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Venkatesh Srinivas <venkateshs@google.com> Cc: stable@vger.kernel.org Signed-off-by: Christoph Hellwig <hch@lst.de>
1 parent cdda0e5 commit 8faeb52

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

drivers/scsi/virtio_scsi.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,16 @@ static void virtscsi_req_done(struct virtqueue *vq)
237237
virtscsi_vq_done(vscsi, req_vq, virtscsi_complete_cmd);
238238
};
239239

240+
static void virtscsi_poll_requests(struct virtio_scsi *vscsi)
241+
{
242+
int i, num_vqs;
243+
244+
num_vqs = vscsi->num_queues;
245+
for (i = 0; i < num_vqs; i++)
246+
virtscsi_vq_done(vscsi, &vscsi->req_vqs[i],
247+
virtscsi_complete_cmd);
248+
}
249+
240250
static void virtscsi_complete_free(struct virtio_scsi *vscsi, void *buf)
241251
{
242252
struct virtio_scsi_cmd *cmd = buf;
@@ -591,6 +601,18 @@ static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd)
591601
cmd->resp.tmf.response == VIRTIO_SCSI_S_FUNCTION_SUCCEEDED)
592602
ret = SUCCESS;
593603

604+
/*
605+
* The spec guarantees that all requests related to the TMF have
606+
* been completed, but the callback might not have run yet if
607+
* we're using independent interrupts (e.g. MSI). Poll the
608+
* virtqueues once.
609+
*
610+
* In the abort case, sc->scsi_done will do nothing, because
611+
* the block layer must have detected a timeout and as a result
612+
* REQ_ATOM_COMPLETE has been set.
613+
*/
614+
virtscsi_poll_requests(vscsi);
615+
594616
out:
595617
mempool_free(cmd, virtscsi_cmd_pool);
596618
return ret;

0 commit comments

Comments
 (0)