All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] makedumpfile: shorten cyclic unnecessary-page scans
@ 2013-08-28 22:08 Cliff Wickman
  2013-09-19  5:40 ` Atsushi Kumagai
  0 siblings, 1 reply; 2+ messages in thread
From: Cliff Wickman @ 2013-08-28 22:08 UTC (permalink / raw)
  To: d.hatayama, kumagai-atsushi; +Cc: kexec

From: Cliff Wickman <cpw@sgi.com>


When the kernel free pages are not detectable with the 'buddy' method
we do a scan for free pages.
In cyclic mode that scan was performed over all of memory for each
cycle region.

This patch records the pfn ranges of each node on the first such cycle.
Then ignores those nodes that are not within the cyclic region on 
subsequent scans.
This shortens these subsequent scans.

Diffed against makedumpfile-1.5.4
Signed-off-by: Cliff Wickman <cpw@sgi.com>
---
 makedumpfile.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 74 insertions(+), 2 deletions(-)

Index: makedumpfile-1.5.4/makedumpfile.c
===================================================================
--- makedumpfile-1.5.4.orig/makedumpfile.c
+++ makedumpfile-1.5.4/makedumpfile.c
@@ -36,6 +36,16 @@ struct DumpInfo		*info = NULL;
 
 char filename_stdout[] = FILENAME_STDOUT;
 
+int nr_nodes;
+int node_free_pfns_recorded = 0;
+struct node_free_pfns {
+	unsigned long low_pfn;
+	unsigned long high_pfn;
+	long count;
+	int valid;
+};
+struct node_free_pfns *nfp, *nfp1;
+
 /*
  * The numbers of the excluded pages
  */
@@ -3609,7 +3619,7 @@ page_to_pfn(unsigned long page)
 }
 
 int
-reset_bitmap_of_free_pages(unsigned long node_zones)
+reset_bitmap_of_free_pages(unsigned long node_zones, int node)
 {
 
 	int order, i, migrate_type, migrate_types;
@@ -3653,6 +3663,18 @@ reset_bitmap_of_free_pages(unsigned long
 					retcd = ANALYSIS_FAILED;
 					return FALSE;
 				}
+				if (info->flag_cyclic) {
+					nfp1 = nfp + node;
+					nfp1->valid = 1;
+					nfp1->count++;
+					for (i = 0; i < (1<<order); i++) {
+						pfn = start_pfn + i;
+						if (pfn > nfp1->high_pfn)
+						    nfp1->high_pfn = pfn;
+						if (pfn < nfp1->low_pfn)
+						    nfp1->low_pfn = pfn;
+					}
+				}
 
 				if (!info->flag_cyclic ||
 				    ((start_pfn >= info->cyclic_start_pfn) &&
@@ -3990,8 +4012,31 @@ _exclude_free_page(void)
 			}
 			if (!spanned_pages)
 				continue;
-			if (!reset_bitmap_of_free_pages(zone))
+			/*don't scan for free pages outside of the cyclic area*/
+			if (info->flag_cyclic) {
+			  nfp1 = nfp + node;
+			  if (nfp1->valid) {
+			  	if (!nfp1->count) {
+				/* this node has no free pages */
+					continue;
+				}
+				if (nfp1->high_pfn < info->cyclic_start_pfn) {
+				/* we're at a node lower than the current
+ 				   cyclic region */
+					continue;
+				}
+			  	if (nfp1->low_pfn > info->cyclic_end_pfn) {
+				/* we're up to a node that is all higher than
+				   the current cyclic region */
+					return TRUE;
+				}
+			  }
+			}
+			if (!reset_bitmap_of_free_pages(zone, node))
 				return FALSE;
+			if (info->flag_cyclic) {
+			  nfp1 = nfp + node;
+			}
 		}
 		if (num_nodes < vt.numnodes) {
 			if ((node = next_online_node(node + 1)) < 0) {
@@ -5306,12 +5351,39 @@ get_num_dumpable(void)
 unsigned long long
 get_num_dumpable_cyclic(void)
 {
+	int i;
 	int cycle = 0;
 	int lastcycle = 0;
 	int newcycle = 1;
+	int node;
 	unsigned long long pfn, num_dumpable=0;
 
 	PROGRESS_MSG("Begin page counting phase.\n");
+	/* build a table for free page pfn's per node */
+	if ((node = next_online_node(0)) < 0) {
+		ERRMSG("Can't get first online node.\n");
+		exit(1);
+	}
+	nr_nodes = 1;
+	while (node >= 0) {
+		if ((node = next_online_node(node + 1)) < 0) {
+			node = -1;
+		} else {
+			nr_nodes++;
+		}
+	}
+	if ((nfp = (struct node_free_pfns *)
+		malloc(nr_nodes * sizeof(struct node_free_pfns))) == NULL) {
+		ERRMSG("Can't malloc %d structures.\n", nr_nodes);
+		exit(1);
+	}
+	for (i = 0, nfp1 = nfp; i < nr_nodes; i++, nfp1++) {
+		nfp1->valid = 0;
+		nfp1->count = 0;
+		nfp1->low_pfn = 0xffffffffffffffff;
+		nfp1->high_pfn = 0;
+	}
+
 	for (pfn = 0; pfn < info->max_mapnr; pfn++) {
 		if (newcycle)
 			PROGRESS_MSG("Scan cycle %d\n", cycle + 1);

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* Re: [PATCH] makedumpfile: shorten cyclic unnecessary-page scans
  2013-08-28 22:08 [PATCH] makedumpfile: shorten cyclic unnecessary-page scans Cliff Wickman
@ 2013-09-19  5:40 ` Atsushi Kumagai
  0 siblings, 0 replies; 2+ messages in thread
From: Atsushi Kumagai @ 2013-09-19  5:40 UTC (permalink / raw)
  To: cpw; +Cc: d.hatayama, kexec

Hello Cliff,

(2013/08/29 7:08), Cliff Wickman wrote:
> From: Cliff Wickman <cpw@sgi.com>
>
>
> When the kernel free pages are not detectable with the 'buddy' method
> we do a scan for free pages.
> In cyclic mode that scan was performed over all of memory for each
> cycle region.
>
> This patch records the pfn ranges of each node on the first such cycle.
> Then ignores those nodes that are not within the cyclic region on
> subsequent scans.
> This shortens these subsequent scans.

I have reviewed your patch, I have some comments.

> Diffed against makedumpfile-1.5.4
> Signed-off-by: Cliff Wickman <cpw@sgi.com>
> ---
>   makedumpfile.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>   1 file changed, 74 insertions(+), 2 deletions(-)
>
> Index: makedumpfile-1.5.4/makedumpfile.c
> ===================================================================
> --- makedumpfile-1.5.4.orig/makedumpfile.c
> +++ makedumpfile-1.5.4/makedumpfile.c
> @@ -36,6 +36,16 @@ struct DumpInfo        *info = NULL;
>
>   char filename_stdout[] = FILENAME_STDOUT;
>
> +int nr_nodes;
> +int node_free_pfns_recorded = 0;

This value is never used.

> +struct node_free_pfns {
> +    unsigned long low_pfn;
> +    unsigned long high_pfn;
> +    long count;
> +    int valid;
> +};
> +struct node_free_pfns *nfp, *nfp1;
> +
>   /*
>    * The numbers of the excluded pages
>    */
> @@ -3609,7 +3619,7 @@ page_to_pfn(unsigned long page)
>   }
>
>   int
> -reset_bitmap_of_free_pages(unsigned long node_zones)
> +reset_bitmap_of_free_pages(unsigned long node_zones, int node)
>   {
>
>       int order, i, migrate_type, migrate_types;
> @@ -3653,6 +3663,18 @@ reset_bitmap_of_free_pages(unsigned long
>                       retcd = ANALYSIS_FAILED;
>                       return FALSE;
>                   }
> +                if (info->flag_cyclic) {
> +                    nfp1 = nfp + node;
> +                    nfp1->valid = 1;
> +                    nfp1->count++;

In your patch, it seems "valid" is enough to fulfill your purpose.
Why do you count up "count" ?

> +                    for (i = 0; i < (1<<order); i++) {
> +                        pfn = start_pfn + i;
> +                        if (pfn > nfp1->high_pfn)
> +                            nfp1->high_pfn = pfn;
> +                        if (pfn < nfp1->low_pfn)
> +                            nfp1->low_pfn = pfn;
> +                    }
> +                }
>
>                   if (!info->flag_cyclic ||
>                       ((start_pfn >= info->cyclic_start_pfn) &&
> @@ -3990,8 +4012,31 @@ _exclude_free_page(void)
>               }
>               if (!spanned_pages)
>                   continue;
> -            if (!reset_bitmap_of_free_pages(zone))
> +            /*don't scan for free pages outside of the cyclic area*/
> +            if (info->flag_cyclic) {
> +              nfp1 = nfp + node;
> +              if (nfp1->valid) {
> +                  if (!nfp1->count) {
> +                /* this node has no free pages */
> +                    continue;
> +                }
> +                if (nfp1->high_pfn < info->cyclic_start_pfn) {
> +                /* we're at a node lower than the current
> +                    cyclic region */
> +                    continue;
> +                }
> +                  if (nfp1->low_pfn > info->cyclic_end_pfn) {
> +                /* we're up to a node that is all higher than
> +                   the current cyclic region */
> +                    return TRUE;
> +                }
> +              }
> +            }
> +            if (!reset_bitmap_of_free_pages(zone, node))
>                   return FALSE;
> +            if (info->flag_cyclic) {
> +              nfp1 = nfp + node;
> +            }

Is this nfp1 counting necessary ?
nfp1 isn't used later.

>           }
>           if (num_nodes < vt.numnodes) {
>               if ((node = next_online_node(node + 1)) < 0) {
> @@ -5306,12 +5351,39 @@ get_num_dumpable(void)
>   unsigned long long
>   get_num_dumpable_cyclic(void)
>   {
> +    int i;
>       int cycle = 0;
>       int lastcycle = 0;
>       int newcycle = 1;
> +    int node;
>       unsigned long long pfn, num_dumpable=0;
>
>       PROGRESS_MSG("Begin page counting phase.\n");
> +    /* build a table for free page pfn's per node */
> +    if ((node = next_online_node(0)) < 0) {
> +        ERRMSG("Can't get first online node.\n");
> +        exit(1);
> +    }
> +    nr_nodes = 1;
> +    while (node >= 0) {
> +        if ((node = next_online_node(node + 1)) < 0) {
> +            node = -1;
> +        } else {
> +            nr_nodes++;
> +        }
> +    }

You can use get_nodes_online() to get the number of online nodes.

> +    if ((nfp = (struct node_free_pfns *)
> +        malloc(nr_nodes * sizeof(struct node_free_pfns))) == NULL) {
> +        ERRMSG("Can't malloc %d structures.\n", nr_nodes);
> +        exit(1);
> +    }
> +    for (i = 0, nfp1 = nfp; i < nr_nodes; i++, nfp1++) {
> +        nfp1->valid = 0;
> +        nfp1->count = 0;
> +        nfp1->low_pfn = 0xffffffffffffffff;

ULONG_MAX is better.


Thanks
Atsushi Kumagai.

> +        nfp1->high_pfn = 0;
> +    }
> +
>       for (pfn = 0; pfn < info->max_mapnr; pfn++) {
>           if (newcycle)
>               PROGRESS_MSG("Scan cycle %d\n", cycle + 1);
>
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

end of thread, other threads:[~2013-09-19  5:43 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-28 22:08 [PATCH] makedumpfile: shorten cyclic unnecessary-page scans Cliff Wickman
2013-09-19  5:40 ` Atsushi Kumagai

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.