public inbox for io-uring@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] registrered buffer coalescing cleanup
@ 2025-04-19 17:47 Pavel Begunkov
  2025-04-19 17:47 ` [PATCH 1/3] io_uring/rsrc: use unpin_user_folio Pavel Begunkov
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Pavel Begunkov @ 2025-04-19 17:47 UTC (permalink / raw)
  To: io-uring; +Cc: asml.silence

Improve how we handle huge page with registrered buffers, in particular
make io_coalesce_buffer() a bit more readable.

Pavel Begunkov (3):
  io_uring/rsrc: use unpin_user_folio
  io_uring/rsrc: clean up io_coalesce_buffer()
  io_uring/rsrc: remove null check on import

 io_uring/rsrc.c | 50 ++++++++++++++++++++++---------------------------
 1 file changed, 22 insertions(+), 28 deletions(-)

-- 
2.48.1


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

* [PATCH 1/3] io_uring/rsrc: use unpin_user_folio
  2025-04-19 17:47 [PATCH 0/3] registrered buffer coalescing cleanup Pavel Begunkov
@ 2025-04-19 17:47 ` Pavel Begunkov
  2025-04-21  2:37   ` Anuj gupta
  2025-04-19 17:47 ` [PATCH 2/3] io_uring/rsrc: clean up io_coalesce_buffer() Pavel Begunkov
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Pavel Begunkov @ 2025-04-19 17:47 UTC (permalink / raw)
  To: io-uring; +Cc: asml.silence

