linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] io_uring : correct timeout req sequence when waiting timeout
@ 2019-10-23  7:10 zhangyi (F)
  2019-10-23  7:10 ` [PATCH 2/2] io_uring: correct timeout req sequence when inserting a new entry zhangyi (F)
  2019-10-24  3:41 ` [PATCH 1/2] io_uring : correct timeout req sequence when waiting timeout Jens Axboe
  0 siblings, 2 replies; 3+ messages in thread
From: zhangyi (F) @ 2019-10-23  7:10 UTC (permalink / raw)
  To: axboe, linux-block; +Cc: yi.zhang, yangerkun

The sequence number of reqs on the timeout_list before the timeout req
should be adjusted in io_timeout_fn(), because the current timeout req
will consumes a slot in the cq_ring and cq_tail pointer will be
increased, otherwise other timeout reqs may return in advance without
waiting for enough wait_nr.

Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
---
 fs/io_uring.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index 67dbe0201e0d..e7a856392a23 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -1877,7 +1877,7 @@ static int io_poll_add(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 static enum hrtimer_restart io_timeout_fn(struct hrtimer *timer)
 {
 	struct io_ring_ctx *ctx;
-	struct io_kiocb *req;
+	struct io_kiocb *req, *prev;
 	unsigned long flags;
 
 	req = container_of(timer, struct io_kiocb, timeout.timer);
@@ -1885,6 +1885,15 @@ static enum hrtimer_restart io_timeout_fn(struct hrtimer *timer)
 	atomic_inc(&ctx->cq_timeouts);
 
 	spin_lock_irqsave(&ctx->completion_lock, flags);
+	/*
+	 * Adjust the reqs sequence before the current one because it
+	 * will consume a slot in the cq_ring and the the cq_tail pointer
+	 * will be increased, otherwise other timeout reqs may return in
+	 * advance without waiting for enough wait_nr.
+	 */
+	prev = req;
+	list_for_each_entry_continue_reverse(prev, &ctx->timeout_list, list)
+		prev->sequence++;
 	list_del(&req->list);
 
 	io_cqring_fill_event(ctx, req->user_data, -ETIME);
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] io_uring: correct timeout req sequence when inserting a new entry
  2019-10-23  7:10 [PATCH 1/2] io_uring : correct timeout req sequence when waiting timeout zhangyi (F)
@ 2019-10-23  7:10 ` zhangyi (F)
  2019-10-24  3:41 ` [PATCH 1/2] io_uring : correct timeout req sequence when waiting timeout Jens Axboe
  1 sibling, 0 replies; 3+ messages in thread
From: zhangyi (F) @ 2019-10-23  7:10 UTC (permalink / raw)
  To: axboe, linux-block; +Cc: yi.zhang, yangerkun

The sequence number of the timeout req (req->sequence) indicate the
expected completion request. Because of each timeout req consume a
sequence number, so the sequence of each timeout req on the timeout
list shouldn't be the same. But now, we may get the same number (also
incorrect) if we insert a new entry before the last one, such as submit
such two timeout reqs on a new ring instance below.

                    req->sequence
 req_1 (count = 2):       2
 req_2 (count = 1):       2

Then, if we submit a nop req, req_2 will still timeout even the nop req
finished. This patch fix this problem by adjust the sequence number of
each reordered reqs when inserting a new entry.

Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
---
 fs/io_uring.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index e7a856392a23..4a395a7a36c1 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -1912,6 +1912,7 @@ static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 	struct io_ring_ctx *ctx = req->ctx;
 	struct list_head *entry;
 	struct timespec64 ts;
+	unsigned span = 0;
 
 	if (unlikely(ctx->flags & IORING_SETUP_IOPOLL))
 		return -EINVAL;
@@ -1960,9 +1961,17 @@ static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 		if (ctx->cached_sq_head < nxt_sq_head)
 			tmp += UINT_MAX;
 
-		if (tmp >= tmp_nxt)
+		if (tmp > tmp_nxt)
 			break;
+
+		/*
+		 * Sequence of reqs after the insert one and itself should
+		 * be adjusted because each timeout req consumes a slot.
+		 */
+		span++;
+		nxt->sequence++;
 	}
+	req->sequence -= span;
 	list_add(&req->list, entry);
 	spin_unlock_irq(&ctx->completion_lock);
 
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/2] io_uring : correct timeout req sequence when waiting timeout
  2019-10-23  7:10 [PATCH 1/2] io_uring : correct timeout req sequence when waiting timeout zhangyi (F)
  2019-10-23  7:10 ` [PATCH 2/2] io_uring: correct timeout req sequence when inserting a new entry zhangyi (F)
@ 2019-10-24  3:41 ` Jens Axboe
  1 sibling, 0 replies; 3+ messages in thread
From: Jens Axboe @ 2019-10-24  3:41 UTC (permalink / raw)
  To: zhangyi (F), linux-block; +Cc: yangerkun

On 10/23/19 1:10 AM, zhangyi (F) wrote:
> The sequence number of reqs on the timeout_list before the timeout req
> should be adjusted in io_timeout_fn(), because the current timeout req
> will consumes a slot in the cq_ring and cq_tail pointer will be
> increased, otherwise other timeout reqs may return in advance without
> waiting for enough wait_nr.

Thanks, applied both patches. Will run them through some extra testing
tomorrow, but looks good so far.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-10-24  3:41 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-23  7:10 [PATCH 1/2] io_uring : correct timeout req sequence when waiting timeout zhangyi (F)
2019-10-23  7:10 ` [PATCH 2/2] io_uring: correct timeout req sequence when inserting a new entry zhangyi (F)
2019-10-24  3:41 ` [PATCH 1/2] io_uring : correct timeout req sequence when waiting timeout Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).