From: Baolin Wang <baolin.wang@linux.alibaba.com>
To: David Hildenbrand <david@redhat.com>, akpm@linux-foundation.org
Cc: 21cnbao@gmail.com, ryan.roberts@arm.com, dev.jain@arm.com,
ziy@nvidia.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3] mm: mincore: use pte_batch_bint() to batch process large folios
Date: Fri, 9 May 2025 20:25:52 +0800 [thread overview]
Message-ID: <3d52c5bb-60c5-4bfd-958e-737a8cc90853@linux.alibaba.com> (raw)
In-Reply-To: <c83ddc32-565b-40e3-b43f-12fe6e70586c@redhat.com>
On 2025/5/9 15:51, David Hildenbrand wrote:
> On 09.05.25 02:45, Baolin Wang wrote:
>> When I tested the mincore() syscall, I observed that it takes longer with
>> 64K mTHP enabled on my Arm64 server. The reason is the
>> mincore_pte_range()
>> still checks each PTE individually, even when the PTEs are contiguous,
>> which is not efficient.
>>
>> Thus we can use pte_batch_hint() to get the batch number of the present
>> contiguous PTEs, which can improve the performance. I tested the
>> mincore()
>> syscall with 1G anonymous memory populated with 64K mTHP, and observed an
>> obvious performance improvement:
>>
>> w/o patch w/ patch changes
>> 6022us 549us +91%
>>
>> Moreover, I also tested mincore() with disabling mTHP/THP, and did not
>> see any obvious regression for base pages.
>>
>> Signed-off-by: Baolin Wang <baolin.wang@linux.alibaba.com>
>> ---
>> Changes from v2:
>> - Re-calculate the max_nr, per Barry.
>> Changes from v1:
>> - Change to use pte_batch_hint() to get the batch number, per Ryan.
>>
>> Note: I observed the min_t() can introduce a slight performance
>> regression
>> for base pages, so I change to add a batch size check for base pages,
>> which can resolve the performance regression issue.
>> ---
>> mm/mincore.c | 22 +++++++++++++++++-----
>> 1 file changed, 17 insertions(+), 5 deletions(-)
>>
>> diff --git a/mm/mincore.c b/mm/mincore.c
>> index 832f29f46767..42d6c9c8da86 100644
>> --- a/mm/mincore.c
>> +++ b/mm/mincore.c
>> @@ -21,6 +21,7 @@
>> #include <linux/uaccess.h>
>> #include "swap.h"
>> +#include "internal.h"
>> static int mincore_hugetlb(pte_t *pte, unsigned long hmask, unsigned
>> long addr,
>> unsigned long end, struct mm_walk *walk)
>> @@ -105,6 +106,7 @@ static int mincore_pte_range(pmd_t *pmd, unsigned
>> long addr, unsigned long end,
>> pte_t *ptep;
>> unsigned char *vec = walk->private;
>> int nr = (end - addr) >> PAGE_SHIFT;
>> + int step, i;
>> ptl = pmd_trans_huge_lock(pmd, vma);
>> if (ptl) {
>> @@ -118,16 +120,26 @@ static int mincore_pte_range(pmd_t *pmd,
>> unsigned long addr, unsigned long end,
>> walk->action = ACTION_AGAIN;
>> return 0;
>> }
>> - for (; addr != end; ptep++, addr += PAGE_SIZE) {
>> + for (; addr != end; ptep += step, addr += step * PAGE_SIZE) {
>> pte_t pte = ptep_get(ptep);
>> + step = 1;
>> /* We need to do cache lookup too for pte markers */
>> if (pte_none_mostly(pte))
>> __mincore_unmapped_range(addr, addr + PAGE_SIZE,
>> vma, vec);
>> - else if (pte_present(pte))
>> - *vec = 1;
>> - else { /* pte is a swap entry */
>> + else if (pte_present(pte)) {
>> + unsigned int batch = pte_batch_hint(ptep, pte);
>> +
>> + if (batch > 1) {
>> + unsigned int max_nr = (end - addr) >> PAGE_SHIFT;
>
> Nit: probably would have called this max_step to match step.
OK. If need respin the patch, I'll rename it.
>> +
>> + step = min_t(unsigned int, batch, max_nr);
>> + }
>> +
>> + for (i = 0; i < step; i++)
>> + vec[i] = 1;
>
> I'm surprised this micro-optimization matters that much. Probably the
Me too.
> compiler
> defers the calculation of max_nr. I am not convinced we need that level of
> micro-optimization in this code ...
>
>
> But if we're already micro-optimizing, you could have optimized out the
> loop as
> well for order-0:
>
> unsigned int batch = pte_batch_hint(ptep, pte);
>
> if (batch > 1) {
> unsigned int max_nr = (end - addr) >> PAGE_SHIFT;
>
> step = min_t(unsigned int, batch, max_nr);
> for (i = 0; i < step; i++)
> vec[i] = 1;
> } else {
> *vec = 1;
> }
I tried this method, and it had no impact on performance.
> In any case
>
> Acked-by: David Hildenbrand <david@redhat.com>
Thanks.
next prev parent reply other threads:[~2025-05-09 12:26 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-09 0:45 [PATCH v3] mm: mincore: use pte_batch_bint() to batch process large folios Baolin Wang
2025-05-09 1:49 ` Barry Song
2025-05-09 7:30 ` Dev Jain
2025-05-09 7:38 ` Baolin Wang
2025-05-09 7:51 ` David Hildenbrand
2025-05-09 12:25 ` Baolin Wang [this message]
2025-05-09 12:42 ` David Hildenbrand
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3d52c5bb-60c5-4bfd-958e-737a8cc90853@linux.alibaba.com \
--to=baolin.wang@linux.alibaba.com \
--cc=21cnbao@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=david@redhat.com \
--cc=dev.jain@arm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ryan.roberts@arm.com \
--cc=ziy@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.