From: Jiri Slaby <jirislaby@gmail.com>
To: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: linux-pm@lists.linux-foundation.org,
Nigel Cunningham <ncunningham@crca.org.au>
Subject: Re: [RFC 09/15] PM / Hibernate: user, implement user_ops writer
Date: Wed, 31 Mar 2010 16:41:32 +0200 [thread overview]
Message-ID: <4BB35F1C.4030100@gmail.com> (raw)
In-Reply-To: <201003302250.26105.rjw@sisk.pl>
[-- Attachment #1: Type: text/plain, Size: 900 bytes --]
On 03/30/2010 10:50 PM, Rafael J. Wysocki wrote:
> So, I definitely would like to see numbers.
With the patch attached, I get similar results for
uncompressed image -> user.c -> s2disk (compress+threads)
compressed image -> user.c -> s2disk (none of compress+threads)
BUT note that there are differences in pages _copied_ in the "user.c ->
s2disk" phase. Compression was about 40 %. So in the former case 100000
pages went through and in the latter one only ~ 38000. So presumably
there will be savings if the pages are compressed in the kernel in the
save-image phase instead of in userspace.
I'll test (after I hack that up) also the case of image compression when
saving the image and let you know.
It was tested on a machine with openSUSE factory with init 5 with KDE 4.
The memory consumption was ~ 400M (100000 pages) after boot every time.
Hibernation lasted 12-13s in both cases.
--
js
[-- Attachment #2: image_compress.patch --]
[-- Type: text/x-patch, Size: 6111 bytes --]
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 1ceea79..1bb7dc0 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -26,6 +26,7 @@
#include <linux/console.h>
#include <linux/highmem.h>
#include <linux/list.h>
+#include <linux/lzo.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
@@ -35,6 +36,10 @@
#include "power.h"
+static void *lzo_buf;
+static void *page_buf;
+struct timeval hib_start_time;
+
struct memory_bitmap;
static int swsusp_page_is_free(struct page *);
@@ -933,15 +938,76 @@ static unsigned int count_data_pages(void)
return n;
}
+static void cccopy(struct memory_bitmap *copy_bm, const char *buffer, int buffer_size)
+{
+ static unsigned long dst_page_pos;
+ static char *dst_page;
+ int bytes_left = buffer_size;
+
+ if (!dst_page)
+ dst_page = phys_to_virt(PFN_PHYS(memory_bm_next_pfn(copy_bm)));
+
+ while (bytes_left) {
+ const char *from = buffer + buffer_size - bytes_left;
+ char *to = dst_page + dst_page_pos;
+ int capacity = PAGE_SIZE - dst_page_pos;
+ int n;
+
+// printk("%s: to=%p from=%p\n", __func__, to, from);
+ if (bytes_left <= capacity) {
+ for (n = 0; n < bytes_left; n++)
+ to[n] = from[n];
+ dst_page_pos += bytes_left;
+ return;
+ }
+
+ /* Complete this page and start a new one */
+ for (n = 0; n < capacity; n++)
+ to[n] = from[n];
+ bytes_left -= capacity;
+
+ dst_page = phys_to_virt(PFN_PHYS(memory_bm_next_pfn(copy_bm)));
+
+ dst_page_pos = 0;
+ }
+}
+
+#define COMPRESS_IMAGE 0
+
/* This is needed, because copy_page and memcpy are not usable for copying
* task structs.
*/
-static inline void do_copy_page(long *dst, long *src)
+static unsigned long do_copy_page(struct memory_bitmap *copy_bm,
+ const unsigned char *src)
{
- int n;
+// static int first = true;
+#if COMPRESS_IMAGE
+ size_t dst_len;
+ int ret;
- for (n = PAGE_SIZE / sizeof(long); n; n--)
- *dst++ = *src++;
+// printk("%s: %p\n", __func__, page_buf);
+ ret = lzo1x_1_compress(src, PAGE_SIZE, page_buf, &dst_len, lzo_buf);
+ if (ret < 0) {
+ printk(KERN_EMERG "%s: compress failed: ret=%d dst_len=%zu\n",
+ __func__, ret, dst_len);
+ BUG();
+ }
+
+ cccopy(copy_bm, (char *)&dst_len, sizeof(dst_len));
+ cccopy(copy_bm, page_buf, dst_len);
+
+ return sizeof(dst_len) + dst_len;
+#else
+ cccopy(copy_bm, src, PAGE_SIZE);
+ return PAGE_SIZE;
+#endif
+
+/* if (first) {
+ print_hex_dump_bytes("O:", DUMP_PREFIX_OFFSET, src, PAGE_SIZE);
+ printk(KERN_DEBUG "len=%zu\n", dst_len);
+ print_hex_dump_bytes("N:", DUMP_PREFIX_OFFSET, dst, dst_len);
+ first = false;
+ }*/
}
@@ -951,6 +1017,7 @@ static inline void do_copy_page(long *dst, long *src)
* CONFIG_DEBUG_PAGEALLOC is not set and in that case
* kernel_page_present() always returns 'true').
*/
+#if 0
static void safe_copy_page(void *dst, struct page *s_page)
{
if (kernel_page_present(s_page)) {
@@ -962,7 +1029,6 @@ static void safe_copy_page(void *dst, struct page *s_page)
}
}
-
#ifdef CONFIG_HIGHMEM
static inline struct page *
page_is_saveable(struct zone *zone, unsigned long pfn)
@@ -999,7 +1065,6 @@ static void copy_data_page(unsigned long dst_pfn, unsigned long src_pfn)
}
}
#else
-#define page_is_saveable(zone, pfn) saveable_page(zone, pfn)
static inline void copy_data_page(unsigned long dst_pfn, unsigned long src_pfn)
{
@@ -1007,12 +1072,14 @@ static inline void copy_data_page(unsigned long dst_pfn, unsigned long src_pfn)
pfn_to_page(src_pfn));
}
#endif /* CONFIG_HIGHMEM */
+#endif
+#define page_is_saveable(zone, pfn) saveable_page(zone, pfn)
-static void
+static unsigned long
copy_data_pages(struct memory_bitmap *copy_bm, struct memory_bitmap *orig_bm)
{
struct zone *zone;
- unsigned long pfn;
+ unsigned long pfn, copied;
for_each_populated_zone(zone) {
unsigned long max_zone_pfn;
@@ -1025,12 +1092,15 @@ copy_data_pages(struct memory_bitmap *copy_bm, struct memory_bitmap *orig_bm)
}
memory_bm_position_reset(orig_bm);
memory_bm_position_reset(copy_bm);
+ copied = 0;
for(;;) {
pfn = memory_bm_next_pfn(orig_bm);
if (unlikely(pfn == BM_END_OF_MAP))
break;
- copy_data_page(memory_bm_next_pfn(copy_bm), pfn);
+ copied += do_copy_page(copy_bm, page_address(pfn_to_page(pfn)));
+// copy_data_page(memory_bm_next_pfn(copy_bm), pfn);
}
+ return copied;
}
/* Total number of image pages */
@@ -1265,8 +1335,19 @@ int hibernate_preallocate_memory(void)
struct timeval start, stop;
int error;
+ if (!lzo_buf)
+ lzo_buf = vmalloc(LZO1X_MEM_COMPRESS);
+
+ if (!page_buf)
+ page_buf = (void *)__get_free_pages(GFP_KERNEL,
+ get_order(lzo1x_worst_compress(PAGE_SIZE)));
+
+ BUG_ON(!lzo_buf);
+ BUG_ON(!page_buf);
+
printk(KERN_INFO "PM: Preallocating image memory... ");
do_gettimeofday(&start);
+ hib_start_time = start;
error = memory_bm_create(&orig_bm, GFP_IMAGE, PG_ANY);
if (error)
@@ -1525,7 +1606,7 @@ asmlinkage int swsusp_save(void)
* Kill them.
*/
drain_local_pages(NULL);
- copy_data_pages(©_bm, &orig_bm);
+ nr_copy_pages = DIV_ROUND_UP(copy_data_pages(©_bm, &orig_bm), PAGE_SIZE);
/*
* End of critical section. From now on, we can write to memory,
@@ -1534,11 +1615,11 @@ asmlinkage int swsusp_save(void)
*/
nr_pages += nr_highmem;
- nr_copy_pages = nr_pages;
+// nr_copy_pages = nr_pages;
nr_meta_pages = DIV_ROUND_UP(nr_pages * sizeof(long), PAGE_SIZE);
- printk(KERN_INFO "PM: Hibernation image created (%d pages copied)\n",
- nr_pages);
+ printk(KERN_INFO "PM: Hibernation image created (%d of %d pages copied)\n",
+ nr_copy_pages, nr_pages);
return 0;
}
diff --git a/kernel/power/user.c b/kernel/power/user.c
index 92688ce..0f2d6c2 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -541,6 +541,12 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
break;
case SNAPSHOT_POWER_OFF:
+ {
+ extern struct timeval hib_start_time;
+ struct timeval stop;
+ do_gettimeofday(&stop);
+ swsusp_show_speed(&hib_start_time, &stop, 0, "Overall");
+ }
if (data->platform_support)
error = hibernation_platform_enter();
break;
[-- Attachment #3: Type: text/plain, Size: 0 bytes --]
next prev parent reply other threads:[~2010-03-31 14:41 UTC|newest]
Thread overview: 158+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-23 16:17 [RFC 01/15] FS: libfs, implement simple_write_to_buffer Jiri Slaby
2010-03-23 16:17 ` Jiri Slaby
2010-03-23 16:17 ` [RFC 02/15] PM / Hibernate: snapshot cleanup Jiri Slaby
2010-03-24 20:29 ` Pavel Machek
2010-03-24 20:29 ` Pavel Machek
2010-03-24 22:35 ` Rafael J. Wysocki
2010-03-24 22:35 ` Rafael J. Wysocki
2010-03-25 5:29 ` Pavel Machek
2010-03-25 5:29 ` Pavel Machek
2010-03-23 16:17 ` Jiri Slaby
2010-03-23 16:17 ` [RFC 03/15] PM / Hibernate: separate block_io Jiri Slaby
2010-03-23 16:17 ` Jiri Slaby
2010-03-24 20:30 ` Pavel Machek
2010-03-24 21:22 ` Jiri Slaby
2010-03-24 21:22 ` Jiri Slaby
2010-03-24 22:58 ` Nigel Cunningham
2010-03-24 22:58 ` Nigel Cunningham
2010-03-25 2:35 ` Nigel Cunningham
2010-03-25 2:35 ` [linux-pm] " Nigel Cunningham
2010-03-25 20:12 ` Rafael J. Wysocki
2010-03-25 20:12 ` [linux-pm] " Rafael J. Wysocki
2010-03-25 20:13 ` Nigel Cunningham
2010-03-25 20:13 ` [linux-pm] " Nigel Cunningham
2010-03-25 20:33 ` Rafael J. Wysocki
2010-03-25 20:36 ` Nigel Cunningham
2010-03-25 20:36 ` Nigel Cunningham
2010-03-25 20:33 ` Rafael J. Wysocki
2010-03-29 13:30 ` Pavel Machek
2010-03-29 13:30 ` [linux-pm] " Pavel Machek
2010-03-25 14:29 ` Pavel Machek
2010-03-25 14:29 ` Pavel Machek
2010-03-24 20:30 ` Pavel Machek
2010-03-23 16:17 ` [RFC 04/15] PM / Hibernate: move the first_sector out of swsusp_write Jiri Slaby
2010-03-23 16:17 ` Jiri Slaby
2010-03-24 20:31 ` Pavel Machek
2010-03-24 20:31 ` Pavel Machek
2010-03-25 21:26 ` Rafael J. Wysocki
2010-03-25 21:26 ` Rafael J. Wysocki
2010-03-23 16:17 ` [RFC 05/15] PM / Hibernate: group swap ops Jiri Slaby
2010-03-23 16:17 ` Jiri Slaby
2010-03-25 21:28 ` Rafael J. Wysocki
2010-03-25 21:28 ` Rafael J. Wysocki
2010-03-23 16:17 ` [RFC 06/15] PM / Hibernate: swap, remove swap_map_handle usages Jiri Slaby
2010-03-24 20:33 ` Pavel Machek
2010-03-24 20:33 ` Pavel Machek
2010-03-24 21:29 ` Jiri Slaby
2010-03-24 21:29 ` Jiri Slaby
2010-03-25 21:35 ` Rafael J. Wysocki
2010-03-25 21:35 ` Rafael J. Wysocki
2010-03-23 16:17 ` Jiri Slaby
2010-03-23 16:17 ` [RFC 07/15] PM / Hibernate: add sws_modules_ops Jiri Slaby
2010-03-23 16:17 ` Jiri Slaby
2010-03-24 20:36 ` Pavel Machek
2010-03-24 20:36 ` Pavel Machek
2010-03-24 21:31 ` Jiri Slaby
2010-03-24 21:31 ` Jiri Slaby
2010-03-25 22:02 ` Rafael J. Wysocki
2010-03-25 22:02 ` Rafael J. Wysocki
2010-03-23 16:17 ` [RFC 08/15] PM / Hibernate: add user module_ops Jiri Slaby
2010-03-23 16:17 ` Jiri Slaby
2010-03-25 22:07 ` Rafael J. Wysocki
2010-03-25 22:07 ` Rafael J. Wysocki
2010-03-26 9:43 ` Jiri Slaby
2010-03-26 9:43 ` Jiri Slaby
2010-03-23 16:17 ` [RFC 09/15] PM / Hibernate: user, implement user_ops writer Jiri Slaby
2010-03-23 16:17 ` Jiri Slaby
2010-03-24 20:42 ` Pavel Machek
2010-03-24 20:42 ` Pavel Machek
2010-03-24 21:40 ` Jiri Slaby
2010-03-25 21:36 ` Pavel Machek
2010-03-25 21:36 ` Pavel Machek
2010-03-25 22:14 ` Rafael J. Wysocki
2010-03-25 22:14 ` Rafael J. Wysocki
2010-03-26 9:34 ` Jiri Slaby
2010-03-26 9:34 ` Jiri Slaby
2010-03-26 22:04 ` Rafael J. Wysocki
2010-03-29 15:33 ` Jiri Slaby
2010-03-29 15:33 ` Jiri Slaby
2010-03-29 22:09 ` Rafael J. Wysocki
2010-03-30 1:14 ` Nigel Cunningham
2010-03-30 21:03 ` Rafael J. Wysocki
2010-03-31 2:31 ` Nigel Cunningham
2010-03-31 14:47 ` Pavel Machek
2010-03-31 21:01 ` Nigel Cunningham
2010-03-31 20:25 ` Rafael J. Wysocki
2010-03-31 21:06 ` Nigel Cunningham
2010-03-31 21:36 ` Rafael J. Wysocki
2010-04-04 23:08 ` Nigel Cunningham
2010-04-04 23:13 ` Rafael J. Wysocki
2010-03-31 21:54 ` Nigel Cunningham
2010-03-30 8:59 ` Jiri Slaby
2010-03-30 20:50 ` Rafael J. Wysocki
2010-03-31 14:41 ` Jiri Slaby [this message]
2010-03-31 20:29 ` Rafael J. Wysocki
2010-04-21 21:22 ` Jiri Slaby
2010-04-22 3:43 ` Rafael J. Wysocki
2010-03-26 22:04 ` Rafael J. Wysocki
2010-03-27 7:02 ` Pavel Machek
2010-03-27 7:02 ` Pavel Machek
2010-03-24 21:40 ` Jiri Slaby
2010-03-23 16:17 ` [RFC 10/15] PM / Hibernate: user, implement user_ops reader Jiri Slaby
2010-03-23 16:17 ` Jiri Slaby
2010-03-25 5:30 ` what the patches do " Pavel Machek
2010-03-25 5:42 ` Nigel Cunningham
2010-03-25 5:42 ` Nigel Cunningham
2010-03-25 6:12 ` Nigel Cunningham
2010-03-25 6:12 ` [linux-pm] " Nigel Cunningham
2010-03-25 20:14 ` Rafael J. Wysocki
2010-03-25 20:14 ` Rafael J. Wysocki
2010-03-25 20:21 ` Nigel Cunningham
2010-03-25 20:29 ` Rafael J. Wysocki
2010-03-25 20:35 ` Nigel Cunningham
2010-03-25 21:13 ` Rafael J. Wysocki
2010-03-25 21:13 ` Rafael J. Wysocki
2010-03-25 20:35 ` Nigel Cunningham
2010-03-25 21:26 ` Pavel Machek
2010-03-25 21:26 ` Pavel Machek
2010-03-25 21:49 ` [linux-pm] " Nigel Cunningham
2010-04-02 6:36 ` Pavel Machek
2010-04-02 6:36 ` [linux-pm] " Pavel Machek
2010-04-02 17:03 ` Rafael J. Wysocki
2010-04-02 17:03 ` [linux-pm] " Rafael J. Wysocki
2010-03-25 21:49 ` Nigel Cunningham
2010-03-25 20:29 ` Rafael J. Wysocki
2010-03-25 20:21 ` Nigel Cunningham
2010-03-25 22:21 ` Rafael J. Wysocki
2010-03-25 22:21 ` Rafael J. Wysocki
2010-03-25 5:30 ` Pavel Machek
2010-03-23 16:17 ` [RFC 11/15] PM / Hibernate: add chunk i/o support Jiri Slaby
2010-03-25 22:38 ` Rafael J. Wysocki
2010-03-25 22:38 ` Rafael J. Wysocki
2010-03-26 9:09 ` Jiri Slaby
2010-03-26 10:02 ` Nigel Cunningham
2010-03-26 10:02 ` Nigel Cunningham
2010-03-26 9:09 ` Jiri Slaby
2010-03-23 16:17 ` Jiri Slaby
2010-03-23 16:17 ` [RFC 12/15] PM / Hibernate: split snapshot_read_next Jiri Slaby
2010-03-25 22:44 ` Rafael J. Wysocki
2010-03-25 22:44 ` Rafael J. Wysocki
2010-03-23 16:17 ` Jiri Slaby
2010-03-23 16:17 ` [RFC 13/15] PM / Hibernate: split snapshot_write_next Jiri Slaby
2010-03-25 22:46 ` Rafael J. Wysocki
2010-03-25 22:46 ` Rafael J. Wysocki
2010-03-23 16:17 ` Jiri Slaby
2010-03-23 16:17 ` [RFC 14/15] PM / Hibernate: dealign swsusp_info Jiri Slaby
2010-03-23 16:17 ` Jiri Slaby
2010-03-25 22:46 ` Rafael J. Wysocki
2010-03-25 22:46 ` Rafael J. Wysocki
2010-03-23 16:17 ` [RFC 15/15] PM / Hibernate: move non-swap code to snapshot.c Jiri Slaby
2010-03-23 16:17 ` Jiri Slaby
2010-03-25 22:50 ` Rafael J. Wysocki
2010-03-25 22:50 ` Rafael J. Wysocki
2010-03-23 21:51 ` [RFC 01/15] FS: libfs, implement simple_write_to_buffer Rafael J. Wysocki
2010-03-23 21:51 ` Rafael J. Wysocki
2010-03-23 22:09 ` [linux-pm] " Nigel Cunningham
2010-03-23 22:09 ` Nigel Cunningham
2010-03-24 22:13 ` Rafael J. Wysocki
2010-03-24 22:13 ` Rafael J. Wysocki
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=4BB35F1C.4030100@gmail.com \
--to=jirislaby@gmail.com \
--cc=linux-pm@lists.linux-foundation.org \
--cc=ncunningham@crca.org.au \
--cc=rjw@sisk.pl \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.