[PATCH] kexec memory ranges dynamic allocation

Simon Horman horms at verge.net.au
Thu Oct 30 22:29:06 EDT 2008


Hi,

Could someone please comment on the satus of this patch?

On Wed, Oct 15, 2008 at 12:46:24PM +0400, Maxim Uvarov wrote:
> Patch corrected. ( git_kexec_powerpc_v2.patch is attached.)
> 
> I tested it on ppc64 pasemi electra board. Both kexec -l and kexec -p works.
> 
> Maxim.
> 
> 
> 
> 2008/10/15 Simon Horman <horms at verge.net.au>
> 
> > On Tue, Oct 14, 2008 at 07:11:19PM +0400, Maxim Uvarov wrote:
> > > Hello all,
> > >
> > > As you all know it is not easy to count exact value of memory ranges from
> > > device tree on powerpc.
> > > It very depends on how dts file was written. What do you think about
> > really
> > > dynamic allocation buffers
> > > for this buffers?
> >
> > Conceptually I have no objections to the change,
> > though I would like to get some review from ppc people.
> > (linuxppc-dev at ozlabs.org CCed)
> >
> > > Patch is attached.
> >
> > This patch doesn't seem to compile for me.
> >
> > # powerpc64-unknown-linux-gnu-gcc --version
> > powerpc64-unknown-linux-gnu-gcc (GCC) 4.1.1
> > Copyright (C) 2006 Free Software Foundation, Inc.
> > This is free software; see the source for copying conditions.  There is NO
> > warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> >
> > #make
> > [snip]
> > kexec/arch/ppc64/kexec-ppc64.c:100: warning: function declaration isn't a
> > prototype
> > kexec/arch/ppc64/kexec-ppc64.c: In function 'realloc_memory_ranges':
> > kexec/arch/ppc64/kexec-ppc64.c:107: warning: passing argument 1 of
> > 'realloc' makes pointer from integer without a cast
> > kexec/arch/ppc64/kexec-ppc64.c:107: error: too few arguments to function
> > 'realloc'
> > kexec/arch/ppc64/kexec-ppc64.c:102: warning: unused variable 'tmp'
> >
> > --
> > Simon Horman
> >  VA Linux Systems Japan K.K., Sydney, Australia Satellite Office
> >  H: www.vergenet.net/~horms/ <http://www.vergenet.net/%7Ehorms/>
> >   W: www.valinux.co.jp/en
> >
> >
> 
> 
> -- 
> Best regards,
> Maxim Uvarov

> diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c
> index 069a9fc..0ad40fa 100644
> --- a/kexec/arch/ppc64/kexec-ppc64.c
> +++ b/kexec/arch/ppc64/kexec-ppc64.c
> @@ -96,96 +96,46 @@ err1:
>  
>  }
>  
> -static int count_dyn_reconf_memory_ranges(void)
> +static int realloc_memory_ranges()
>  {
> -	char device_tree[] = "/proc/device-tree/";
> -	char fname[128];
> -	char buf[32];
> -	FILE *file;
> -
> -	strcpy(fname, device_tree);
> -	strcat(fname, "ibm,dynamic-reconfiguration-memory/ibm,lmb-size");
> -	if ((file = fopen(fname, "r")) == NULL) {
> -		perror(fname);
> -		return -1;
> -	}
> +	size_t memory_range_len;
>  
> -	if (fread(buf, 1, 8, file) < 0) {
> -		perror(fname);
> -		fclose(file);
> -		return -1;
> -	}
> -
> -	lmb_size = ((uint64_t *)buf)[0];
> -	fclose(file);
> +	max_memory_ranges++;
> +	memory_range_len = sizeof(struct memory_range) * max_memory_ranges;
>  
> -	/* Get number of lmbs from ibm,dynamic-memory */
> -	strcpy(fname, device_tree);
> -	strcat(fname, "ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory");
> -	if ((file = fopen(fname, "r")) == NULL) {
> -		perror(fname);
> -		return -1;
> -	}
> -	/*
> -	 * first 4 bytes provide number of entries(lmbs)
> -	 */
> -	if (fread(buf, 1, 4, file) < 0) {
> -		perror(fname);
> -		fclose(file);
> -		return -1;
> -	}
> -	num_of_lmbs = ((unsigned int *)buf)[0];
> -	max_memory_ranges += num_of_lmbs;
> -	fclose(file);
> +	memory_range = (struct memory_range *) realloc(memory_range, memory_range_len);
> +	if (!memory_range)
> +		goto err;
>  
> -	return 0;
> -}
> +	base_memory_range = (struct memory_range *) realloc(memory_range, memory_range_len);
> +	if (!base_memory_range)
> +		goto err;
>  
> -/*
> - * Count the memory nodes under /proc/device-tree and populate the
> - * max_memory_ranges variable. This variable replaces MAX_MEMORY_RANGES
> - * macro used earlier.
> - */
> -static int count_memory_ranges(void)
> -{
> -	char device_tree[256] = "/proc/device-tree/";
> -	struct dirent *dentry;
> -	DIR *dir;
> +	exclude_range = (struct memory_range *) realloc(exclude_range, memory_range_len);
> +	if (!exclude_range)
> +		goto err;
>  
> -	if ((dir = opendir(device_tree)) == NULL) {
> -		perror(device_tree);
> -		return -1;
> -	}
> +	usablemem_rgns.ranges = (struct memory_range *)
> +				realloc(usablemem_rgns.ranges, memory_range_len);
> +	if (!(usablemem_rgns.ranges))
> +		goto err;
>  
> -	while ((dentry = readdir(dir)) != NULL) {
> -		if (!strncmp(dentry->d_name,
> -				"ibm,dynamic-reconfiguration-memory", 35)){
> -			if (count_dyn_reconf_memory_ranges() != 0)
> -				return -1;
> -			continue;
> -		}
> +	return 0;
>  
> -		if (strncmp(dentry->d_name, "memory@", 7) &&
> -			strcmp(dentry->d_name, "memory") &&
> -			strncmp(dentry->d_name, "pci@", 4))
> -			continue;
> -		max_memory_ranges++;
> -	}
> -	/* need to add extra region for retained initrd */
> -	if (reuse_initrd) {
> -		max_memory_ranges++;
> -	}
> +err:
> +	fprintf(stderr, "memory range structure re-allocation failure\n");
> +	return -1;
> +}
>  
> -	closedir(dir);
>  
> -	return 0;
> -}
>  static void add_base_memory_range(uint64_t start, uint64_t end)
>  {
>  	base_memory_range[nr_memory_ranges].start = start;
>  	base_memory_range[nr_memory_ranges].end  = end;
>  	base_memory_range[nr_memory_ranges].type = RANGE_RAM;
>  	nr_memory_ranges++;
> +	if (nr_memory_ranges >= max_memory_ranges) 
> +		realloc_memory_ranges(); 
>  
>  	dbgprintf("%016llx-%016llx : %x\n",
>  		base_memory_range[nr_memory_ranges-1].start,
> @@ -300,8 +250,8 @@ static int get_base_ranges(void)
>  				return -1;
>  			}
>  			if (nr_memory_ranges >= max_memory_ranges) {
> -				fclose(file);
> -				break;
> +				if (realloc_memory_ranges() < 0)
> +					break;
>  			}
>  			start = ((uint64_t *)buf)[0];
>  			end = start + ((uint64_t *)buf)[1];
> @@ -396,6 +346,8 @@ static int get_devtree_details(unsigned long kexec_flags)
>  			exclude_range[i].start = 0x0UL;
>  			exclude_range[i].end = kernel_end;
>  			i++;
> +			if (i >= max_memory_ranges)
> +				realloc_memory_ranges();
>  
>  			if (kexec_flags & KEXEC_ON_CRASH) {
>  				memset(fname, 0, sizeof(fname));
> @@ -470,6 +422,8 @@ static int get_devtree_details(unsigned long kexec_flags)
>  			exclude_range[i].start = htab_base;
>  			exclude_range[i].end = htab_base + htab_size;
>  			i++;
> +			if (i >= max_memory_ranges)
> +				realloc_memory_ranges();
>  
>  			/* reserve the initrd_start and end locations. */
>  			if (reuse_initrd) {
> @@ -545,6 +499,8 @@ static int get_devtree_details(unsigned long kexec_flags)
>  			exclude_range[i].start = rtas_base;
>  			exclude_range[i].end = rtas_base + rtas_size;
>  			i++;
> +			if (i >= max_memory_ranges)
> +				realloc_memory_ranges();
>  			if (kexec_flags & KEXEC_ON_CRASH)
>  				add_usable_mem_rgns(rtas_base, rtas_size);
>  		} /* rtas */
> @@ -740,9 +696,10 @@ out:
>  /* Return a list of valid memory ranges */
>  int get_memory_ranges(struct memory_range **range, int *ranges,
>  			unsigned long kexec_flags)
> -{
> -	if (count_memory_ranges())
> -		return -1;
> +{	
> +        /* allocate memory_range dynamically */
> +        max_memory_ranges = 1;
> +
>  	if (alloc_memory_ranges())
>  		return -1;
>  	if (setup_memory_ranges(kexec_flags))


-- 
Simon Horman
  VA Linux Systems Japan K.K., Sydney, Australia Satellite Office
  H: www.vergenet.net/~horms/             W: www.valinux.co.jp/en




More information about the kexec mailing list