Re: [PATCH 7/9] PM / Hibernate: split snapshot_write_next

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wednesday, June 02, 2010, Jiri Slaby wrote:
> When reading the snapshot, do the initialization and header read in
> a separate function. This makes the code more readable and lowers
> complexity of snapshot_write_next.

Same as for [6/9], looks good by itself, but seems to depend on
[3/9] and [4/9].

> Signed-off-by: Jiri Slaby <jslaby@xxxxxxx>
> Cc: "Rafael J. Wysocki" <rjw@xxxxxxx>
> ---
>  kernel/power/power.h    |    2 +
>  kernel/power/snapshot.c |  100 ++++++++++++++++++++++++++++++-----------------
>  kernel/power/swap.c     |   20 ++++------
>  3 files changed, 74 insertions(+), 48 deletions(-)
> 
> diff --git a/kernel/power/power.h b/kernel/power/power.h
> index ff3f63f..6e2e796 100644
> --- a/kernel/power/power.h
> +++ b/kernel/power/power.h
> @@ -171,6 +171,8 @@ struct hibernate_io_ops {
>  
>  extern unsigned int snapshot_additional_pages(struct zone *zone);
>  extern unsigned long snapshot_get_image_size(void);
> +extern int snapshot_read_init(struct hibernate_io_handle *io_handle,
> +		struct snapshot_handle *handle);
>  extern int snapshot_write_init(struct hibernate_io_handle *io_handle,
>  		struct snapshot_handle *handle);
>  extern int snapshot_read_next(struct snapshot_handle *handle);
> diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
> index 4600d15..9cd6931 100644
> --- a/kernel/power/snapshot.c
> +++ b/kernel/power/snapshot.c
> @@ -2129,10 +2129,54 @@ static void *get_buffer(struct memory_bitmap *bm, struct chain_allocator *ca)
>  }
>  
>  /**
> + *	snapshot_read_init - initialization before reading the snapshot from
> + *	a backing storage
> + *
> + *	This function *must* be called before snapshot_write_next to initialize
> + *	@handle and read header.
> + *
> + *	@io_handle: io handle used for reading
> + *	@handle: snapshot handle to init
> + */
> +int snapshot_read_init(struct hibernate_io_handle *io_handle,
> +		struct snapshot_handle *handle)
> +{
> +	int ret;
> +
> +	/* This makes the buffer be freed by swsusp_free() */
> +	buffer = get_image_page(GFP_ATOMIC, PG_ANY);
> +	if (!buffer)
> +		return -ENOMEM;
> +
> +	ret = hib_buffer_init_read(io_handle);
> +	if (ret)
> +		return ret;
> +	ret = hib_buffer_read(io_handle, buffer, sizeof(struct swsusp_info));
> +	if (ret)
> +		goto finish;
> +	hib_buffer_finish_read(io_handle);
> +
> +	ret = load_header(buffer);
> +	if (ret)
> +		return ret;
> +
> +	ret = memory_bm_create(&copy_bm, GFP_ATOMIC, PG_ANY);
> +	if (ret)
> +		return ret;
> +
> +	handle->buffer = buffer;
> +	handle->sync_read = 1;
> +	return 0;
> +finish:
> +	hib_buffer_finish_read(io_handle);
> +	return ret;
> +}
> +
> +/**
>   *	snapshot_write_next - used for writing the system memory snapshot.
>   *
> - *	On the first call to it @handle should point to a zeroed
> - *	snapshot_handle structure.  The structure gets updated and a pointer
> + *	Before calling this function, snapshot_read_init has to be called with
> + *	handle passed as @handle here. The structure gets updated and a pointer
>   *	to it should be passed to this function every next time.
>   *
>   *	On success the function returns a positive number.  Then, the caller
> @@ -2144,42 +2188,20 @@ static void *get_buffer(struct memory_bitmap *bm, struct chain_allocator *ca)
>   *	structure pointed to by @handle is not updated and should not be used
>   *	any more.
>   */
> -
>  int snapshot_write_next(struct snapshot_handle *handle)
>  {
>  	static struct chain_allocator ca;
>  	int error = 0;
>  
> -	/* Check if we have already loaded the entire image */
> -	if (handle->cur > 1 && handle->cur > nr_meta_pages + nr_copy_pages)
> -		return 0;
> -
>  	handle->sync_read = 1;
> -
> -	if (!handle->cur) {
> -		if (!buffer)
> -			/* This makes the buffer be freed by swsusp_free() */
> -			buffer = get_image_page(GFP_ATOMIC, PG_ANY);
> -
> -		if (!buffer)
> -			return -ENOMEM;
> -
> -		handle->buffer = buffer;
> -	} else if (handle->cur == 1) {
> -		error = load_header(buffer);
> -		if (error)
> -			return error;
> -
> -		error = memory_bm_create(&copy_bm, GFP_ATOMIC, PG_ANY);
> -		if (error)
> -			return error;
> -
> -	} else if (handle->cur <= nr_meta_pages + 1) {
> +	if (handle->cur < nr_meta_pages) {
>  		error = unpack_orig_pfns(buffer, &copy_bm);
>  		if (error)
>  			return error;
>  
> -		if (handle->cur == nr_meta_pages + 1) {
> +		/* well, this was the last meta page
> +		   prepare for ordinary pages */
> +		if (handle->cur + 1 == nr_meta_pages) {
>  			error = prepare_image(&orig_bm, &copy_bm);
>  			if (error)
>  				return error;
> @@ -2192,16 +2214,22 @@ int snapshot_write_next(struct snapshot_handle *handle)
>  			if (IS_ERR(handle->buffer))
>  				return PTR_ERR(handle->buffer);
>  		}
> +		error = PAGE_SIZE;
>  	} else {
>  		copy_last_highmem_page();
> -		handle->buffer = get_buffer(&orig_bm, &ca);
> -		if (IS_ERR(handle->buffer))
> -			return PTR_ERR(handle->buffer);
> -		if (handle->buffer != buffer)
> -			handle->sync_read = 0;
> +		/* prepare next unless this was the last one */
> +		if (handle->cur + 1 < nr_meta_pages + nr_copy_pages) {
> +			handle->buffer = get_buffer(&orig_bm, &ca);
> +			if (IS_ERR(handle->buffer))
> +				return PTR_ERR(handle->buffer);
> +			if (handle->buffer != buffer)
> +				handle->sync_read = 0;
> +			error = PAGE_SIZE;
> +		}
>  	}
> +
>  	handle->cur++;
> -	return PAGE_SIZE;
> +	return error;
>  }
>  
>  /**
> @@ -2216,7 +2244,7 @@ void snapshot_write_finalize(struct snapshot_handle *handle)
>  {
>  	copy_last_highmem_page();
>  	/* Free only if we have loaded the image entirely */
> -	if (handle->cur > 1 && handle->cur > nr_meta_pages + nr_copy_pages) {
> +	if (handle->cur >= nr_meta_pages + nr_copy_pages) {
>  		memory_bm_free(&orig_bm, PG_UNSAFE_CLEAR);
>  		free_highmem_data();
>  	}
> @@ -2225,7 +2253,7 @@ void snapshot_write_finalize(struct snapshot_handle *handle)
>  int snapshot_image_loaded(struct snapshot_handle *handle)
>  {
>  	return !(!nr_copy_pages || !last_highmem_page_copied() ||
> -			handle->cur <= nr_meta_pages + nr_copy_pages);
> +			handle->cur < nr_meta_pages + nr_copy_pages);
>  }
>  
>  #ifdef CONFIG_HIGHMEM
> diff --git a/kernel/power/swap.c b/kernel/power/swap.c
> index 9b319f1..f7864bc 100644
> --- a/kernel/power/swap.c
> +++ b/kernel/power/swap.c
> @@ -599,9 +599,6 @@ static int load_image(struct hibernate_io_handle *io_handle,
>  	bio = NULL;
>  	do_gettimeofday(&start);
>  	for ( ; ; ) {
> -		error = snapshot_write_next(snapshot);
> -		if (error <= 0)
> -			break;
>  		error = hibernate_io_ops->read_page(io_handle,
>  				data_of(*snapshot), &bio);
>  		if (error)
> @@ -610,9 +607,13 @@ static int load_image(struct hibernate_io_handle *io_handle,
>  			error = hib_wait_on_bio_chain(&bio);
>  		if (error)
>  			break;
> +		error = snapshot_write_next(snapshot);
> +		if (error >= 0)
> +			nr_pages++;
> +		if (error <= 0)
> +			break;
>  		if (!(nr_pages % m))
>  			printk("\b\b\b\b%3d%%", nr_pages / m);
> -		nr_pages++;
>  	}
>  	err2 = hib_wait_on_bio_chain(&bio);
>  	do_gettimeofday(&stop);
> @@ -640,22 +641,17 @@ int swsusp_read(unsigned int *flags_p)
>  	int error;
>  	struct hibernate_io_handle *io_handle;
>  	struct snapshot_handle snapshot;
> -	struct swsusp_info *header;
>  
>  	memset(&snapshot, 0, sizeof(struct snapshot_handle));
> -	error = snapshot_write_next(&snapshot);
> -	if (error < PAGE_SIZE)
> -		return error < 0 ? error : -EFAULT;
> -	header = (struct swsusp_info *)data_of(snapshot);
>  	io_handle = hibernate_io_ops->reader_start(flags_p);
>  	if (IS_ERR(io_handle)) {
>  		error = PTR_ERR(io_handle);
>  		goto end;
>  	}
> +	error = snapshot_read_init(io_handle, &snapshot);
>  	if (!error)
> -		error = hibernate_io_ops->read_page(io_handle, header, NULL);
> -	if (!error)
> -		error = load_image(io_handle, &snapshot, header->pages - 1);
> +		error = load_image(io_handle, &snapshot,
> +				snapshot_get_image_size()  - 1);
>  	hibernate_io_ops->reader_finish(io_handle);
>  end:
>  	if (!error)
> 

_______________________________________________
linux-pm mailing list
linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx
https://lists.linux-foundation.org/mailman/listinfo/linux-pm


[Index of Archives]     [Linux ACPI]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [CPU Freq]     [Kernel Newbies]     [Fedora Kernel]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux