linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Kefeng Wang <wangkefeng.wang@huawei.com>
To: "Huang, Ying" <ying.huang@intel.com>
Cc: David Hildenbrand <david@redhat.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Matthew Wilcox <willy@infradead.org>,
	Muchun Song <muchun.song@linux.dev>, <linux-mm@kvack.org>,
	Zi Yan <ziy@nvidia.com>
Subject: Re: [PATCH v2 1/2] mm: use aligned address in clear_gigantic_page()
Date: Fri, 1 Nov 2024 17:45:42 +0800	[thread overview]
Message-ID: <5f752263-ba3c-4d85-939e-6da7648a9011@huawei.com> (raw)
In-Reply-To: <87msij8j2f.fsf@yhuang6-desk2.ccr.corp.intel.com>



On 2024/11/1 16:16, Huang, Ying wrote:
> Kefeng Wang <wangkefeng.wang@huawei.com> writes:
> 
>> On 2024/10/31 16:39, Huang, Ying wrote:
>>> Kefeng Wang <wangkefeng.wang@huawei.com> writes:
>>> [snip]
>>>>
>>>>>> 1) Will test some rand test to check the different of performance as
>>>>>> David suggested.>>>>
>>>>>> 2) Hope the LKP to run more tests since it is very useful(more test
>>>>>> set and different machines)
>>>>> I'm starting to use LKP to test.
>>>>
>>>> Greet.
>>
>>
>> Sorry for the late,
>>
>>> I have run some tests with LKP to test.
>>> Firstly, there's almost no measurable difference between clearing
>>> pages
>>> from start to end or from end to start on Intel server CPU.  I guess
>>> that there's some similar optimization for both direction.
>>> For multiple processes (same as logical CPU number)
>>> vm-scalability/anon-w-seq test case, the benchmark score increases
>>> about 22.4%.
>>
>> So process_huge_page is better than clear_gigantic_page() on Intel?
> 
> For vm-scalability/anon-w-seq test case, it is.  Because the performance
> of forward and backward clearing is almost same, and the user space
> accessing has cache-hot benefit.
> 
>> Could you test the following case on x86?
>> echo 10240 >
>> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
>> mkdir -p /hugetlbfs/
>> mount none /hugetlbfs/ -t hugetlbfs
>> rm -f /hugetlbfs/test && fallocate -l 20G /hugetlbfs/test && fallocate
>> -d -l 20G /hugetlbfs/test && time taskset -c 10 fallocate -l 20G
>> /hugetlbfs/test
> 
> It's not trivial for me to do this test.  Because 0day wraps test cases.
> Do you know which existing test cases provide this?  For example, in
> vm-scalability?

I don't know the public fallocate test, I will try to find a intel 
machine to test this case.
> 
>>> For multiple processes vm-scalability/anon-w-rand test case, no
>>> measurable difference for benchmark score.
>>> So, the optimization helps sequential workload mainly.
>>> In summary, on x86, process_huge_page() will not introduce any
>>> regression.  And it helps some workload.
>>> However, on ARM64, it does introduce some regression for clearing
>>> pages
>>> from end to start.  That needs to be addressed.  I guess that the
>>> regression can be resolved via using more clearing from start to end
>>> (but not all).  For example, can you take a look at the patch below?
>>> Which uses the similar framework as before, but clear each small trunk
>>> (mpage) from start to end.  You can adjust MPAGE_NRPAGES to check when
>>> the regression can be restored.
>>> WARNING: the patch is only build tested.
>>
>>
>> Base: baseline
>> Change1: using clear_gigantic_page() for 2M PMD
>> Change2: your patch with MPAGE_NRPAGES=16
>> Change3: Case3 + fix[1]
> 
> What is case3?

Oh, it is Change2.

> 
>> Change4: your patch with MPAGE_NRPAGES=64 + fix[1]
>>
>> 1. For rand write,
>>     case-anon-w-rand/case-anon-w-rand-hugetlb no measurable difference
>>
>> 2. For seq write,
>>
>> 1) case-anon-w-seq-mt:
> 
> Can you try case-anon-w-seq?  That may be more stable.
> 
>> base:
>> real    0m2.490s    0m2.254s    0m2.272s
>> user    1m59.980s   2m23.431s   2m18.739s
>> sys     1m3.675s    1m15.462s   1m15.030s
>>
>> Change1:
>> real    0m2.234s    0m2.225s    0m2.159s
>> user    2m56.105s   2m57.117s   3m0.489s
>> sys     0m17.064s   0m17.564s   0m16.150s
>>
>> Change2:
>> real	0m2.244s    0m2.384s	0m2.370s
>> user	2m39.413s   2m41.990s   2m42.229s
>> sys	0m19.826s   0m18.491s   0m18.053s
> 
> It appears strange.  There's no much cache hot benefit even if we clear
> pages from end to begin (with larger chunk).
> 
> However, sys time improves a lot.  This shows clearing page with large
> chunk helps on ARM64.
> 
>> Change3:  // best performance
>> real	0m2.155s    0m2.204s	0m2.194s
>> user	3m2.640s    2m55.837s   3m0.902s
>> sys	0m17.346s   0m17.630s   0m18.197s
>>
>> Change4:
>> real	0m2.287s    0m2.377s	0m2.284s	
>> user	2m37.030s   2m52.868s   3m17.593s
>> sys	0m15.445s   0m34.430s   0m45.224s
> 
> Change4 is essentially same as Change1.  I don't know why they are
> different.  Is there some large variation among run to run?

