Re: [PATCH] mm, kmemleak: Little optimization while scanning

2018-12-07 Thread Catalin Marinas
On Thu, Dec 06, 2018 at 02:19:18PM +0100, Oscar Salvador wrote:
> kmemleak_scan() goes through all online nodes and tries
> to scan all used pages.
> We can do better and use pfn_to_online_page(), so in case we have
> CONFIG_MEMORY_HOTPLUG, offlined pages will be skiped automatically.
> For boxes where CONFIG_MEMORY_HOTPLUG is not present, pfn_to_online_page()
> will fallback to pfn_valid().
> 
> Another little optimization is to check if the page belongs to the node
> we are currently checking, so in case we have nodes interleaved we will
> not check the same pfn multiple times.
> 
> I ran some tests:
> 
> Add some memory to node1 and node2 making it interleaved:
> 
> (qemu) object_add memory-backend-ram,id=ram0,size=1G
> (qemu) device_add pc-dimm,id=dimm0,memdev=ram0,node=1
> (qemu) object_add memory-backend-ram,id=ram1,size=1G
> (qemu) device_add pc-dimm,id=dimm1,memdev=ram1,node=2
> (qemu) object_add memory-backend-ram,id=ram2,size=1G
> (qemu) device_add pc-dimm,id=dimm2,memdev=ram2,node=1
> 
> Then, we offline that memory:
>  # for i in {32..39} ; do echo "offline" > 
> /sys/devices/system/node/node1/memory$i/state;done
>  # for i in {48..55} ; do echo "offline" > 
> /sys/devices/system/node/node1/memory$i/state;don
>  # for i in {40..47} ; do echo "offline" > 
> /sys/devices/system/node/node2/memory$i/state;done
> 
> And we run kmemleak_scan:
> 
>  # echo "scan" > /sys/kernel/debug/kmemleak
> 
> before the patch:
> 
> kmemleak: time spend: 41596 us
> 
> after the patch:
> 
> kmemleak: time spend: 34899 us
> 
> Signed-off-by: Oscar Salvador 

Acked-by: Catalin Marinas 


Re: [PATCH] mm, kmemleak: Little optimization while scanning

2018-12-07 Thread Catalin Marinas
On Thu, Dec 06, 2018 at 02:19:18PM +0100, Oscar Salvador wrote:
> kmemleak_scan() goes through all online nodes and tries
> to scan all used pages.
> We can do better and use pfn_to_online_page(), so in case we have
> CONFIG_MEMORY_HOTPLUG, offlined pages will be skiped automatically.
> For boxes where CONFIG_MEMORY_HOTPLUG is not present, pfn_to_online_page()
> will fallback to pfn_valid().
> 
> Another little optimization is to check if the page belongs to the node
> we are currently checking, so in case we have nodes interleaved we will
> not check the same pfn multiple times.
> 
> I ran some tests:
> 
> Add some memory to node1 and node2 making it interleaved:
> 
> (qemu) object_add memory-backend-ram,id=ram0,size=1G
> (qemu) device_add pc-dimm,id=dimm0,memdev=ram0,node=1
> (qemu) object_add memory-backend-ram,id=ram1,size=1G
> (qemu) device_add pc-dimm,id=dimm1,memdev=ram1,node=2
> (qemu) object_add memory-backend-ram,id=ram2,size=1G
> (qemu) device_add pc-dimm,id=dimm2,memdev=ram2,node=1
> 
> Then, we offline that memory:
>  # for i in {32..39} ; do echo "offline" > 
> /sys/devices/system/node/node1/memory$i/state;done
>  # for i in {48..55} ; do echo "offline" > 
> /sys/devices/system/node/node1/memory$i/state;don
>  # for i in {40..47} ; do echo "offline" > 
> /sys/devices/system/node/node2/memory$i/state;done
> 
> And we run kmemleak_scan:
> 
>  # echo "scan" > /sys/kernel/debug/kmemleak
> 
> before the patch:
> 
> kmemleak: time spend: 41596 us
> 
> after the patch:
> 
> kmemleak: time spend: 34899 us
> 
> Signed-off-by: Oscar Salvador 

