diff options
author | Josef Bacik <josef@toxicpanda.com> | 2018-07-16 12:11:34 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-07-16 12:14:39 -0400 |
commit | d7d94d48a272fd7583dc3c83acb8f5ed4ef456a4 (patch) | |
tree | 82545e7495d193b4f1e6794aae23e2dcfc7ad08b | |
parent | 70dbcc2254fa2a9add74a122b9dac954c4736e01 (diff) |
nbd: don't requeue the same request twice.
We can race with the snd timeout and the per-request timeout and end up
requeuing the same request twice. We can't use the send_complete
completion to tell if everything is ok because we hold the tx_lock
during send, so the timeout stuff will block waiting to mark the socket
dead, and we could be marked complete and still requeue. Instead add a
flag to the socket so we know whether we've been requeued yet.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | drivers/block/nbd.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 74a05561b620..f8cf7d4cca7f 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -112,12 +112,15 @@ struct nbd_device { | |||
112 | struct task_struct *task_setup; | 112 | struct task_struct *task_setup; |
113 | }; | 113 | }; |
114 | 114 | ||
115 | #define NBD_CMD_REQUEUED 1 | ||
116 | |||
115 | struct nbd_cmd { | 117 | struct nbd_cmd { |
116 | struct nbd_device *nbd; | 118 | struct nbd_device *nbd; |
117 | int index; | 119 | int index; |
118 | int cookie; | 120 | int cookie; |
119 | struct completion send_complete; | 121 | struct completion send_complete; |
120 | blk_status_t status; | 122 | blk_status_t status; |
123 | unsigned long flags; | ||
121 | }; | 124 | }; |
122 | 125 | ||
123 | #if IS_ENABLED(CONFIG_DEBUG_FS) | 126 | #if IS_ENABLED(CONFIG_DEBUG_FS) |
@@ -146,6 +149,14 @@ static inline struct device *nbd_to_dev(struct nbd_device *nbd) | |||
146 | return disk_to_dev(nbd->disk); | 149 | return disk_to_dev(nbd->disk); |
147 | } | 150 | } |
148 | 151 | ||
152 | static void nbd_requeue_cmd(struct nbd_cmd *cmd) | ||
153 | { | ||
154 | struct request *req = blk_mq_rq_from_pdu(cmd); | ||
155 | |||
156 | if (!test_and_set_bit(NBD_CMD_REQUEUED, &cmd->flags)) | ||
157 | blk_mq_requeue_request(req, true); | ||
158 | } | ||
159 | |||
149 | static const char *nbdcmd_to_ascii(int cmd) | 160 | static const char *nbdcmd_to_ascii(int cmd) |
150 | { | 161 | { |
151 | switch (cmd) { | 162 | switch (cmd) { |
@@ -343,7 +354,7 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req, | |||
343 | nbd_mark_nsock_dead(nbd, nsock, 1); | 354 | nbd_mark_nsock_dead(nbd, nsock, 1); |
344 | mutex_unlock(&nsock->tx_lock); | 355 | mutex_unlock(&nsock->tx_lock); |
345 | } | 356 | } |
346 | blk_mq_requeue_request(req, true); | 357 | nbd_requeue_cmd(cmd); |
347 | nbd_config_put(nbd); | 358 | nbd_config_put(nbd); |
348 | return BLK_EH_DONE; | 359 | return BLK_EH_DONE; |
349 | } | 360 | } |
@@ -500,6 +511,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) | |||
500 | nsock->pending = req; | 511 | nsock->pending = req; |
501 | nsock->sent = sent; | 512 | nsock->sent = sent; |
502 | } | 513 | } |
514 | set_bit(NBD_CMD_REQUEUED, &cmd->flags); | ||
503 | return BLK_STS_RESOURCE; | 515 | return BLK_STS_RESOURCE; |
504 | } | 516 | } |
505 | dev_err_ratelimited(disk_to_dev(nbd->disk), | 517 | dev_err_ratelimited(disk_to_dev(nbd->disk), |
@@ -541,6 +553,7 @@ send_pages: | |||
541 | */ | 553 | */ |
542 | nsock->pending = req; | 554 | nsock->pending = req; |
543 | nsock->sent = sent; | 555 | nsock->sent = sent; |
556 | set_bit(NBD_CMD_REQUEUED, &cmd->flags); | ||
544 | return BLK_STS_RESOURCE; | 557 | return BLK_STS_RESOURCE; |
545 | } | 558 | } |
546 | dev_err(disk_to_dev(nbd->disk), | 559 | dev_err(disk_to_dev(nbd->disk), |
@@ -805,7 +818,7 @@ again: | |||
805 | */ | 818 | */ |
806 | blk_mq_start_request(req); | 819 | blk_mq_start_request(req); |
807 | if (unlikely(nsock->pending && nsock->pending != req)) { | 820 | if (unlikely(nsock->pending && nsock->pending != req)) { |
808 | blk_mq_requeue_request(req, true); | 821 | nbd_requeue_cmd(cmd); |
809 | ret = 0; | 822 | ret = 0; |
810 | goto out; | 823 | goto out; |
811 | } | 824 | } |
@@ -818,7 +831,7 @@ again: | |||
818 | dev_err_ratelimited(disk_to_dev(nbd->disk), | 831 | dev_err_ratelimited(disk_to_dev(nbd->disk), |
819 | "Request send failed, requeueing\n"); | 832 | "Request send failed, requeueing\n"); |
820 | nbd_mark_nsock_dead(nbd, nsock, 1); | 833 | nbd_mark_nsock_dead(nbd, nsock, 1); |
821 | blk_mq_requeue_request(req, true); | 834 | nbd_requeue_cmd(cmd); |
822 | ret = 0; | 835 | ret = 0; |
823 | } | 836 | } |
824 | out: | 837 | out: |
@@ -843,6 +856,7 @@ static blk_status_t nbd_queue_rq(struct blk_mq_hw_ctx *hctx, | |||
843 | * done sending everything over the wire. | 856 | * done sending everything over the wire. |
844 | */ | 857 | */ |
845 | init_completion(&cmd->send_complete); | 858 | init_completion(&cmd->send_complete); |
859 | clear_bit(NBD_CMD_REQUEUED, &cmd->flags); | ||
846 | 860 | ||
847 | /* We can be called directly from the user space process, which means we | 861 | /* We can be called directly from the user space process, which means we |
848 | * could possibly have signals pending so our sendmsg will fail. In | 862 | * could possibly have signals pending so our sendmsg will fail. In |
@@ -1460,6 +1474,7 @@ static int nbd_init_request(struct blk_mq_tag_set *set, struct request *rq, | |||
1460 | { | 1474 | { |
1461 | struct nbd_cmd *cmd = blk_mq_rq_to_pdu(rq); | 1475 | struct nbd_cmd *cmd = blk_mq_rq_to_pdu(rq); |
1462 | cmd->nbd = set->driver_data; | 1476 | cmd->nbd = set->driver_data; |
1477 | cmd->flags = 0; | ||
1463 | return 0; | 1478 | return 0; |
1464 | } | 1479 | } |
1465 | 1480 | ||