As above shown, I test three times, the test results are relatively
stable, at least for real, I will try case-anon-w-seq.

> 
> Can you further optimize the prototype patch below?  I think that it has
> potential to fix your issue.

Yes, thanks for you helper, but this will make process_huge_page() a
little more complicated :)
> 
>> 2) case-anon-w-seq-hugetlb
>>     very similar 1), Change4 slightly better than Change3, but not big
>>     different.
>>
>> 3) hugetlbfs fallocate 20G
>>     Change1(0m1.136s) = Change3(0m1.136s) =  Change4(0m1.135s) <
>>     Change2(0m1.275s) < base(0m3.016s)
>>
>> In summary, the Change3 is best and Change1 is good on my arm64 machine.
>>
>>> Best Regards,
>>> Huang, Ying
>>> -----------------------------------8<----------------------------------------
>>>   From 406bcd1603987fdd7130d2df6f7d4aee4cc6b978 Mon Sep 17 00:00:00 2001
>>> From: Huang Ying <ying.huang@intel.com>
>>> Date: Thu, 31 Oct 2024 11:13:57 +0800
>>> Subject: [PATCH] mpage clear
>>> ---
>>>    mm/memory.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++---
>>>    1 file changed, 67 insertions(+), 3 deletions(-)
>>> diff --git a/mm/memory.c b/mm/memory.c
>>> index 3ccee51adfbb..1fdc548c4275 100644
>>> --- a/mm/memory.c
>>> +++ b/mm/memory.c
>>> @@ -6769,6 +6769,68 @@ static inline int process_huge_page(
>>>    	return 0;
>>>    }
>>>    +#define MPAGE_NRPAGES	(1<<4)
>>> +#define MPAGE_SIZE	(PAGE_SIZE * MPAGE_NRPAGES)
>>> +static inline int clear_huge_page(
>>> +	unsigned long addr_hint, unsigned int nr_pages,
>>> +	int (*process_subpage)(unsigned long addr, int idx, void *arg),
>>> +	void *arg)
>>> +{
>>> +	int i, n, base, l, ret;
>>> +	unsigned long addr = addr_hint &
>>> +		~(((unsigned long)nr_pages << PAGE_SHIFT) - 1);
>>> +	unsigned long nr_mpages = ((unsigned long)nr_pages << PAGE_SHIFT) / MPAGE_SIZE;
>>> +
>>> +	/* Process target subpage last to keep its cache lines hot */
>>> +	might_sleep();
>>> +	n = (addr_hint - addr) / MPAGE_SIZE;
>>> +	if (2 * n <= nr_mpages) {
>>> +		/* If target subpage in first half of huge page */
>>> +		base = 0;
>>> +		l = n;
>>> +		/* Process subpages at the end of huge page */
>>> +		for (i = nr_mpages - 1; i >= 2 * n; i--) {
>>> +			cond_resched();
>>> +			ret = process_subpage(addr + i * MPAGE_SIZE,
>>> +					      i * MPAGE_NRPAGES, arg);
>>> +			if (ret)
>>> +				return ret;
>>> +		}
>>> +	} else {
>>> +		/* If target subpage in second half of huge page */
>>> +		base = nr_mpages - 2 * (nr_mpages - n);
>>> +		l = nr_mpages - n;
>>> +		/* Process subpages at the begin of huge page */
>>> +		for (i = 0; i < base; i++) {
>>> +			cond_resched();
>>> +			ret = process_subpage(addr + i * MPAGE_SIZE,
>>> +					      i * MPAGE_NRPAGES, arg);
>>> +			if (ret)
>>> +				return ret;
>>> +		}
>>> +	}
>>> +	/*
>>> +	 * Process remaining subpages in left-right-left-right pattern
>>> +	 * towards the target subpage
>>> +	 */
>>> +	for (i = 0; i < l; i++) {
>>> +		int left_idx = base + i;
>>> +		int right_idx = base + 2 * l - 1 - i;
>>> +
>>> +		cond_resched();
>>> +		ret = process_subpage(addr + left_idx * MPAGE_SIZE,
>>> +				      left_idx * MPAGE_NRPAGES, arg);
>>> +		if (ret)
>>> +			return ret;
>>> +		cond_resched();
>>> +		ret = process_subpage(addr + right_idx * MPAGE_SIZE,
>>> +				      right_idx * MPAGE_NRPAGES, arg);
>>> +		if (ret)
>>> +			return ret;
>>> +	}
>>> +	return 0;
>>> +}
>>> +
>>>    static void clear_gigantic_page(struct folio *folio, unsigned long addr,
>>>    				unsigned int nr_pages)
>>>    {
>>> @@ -6784,8 +6846,10 @@ static void clear_gigantic_page(struct folio *folio, unsigned long addr,
>>>    static int clear_subpage(unsigned long addr, int idx, void *arg)
>>>    {
>>>    	struct folio *folio = arg;
>>> +	int i;
>>>    -	clear_user_highpage(folio_page(folio, idx), addr);
>>> +	for (i = 0; i < MPAGE_NRPAGES; i++)
>>> +		clear_user_highpage(folio_page(folio, idx + i), addr + i * PAGE_SIZE);
>>>    	return 0;
>>>    }
>>>    @@ -6798,10 +6862,10 @@ void folio_zero_user(struct folio *folio,
>>> unsigned long addr_hint)
>>>    {
>>>    	unsigned int nr_pages = folio_nr_pages(folio);
>>>    -	if (unlikely(nr_pages > MAX_ORDER_NR_PAGES))
>>> +	if (unlikely(nr_pages != HPAGE_PMD_NR))
>>>    		clear_gigantic_page(folio, addr_hint, nr_pages);
>>>    	else
>>> -		process_huge_page(addr_hint, nr_pages, clear_subpage, folio);
>>> +		clear_huge_page(addr_hint, nr_pages, clear_subpage, folio);
>>>    }
>>>      static int copy_user_gigantic_page(struct folio *dst, struct
>>> folio *src,
>>
>>
>> [1] fix patch
>>
>> diff --git a/mm/memory.c b/mm/memory.c
>> index b22d4b83295b..aee99ede0c4f 100644
>> --- a/mm/memory.c
>> +++ b/mm/memory.c
>> @@ -6816,7 +6816,7 @@ static inline int clear_huge_page(
>>                  base = 0;
>>                  l = n;
>>                  /* Process subpages at the end of huge page */
>> -               for (i = nr_mpages - 1; i >= 2 * n; i--) {
>> +               for (i = 2 * n; i < nr_mpages; i++) {
>>                          cond_resched();
>>                          ret = process_subpage(addr + i * MPAGE_SIZE,
>>                                                i * MPAGE_NRPAGES, arg);
> 



  reply	other threads:[~2024-11-01  9:45 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-26  5:43 Kefeng Wang
2024-10-26  5:43 ` [PATCH v2 2/2] mm: use aligned address in copy_user_gigantic_page() Kefeng Wang
2024-10-28 10:01   ` David Hildenbrand
2024-10-28  6:17 ` [PATCH v2 1/2] mm: use aligned address in clear_gigantic_page() Huang, Ying
2024-10-28  6:35   ` Kefeng Wang
2024-10-28  7:03     ` Huang, Ying
2024-10-28  8:35       ` Kefeng Wang
2024-10-28 10:00 ` David Hildenbrand
2024-10-28 12:52   ` Kefeng Wang
2024-10-28 13:14     ` David Hildenbrand
2024-10-28 13:33       ` Kefeng Wang
2024-10-28 13:46         ` David Hildenbrand
2024-10-28 14:22           ` Kefeng Wang
2024-10-28 14:24             ` David Hildenbrand
2024-10-29 13:04               ` Kefeng Wang
2024-10-29 14:04                 ` David Hildenbrand
2024-10-30  1:04                   ` Huang, Ying
2024-10-30  3:04                     ` Kefeng Wang
2024-10-30  3:21                       ` Huang, Ying
2024-10-30  5:05                         ` Kefeng Wang
2024-10-31  8:39                           ` Huang, Ying
2024-11-01  7:43                             ` Kefeng Wang
2024-11-01  8:16                               ` Huang, Ying
2024-11-01  9:45                                 ` Kefeng Wang [this message]
2024-11-04  2:35                                   ` Huang, Ying
2024-11-05  2:06                                     ` Kefeng Wang
2024-12-01  2:15                             ` Andrew Morton
2024-12-01  5:37                               ` Huang, Ying
2024-12-02  1:03                                 ` Kefeng Wang
2024-12-06  1:47                                   ` Andrew Morton
2024-12-06  2:08                                     ` Kefeng Wang
2024-11-01  6:18                           ` Huang, Ying
2024-11-01  7:51                             ` Kefeng Wang

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=5f752263-ba3c-4d85-939e-6da7648a9011@huawei.com \
    --to=wangkefeng.wang@huawei.com \
    --cc=akpm@linux-foundation.org \
    --cc=david@redhat.com \
    --cc=linux-mm@kvack.org \
    --cc=muchun.song@linux.dev \
    --cc=willy@infradead.org \
    --cc=ying.huang@intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox