public inbox for kexec@lists.infradead.org
 help / color / mirror / Atom feed
From: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
To: Thomas Renninger <trenn@suse.de>
Cc: kexec@lists.infradead.org, horms@verge.net.au,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	"H. Peter Anvin" <hpa@zytor.com>,
	yinghai@kernel.org, cpw@sgi.com, vgoyal@redhat.com
Subject: Re: [PATCH 5/5] kexec: X86: Pass memory ranges via e820 table instead of memmap= boot parameter
Date: Fri, 12 Apr 2013 17:56:08 +0800	[thread overview]
Message-ID: <5167DA38.3050600@cn.fujitsu.com> (raw)
In-Reply-To: <1365683207-42425-6-git-send-email-trenn@suse.de>

于 2013年04月11日 20:26, Thomas Renninger 写道:
> Currently ranges are passed via kernel boot parameters:
> memmap=exactmap memmap=X#Y memmap=
> 
> Pass them via e820 table directly instead.
> 
> CC: Simon Horman <horms@verge.net.au>
> CC: kexec@lists.infradead.org
> CC: H. Peter Anvin <hpa@zytor.com>
> CC: Eric W. Biederman <ebiederm@xmission.com>
> CC: vgoyal@redhat.com
> CC: yinghai@kernel.org
> CC: cpw@sgi.com
> 
> Signed-off-by: Thomas Renninger <trenn@suse.de>
> Signed-off-by: Thomas Renninger <Thomas Renninger" trenn@suse.de>
> ---
>  kexec/arch/i386/crashdump-x86.c   |  221 ++++++++++++++++++-------------------
>  kexec/arch/i386/x86-linux-setup.c |   11 ++-
>  2 files changed, 116 insertions(+), 116 deletions(-)
> 
> diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
> index f7821bc..8009efe 100644
> --- a/kexec/arch/i386/crashdump-x86.c
> +++ b/kexec/arch/i386/crashdump-x86.c
> @@ -659,70 +659,6 @@ static void ultoa(unsigned long i, char *str)
>  	}
>  }
>  
> -static void cmdline_add_memmap_internal(char *cmdline, unsigned long startk,
> -					unsigned long endk, int type)
> -{
> -	int cmdlen, len;
> -	char str_mmap[256], str_tmp[20];
> -
> -	strcpy (str_mmap, " memmap=");
> -	ultoa((endk-startk), str_tmp);
> -	strcat (str_mmap, str_tmp);
> -
> -	if (type == RANGE_RAM)
> -		strcat (str_mmap, "K@");
> -	else if (type == RANGE_RESERVED)
> -		strcat (str_mmap, "K$");
> -	else if (type == RANGE_ACPI || type == RANGE_ACPI_NVS)
> -		strcat (str_mmap, "K#");
> -
> -	ultoa(startk, str_tmp);
> -	strcat (str_mmap, str_tmp);
> -	strcat (str_mmap, "K");
> -	len = strlen(str_mmap);
> -	cmdlen = strlen(cmdline) + len;
> -	if (cmdlen > (COMMAND_LINE_SIZE - 1))
> -		die("Command line overflow\n");
> -	strcat(cmdline, str_mmap);
> -}
> -
> -/* Adds the appropriate memmap= options to command line, indicating the
> - * memory regions the new kernel can use to boot into. */
> -static int cmdline_add_memmap(char *cmdline, struct memory_range *memmap_p)
> -{
> -	int i, cmdlen, len;
> -	unsigned long min_sizek = 100;
> -	char str_mmap[256];
> -
> -	/* Exact map */
> -	strcpy(str_mmap, " memmap=exactmap");
> -	len = strlen(str_mmap);
> -	cmdlen = strlen(cmdline) + len;
> -	if (cmdlen > (COMMAND_LINE_SIZE - 1))
> -		die("Command line overflow\n");
> -	strcat(cmdline, str_mmap);
> -
> -	for (i = 0; i < CRASH_MAX_MEMMAP_NR;  i++) {
> -		unsigned long startk, endk;
> -		startk = (memmap_p[i].start/1024);
> -		endk = ((memmap_p[i].end + 1)/1024);
> -		if (!startk && !endk)
> -			/* All regions traversed. */
> -			break;
> -
> -		/* A region is not worth adding if region size < 100K. It eats
> -		 * up precious command line length. */
> -		if ((endk - startk) < min_sizek)
> -			continue;
> -		cmdline_add_memmap_internal(cmdline, startk, endk, RANGE_RAM);
> -	}
> -
> -	dbgprintf("Command line after adding memmap\n");
> -	dbgprintf("%s\n", cmdline);
> -
> -	return 0;
> -}
> -
>  /* Adds the elfcorehdr= command line parameter to command line. */
>  static int cmdline_add_elfcorehdr(char *cmdline, unsigned long addr)
>  {
> @@ -803,26 +739,6 @@ static enum coretype get_core_type(struct crash_elf_info *elf_info,
>  	}
>  }
>  
> -/* Appends memmap=X#Y commandline for ACPI to command line*/
> -static int cmdline_add_memmap_acpi(char *cmdline, unsigned long start,
> -					unsigned long end)
> -{
> -	int align = 1024;
> -	unsigned long startk, endk;
> -
> -	if (!(end - start))
> -		return 0;
> -
> -	startk = start/1024;
> -	endk = (end + align - 1)/1024;
> -	cmdline_add_memmap_internal(cmdline, startk, endk, RANGE_ACPI);
> -
> -	dbgprintf("Command line after adding acpi memmap\n");
> -	dbgprintf("%s\n", cmdline);
> -
> -	return 0;
> -}
> -
>  /* Appends 'acpi_rsdp=' commandline for efi boot crash dump */
>  static void cmdline_add_efi(char *cmdline)
>  {
> @@ -881,24 +797,101 @@ static void get_backup_area(struct kexec_info *info,
>  	info->backup_src_size = BACKUP_SRC_END - BACKUP_SRC_START + 1;
>  }
>  
> -/* Appends memmap=X$Y commandline for reserved memory to command line*/
> -static int cmdline_add_memmap_reserved(char *cmdline, unsigned long start,
> -					unsigned long end)
> +/*
> + * This function takes reserved (all kind of) memory from global
> + * crash_memory_range[] memory ranges and takes memory the kdump/crash
> + * kernel is allowed to use from the passed usable_mem memory ranges. 
> + * The passed usable_mem ranges are zero (!start && !end) terminated.
> + *
> + * The final memory map is again written into crash_memory_range[]
> + * and intended to get passed as e820 table to the crash kernel
> + */
> +static int create_final_crash_map(struct memory_range *usable_mem)
>  {
> -	int align = 1024;
> -	unsigned long startk, endk;
> +	int i, m, c, tmp_map1_ranges, tmp_map2_ranges;
> +	unsigned long min_sizek = 100;
> +	/* crash_memory_map with usable memory ranges cut out */
> +	struct memory_range tmp_map1[MAX_MEMORY_RANGES];
> +	/* merge_map, but small ranges cut out */
> +	struct memory_range tmp_map2[MAX_MEMORY_RANGES];
>  
> -	if (!(end - start))
> -		return 0;
> +	/*
> +	 * Ignore usable memory ranges for kdump kernel smaller
> +	 * than 100k to avoid too much ranges passed
> +	 * Save the new ranges (exluding lower than 100k ranges) in tmp_map
> +	 * and store the number of elements in tmp_map_ranges
> +	 */
> +	for (m = 0, i = 0; i < CRASH_MAX_MEMMAP_NR; i++) {
> +		unsigned long startk, endk;
> +		startk = (usable_mem[i].start/1024);
> +		endk = ((usable_mem[i].end + 1)/1024);
> +		if (!startk && !endk)
> +			/* All regions traversed. */
> +			break;
> +
> +		/* A region is not worth adding if region size < 100K. It eats
> +		 * up precious command line length. */

Now you are passing the e820 table directly instead of the commandline, so does
this comment make sense now?

> +		if ((endk - startk) < min_sizek) {
> +			dbgprintf("Removing: %luk - %luk\n", startk, endk);
> +			continue;
> +		} else {
> +			tmp_map1[m].start = usable_mem[i].start;
> +			tmp_map1[m].end   = usable_mem[i].end;
> +			tmp_map1[m].type = usable_mem[i].type;
> +			m++;
> +		}
> +	}
> +	/* No need to check for !start && !end anymore */
> +	tmp_map1_ranges = m;
>  
> -	startk = start/1024;
> -	endk = (end + align - 1)/1024;
> -	cmdline_add_memmap_internal(cmdline, startk, endk, RANGE_RESERVED);
> +	for(i = 0; i < tmp_map1_ranges; ++i)
> +		dbgprintf("%016Lx-%016Lx (%d)\n", tmp_map1[i].start,
> +			  tmp_map1[i].end, tmp_map1[i].type);
> +
> +	/*
> +	 * Cut out RANGE_RAM regions from crash_memory_ranges and store
> +	 * them in tmp_map2_ranges
> +	 */
> +	for (c = 0, i = 0; i < crash_ranges; i++) {
> +		if (crash_memory_range[i].type == RANGE_RAM)
> +			continue;
> +		tmp_map2[c].start = crash_memory_range[i].start;
> +		tmp_map2[c].end = crash_memory_range[i].end;
> +		tmp_map2[c].type = crash_memory_range[i].type;
> +		c++;
> +	}
> +	tmp_map2_ranges = c;
> +
> +	/*
> +	 * TBD: Check that no ranges overlap?
> +	 * Can this happen at all?
> +	 */
> +	for (c = 0, m = 0, i = 0; i < MAX_MEMORY_RANGES; i++) {
> +		if (m < tmp_map1_ranges &&
> +		    (c >= tmp_map2_ranges ||
> +		     tmp_map2[c].start > tmp_map1[m].start)) {
> +			crash_memory_range[i].start = tmp_map1[m].start;
> +			crash_memory_range[i].end   = tmp_map1[m].end;
> +			crash_memory_range[i].type  = RANGE_RAM;
> +			m++;
> +			continue;
> +		} else if (c < tmp_map2_ranges) {
> +			crash_memory_range[i] = tmp_map2[c];
> +			c++;
> +			continue;
> +		} else
> +			break;
> +	}
> +	crash_ranges = i;
> +
> +	/*
> +	 * End address has to be exlusive for e820 map
> +	 * x        - 00010000
> +	 * 00010000 - y
> +	 */
> +	for(i = 0; i < crash_ranges; ++i)
> +		crash_memory_range[i].end++;
>  
> -#ifdef DEBUG
> -		printf("Command line after adding reserved memmap\n");
> -		printf("%s\n", cmdline);
> -#endif
>  	return 0;
>  }
>  
> @@ -944,6 +937,12 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
>  		return -1;
>  	}
>  
> +	/*
> +	 * From now on the memory regions are stored in crash_memory_range[]
> +	 * Currently the end address is inclusive at this point:
> +	 * x        - 0000ffff
> +	 * 00010000 - y
> +	 */
>  	if (xen_present()) {
>  		if (get_crash_memory_ranges_xen(&mem_range, &crash_ranges,
>  						elf_info.lowmem_limit) < 0)
> @@ -971,7 +970,7 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
>  
>  	get_backup_area(info, mem_range, crash_ranges);
>  
> -	dbgprintf("CRASH MEMORY RANGES\n");
> +	dbgprintf("TEMPORARY CRASH MEMORY RANGES\n");
>  
>  	for(i = 0; i < crash_ranges; ++i)
>  		dbgprintf("%016Lx-%016Lx (%d)\n", mem_range[i].start,
> @@ -1063,24 +1062,18 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
>  	dbgprintf("Created elf header segment at 0x%lx\n", elfcorehdr);
>  	if (delete_memmap(memmap_p, elfcorehdr, memsz) < 0)
>  		return -1;
> -	cmdline_add_memmap(mod_cmdline, memmap_p);
>  	cmdline_add_efi(mod_cmdline);
>  	cmdline_add_elfcorehdr(mod_cmdline, elfcorehdr);
>  
> -	/* Inform second kernel about the presence of ACPI tables. */
> -	for (i = 0; i < MAX_MEMORY_RANGES; i++) {
> -		unsigned long start, end;
> -		if ( !( mem_range[i].type == RANGE_ACPI
> -			|| mem_range[i].type == RANGE_ACPI_NVS
> -			|| mem_range[i].type == RANGE_RESERVED) )
> -			continue;
> -		start = mem_range[i].start;
> -		end = mem_range[i].end;
> -		if (mem_range[i].type == RANGE_RESERVED)
> -			cmdline_add_memmap_reserved(mod_cmdline, start, end);
> -		else
> -			cmdline_add_memmap_acpi(mod_cmdline, start, end);
> -	}
> +	/*
> +	 * Redo crash_memory_range so that it can get passed as e820 info
> +	 */
> +	create_final_crash_map(memmap_p);
> +
> +	dbgprintf("FINAL CRASH MEMORY RANGES\n");
> +	for(i = 0; i < crash_ranges; ++i)
> +		dbgprintf("%016Lx-%016Lx (%d)\n", mem_range[i].start,
> +			  mem_range[i].end, mem_range[i].type);
>  	return 0;
>  }
>  
> diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c
> index c538897..82b4bb9 100644
> --- a/kexec/arch/i386/x86-linux-setup.c
> +++ b/kexec/arch/i386/x86-linux-setup.c
> @@ -505,8 +505,15 @@ void setup_linux_system_parameters(struct kexec_info *info,
>  	/* another safe default */
>  	real_mode->aux_device_info = 0;
>  
> -	range = info->memory_range;
> -	ranges = info->memory_ranges;
> +	if (info->kexec_flags & KEXEC_ON_CRASH || 
> +	    info->kexec_flags & KEXEC_PRESERVE_CONTEXT) {
> +		range = crash_memory_range;
> +		ranges = crash_ranges;
> +	} else {
> +		range = info->memory_range;
> +		ranges = info->memory_ranges;
> +	}
> +
>  	if (ranges > E820MAX) {
>  		if (!(info->kexec_flags & KEXEC_ON_CRASH))
>  			/*


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

  parent reply	other threads:[~2013-04-12  9:57 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-11 12:26 Cleanups and passing memory ranges via e820 table instead of memmap= Thomas Renninger
2013-04-11 12:26 ` [PATCH 1/5] kexec: X86: Show e820 table which gets passed in debug mode Thomas Renninger
2013-04-11 12:26 ` [PATCH 2/5] kexec: X86: Enhance crash range debug output Thomas Renninger
2013-04-11 12:26 ` [PATCH 3/5] kexec: X86: Do not exclude memory regions in each get_xy_memory_range() func Thomas Renninger
2013-04-11 12:26 ` [PATCH 4/5] kexec: X86: make crash_memory_range global and store its no of elements in crash_ranges Thomas Renninger
2013-04-11 12:26 ` [PATCH 5/5] kexec: X86: Pass memory ranges via e820 table instead of memmap= boot parameter Thomas Renninger
2013-04-11 14:55   ` Yinghai Lu
2013-04-11 15:06     ` H. Peter Anvin
2013-04-12 14:31       ` Vivek Goyal
2013-04-12 14:56         ` H. Peter Anvin
2013-04-12 22:17           ` Dave Hansen
2013-04-12 23:17             ` H. Peter Anvin
2013-04-15  4:52             ` HATAYAMA Daisuke
2013-04-15  5:58               ` Dave Hansen
2013-04-15  7:58                 ` HATAYAMA Daisuke
2013-04-15 14:49                 ` H. Peter Anvin
2013-04-12 12:24     ` Thomas Renninger
2013-04-12  9:56   ` Zhang Yanfei [this message]
2013-04-12 11:12     ` Thomas Renninger
2013-04-15  9:05     ` Thomas Renninger
2013-04-15 12:20       ` H. Peter Anvin
2013-04-15 19:48         ` Thomas Renninger
2013-04-15 19:54           ` H. Peter Anvin
2013-04-16  7:52             ` Thomas Renninger
2013-04-16 11:59               ` H. Peter Anvin
2013-04-16 12:41               ` Zhang Yanfei
2013-04-12 15:24   ` Eric W. Biederman
2013-04-15 11:48     ` Thomas Renninger

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=5167DA38.3050600@cn.fujitsu.com \
    --to=zhangyanfei@cn.fujitsu.com \
    --cc=cpw@sgi.com \
    --cc=ebiederm@xmission.com \
    --cc=horms@verge.net.au \
    --cc=hpa@zytor.com \
    --cc=kexec@lists.infradead.org \
    --cc=trenn@suse.de \
    --cc=vgoyal@redhat.com \
    --cc=yinghai@kernel.org \
    /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