diff options
| author | Rusty Russell <rusty@rustcorp.com.au> | 2014-05-20 21:55:04 -0400 |
|---|---|---|
| committer | Rusty Russell <rusty@rustcorp.com.au> | 2014-05-20 21:55:41 -0400 |
| commit | c77fba9ab058d1e96ed51d4215e56905c9ef8d2a (patch) | |
| tree | db7a68864ef1f3ba182b3a9471211bd2fd5118bc | |
| parent | a17597d3b418ca5a394d14724ccfc295cb3186c8 (diff) | |
virtio_scsi: don't call virtqueue_add_sgs(... GFP_NOIO) holding spinlock.
This triggers every time we do a SCSI abort:
virtscsi_tmf -> virtscsi_kick_cmd (grab lock and call) -> virtscsi_add_cmd
-> virtqueue_add_sgs (GFP_NOIO)
Logs look like this:
sd 0:0:0:0: [sda] abort
BUG: sleeping function called from invalid context at mm/slub.c:966
in_atomic(): 1, irqs_disabled(): 1, pid: 6, name: kworker/u2:0
3 locks held by kworker/u2:0/6:
#0: ("scsi_tmf_%d"shost->host_no){......}, at: [<c0153180>] process_one_work+0xe0/0x3d0
#1: ((&(&cmd->abort_work)->work)){......}, at: [<c0153180>] process_one_work+0xe0/0x3d0
#2: (&(&virtscsi_vq->vq_lock)->rlock){......}, at: [<c043f508>] virtscsi_kick_cmd+0x18/0x1b0
CPU: 0 PID: 6 Comm: kworker/u2:0 Not tainted 3.15.0-rc5+ #110
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-rc1-0-gb1d4dc9-20140515_140003-nilsson.home.kraxel.org 04/01/2014
Workqueue: scsi_tmf_0 scmd_eh_abort_handler
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
| -rw-r--r-- | drivers/scsi/virtio_scsi.c | 15 |
1 files changed, 6 insertions, 9 deletions
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 16bfd50cd3fe..e2a68aece3da 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c | |||
| @@ -433,11 +433,10 @@ static void virtscsi_event_done(struct virtqueue *vq) | |||
| 433 | * @cmd : command structure | 433 | * @cmd : command structure |
| 434 | * @req_size : size of the request buffer | 434 | * @req_size : size of the request buffer |
| 435 | * @resp_size : size of the response buffer | 435 | * @resp_size : size of the response buffer |
| 436 | * @gfp : flags to use for memory allocations | ||
| 437 | */ | 436 | */ |
| 438 | static int virtscsi_add_cmd(struct virtqueue *vq, | 437 | static int virtscsi_add_cmd(struct virtqueue *vq, |
| 439 | struct virtio_scsi_cmd *cmd, | 438 | struct virtio_scsi_cmd *cmd, |
| 440 | size_t req_size, size_t resp_size, gfp_t gfp) | 439 | size_t req_size, size_t resp_size) |
| 441 | { | 440 | { |
| 442 | struct scsi_cmnd *sc = cmd->sc; | 441 | struct scsi_cmnd *sc = cmd->sc; |
| 443 | struct scatterlist *sgs[4], req, resp; | 442 | struct scatterlist *sgs[4], req, resp; |
| @@ -469,19 +468,19 @@ static int virtscsi_add_cmd(struct virtqueue *vq, | |||
| 469 | if (in) | 468 | if (in) |
| 470 | sgs[out_num + in_num++] = in->sgl; | 469 | sgs[out_num + in_num++] = in->sgl; |
| 471 | 470 | ||
| 472 | return virtqueue_add_sgs(vq, sgs, out_num, in_num, cmd, gfp); | 471 | return virtqueue_add_sgs(vq, sgs, out_num, in_num, cmd, GFP_ATOMIC); |
| 473 | } | 472 | } |
| 474 | 473 | ||
| 475 | static int virtscsi_kick_cmd(struct virtio_scsi_vq *vq, | 474 | static int virtscsi_kick_cmd(struct virtio_scsi_vq *vq, |
| 476 | struct virtio_scsi_cmd *cmd, | 475 | struct virtio_scsi_cmd *cmd, |
| 477 | size_t req_size, size_t resp_size, gfp_t gfp) | 476 | size_t req_size, size_t resp_size) |
| 478 | { | 477 | { |
| 479 | unsigned long flags; | 478 | unsigned long flags; |
| 480 | int err; | 479 | int err; |
| 481 | bool needs_kick = false; | 480 | bool needs_kick = false; |
| 482 | 481 | ||
| 483 | spin_lock_irqsave(&vq->vq_lock, flags); | 482 | spin_lock_irqsave(&vq->vq_lock, flags); |
| 484 | err = virtscsi_add_cmd(vq->vq, cmd, req_size, resp_size, gfp); | 483 | err = virtscsi_add_cmd(vq->vq, cmd, req_size, resp_size); |
| 485 | if (!err) | 484 | if (!err) |
| 486 | needs_kick = virtqueue_kick_prepare(vq->vq); | 485 | needs_kick = virtqueue_kick_prepare(vq->vq); |
| 487 | 486 | ||
| @@ -530,8 +529,7 @@ static int virtscsi_queuecommand(struct virtio_scsi *vscsi, | |||
| 530 | memcpy(cmd->req.cmd.cdb, sc->cmnd, sc->cmd_len); | 529 | memcpy(cmd->req.cmd.cdb, sc->cmnd, sc->cmd_len); |
| 531 | 530 | ||
| 532 | if (virtscsi_kick_cmd(req_vq, cmd, | 531 | if (virtscsi_kick_cmd(req_vq, cmd, |
| 533 | sizeof cmd->req.cmd, sizeof cmd->resp.cmd, | 532 | sizeof cmd->req.cmd, sizeof cmd->resp.cmd) == 0) |
| 534 | GFP_ATOMIC) == 0) | ||
| 535 | ret = 0; | 533 | ret = 0; |
| 536 | else | 534 | else |
| 537 | mempool_free(cmd, virtscsi_cmd_pool); | 535 | mempool_free(cmd, virtscsi_cmd_pool); |
| @@ -596,8 +594,7 @@ static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) | |||
| 596 | 594 | ||
| 597 | cmd->comp = ∁ | 595 | cmd->comp = ∁ |
| 598 | if (virtscsi_kick_cmd(&vscsi->ctrl_vq, cmd, | 596 | if (virtscsi_kick_cmd(&vscsi->ctrl_vq, cmd, |
| 599 | sizeof cmd->req.tmf, sizeof cmd->resp.tmf, | 597 | sizeof cmd->req.tmf, sizeof cmd->resp.tmf) < 0) |
| 600 | GFP_NOIO) < 0) | ||
| 601 | goto out; | 598 | goto out; |
| 602 | 599 | ||
| 603 | wait_for_completion(&comp); | 600 | wait_for_completion(&comp); |
