[PATCH] makedumpfile: clean up readmem() by removing its recursive call

Atsushi Kumagai kumagai-atsushi at mxc.nes.nec.co.jp
Tue Feb 19 21:25:20 EST 2013


Hello HATAYAMA-san,

On Tue, 19 Feb 2013 05:05:39 +0000
"Hatayama, Daisuke" <d.hatayama at jp.fujitsu.com> wrote:

> Currently, readmem() calls itself recursively and its depth grows in
> proportin to the number of requested pages.
> 
> For example, in __exclude_unnecessary_pages(), PGMM_CACHED is defined
> as 512 and page structure is of 56 bytes on x86_64, so size of page
> cache on x86_64 is now 56 * 512 = 28KiB, and this is 7 pages. This
> means that on the existing implementation readmem() is called
> recursively 7 times when reading mem_map array, but 6 of the 7 are
> in fact unnecessary.
> 
> This patch cleans up readmem() by removing the recursive
> call. Instead, readmem() proceeds to the processing for next page by
> jump.
> 
> Also, by this change, read operation is done in increasing order. This
> is more natural than the existing implementation in decreasing order.
> 
> Signed-off-by: HATAYAMA Daisuke <d.hatayama at jp.fujitsu.com>

Thanks, I'll merge this patch into v1.5.4.


Atsushi Kumagai

> ---
>  makedumpfile.c |   28 ++++++++++++++--------------
>  1 files changed, 14 insertions(+), 14 deletions(-)
> 
> diff --git a/makedumpfile.c b/makedumpfile.c
> index acb1b21..0bc8e1c 100644
> --- a/makedumpfile.c
> +++ b/makedumpfile.c
> @@ -337,13 +337,12 @@ readpage_kdump_compressed(unsigned long long paddr, void *bufptr)
>  int
>  readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size)
>  {
> -	size_t read_size, next_size;
> -	unsigned long long next_addr;
> +	size_t read_size, size_orig = size;
>  	unsigned long long paddr, maddr = NOT_PADDR;
>  	unsigned long long pgaddr;
>  	void *pgbuf;
> -	char *next_ptr;
>  
> +next_page:
>  	switch (type_addr) {
>  	case VADDR:
>  		if ((paddr = vaddr_to_paddr(addr)) == NOT_PADDR) {
> @@ -386,21 +385,14 @@ readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size)
>  		goto error;
>  	}
>  
> -	read_size = size;
> -
>  	/*
>  	 * Read each page, because pages are not necessarily continuous.
>  	 * Ex) pages in vmalloc area
>  	 */
> -	if (!is_in_same_page(addr, addr + size - 1)) {
> -		read_size = info->page_size - (addr % info->page_size);
> -		next_addr = roundup(addr + 1, info->page_size);
> -		next_size = size - read_size;
> -		next_ptr  = (char *)bufptr + read_size;
> +	read_size = info->page_size - PAGEOFFSET(paddr);
>  
> -		if (!readmem(type_addr, next_addr, next_ptr, next_size))
> -			goto error;
> -	}
> +	if (read_size > size)
> +		read_size = size;
>  
>  	pgaddr = PAGEBASE(paddr);
>  	pgbuf = cache_search(pgaddr);
> @@ -423,7 +415,15 @@ readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size)
>  	}
>  
>  	memcpy(bufptr, pgbuf + PAGEOFFSET(paddr), read_size);
> -	return size;
> +
> +	addr += read_size;
> +	bufptr += read_size;
> +	size -= read_size;
> +
> +	if (size > 0)
> +		goto next_page;
> +
> +	return size_orig;
>  
>  error:
>  	ERRMSG("type_addr: %d, addr:%llx, size:%zd\n", type_addr, addr, size);
> -- 
> 1.7.7.6
> 



More information about the kexec mailing list