linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [BUG] io_uring: defer logic based on shared data
@ 2019-10-25  9:55 Pavel Begunkov
  2019-10-25 16:03 ` Jens Axboe
  0 siblings, 1 reply; 13+ messages in thread
From: Pavel Begunkov @ 2019-10-25  9:55 UTC (permalink / raw)
  To: Jens Axboe, linux-block, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 343 bytes --]

I found 2 problems with __io_sequence_defer().

1. it uses @sq_dropped, but doesn't consider @cq_overflow
2. @sq_dropped and @cq_overflow are write-shared with userspace, so
it can be maliciously changed.

see sent liburing test (test/defer *_hung()), which left an unkillable
process for me

-- 
Yours sincerely,
Pavel Begunkov


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [BUG] io_uring: defer logic based on shared data
  2019-10-25  9:55 [BUG] io_uring: defer logic based on shared data Pavel Begunkov
@ 2019-10-25 16:03 ` Jens Axboe
  2019-10-25 16:09   ` Jens Axboe
  2019-10-25 16:21   ` Pavel Begunkov
  0 siblings, 2 replies; 13+ messages in thread
From: Jens Axboe @ 2019-10-25 16:03 UTC (permalink / raw)
  To: Pavel Begunkov, linux-block, linux-kernel

On 10/25/19 3:55 AM, Pavel Begunkov wrote:
> I found 2 problems with __io_sequence_defer().
> 
> 1. it uses @sq_dropped, but doesn't consider @cq_overflow
> 2. @sq_dropped and @cq_overflow are write-shared with userspace, so
> it can be maliciously changed.
> 
> see sent liburing test (test/defer *_hung()), which left an unkillable
> process for me

OK, how about the below. I'll split this in two, as it's really two
separate fixes.


diff --git a/fs/io_uring.c b/fs/io_uring.c
index 5d10984381cf..5d9d960c1c17 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -191,6 +191,7 @@ struct io_ring_ctx {
 		unsigned		sq_entries;
 		unsigned		sq_mask;
 		unsigned		sq_thread_idle;
+		unsigned		cached_sq_dropped;
 		struct io_uring_sqe	*sq_sqes;
 
 		struct list_head	defer_list;
@@ -208,6 +209,7 @@ struct io_ring_ctx {
 
 	struct {
 		unsigned		cached_cq_tail;
+		unsigned		cached_cq_overflow;
 		unsigned		cq_entries;
 		unsigned		cq_mask;
 		struct wait_queue_head	cq_wait;
@@ -419,7 +421,8 @@ static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
 static inline bool __io_sequence_defer(struct io_ring_ctx *ctx,
 				       struct io_kiocb *req)
 {
-	return req->sequence != ctx->cached_cq_tail + ctx->rings->sq_dropped;
+	return req->sequence != ctx->cached_cq_tail + ctx->cached_sq_dropped
+					+ ctx->cached_cq_overflow;
 }
 
 static inline bool io_sequence_defer(struct io_ring_ctx *ctx,
@@ -590,9 +593,8 @@ static void io_cqring_fill_event(struct io_ring_ctx *ctx, u64 ki_user_data,
 		WRITE_ONCE(cqe->res, res);
 		WRITE_ONCE(cqe->flags, 0);
 	} else {
-		unsigned overflow = READ_ONCE(ctx->rings->cq_overflow);
-
-		WRITE_ONCE(ctx->rings->cq_overflow, overflow + 1);
+		ctx->cached_cq_overflow++;
+		WRITE_ONCE(ctx->rings->cq_overflow, ctx->cached_cq_overflow);
 	}
 }
 
@@ -2601,7 +2603,8 @@ static bool io_get_sqring(struct io_ring_ctx *ctx, struct sqe_submit *s)
 
 	/* drop invalid entries */
 	ctx->cached_sq_head++;
-	rings->sq_dropped++;
+	ctx->cached_sq_dropped++;
+	WRITE_ONCE(rings->sq_dropped, ctx->cached_sq_dropped);
 	return false;
 }
 
@@ -2685,6 +2688,7 @@ static int io_sq_thread(void *data)
 
 	timeout = inflight = 0;
 	while (!kthread_should_park()) {
+		unsigned prev_cq, cur_cq;
 		bool mm_fault = false;
 		unsigned int to_submit;
 
@@ -2767,8 +2771,12 @@ static int io_sq_thread(void *data)
 		}
 
 		to_submit = min(to_submit, ctx->sq_entries);
+		prev_cq = ctx->cached_cq_tail + ctx->cached_cq_overflow;
 		inflight += io_submit_sqes(ctx, to_submit, cur_mm != NULL,
 					   mm_fault);
+		cur_cq = ctx->cached_cq_tail + ctx->cached_cq_overflow;
+		if ((ctx->flags & IORING_SETUP_IOPOLL) && (prev_cq != cur_cq))
+			inflight -= cur_cq - prev_cq;
 
 		/* Commit SQ ring head once we've consumed all SQEs */
 		io_commit_sqring(ctx);

-- 
Jens Axboe


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

* Re: [BUG] io_uring: defer logic based on shared data
  2019-10-25 16:03 ` Jens Axboe
@ 2019-10-25 16:09   ` Jens Axboe
  2019-10-25 16:21     ` Jens Axboe
  2019-10-25 16:21   ` Pavel Begunkov
  1 sibling, 1 reply; 13+ messages in thread
From: Jens Axboe @ 2019-10-25 16:09 UTC (permalink / raw)
  To: Pavel Begunkov, linux-block, linux-kernel

On 10/25/19 10:03 AM, Jens Axboe wrote:
> On 10/25/19 3:55 AM, Pavel Begunkov wrote:
>> I found 2 problems with __io_sequence_defer().
>>
>> 1. it uses @sq_dropped, but doesn't consider @cq_overflow
>> 2. @sq_dropped and @cq_overflow are write-shared with userspace, so
>> it can be maliciously changed.
>>
>> see sent liburing test (test/defer *_hung()), which left an unkillable
>> process for me
> 
> OK, how about the below. I'll split this in two, as it's really two
> separate fixes.

Patch 1:

http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=9a9a21d9cf65cb621cce4052a4527868a80009ad

and patch 2:

http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=ed348662f74c4f63537b3c188585e39cdea22713

Let me know what you think, and if/when I can add your reviewed/test-by
to them.

-- 
Jens Axboe


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

* Re: [BUG] io_uring: defer logic based on shared data
  2019-10-25 16:03 ` Jens Axboe
  2019-10-25 16:09   ` Jens Axboe
@ 2019-10-25 16:21   ` Pavel Begunkov
  2019-10-25 16:27     ` Jens Axboe
  1 sibling, 1 reply; 13+ messages in thread
From: Pavel Begunkov @ 2019-10-25 16:21 UTC (permalink / raw)
  To: Jens Axboe, linux-block, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 3294 bytes --]

On 25/10/2019 19:03, Jens Axboe wrote:
> On 10/25/19 3:55 AM, Pavel Begunkov wrote:
>> I found 2 problems with __io_sequence_defer().
>>
>> 1. it uses @sq_dropped, but doesn't consider @cq_overflow
>> 2. @sq_dropped and @cq_overflow are write-shared with userspace, so
>> it can be maliciously changed.
>>
>> see sent liburing test (test/defer *_hung()), which left an unkillable
>> process for me
> 
> OK, how about the below. I'll split this in two, as it's really two
> separate fixes.
cached_sq_dropped is good, but I was concerned about cached_cq_overflow.
io_cqring_fill_event() can be called in async, so shouldn't we do some
synchronisation then?

> 
> 
> diff --git a/fs/io_uring.c b/fs/io_uring.c
> index 5d10984381cf..5d9d960c1c17 100644
> --- a/fs/io_uring.c
> +++ b/fs/io_uring.c
> @@ -191,6 +191,7 @@ struct io_ring_ctx {
>  		unsigned		sq_entries;
>  		unsigned		sq_mask;
>  		unsigned		sq_thread_idle;
> +		unsigned		cached_sq_dropped;
>  		struct io_uring_sqe	*sq_sqes;
>  
>  		struct list_head	defer_list;
> @@ -208,6 +209,7 @@ struct io_ring_ctx {
>  
>  	struct {
>  		unsigned		cached_cq_tail;
> +		unsigned		cached_cq_overflow;
>  		unsigned		cq_entries;
>  		unsigned		cq_mask;
>  		struct wait_queue_head	cq_wait;
> @@ -419,7 +421,8 @@ static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
>  static inline bool __io_sequence_defer(struct io_ring_ctx *ctx,
>  				       struct io_kiocb *req)
>  {
> -	return req->sequence != ctx->cached_cq_tail + ctx->rings->sq_dropped;
> +	return req->sequence != ctx->cached_cq_tail + ctx->cached_sq_dropped
> +					+ ctx->cached_cq_overflow;
>  }
>  
>  static inline bool io_sequence_defer(struct io_ring_ctx *ctx,
> @@ -590,9 +593,8 @@ static void io_cqring_fill_event(struct io_ring_ctx *ctx, u64 ki_user_data,
>  		WRITE_ONCE(cqe->res, res);
>  		WRITE_ONCE(cqe->flags, 0);
>  	} else {
> -		unsigned overflow = READ_ONCE(ctx->rings->cq_overflow);
> -
> -		WRITE_ONCE(ctx->rings->cq_overflow, overflow + 1);
> +		ctx->cached_cq_overflow++;
> +		WRITE_ONCE(ctx->rings->cq_overflow, ctx->cached_cq_overflow);
>  	}
>  }
>  
> @@ -2601,7 +2603,8 @@ static bool io_get_sqring(struct io_ring_ctx *ctx, struct sqe_submit *s)
>  
>  	/* drop invalid entries */
>  	ctx->cached_sq_head++;
> -	rings->sq_dropped++;
> +	ctx->cached_sq_dropped++;
> +	WRITE_ONCE(rings->sq_dropped, ctx->cached_sq_dropped);
>  	return false;
>  }
>  
> @@ -2685,6 +2688,7 @@ static int io_sq_thread(void *data)
>  
>  	timeout = inflight = 0;
>  	while (!kthread_should_park()) {
> +		unsigned prev_cq, cur_cq;
>  		bool mm_fault = false;
>  		unsigned int to_submit;
>  
> @@ -2767,8 +2771,12 @@ static int io_sq_thread(void *data)
>  		}
>  
>  		to_submit = min(to_submit, ctx->sq_entries);
> +		prev_cq = ctx->cached_cq_tail + ctx->cached_cq_overflow;
>  		inflight += io_submit_sqes(ctx, to_submit, cur_mm != NULL,
>  					   mm_fault);
> +		cur_cq = ctx->cached_cq_tail + ctx->cached_cq_overflow;
> +		if ((ctx->flags & IORING_SETUP_IOPOLL) && (prev_cq != cur_cq))
> +			inflight -= cur_cq - prev_cq;
>  
>  		/* Commit SQ ring head once we've consumed all SQEs */
>  		io_commit_sqring(ctx);
> 

-- 
Yours sincerely,
Pavel Begunkov


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [BUG] io_uring: defer logic based on shared data
  2019-10-25 16:09   ` Jens Axboe
@ 2019-10-25 16:21     ` Jens Axboe
  0 siblings, 0 replies; 13+ messages in thread
From: Jens Axboe @ 2019-10-25 16:21 UTC (permalink / raw)
  To: Pavel Begunkov, linux-block, linux-kernel

On 10/25/19 10:09 AM, Jens Axboe wrote:
> On 10/25/19 10:03 AM, Jens Axboe wrote:
>> On 10/25/19 3:55 AM, Pavel Begunkov wrote:
>>> I found 2 problems with __io_sequence_defer().
>>>
>>> 1. it uses @sq_dropped, but doesn't consider @cq_overflow
>>> 2. @sq_dropped and @cq_overflow are write-shared with userspace, so
>>> it can be maliciously changed.
>>>
>>> see sent liburing test (test/defer *_hung()), which left an unkillable
>>> process for me
>>
>> OK, how about the below. I'll split this in two, as it's really two
>> separate fixes.
> 
> Patch 1:
> 
> http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=9a9a21d9cf65cb621cce4052a4527868a80009ad
> 
> and patch 2:
> 
> http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=ed348662f74c4f63537b3c188585e39cdea22713
> 
> Let me know what you think, and if/when I can add your reviewed/test-by
> to them.

Updated patch 2 as per the other discussion, here it is:

http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=b6c2c446c0fca0318dec904821bd11f52d2445d3


-- 
Jens Axboe


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

* Re: [BUG] io_uring: defer logic based on shared data
  2019-10-25 16:21   ` Pavel Begunkov
@ 2019-10-25 16:27     ` Jens Axboe
  2019-10-25 16:32       ` Jens Axboe
  0 siblings, 1 reply; 13+ messages in thread
From: Jens Axboe @ 2019-10-25 16:27 UTC (permalink / raw)
  To: Pavel Begunkov, linux-block, linux-kernel

On 10/25/19 10:21 AM, Pavel Begunkov wrote:
> On 25/10/2019 19:03, Jens Axboe wrote:
>> On 10/25/19 3:55 AM, Pavel Begunkov wrote:
>>> I found 2 problems with __io_sequence_defer().
>>>
>>> 1. it uses @sq_dropped, but doesn't consider @cq_overflow
>>> 2. @sq_dropped and @cq_overflow are write-shared with userspace, so
>>> it can be maliciously changed.
>>>
>>> see sent liburing test (test/defer *_hung()), which left an unkillable
>>> process for me
>>
>> OK, how about the below. I'll split this in two, as it's really two
>> separate fixes.
> cached_sq_dropped is good, but I was concerned about cached_cq_overflow.
> io_cqring_fill_event() can be called in async, so shouldn't we do some
> synchronisation then?

We should probably make it an atomic just to be on the safe side, I'll
update the series.

-- 
Jens Axboe


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

* Re: [BUG] io_uring: defer logic based on shared data
  2019-10-25 16:27     ` Jens Axboe
@ 2019-10-25 16:32       ` Jens Axboe
  2019-10-25 16:40         ` Pavel Begunkov
  0 siblings, 1 reply; 13+ messages in thread
From: Jens Axboe @ 2019-10-25 16:32 UTC (permalink / raw)
  To: Pavel Begunkov, linux-block, linux-kernel

On 10/25/19 10:27 AM, Jens Axboe wrote:
> On 10/25/19 10:21 AM, Pavel Begunkov wrote:
>> On 25/10/2019 19:03, Jens Axboe wrote:
>>> On 10/25/19 3:55 AM, Pavel Begunkov wrote:
>>>> I found 2 problems with __io_sequence_defer().
>>>>
>>>> 1. it uses @sq_dropped, but doesn't consider @cq_overflow
>>>> 2. @sq_dropped and @cq_overflow are write-shared with userspace, so
>>>> it can be maliciously changed.
>>>>
>>>> see sent liburing test (test/defer *_hung()), which left an unkillable
>>>> process for me
>>>
>>> OK, how about the below. I'll split this in two, as it's really two
>>> separate fixes.
>> cached_sq_dropped is good, but I was concerned about cached_cq_overflow.
>> io_cqring_fill_event() can be called in async, so shouldn't we do some
>> synchronisation then?
> 
> We should probably make it an atomic just to be on the safe side, I'll
> update the series.

Here we go, patch 1:

http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=f2a241f596ed9e12b7c8f960e79ccda8053ea294

patch 2:

http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=b7d0297d2df5bfa0d1ecf9d6c66d23676751ef6a

-- 
Jens Axboe


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

* Re: [BUG] io_uring: defer logic based on shared data
  2019-10-25 16:32       ` Jens Axboe
@ 2019-10-25 16:40         ` Pavel Begunkov
  2019-10-25 16:44           ` Jens Axboe
  0 siblings, 1 reply; 13+ messages in thread
From: Pavel Begunkov @ 2019-10-25 16:40 UTC (permalink / raw)
  To: Jens Axboe, linux-block, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 1493 bytes --]

On 25/10/2019 19:32, Jens Axboe wrote:
> On 10/25/19 10:27 AM, Jens Axboe wrote:
>> On 10/25/19 10:21 AM, Pavel Begunkov wrote:
>>> On 25/10/2019 19:03, Jens Axboe wrote:
>>>> On 10/25/19 3:55 AM, Pavel Begunkov wrote:
>>>>> I found 2 problems with __io_sequence_defer().
>>>>>
>>>>> 1. it uses @sq_dropped, but doesn't consider @cq_overflow
>>>>> 2. @sq_dropped and @cq_overflow are write-shared with userspace, so
>>>>> it can be maliciously changed.
>>>>>
>>>>> see sent liburing test (test/defer *_hung()), which left an unkillable
>>>>> process for me
>>>>
>>>> OK, how about the below. I'll split this in two, as it's really two
>>>> separate fixes.
>>> cached_sq_dropped is good, but I was concerned about cached_cq_overflow.
>>> io_cqring_fill_event() can be called in async, so shouldn't we do some
>>> synchronisation then?
>>
>> We should probably make it an atomic just to be on the safe side, I'll
>> update the series.
> 
> Here we go, patch 1:
> 
> http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=f2a241f596ed9e12b7c8f960e79ccda8053ea294
> 
> patch 2:
> 
> http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=b7d0297d2df5bfa0d1ecf9d6c66d23676751ef6a
> 
1. submit rqs (not yet completed)
2. poll_list is empty, inflight = 0
3. async completed and placed into poll_list

So, poll_list is not empty, but we won't get to polling again.
At least until someone submitted something.

-- 
Yours sincerely,
Pavel Begunkov


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [BUG] io_uring: defer logic based on shared data
  2019-10-25 16:40         ` Pavel Begunkov
@ 2019-10-25 16:44           ` Jens Axboe
  2019-10-25 16:55             ` Pavel Begunkov
  0 siblings, 1 reply; 13+ messages in thread
From: Jens Axboe @ 2019-10-25 16:44 UTC (permalink / raw)
  To: Pavel Begunkov, linux-block, linux-kernel

On 10/25/19 10:40 AM, Pavel Begunkov wrote:
> On 25/10/2019 19:32, Jens Axboe wrote:
>> On 10/25/19 10:27 AM, Jens Axboe wrote:
>>> On 10/25/19 10:21 AM, Pavel Begunkov wrote:
>>>> On 25/10/2019 19:03, Jens Axboe wrote:
>>>>> On 10/25/19 3:55 AM, Pavel Begunkov wrote:
>>>>>> I found 2 problems with __io_sequence_defer().
>>>>>>
>>>>>> 1. it uses @sq_dropped, but doesn't consider @cq_overflow
>>>>>> 2. @sq_dropped and @cq_overflow are write-shared with userspace, so
>>>>>> it can be maliciously changed.
>>>>>>
>>>>>> see sent liburing test (test/defer *_hung()), which left an unkillable
>>>>>> process for me
>>>>>
>>>>> OK, how about the below. I'll split this in two, as it's really two
>>>>> separate fixes.
>>>> cached_sq_dropped is good, but I was concerned about cached_cq_overflow.
>>>> io_cqring_fill_event() can be called in async, so shouldn't we do some
>>>> synchronisation then?
>>>
>>> We should probably make it an atomic just to be on the safe side, I'll
>>> update the series.
>>
>> Here we go, patch 1:
>>
>> http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=f2a241f596ed9e12b7c8f960e79ccda8053ea294
>>
>> patch 2:
>>
>> http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=b7d0297d2df5bfa0d1ecf9d6c66d23676751ef6a
>>
> 1. submit rqs (not yet completed)
> 2. poll_list is empty, inflight = 0
> 3. async completed and placed into poll_list
> 
> So, poll_list is not empty, but we won't get to polling again.
> At least until someone submitted something.

But if they are issued, the will sit in ->poll_list as well. That list
holds both "submitted, but pending" and completed entries.

-- 
Jens Axboe


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

* Re: [BUG] io_uring: defer logic based on shared data
  2019-10-25 16:44           ` Jens Axboe
@ 2019-10-25 16:55             ` Pavel Begunkov
  2019-10-25 16:57               ` Jens Axboe
  0 siblings, 1 reply; 13+ messages in thread
From: Pavel Begunkov @ 2019-10-25 16:55 UTC (permalink / raw)
  To: Jens Axboe, linux-block, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 2086 bytes --]

On 25/10/2019 19:44, Jens Axboe wrote:
> On 10/25/19 10:40 AM, Pavel Begunkov wrote:
>> On 25/10/2019 19:32, Jens Axboe wrote:
>>> On 10/25/19 10:27 AM, Jens Axboe wrote:
>>>> On 10/25/19 10:21 AM, Pavel Begunkov wrote:
>>>>> On 25/10/2019 19:03, Jens Axboe wrote:
>>>>>> On 10/25/19 3:55 AM, Pavel Begunkov wrote:
>>>>>>> I found 2 problems with __io_sequence_defer().
>>>>>>>
>>>>>>> 1. it uses @sq_dropped, but doesn't consider @cq_overflow
>>>>>>> 2. @sq_dropped and @cq_overflow are write-shared with userspace, so
>>>>>>> it can be maliciously changed.
>>>>>>>
>>>>>>> see sent liburing test (test/defer *_hung()), which left an unkillable
>>>>>>> process for me
>>>>>>
>>>>>> OK, how about the below. I'll split this in two, as it's really two
>>>>>> separate fixes.
>>>>> cached_sq_dropped is good, but I was concerned about cached_cq_overflow.
>>>>> io_cqring_fill_event() can be called in async, so shouldn't we do some
>>>>> synchronisation then?
>>>>
>>>> We should probably make it an atomic just to be on the safe side, I'll
>>>> update the series.
>>>
>>> Here we go, patch 1:
>>>
>>> http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=f2a241f596ed9e12b7c8f960e79ccda8053ea294
>>>
>>> patch 2:
>>>
>>> http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=b7d0297d2df5bfa0d1ecf9d6c66d23676751ef6a
>>>
>> 1. submit rqs (not yet completed)
>> 2. poll_list is empty, inflight = 0
>> 3. async completed and placed into poll_list
>>
>> So, poll_list is not empty, but we won't get to polling again.
>> At least until someone submitted something.
> 
> But if they are issued, the will sit in ->poll_list as well. That list
> holds both "submitted, but pending" and completed entries.
> 
Missed it, then should work. Thanks!

> + ret = iters = 0;
A small suggestion, could we just initialise it in declaration
to be a bit more concise?
e.g. int ret = 0, iters = 0; 

Reviewed-by: Pavel Begunkov <asml.silence@gmail.com>
And let me test it as both patches are ready.

-- 
Yours sincerely,
Pavel Begunkov


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [BUG] io_uring: defer logic based on shared data
  2019-10-25 16:55             ` Pavel Begunkov
@ 2019-10-25 16:57               ` Jens Axboe
  2019-10-25 18:13                 ` Pavel Begunkov
  0 siblings, 1 reply; 13+ messages in thread
From: Jens Axboe @ 2019-10-25 16:57 UTC (permalink / raw)
  To: Pavel Begunkov, linux-block, linux-kernel

On 10/25/19 10:55 AM, Pavel Begunkov wrote:
> On 25/10/2019 19:44, Jens Axboe wrote:
>> On 10/25/19 10:40 AM, Pavel Begunkov wrote:
>>> On 25/10/2019 19:32, Jens Axboe wrote:
>>>> On 10/25/19 10:27 AM, Jens Axboe wrote:
>>>>> On 10/25/19 10:21 AM, Pavel Begunkov wrote:
>>>>>> On 25/10/2019 19:03, Jens Axboe wrote:
>>>>>>> On 10/25/19 3:55 AM, Pavel Begunkov wrote:
>>>>>>>> I found 2 problems with __io_sequence_defer().
>>>>>>>>
>>>>>>>> 1. it uses @sq_dropped, but doesn't consider @cq_overflow
>>>>>>>> 2. @sq_dropped and @cq_overflow are write-shared with userspace, so
>>>>>>>> it can be maliciously changed.
>>>>>>>>
>>>>>>>> see sent liburing test (test/defer *_hung()), which left an unkillable
>>>>>>>> process for me
>>>>>>>
>>>>>>> OK, how about the below. I'll split this in two, as it's really two
>>>>>>> separate fixes.
>>>>>> cached_sq_dropped is good, but I was concerned about cached_cq_overflow.
>>>>>> io_cqring_fill_event() can be called in async, so shouldn't we do some
>>>>>> synchronisation then?
>>>>>
>>>>> We should probably make it an atomic just to be on the safe side, I'll
>>>>> update the series.
>>>>
>>>> Here we go, patch 1:
>>>>
>>>> http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=f2a241f596ed9e12b7c8f960e79ccda8053ea294
>>>>
>>>> patch 2:
>>>>
>>>> http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=b7d0297d2df5bfa0d1ecf9d6c66d23676751ef6a
>>>>
>>> 1. submit rqs (not yet completed)
>>> 2. poll_list is empty, inflight = 0
>>> 3. async completed and placed into poll_list
>>>
>>> So, poll_list is not empty, but we won't get to polling again.
>>> At least until someone submitted something.
>>
>> But if they are issued, the will sit in ->poll_list as well. That list
>> holds both "submitted, but pending" and completed entries.
>>
> Missed it, then should work. Thanks!

Glad we agree :-)

>> + ret = iters = 0;
> A small suggestion, could we just initialise it in declaration
> to be a bit more concise?
> e.g. int ret = 0, iters = 0;
> 
> Reviewed-by: Pavel Begunkov <asml.silence@gmail.com>
> And let me test it as both patches are ready.

Sure, I'll make that change and add your reviewed-by. Thanks!

-- 
Jens Axboe


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

* Re: [BUG] io_uring: defer logic based on shared data
  2019-10-25 16:57               ` Jens Axboe
@ 2019-10-25 18:13                 ` Pavel Begunkov
  2019-10-25 18:17                   ` Jens Axboe
  0 siblings, 1 reply; 13+ messages in thread
From: Pavel Begunkov @ 2019-10-25 18:13 UTC (permalink / raw)
  To: Jens Axboe, linux-block, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 2461 bytes --]

On 25/10/2019 19:57, Jens Axboe wrote:
> On 10/25/19 10:55 AM, Pavel Begunkov wrote:
>> On 25/10/2019 19:44, Jens Axboe wrote:
>>> On 10/25/19 10:40 AM, Pavel Begunkov wrote:
>>>> On 25/10/2019 19:32, Jens Axboe wrote:
>>>>> On 10/25/19 10:27 AM, Jens Axboe wrote:
>>>>>> On 10/25/19 10:21 AM, Pavel Begunkov wrote:
>>>>>>> On 25/10/2019 19:03, Jens Axboe wrote:
>>>>>>>> On 10/25/19 3:55 AM, Pavel Begunkov wrote:
>>>>>>>>> I found 2 problems with __io_sequence_defer().
>>>>>>>>>
>>>>>>>>> 1. it uses @sq_dropped, but doesn't consider @cq_overflow
>>>>>>>>> 2. @sq_dropped and @cq_overflow are write-shared with userspace, so
>>>>>>>>> it can be maliciously changed.
>>>>>>>>>
>>>>>>>>> see sent liburing test (test/defer *_hung()), which left an unkillable
>>>>>>>>> process for me
>>>>>>>>
>>>>>>>> OK, how about the below. I'll split this in two, as it's really two
>>>>>>>> separate fixes.
>>>>>>> cached_sq_dropped is good, but I was concerned about cached_cq_overflow.
>>>>>>> io_cqring_fill_event() can be called in async, so shouldn't we do some
>>>>>>> synchronisation then?
>>>>>>
>>>>>> We should probably make it an atomic just to be on the safe side, I'll
>>>>>> update the series.
>>>>>
>>>>> Here we go, patch 1:
>>>>>
>>>>> http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=f2a241f596ed9e12b7c8f960e79ccda8053ea294
>>>>>
>>>>> patch 2:
>>>>>
>>>>> http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=b7d0297d2df5bfa0d1ecf9d6c66d23676751ef6a
>>>>>
>>>> 1. submit rqs (not yet completed)
>>>> 2. poll_list is empty, inflight = 0
>>>> 3. async completed and placed into poll_list
>>>>
>>>> So, poll_list is not empty, but we won't get to polling again.
>>>> At least until someone submitted something.
>>>
>>> But if they are issued, the will sit in ->poll_list as well. That list
>>> holds both "submitted, but pending" and completed entries.
>>>
>> Missed it, then should work. Thanks!
> 
> Glad we agree :-)
> 
>>> + ret = iters = 0;
>> A small suggestion, could we just initialise it in declaration
>> to be a bit more concise?
>> e.g. int ret = 0, iters = 0;
>>
>> Reviewed-by: Pavel Begunkov <asml.silence@gmail.com>
>> And let me test it as both patches are ready.
> 
> Sure, I'll make that change and add your reviewed-by. Thanks!
> 
Stress tested, works well!

Tested-by: Pavel Begunkov <asml.silence@gmail.com>

-- 
Yours sincerely,
Pavel Begunkov


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [BUG] io_uring: defer logic based on shared data
  2019-10-25 18:13                 ` Pavel Begunkov
@ 2019-10-25 18:17                   ` Jens Axboe
  0 siblings, 0 replies; 13+ messages in thread
From: Jens Axboe @ 2019-10-25 18:17 UTC (permalink / raw)
  To: Pavel Begunkov, linux-block, linux-kernel

On 10/25/19 12:13 PM, Pavel Begunkov wrote:
> On 25/10/2019 19:57, Jens Axboe wrote:
>> On 10/25/19 10:55 AM, Pavel Begunkov wrote:
>>> On 25/10/2019 19:44, Jens Axboe wrote:
>>>> On 10/25/19 10:40 AM, Pavel Begunkov wrote:
>>>>> On 25/10/2019 19:32, Jens Axboe wrote:
>>>>>> On 10/25/19 10:27 AM, Jens Axboe wrote:
>>>>>>> On 10/25/19 10:21 AM, Pavel Begunkov wrote:
>>>>>>>> On 25/10/2019 19:03, Jens Axboe wrote:
>>>>>>>>> On 10/25/19 3:55 AM, Pavel Begunkov wrote:
>>>>>>>>>> I found 2 problems with __io_sequence_defer().
>>>>>>>>>>
>>>>>>>>>> 1. it uses @sq_dropped, but doesn't consider @cq_overflow
>>>>>>>>>> 2. @sq_dropped and @cq_overflow are write-shared with userspace, so
>>>>>>>>>> it can be maliciously changed.
>>>>>>>>>>
>>>>>>>>>> see sent liburing test (test/defer *_hung()), which left an unkillable
>>>>>>>>>> process for me
>>>>>>>>>
>>>>>>>>> OK, how about the below. I'll split this in two, as it's really two
>>>>>>>>> separate fixes.
>>>>>>>> cached_sq_dropped is good, but I was concerned about cached_cq_overflow.
>>>>>>>> io_cqring_fill_event() can be called in async, so shouldn't we do some
>>>>>>>> synchronisation then?
>>>>>>>
>>>>>>> We should probably make it an atomic just to be on the safe side, I'll
>>>>>>> update the series.
>>>>>>
>>>>>> Here we go, patch 1:
>>>>>>
>>>>>> http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=f2a241f596ed9e12b7c8f960e79ccda8053ea294
>>>>>>
>>>>>> patch 2:
>>>>>>
>>>>>> http://git.kernel.dk/cgit/linux-block/commit/?h=for-linus&id=b7d0297d2df5bfa0d1ecf9d6c66d23676751ef6a
>>>>>>
>>>>> 1. submit rqs (not yet completed)
>>>>> 2. poll_list is empty, inflight = 0
>>>>> 3. async completed and placed into poll_list
>>>>>
>>>>> So, poll_list is not empty, but we won't get to polling again.
>>>>> At least until someone submitted something.
>>>>
>>>> But if they are issued, the will sit in ->poll_list as well. That list
>>>> holds both "submitted, but pending" and completed entries.
>>>>
>>> Missed it, then should work. Thanks!
>>
>> Glad we agree :-)
>>
>>>> + ret = iters = 0;
>>> A small suggestion, could we just initialise it in declaration
>>> to be a bit more concise?
>>> e.g. int ret = 0, iters = 0;
>>>
>>> Reviewed-by: Pavel Begunkov <asml.silence@gmail.com>
>>> And let me test it as both patches are ready.
>>
>> Sure, I'll make that change and add your reviewed-by. Thanks!
>>
> Stress tested, works well!
> 
> Tested-by: Pavel Begunkov <asml.silence@gmail.com>

Great, thanks for finding these, sending patches, and testing the ones
that I fixed!

-- 
Jens Axboe


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

end of thread, other threads:[~2019-10-25 18:18 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-25  9:55 [BUG] io_uring: defer logic based on shared data Pavel Begunkov
2019-10-25 16:03 ` Jens Axboe
2019-10-25 16:09   ` Jens Axboe
2019-10-25 16:21     ` Jens Axboe
2019-10-25 16:21   ` Pavel Begunkov
2019-10-25 16:27     ` Jens Axboe
2019-10-25 16:32       ` Jens Axboe
2019-10-25 16:40         ` Pavel Begunkov
2019-10-25 16:44           ` Jens Axboe
2019-10-25 16:55             ` Pavel Begunkov
2019-10-25 16:57               ` Jens Axboe
2019-10-25 18:13                 ` Pavel Begunkov
2019-10-25 18:17                   ` 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).