Acked-by: Catalin Marinas 


Re: [PATCH] mm, kmemleak: Little optimization while scanning

2018-12-07 Thread Wei Yang
On Fri, Dec 07, 2018 at 07:14:10AM +0100, Oscar Salvador wrote:
>
>> > +
>> 
>> This one maybe not necessary.
>
>Yeah, that is a remind of an include file I used for time measurement.
>I hope Andrew can drop that if this is taken.
>
>> > /*
>> >  * Kmemleak configuration and common defines.
>> >  */
>> > @@ -1547,11 +1548,14 @@ static void kmemleak_scan(void)
>> >unsigned long pfn;
>> > 
>> >for (pfn = start_pfn; pfn < end_pfn; pfn++) {
>> > -  struct page *page;
>> > +  struct page *page =
>> > pfn_to_online_page(pfn);
>> > +
>> > +  if (!page)
>> > +  continue;
>> > 
>> > -  if (!pfn_valid(pfn))
>> > +  /* only scan pages belonging to this node
>> > */
>> > +  if (page_to_nid(page) != i)
>> >continue;
>> 
>> Not farmiliar with this situation. Is this often?
>Well, hard to tell how often that happens because that mostly depends
>on the Hardware in case of baremetal.
>Virtual systems can also have it though.
>

Ok, generally looks good to me.

Reviewed-by: Wei Yang 

>> 
>> > -  page = pfn_to_page(pfn);
>> >/* only scan if page is in use */
>> >if (page_count(page) == 0)
>> >continue;
>> > -- 
>> > 2.13.7
>> 
>> 
>-- 
>Oscar Salvador
>SUSE L3

-- 
Wei Yang
Help you, Help me


Re: [PATCH] mm, kmemleak: Little optimization while scanning

2018-12-07 Thread Wei Yang
On Fri, Dec 07, 2018 at 07:14:10AM +0100, Oscar Salvador wrote:
>
>> > +
>> 
>> This one maybe not necessary.
>
>Yeah, that is a remind of an include file I used for time measurement.
>I hope Andrew can drop that if this is taken.
>
>> > /*
>> >  * Kmemleak configuration and common defines.
>> >  */
>> > @@ -1547,11 +1548,14 @@ static void kmemleak_scan(void)
>> >unsigned long pfn;
>> > 
>> >for (pfn = start_pfn; pfn < end_pfn; pfn++) {
>> > -  struct page *page;
>> > +  struct page *page =
>> > pfn_to_online_page(pfn);
>> > +
>> > +  if (!page)
>> > +  continue;
>> > 
>> > -  if (!pfn_valid(pfn))
>> > +  /* only scan pages belonging to this node
>> > */
>> > +  if (page_to_nid(page) != i)
>> >continue;
>> 
>> Not farmiliar with this situation. Is this often?
>Well, hard to tell how often that happens because that mostly depends
>on the Hardware in case of baremetal.
>Virtual systems can also have it though.
>

Ok, generally looks good to me.

Reviewed-by: Wei Yang 

>> 
>> > -  page = pfn_to_page(pfn);
>> >/* only scan if page is in use */
>> >if (page_count(page) == 0)
>> >continue;
>> > -- 
>> > 2.13.7
>> 
>> 
>-- 
>Oscar Salvador
>SUSE L3

-- 
Wei Yang
Help you, Help me


Re: [PATCH] mm, kmemleak: Little optimization while scanning

2018-12-06 Thread Oscar Salvador


> > +
> 
> This one maybe not necessary.

Yeah, that is a remind of an include file I used for time measurement.
I hope Andrew can drop that if this is taken.

> > /*
> >  * Kmemleak configuration and common defines.
> >  */
> > @@ -1547,11 +1548,14 @@ static void kmemleak_scan(void)
> > unsigned long pfn;
> > 
> > for (pfn = start_pfn; pfn < end_pfn; pfn++) {
> > -   struct page *page;
> > +   struct page *page =
> > pfn_to_online_page(pfn);
> > +
> > +   if (!page)
> > +   continue;
> > 
> > -   if (!pfn_valid(pfn))
> > +   /* only scan pages belonging to this node
> > */
> > +   if (page_to_nid(page) != i)
> > continue;
> 
> Not farmiliar with this situation. Is this often?
Well, hard to tell how often that happens because that mostly depends
on the Hardware in case of baremetal.
Virtual systems can also have it though.

> 
> > -   page = pfn_to_page(pfn);
> > /* only scan if page is in use */
> > if (page_count(page) == 0)
> > continue;
> > -- 
> > 2.13.7
> 
> 
-- 
Oscar Salvador
SUSE L3


Re: [PATCH] mm, kmemleak: Little optimization while scanning

2018-12-06 Thread Oscar Salvador


> > +
> 
> This one maybe not necessary.

Yeah, that is a remind of an include file I used for time measurement.
I hope Andrew can drop that if this is taken.

> > /*
> >  * Kmemleak configuration and common defines.
> >  */
> > @@ -1547,11 +1548,14 @@ static void kmemleak_scan(void)
> > unsigned long pfn;
> > 
> > for (pfn = start_pfn; pfn < end_pfn; pfn++) {
> > -   struct page *page;
> > +   struct page *page =
> > pfn_to_online_page(pfn);
> > +
> > +   if (!page)
> > +   continue;
> > 
> > -   if (!pfn_valid(pfn))
> > +   /* only scan pages belonging to this node
> > */
> > +   if (page_to_nid(page) != i)
> > continue;
> 
> Not farmiliar with this situation. Is this often?
Well, hard to tell how often that happens because that mostly depends
on the Hardware in case of baremetal.
Virtual systems can also have it though.

> 
> > -   page = pfn_to_page(pfn);
> > /* only scan if page is in use */
> > if (page_count(page) == 0)
> > continue;
> > -- 
> > 2.13.7
> 
> 
-- 
Oscar Salvador
SUSE L3


Re: [PATCH] mm, kmemleak: Little optimization while scanning

2018-12-06 Thread Oscar Salvador
I just realized I forgot to add that this was suggested by Michal.
Sorry, I was a but rushy.

On Thu, 2018-12-06 at 14:19 +0100, Oscar Salvador wrote:
> kmemleak_scan() goes through all online nodes and tries
> to scan all used pages.
> We can do better and use pfn_to_online_page(), so in case we have
> CONFIG_MEMORY_HOTPLUG, offlined pages will be skiped automatically.
> For boxes where CONFIG_MEMORY_HOTPLUG is not present,
> pfn_to_online_page()
> will fallback to pfn_valid().
> 
> Another little optimization is to check if the page belongs to the
> node
> we are currently checking, so in case we have nodes interleaved we
> will
> not check the same pfn multiple times.
> 
> I ran some tests:
> 
> Add some memory to node1 and node2 making it interleaved:
> 
> (qemu) object_add memory-backend-ram,id=ram0,size=1G
> (qemu) device_add pc-dimm,id=dimm0,memdev=ram0,node=1
> (qemu) object_add memory-backend-ram,id=ram1,size=1G
> (qemu) device_add pc-dimm,id=dimm1,memdev=ram1,node=2
> (qemu) object_add memory-backend-ram,id=ram2,size=1G
> (qemu) device_add pc-dimm,id=dimm2,memdev=ram2,node=1
> 
> Then, we offline that memory:
>  # for i in {32..39} ; do echo "offline" >
> /sys/devices/system/node/node1/memory$i/state;done
>  # for i in {48..55} ; do echo "offline" >
> /sys/devices/system/node/node1/memory$i/state;don
>  # for i in {40..47} ; do echo "offline" >
> /sys/devices/system/node/node2/memory$i/state;done
> 
> And we run kmemleak_scan:
> 
>  # echo "scan" > /sys/kernel/debug/kmemleak
> 
> before the patch:
> 
> kmemleak: time spend: 41596 us
> 
> after the patch:
> 
> kmemleak: time spend: 34899 us
> 
> Signed-off-by: Oscar Salvador 
Suggested-by: Michal Hocko 

> ---
>  mm/kmemleak.c | 10 +++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/mm/kmemleak.c b/mm/kmemleak.c
> index 877de4fa0720..5ce1e6a46d77 100644
> --- a/mm/kmemleak.c
> +++ b/mm/kmemleak.c
> @@ -113,6 +113,7 @@
>  #include 
>  #include 
>  
> +
>  /*
>   * Kmemleak configuration and common defines.
>   */
> @@ -1547,11 +1548,14 @@ static void kmemleak_scan(void)
>   unsigned long pfn;
>  
>   for (pfn = start_pfn; pfn < end_pfn; pfn++) {
> - struct page *page;
> + struct page *page = pfn_to_online_page(pfn);
> +
> + if (!page)
> + continue;
>  
> - if (!pfn_valid(pfn))
> + /* only scan pages belonging to this node */
> + if (page_to_nid(page) != i)
>   continue;
> - page = pfn_to_page(pfn);
>   /* only scan if page is in use */
>   if (page_count(page) == 0)
>   continue;
-- 
Oscar Salvador
SUSE L3


Re: [PATCH] mm, kmemleak: Little optimization while scanning

2018-12-06 Thread Oscar Salvador
I just realized I forgot to add that this was suggested by Michal.
Sorry, I was a but rushy.

On Thu, 2018-12-06 at 14:19 +0100, Oscar Salvador wrote:
> kmemleak_scan() goes through all online nodes and tries
> to scan all used pages.
> We can do better and use pfn_to_online_page(), so in case we have
> CONFIG_MEMORY_HOTPLUG, offlined pages will be skiped automatically.
> For boxes where CONFIG_MEMORY_HOTPLUG is not present,
> pfn_to_online_page()
> will fallback to pfn_valid().
> 
> Another little optimization is to check if the page belongs to the
> node
> we are currently checking, so in case we have nodes interleaved we
> will
> not check the same pfn multiple times.
> 
> I ran some tests:
> 
> Add some memory to node1 and node2 making it interleaved:
> 
> (qemu) object_add memory-backend-ram,id=ram0,size=1G
> (qemu) device_add pc-dimm,id=dimm0,memdev=ram0,node=1
> (qemu) object_add memory-backend-ram,id=ram1,size=1G
> (qemu) device_add pc-dimm,id=dimm1,memdev=ram1,node=2
> (qemu) object_add memory-backend-ram,id=ram2,size=1G
> (qemu) device_add pc-dimm,id=dimm2,memdev=ram2,node=1
> 
> Then, we offline that memory:
>  # for i in {32..39} ; do echo "offline" >
> /sys/devices/system/node/node1/memory$i/state;done
>  # for i in {48..55} ; do echo "offline" >
> /sys/devices/system/node/node1/memory$i/state;don
>  # for i in {40..47} ; do echo "offline" >
> /sys/devices/system/node/node2/memory$i/state;done
> 
> And we run kmemleak_scan:
> 
>  # echo "scan" > /sys/kernel/debug/kmemleak
> 
> before the patch:
> 
> kmemleak: time spend: 41596 us
> 
> after the patch:
> 
> kmemleak: time spend: 34899 us
> 
> Signed-off-by: Oscar Salvador 
Suggested-by: Michal Hocko 

> ---
>  mm/kmemleak.c | 10 +++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/mm/kmemleak.c b/mm/kmemleak.c
> index 877de4fa0720..5ce1e6a46d77 100644
> --- a/mm/kmemleak.c
> +++ b/mm/kmemleak.c
> @@ -113,6 +113,7 @@
>  #include 
>  #include 
>  
> +
>  /*
>   * Kmemleak configuration and common defines.
>   */
> @@ -1547,11 +1548,14 @@ static void kmemleak_scan(void)
>   unsigned long pfn;
>  
>   for (pfn = start_pfn; pfn < end_pfn; pfn++) {
> - struct page *page;
> + struct page *page = pfn_to_online_page(pfn);
> +
> + if (!page)
> + continue;
>  
> - if (!pfn_valid(pfn))
> + /* only scan pages belonging to this node */
> + if (page_to_nid(page) != i)
>   continue;
> - page = pfn_to_page(pfn);
>   /* only scan if page is in use */
>   if (page_count(page) == 0)
>   continue;
-- 
Oscar Salvador
SUSE L3


Re: [PATCH] mm, kmemleak: Little optimization while scanning

2018-12-06 Thread Wei Yang
On Thu, Dec 06, 2018 at 02:19:18PM +0100, Oscar Salvador wrote:
>kmemleak_scan() goes through all online nodes and tries
>to scan all used pages.
>We can do better and use pfn_to_online_page(), so in case we have
>CONFIG_MEMORY_HOTPLUG, offlined pages will be skiped automatically.
>For boxes where CONFIG_MEMORY_HOTPLUG is not present, pfn_to_online_page()
>will fallback to pfn_valid().
>
>Another little optimization is to check if the page belongs to the node
>we are currently checking, so in case we have nodes interleaved we will
>not check the same pfn multiple times.
>
>I ran some tests:
>
>Add some memory to node1 and node2 making it interleaved:
>
>(qemu) object_add memory-backend-ram,id=ram0,size=1G
>(qemu) device_add pc-dimm,id=dimm0,memdev=ram0,node=1
>(qemu) object_add memory-backend-ram,id=ram1,size=1G
>(qemu) device_add pc-dimm,id=dimm1,memdev=ram1,node=2
>(qemu) object_add memory-backend-ram,id=ram2,size=1G
>(qemu) device_add pc-dimm,id=dimm2,memdev=ram2,node=1
>
>Then, we offline that memory:
> # for i in {32..39} ; do echo "offline" > 
> /sys/devices/system/node/node1/memory$i/state;done
> # for i in {48..55} ; do echo "offline" > 
> /sys/devices/system/node/node1/memory$i/state;don
> # for i in {40..47} ; do echo "offline" > 
> /sys/devices/system/node/node2/memory$i/state;done
>
>And we run kmemleak_scan:
>
> # echo "scan" > /sys/kernel/debug/kmemleak
>
>before the patch:
>
>kmemleak: time spend: 41596 us
>
>after the patch:
>
>kmemleak: time spend: 34899 us
>
>Signed-off-by: Oscar Salvador 
>---
> mm/kmemleak.c | 10 +++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>
>diff --git a/mm/kmemleak.c b/mm/kmemleak.c
>index 877de4fa0720..5ce1e6a46d77 100644
>--- a/mm/kmemleak.c
>+++ b/mm/kmemleak.c
>@@ -113,6 +113,7 @@
> #include 
> #include 
> 
>+

This one maybe not necessary.

> /*
>  * Kmemleak configuration and common defines.
>  */
>@@ -1547,11 +1548,14 @@ static void kmemleak_scan(void)
>   unsigned long pfn;
> 
>   for (pfn = start_pfn; pfn < end_pfn; pfn++) {
>-  struct page *page;
>+  struct page *page = pfn_to_online_page(pfn);
>+
>+  if (!page)
>+  continue;
> 
>-  if (!pfn_valid(pfn))
>+  /* only scan pages belonging to this node */
>+  if (page_to_nid(page) != i)
>   continue;

Not farmiliar with this situation. Is this often?

>-  page = pfn_to_page(pfn);
>   /* only scan if page is in use */
>   if (page_count(page) == 0)
>   continue;
>-- 
>2.13.7

-- 
Wei Yang
Help you, Help me


Re: [PATCH] mm, kmemleak: Little optimization while scanning

2018-12-06 Thread Wei Yang
On Thu, Dec 06, 2018 at 02:19:18PM +0100, Oscar Salvador wrote:
>kmemleak_scan() goes through all online nodes and tries
>to scan all used pages.
>We can do better and use pfn_to_online_page(), so in case we have
>CONFIG_MEMORY_HOTPLUG, offlined pages will be skiped automatically.
>For boxes where CONFIG_MEMORY_HOTPLUG is not present, pfn_to_online_page()
>will fallback to pfn_valid().
>
>Another little optimization is to check if the page belongs to the node
>we are currently checking, so in case we have nodes interleaved we will
>not check the same pfn multiple times.
>
>I ran some tests:
>
>Add some memory to node1 and node2 making it interleaved:
>
>(qemu) object_add memory-backend-ram,id=ram0,size=1G
>(qemu) device_add pc-dimm,id=dimm0,memdev=ram0,node=1
>(qemu) object_add memory-backend-ram,id=ram1,size=1G
>(qemu) device_add pc-dimm,id=dimm1,memdev=ram1,node=2
>(qemu) object_add memory-backend-ram,id=ram2,size=1G
>(qemu) device_add pc-dimm,id=dimm2,memdev=ram2,node=1
>
>Then, we offline that memory:
> # for i in {32..39} ; do echo "offline" > 
> /sys/devices/system/node/node1/memory$i/state;done
> # for i in {48..55} ; do echo "offline" > 
> /sys/devices/system/node/node1/memory$i/state;don
> # for i in {40..47} ; do echo "offline" > 
> /sys/devices/system/node/node2/memory$i/state;done
>
>And we run kmemleak_scan:
>
> # echo "scan" > /sys/kernel/debug/kmemleak
>
>before the patch:
>
>kmemleak: time spend: 41596 us
>
>after the patch:
>
>kmemleak: time spend: 34899 us
>
>Signed-off-by: Oscar Salvador 
>---
> mm/kmemleak.c | 10 +++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>
>diff --git a/mm/kmemleak.c b/mm/kmemleak.c
>index 877de4fa0720..5ce1e6a46d77 100644
>--- a/mm/kmemleak.c
>+++ b/mm/kmemleak.c
>@@ -113,6 +113,7 @@
> #include 
> #include 
> 
>+

This one maybe not necessary.

> /*
>  * Kmemleak configuration and common defines.
>  */
>@@ -1547,11 +1548,14 @@ static void kmemleak_scan(void)
>   unsigned long pfn;
> 
>   for (pfn = start_pfn; pfn < end_pfn; pfn++) {
>-  struct page *page;
>+  struct page *page = pfn_to_online_page(pfn);
>+
>+  if (!page)
>+  continue;
> 
>-  if (!pfn_valid(pfn))
>+  /* only scan pages belonging to this node */
>+  if (page_to_nid(page) != i)
>   continue;

Not farmiliar with this situation. Is this often?

>-  page = pfn_to_page(pfn);
>   /* only scan if page is in use */
>   if (page_count(page) == 0)
>   continue;
>-- 
>2.13.7

-- 
Wei Yang
Help you, Help me


[PATCH] mm, kmemleak: Little optimization while scanning

2018-12-06 Thread Oscar Salvador
kmemleak_scan() goes through all online nodes and tries
to scan all used pages.
We can do better and use pfn_to_online_page(), so in case we have
CONFIG_MEMORY_HOTPLUG, offlined pages will be skiped automatically.
For boxes where CONFIG_MEMORY_HOTPLUG is not present, pfn_to_online_page()
will fallback to pfn_valid().

Another little optimization is to check if the page belongs to the node
we are currently checking, so in case we have nodes interleaved we will
not check the same pfn multiple times.

I ran some tests:

Add some memory to node1 and node2 making it interleaved:

(qemu) object_add memory-backend-ram,id=ram0,size=1G
(qemu) device_add pc-dimm,id=dimm0,memdev=ram0,node=1
(qemu) object_add memory-backend-ram,id=ram1,size=1G
(qemu) device_add pc-dimm,id=dimm1,memdev=ram1,node=2
(qemu) object_add memory-backend-ram,id=ram2,size=1G
(qemu) device_add pc-dimm,id=dimm2,memdev=ram2,node=1

Then, we offline that memory:
 # for i in {32..39} ; do echo "offline" > 
/sys/devices/system/node/node1/memory$i/state;done
 # for i in {48..55} ; do echo "offline" > 
/sys/devices/system/node/node1/memory$i/state;don
 # for i in {40..47} ; do echo "offline" > 
/sys/devices/system/node/node2/memory$i/state;done

And we run kmemleak_scan:

 # echo "scan" > /sys/kernel/debug/kmemleak

before the patch:

kmemleak: time spend: 41596 us

after the patch:

kmemleak: time spend: 34899 us

Signed-off-by: Oscar Salvador 
---
 mm/kmemleak.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 877de4fa0720..5ce1e6a46d77 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -113,6 +113,7 @@
 #include 
 #include 
 
+
 /*
  * Kmemleak configuration and common defines.
  */
@@ -1547,11 +1548,14 @@ static void kmemleak_scan(void)
unsigned long pfn;
 
for (pfn = start_pfn; pfn < end_pfn; pfn++) {
-   struct page *page;
+   struct page *page = pfn_to_online_page(pfn);
+
+   if (!page)
+   continue;
 
-   if (!pfn_valid(pfn))
+   /* only scan pages belonging to this node */
+   if (page_to_nid(page) != i)
continue;
-   page = pfn_to_page(pfn);
/* only scan if page is in use */
if (page_count(page) == 0)
continue;
-- 
2.13.7



[PATCH] mm, kmemleak: Little optimization while scanning

2018-12-06 Thread Oscar Salvador
kmemleak_scan() goes through all online nodes and tries
to scan all used pages.
We can do better and use pfn_to_online_page(), so in case we have
CONFIG_MEMORY_HOTPLUG, offlined pages will be skiped automatically.
For boxes where CONFIG_MEMORY_HOTPLUG is not present, pfn_to_online_page()
will fallback to pfn_valid().

Another little optimization is to check if the page belongs to the node
we are currently checking, so in case we have nodes interleaved we will
not check the same pfn multiple times.

I ran some tests:

Add some memory to node1 and node2 making it interleaved:

(qemu) object_add memory-backend-ram,id=ram0,size=1G
(qemu) device_add pc-dimm,id=dimm0,memdev=ram0,node=1
(qemu) object_add memory-backend-ram,id=ram1,size=1G
(qemu) device_add pc-dimm,id=dimm1,memdev=ram1,node=2
(qemu) object_add memory-backend-ram,id=ram2,size=1G
(qemu) device_add pc-dimm,id=dimm2,memdev=ram2,node=1

Then, we offline that memory:
 # for i in {32..39} ; do echo "offline" > 
/sys/devices/system/node/node1/memory$i/state;done
 # for i in {48..55} ; do echo "offline" > 
/sys/devices/system/node/node1/memory$i/state;don
 # for i in {40..47} ; do echo "offline" > 
/sys/devices/system/node/node2/memory$i/state;done

And we run kmemleak_scan:

 # echo "scan" > /sys/kernel/debug/kmemleak

before the patch:

kmemleak: time spend: 41596 us

after the patch:

kmemleak: time spend: 34899 us

Signed-off-by: Oscar Salvador 
---
 mm/kmemleak.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 877de4fa0720..5ce1e6a46d77 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -113,6 +113,7 @@
 #include 
 #include 
 
+
 /*
  * Kmemleak configuration and common defines.
  */
@@ -1547,11 +1548,14 @@ static void kmemleak_scan(void)
unsigned long pfn;
 
for (pfn = start_pfn; pfn < end_pfn; pfn++) {
-   struct page *page;
+   struct page *page = pfn_to_online_page(pfn);
+
+   if (!page)
+   continue;
 
-   if (!pfn_valid(pfn))
+   /* only scan pages belonging to this node */
+   if (page_to_nid(page) != i)
continue;
-   page = pfn_to_page(pfn);
/* only scan if page is in use */
if (page_count(page) == 0)
continue;
-- 
2.13.7