blob: 28d831a1b1aaa346aeca679bdcfaf086b21c14d5 [file] [log] [blame]
From foo@baz Sun Aug 26 09:13:00 CEST 2018
From: Josef Bacik <josef@toxicpanda.com>
Date: Mon, 16 Jul 2018 12:11:34 -0400
Subject: nbd: don't requeue the same request twice.
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit d7d94d48a272fd7583dc3c83acb8f5ed4ef456a4 ]
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>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/block/nbd.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -112,12 +112,15 @@ struct nbd_device {
struct task_struct *task_setup;
};
+#define NBD_CMD_REQUEUED 1
+
struct nbd_cmd {
struct nbd_device *nbd;
int index;
int cookie;
struct completion send_complete;
blk_status_t status;
+ unsigned long flags;
};
#if IS_ENABLED(CONFIG_DEBUG_FS)
@@ -146,6 +149,14 @@ static inline struct device *nbd_to_dev(
return disk_to_dev(nbd->disk);
}
+static void nbd_requeue_cmd(struct nbd_cmd *cmd)
+{
+ struct request *req = blk_mq_rq_from_pdu(cmd);
+
+ if (!test_and_set_bit(NBD_CMD_REQUEUED, &cmd->flags))
+ blk_mq_requeue_request(req, true);
+}
+
static const char *nbdcmd_to_ascii(int cmd)
{
switch (cmd) {
@@ -328,7 +339,7 @@ static enum blk_eh_timer_return nbd_xmit
nbd_mark_nsock_dead(nbd, nsock, 1);
mutex_unlock(&nsock->tx_lock);
}
- blk_mq_requeue_request(req, true);
+ nbd_requeue_cmd(cmd);
nbd_config_put(nbd);
return BLK_EH_NOT_HANDLED;
}
@@ -484,6 +495,7 @@ static int nbd_send_cmd(struct nbd_devic
nsock->pending = req;
nsock->sent = sent;
}
+ set_bit(NBD_CMD_REQUEUED, &cmd->flags);
return BLK_STS_RESOURCE;
}
dev_err_ratelimited(disk_to_dev(nbd->disk),
@@ -525,6 +537,7 @@ send_pages:
*/
nsock->pending = req;
nsock->sent = sent;
+ set_bit(NBD_CMD_REQUEUED, &cmd->flags);
return BLK_STS_RESOURCE;
}
dev_err(disk_to_dev(nbd->disk),
@@ -793,7 +806,7 @@ again:
*/
blk_mq_start_request(req);
if (unlikely(nsock->pending && nsock->pending != req)) {
- blk_mq_requeue_request(req, true);
+ nbd_requeue_cmd(cmd);
ret = 0;
goto out;
}
@@ -806,7 +819,7 @@ again:
dev_err_ratelimited(disk_to_dev(nbd->disk),
"Request send failed, requeueing\n");
nbd_mark_nsock_dead(nbd, nsock, 1);
- blk_mq_requeue_request(req, true);
+ nbd_requeue_cmd(cmd);
ret = 0;
}
out:
@@ -831,6 +844,7 @@ static blk_status_t nbd_queue_rq(struct
* done sending everything over the wire.
*/
init_completion(&cmd->send_complete);
+ clear_bit(NBD_CMD_REQUEUED, &cmd->flags);
/* We can be called directly from the user space process, which means we
* could possibly have signals pending so our sendmsg will fail. In
@@ -1446,6 +1460,7 @@ static int nbd_init_request(struct blk_m
{
struct nbd_cmd *cmd = blk_mq_rq_to_pdu(rq);
cmd->nbd = set->driver_data;
+ cmd->flags = 0;
return 0;
}