[PATCH] makedumpfile: shorten cyclic unnecessary-page scans
Atsushi Kumagai
kumagai-atsushi at mxc.nes.nec.co.jp
Thu Sep 19 01:40:35 EDT 2013
Hello Cliff,
(2013/08/29 7:08), Cliff Wickman wrote:
> From: Cliff Wickman <cpw at 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 at 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 at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
More information about the kexec
mailing list