We want to have a full folio to be left pinned but with only one
reference, for that we "unpin" all but the first page with
unpin_user_pages(), which can be confusing. There is a new helper to
achieve that called unpin_user_folio(), so use that.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 io_uring/rsrc.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
index f80a77c4973f..40061a31cc1f 100644
--- a/io_uring/rsrc.c
+++ b/io_uring/rsrc.c
@@ -699,10 +699,9 @@ static bool io_coalesce_buffer(struct page ***pages, int *nr_pages,
 	 * The pages are bound to the folio, it doesn't
 	 * actually unpin them but drops all but one reference,
 	 * which is usually put down by io_buffer_unmap().
-	 * Note, needs a better helper.
 	 */
 	if (data->nr_pages_head > 1)
-		unpin_user_pages(&page_array[1], data->nr_pages_head - 1);
+		unpin_user_folio(page_folio(new_array[0]), data->nr_pages_head - 1);
 
 	j = data->nr_pages_head;
 	nr_pages_left -= data->nr_pages_head;
@@ -713,7 +712,7 @@ static bool io_coalesce_buffer(struct page ***pages, int *nr_pages,
 		nr_unpin = min_t(unsigned int, nr_pages_left - 1,
 					data->nr_pages_mid - 1);
 		if (nr_unpin)
-			unpin_user_pages(&page_array[j+1], nr_unpin);
+			unpin_user_folio(page_folio(new_array[i]), nr_unpin);
 		j += data->nr_pages_mid;
 		nr_pages_left -= data->nr_pages_mid;
 	}
-- 
2.48.1


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

* [PATCH 2/3] io_uring/rsrc: clean up io_coalesce_buffer()
  2025-04-19 17:47 [PATCH 0/3] registrered buffer coalescing cleanup Pavel Begunkov
  2025-04-19 17:47 ` [PATCH 1/3] io_uring/rsrc: use unpin_user_folio Pavel Begunkov
@ 2025-04-19 17:47 ` Pavel Begunkov
  2025-04-21  2:38   ` Anuj gupta
       [not found]   ` <CGME20250421115925epcas5p18c9a46be72b98c089dc1833befc4d06d@epcas5p1.samsung.com>
  2025-04-19 17:47 ` [PATCH 3/3] io_uring/rsrc: remove null check on import Pavel Begunkov
  2025-04-21 11:13 ` [PATCH 0/3] registrered buffer coalescing cleanup Jens Axboe
  3 siblings, 2 replies; 9+ messages in thread
From: Pavel Begunkov @ 2025-04-19 17:47 UTC (permalink / raw)
  To: io-uring; +Cc: asml.silence

We don't need special handling for the first page in
io_coalesce_buffer(), move it inside the loop.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 io_uring/rsrc.c | 47 ++++++++++++++++++++++-------------------------
 1 file changed, 22 insertions(+), 25 deletions(-)

diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
index 40061a31cc1f..21613e6074d4 100644
--- a/io_uring/rsrc.c
+++ b/io_uring/rsrc.c
@@ -685,37 +685,34 @@ static bool io_coalesce_buffer(struct page ***pages, int *nr_pages,
 				struct io_imu_folio_data *data)
 {
 	struct page **page_array = *pages, **new_array = NULL;
-	int nr_pages_left = *nr_pages, i, j;
-	int nr_folios = data->nr_folios;
+	unsigned nr_pages_left = *nr_pages;
+	unsigned nr_folios = data->nr_folios;
+	unsigned i, j;
 
 	/* Store head pages only*/
-	new_array = kvmalloc_array(nr_folios, sizeof(struct page *),
-					GFP_KERNEL);
+	new_array = kvmalloc_array(nr_folios, sizeof(struct page *), GFP_KERNEL);
 	if (!new_array)
 		return false;
 
-	new_array[0] = compound_head(page_array[0]);
-	/*
-	 * The pages are bound to the folio, it doesn't
-	 * actually unpin them but drops all but one reference,
-	 * which is usually put down by io_buffer_unmap().
-	 */
-	if (data->nr_pages_head > 1)
-		unpin_user_folio(page_folio(new_array[0]), data->nr_pages_head - 1);
-
-	j = data->nr_pages_head;
-	nr_pages_left -= data->nr_pages_head;
-	for (i = 1; i < nr_folios; i++) {
-		unsigned int nr_unpin;
-
-		new_array[i] = page_array[j];
-		nr_unpin = min_t(unsigned int, nr_pages_left - 1,
-					data->nr_pages_mid - 1);
-		if (nr_unpin)
-			unpin_user_folio(page_folio(new_array[i]), nr_unpin);
-		j += data->nr_pages_mid;
-		nr_pages_left -= data->nr_pages_mid;
+	for (i = 0, j = 0; i < nr_folios; i++) {
+		struct page *p = compound_head(page_array[j]);
+		struct folio *folio = page_folio(p);
+		unsigned int nr;
+
+		WARN_ON_ONCE(i > 0 && p != page_array[j]);
+
+		nr = i ? data->nr_pages_mid : data->nr_pages_head;
+		nr = min(nr, nr_pages_left);
+		/* Drop all but one ref, the entire folio will remain pinned. */
+		if (nr > 1)
+			unpin_user_folio(folio, nr - 1);
+		j += nr;
+		nr_pages_left -= nr;
+		new_array[i] = p;
 	}
+
+	WARN_ON_ONCE(j != *nr_pages);
+
 	kvfree(page_array);
 	*pages = new_array;
 	*nr_pages = nr_folios;
-- 
2.48.1


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

* [PATCH 3/3] io_uring/rsrc: remove null check on import
  2025-04-19 17:47 [PATCH 0/3] registrered buffer coalescing cleanup Pavel Begunkov
  2025-04-19 17:47 ` [PATCH 1/3] io_uring/rsrc: use unpin_user_folio Pavel Begunkov
  2025-04-19 17:47 ` [PATCH 2/3] io_uring/rsrc: clean up io_coalesce_buffer() Pavel Begunkov
@ 2025-04-19 17:47 ` Pavel Begunkov
  2025-04-21 11:13 ` [PATCH 0/3] registrered buffer coalescing cleanup Jens Axboe
  3 siblings, 0 replies; 9+ messages in thread
From: Pavel Begunkov @ 2025-04-19 17:47 UTC (permalink / raw)
  To: io-uring; +Cc: asml.silence

WARN_ON_ONCE() checking imu for NULL in io_import_fixed() is in the hot
path and too protective, it's time to get rid of it.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 io_uring/rsrc.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
index 21613e6074d4..b2b9053b31c7 100644
--- a/io_uring/rsrc.c
+++ b/io_uring/rsrc.c
@@ -1058,8 +1058,6 @@ static int io_import_fixed(int ddir, struct iov_iter *iter,
 	size_t offset;
 	int ret;
 
-	if (WARN_ON_ONCE(!imu))
-		return -EFAULT;
 	ret = validate_fixed_range(buf_addr, len, imu);
 	if (unlikely(ret))
 		return ret;
-- 
2.48.1


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

* Re: [PATCH 1/3] io_uring/rsrc: use unpin_user_folio
  2025-04-19 17:47 ` [PATCH 1/3] io_uring/rsrc: use unpin_user_folio Pavel Begunkov
@ 2025-04-21  2:37   ` Anuj gupta
  0 siblings, 0 replies; 9+ messages in thread
From: Anuj gupta @ 2025-04-21  2:37 UTC (permalink / raw)
  To: Pavel Begunkov; +Cc: io-uring

Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>

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

* Re: [PATCH 2/3] io_uring/rsrc: clean up io_coalesce_buffer()
  2025-04-19 17:47 ` [PATCH 2/3] io_uring/rsrc: clean up io_coalesce_buffer() Pavel Begunkov
@ 2025-04-21  2:38   ` Anuj gupta
       [not found]   ` <CGME20250421115925epcas5p18c9a46be72b98c089dc1833befc4d06d@epcas5p1.samsung.com>
  1 sibling, 0 replies; 9+ messages in thread
From: Anuj gupta @ 2025-04-21  2:38 UTC (permalink / raw)
  To: Pavel Begunkov; +Cc: io-uring

Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>

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

* Re: [PATCH 0/3] registrered buffer coalescing cleanup
  2025-04-19 17:47 [PATCH 0/3] registrered buffer coalescing cleanup Pavel Begunkov
                   ` (2 preceding siblings ...)
  2025-04-19 17:47 ` [PATCH 3/3] io_uring/rsrc: remove null check on import Pavel Begunkov
@ 2025-04-21 11:13 ` Jens Axboe
  3 siblings, 0 replies; 9+ messages in thread
From: Jens Axboe @ 2025-04-21 11:13 UTC (permalink / raw)
  To: io-uring, Pavel Begunkov


On Sat, 19 Apr 2025 18:47:03 +0100, Pavel Begunkov wrote:
> Improve how we handle huge page with registrered buffers, in particular
> make io_coalesce_buffer() a bit more readable.
> 
> Pavel Begunkov (3):
>   io_uring/rsrc: use unpin_user_folio
>   io_uring/rsrc: clean up io_coalesce_buffer()
>   io_uring/rsrc: remove null check on import
> 
> [...]

Applied, thanks!

[1/3] io_uring/rsrc: use unpin_user_folio
      commit: ea76925614189bdcb6571e2ea8de68af409ebd56
[2/3] io_uring/rsrc: clean up io_coalesce_buffer()
      commit: 9cebcf7b0c38bca1b501d8716163aa254b230559
[3/3] io_uring/rsrc: remove null check on import
      commit: be6bad57b217491733754ae8113eec94a90a2769

Best regards,
-- 
Jens Axboe




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

* Re: [PATCH 2/3] io_uring/rsrc: clean up io_coalesce_buffer()
       [not found]   ` <CGME20250421115925epcas5p18c9a46be72b98c089dc1833befc4d06d@epcas5p1.samsung.com>
@ 2025-04-21 11:50     ` Nitesh Shetty
  2025-04-21 14:50       ` Jens Axboe
  0 siblings, 1 reply; 9+ messages in thread
From: Nitesh Shetty @ 2025-04-21 11:50 UTC (permalink / raw)
  To: Pavel Begunkov; +Cc: io-uring

[-- Attachment #1: Type: text/plain, Size: 1213 bytes --]

On 19/04/25 06:47PM, Pavel Begunkov wrote:
>We don't need special handling for the first page in
>io_coalesce_buffer(), move it inside the loop.
>
>Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
>---
> io_uring/rsrc.c | 47 ++++++++++++++++++++++-------------------------
> 1 file changed, 22 insertions(+), 25 deletions(-)
>
>diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
>index 40061a31cc1f..21613e6074d4 100644
>--- a/io_uring/rsrc.c
>+++ b/io_uring/rsrc.c
>@@ -685,37 +685,34 @@ static bool io_coalesce_buffer(struct page ***pages, int *nr_pages,
> 				struct io_imu_folio_data *data)
> {
> 	struct page **page_array = *pages, **new_array = NULL;
>-	int nr_pages_left = *nr_pages, i, j;
>-	int nr_folios = data->nr_folios;
>+	unsigned nr_pages_left = *nr_pages;
>+	unsigned nr_folios = data->nr_folios;
>+	unsigned i, j;
checkpatch.pl complains about just "unsigned", "unsigned int" is preferred.

>
> 	/* Store head pages only*/
>-	new_array = kvmalloc_array(nr_folios, sizeof(struct page *),
>-					GFP_KERNEL);
>+	new_array = kvmalloc_array(nr_folios, sizeof(struct page *), GFP_KERNEL);
Not sure whether 80 line length is preferred in uring subsystem, if yes
then this breaks it.

--Nitesh Shetty

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



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

* Re: [PATCH 2/3] io_uring/rsrc: clean up io_coalesce_buffer()
  2025-04-21 11:50     ` Nitesh Shetty
@ 2025-04-21 14:50       ` Jens Axboe
  0 siblings, 0 replies; 9+ messages in thread
From: Jens Axboe @ 2025-04-21 14:50 UTC (permalink / raw)
  To: Nitesh Shetty, Pavel Begunkov; +Cc: io-uring

On 4/21/25 5:50 AM, Nitesh Shetty wrote:
> On 19/04/25 06:47PM, Pavel Begunkov wrote:
>> We don't need special handling for the first page in
>> io_coalesce_buffer(), move it inside the loop.
>>
>> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
>> ---
>> io_uring/rsrc.c | 47 ++++++++++++++++++++++-------------------------
>> 1 file changed, 22 insertions(+), 25 deletions(-)
>>
>> diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
>> index 40061a31cc1f..21613e6074d4 100644
>> --- a/io_uring/rsrc.c
>> +++ b/io_uring/rsrc.c
>> @@ -685,37 +685,34 @@ static bool io_coalesce_buffer(struct page ***pages, int *nr_pages,
>>                 struct io_imu_folio_data *data)
>> {
>>     struct page **page_array = *pages, **new_array = NULL;
>> -    int nr_pages_left = *nr_pages, i, j;
>> -    int nr_folios = data->nr_folios;
>> +    unsigned nr_pages_left = *nr_pages;
>> +    unsigned nr_folios = data->nr_folios;
>> +    unsigned i, j;
> checkpatch.pl complains about just "unsigned", "unsigned int" is preferred.
> 
>>
>>     /* Store head pages only*/
>> -    new_array = kvmalloc_array(nr_folios, sizeof(struct page *),
>> -                    GFP_KERNEL);
>> +    new_array = kvmalloc_array(nr_folios, sizeof(struct page *), GFP_KERNEL);
> Not sure whether 80 line length is preferred in uring subsystem, if yes
> then this breaks it.

It's fine to use checkpatch for new contributors, but it's generally
just pretty useless imho. io_uring does exceed 80 chars regularly, if it
improves readability. And we also do use unsigned, not sure why
checkpatch is against that.

-- 
Jens Axboe

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

end of thread, other threads:[~2025-04-21 14:50 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-19 17:47 [PATCH 0/3] registrered buffer coalescing cleanup Pavel Begunkov
2025-04-19 17:47 ` [PATCH 1/3] io_uring/rsrc: use unpin_user_folio Pavel Begunkov
2025-04-21  2:37   ` Anuj gupta
2025-04-19 17:47 ` [PATCH 2/3] io_uring/rsrc: clean up io_coalesce_buffer() Pavel Begunkov
2025-04-21  2:38   ` Anuj gupta
     [not found]   ` <CGME20250421115925epcas5p18c9a46be72b98c089dc1833befc4d06d@epcas5p1.samsung.com>
2025-04-21 11:50     ` Nitesh Shetty
2025-04-21 14:50       ` Jens Axboe
2025-04-19 17:47 ` [PATCH 3/3] io_uring/rsrc: remove null check on import Pavel Begunkov
2025-04-21 11:13 ` [PATCH 0/3] registrered buffer coalescing cleanup Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox