swsusp: code separation continued
Subsystems (2)
cover swsusp: code separation continued
Hi,
The following series of patches continues the process of separating the snapshot-handling code in swsusp from the storage-handling and core code.
The patches are against the vanilla 2.6.14-rc5-mm1. They have already been acked by Pavel. Please apply.
Greetings,
Rafael
PATCH 1/3 swsusp: rework swsusp_suspend
This patch makes only the functions in swsusp.c call functions in snapshot.c and not both ways. Basically, it moves the code without changing its functionality.
kernel/power/power.h | 2 - kernel/power/snapshot.c | 14 +--------- kernel/power/swsusp.c | 62 +++++++++++++++++++++++++++--------------------- 3 files changed, 39 insertions(+), 39 deletions(-)
kernel/power/snapshot.c +2 -12
@@ -89,7 +89,7 @@ } -static int save_highmem (void ) +int save_highmem (void ) {struct zone *zone;int res =0 ;
@@ -121,7 +121,7 @@ return 0; }#else -static int save_highmem (void ) {return 0 ; } +int save_highmem (void ) {return 0 ; }int restore_highmem (void ) {return 0 ; }#endif /* CONFIG_HIGHMEM */
@@ -383,11 +383,6 @@unsigned nr_pages;pr_debug ("swsusp: critical section: \n" ); -if (save_highmem ()) { -printk (KERN_CRIT "swsusp: Not enough free pages for highmem\n" ); -restore_highmem (); -return -ENOMEM ; - }drain_local_pages (); nr_pages =count_data_pages ();
@@ -407,11 +402,6 @@return -ENOMEM ; } -if (!enough_swap (nr_pages)) { -printk (KERN_ERR "swsusp: Not enough free swap\n" ); -return -ENOSPC ; - } - pagedir_nosave =swsusp_alloc (nr_pages);if (!pagedir_nosave)return -ENOMEM ;
kernel/power/swsusp.c +36 -26
104 lines not on this page · raw message
kernel/power/power.h +1 -1
@@ -65,8 +65,8 @@ extern asmlinkage int swsusp_arch_suspend(void); extern asmlinkage int swsusp_arch_resume(void); +extern int save_highmem (void );extern int restore_highmem (void );extern struct pbe *alloc_pagedir (unsigned nr_pages);extern void create_pbe_list (struct pbe *pblist,unsigned nr_pages);extern void swsusp_free (void ); -extern int enough_swap (unsigned nr_pages);
Re: [PATCH 1/3] swsusp: rework swsusp_suspend
Hi Rafael,
Quoted 3 lines · Rafael J. Wysocki
This patch makes only the functions in
swsusp.ccall functions insnapshot.cand not both ways. Basically, it moves the code without changing its functionality.
This is not quite true.
kernel/power/snapshot.c line 126
Quoted 5 lines
#else
kernel/power/snapshot.c +1
-1-static int save_highmem (void ) {return 0 ; } +int save_highmem (void ) {return 0 ; }int restore_highmem (void ) {return 0 ; }#endif /* CONFIG_HIGHMEM */
Here you change code, which will be optimized completely away to an empty function, which bloats the kernel.
Please put these two functions into a local header like this:
#ifdef CONFIG_HIGHMEM
int save_highmem(void);
int restore_highmem(void);
#else
static inline int save_highmem(void) { return 0; } static inline int restore_highmem(void) { return 0; } #endif
That way no having no highmem means, this code is not used at all and everything using the return code and expecting != 0 is going to be optimized away.
I think everyone CCed will agree here :-)
Many thanks & Regards
Ingo Oeser
Re: [PATCH 1/3] swsusp: rework swsusp_suspend
Hi,
Quoted 29 lines · Ingo Oeser
Hi Rafael,
Quoted 3 lines · Rafael J. Wysocki
This patch makes only the functions in
swsusp.ccall functions insnapshot.cand not both ways. Basically, it moves the code without changing its functionality.This is not quite true.
kernel/power/snapshot.c line 126
Quoted 5 lines
#else
kernel/power/snapshot.c +1
-1-static int save_highmem (void ) {return 0 ; } +int save_highmem (void ) {return 0 ; }int restore_highmem (void ) {return 0 ; }#endif /* CONFIG_HIGHMEM */ Here you change code, which will be optimized completely away to an empty function, which bloats the kernel.
Please put these two functions into a local header like this:
#ifdef
CONFIG_HIGHMEM
intsave_highmem(void);
intrestore_highmem(void);
#else
static inline intsave_highmem(void){ return 0; } static inline intrestore_highmem(void){ return 0; } #endif
Quoted 5 lines
That way no having no highmem means, this code is not used at all and everything using the return code and expecting != 0 is going to be optimized away.
I think everyone CCed will agree here :-)
Of course you're right, I'll do that.
Thanks a lot for the comment.
Greetings,
Rafael
PATCH 2/3 swsusp: move snapshot-handling functions to snapshot.c
In reply to Rafael J. WysockiThis patch moves the snapshot-handling functions remaining in swsusp.c to snapshot.c (ie. it moves the code without changing the functionality).
kernel/power/power.h | 2 kernel/power/snapshot.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++ kernel/power/swsusp.c | 126 ------------------------------------------------ 3 files changed, 125 insertions(+), 124 deletions(-)
kernel/power/power.h +2 -0
@@ -69,4 +69,6 @@extern int restore_highmem (void );extern struct pbe *alloc_pagedir (unsigned nr_pages);extern void create_pbe_list (struct pbe *pblist,unsigned nr_pages); +extern int check_pagedir (struct pbe *pblist); +extern struct pbe *swsusp_pagedir_relocate (struct pbe *pblist);extern void swsusp_free (void );
kernel/power/snapshot.c +121 -0
124 lines not on this page · raw message
kernel/power/swsusp.c +2 -124
138 lines not on this page · raw message
Re: [PATCH 2/3] swsusp: move snapshot-handling functions to snapshot.c
Hi!
Quoted 3 lines
This patch moves the snapshot-handling functions remaining in
swsusp.ctosnapshot.c(ie. it moves the code without changing the functionality).
I'm sorry, but I acked this one too quickly. I'd prefer to keep "relocate" code where it is, and define "must not collide" as a part of interface. That will keep snapshot.c smaller/simpler, and I plan to
eventually put responsibility for relocation to userspace.
That should simplify error handling at least: data structures needed for relocation can be kept in userspace memory, and therefore we do not risk memory leak in case something goes wrong.
Pavel
Signature · 1 line
64 bytes from 195.113.31.123: icmp_seq=28 ttl=51 time=448769.1 ms
Re: [PATCH 2/3] swsusp: move snapshot-handling functions to snapshot.c
Hi,
Quoted 7 lines · Pavel Machek
Hi!
Quoted 3 lines
This patch moves the snapshot-handling functions remaining in
swsusp.ctosnapshot.c(ie. it moves the code without changing the functionality).I'm sorry, but I acked this one too quickly. I'd prefer to keep "relocate" code where it is, and define "must not collide" as a part of interface.
That's doable, but frankly I don't like the idea.
Quoted 2 lines
That will keep
snapshot.csmaller/simpler, and I plan to eventually put responsibility for relocation to userspace.
Please note that the relocating code uses the page flags to mark the allocated pages as well as to avoid the pages that should not be used. In my opinion no userspace process should be allowed to fiddle with the page flags.
Moreover, get_safe_page() is called directly by the arch code on x86-64, so it has to stay in the kernel and hence it should be in snapshot.c. OTOH the relocating code is nothing more than "if the page is not safe, use get_safe_page() to allocate one" kind of thing, so I don't see a point in taking it out of the kernel (in the future) too.
Quoted 2 lines
That should simplify error handling at least: data structures needed for relocation can be kept in userspace memory,
Well, after the patches that are already in -mm we don't use any additional data structures for this purpose, so that's not a problem, I think. ;-)
Quoted 1 line
and therefore we do not risk memory leak in case something goes wrong.
We don't. All memory allocated with either get_image_page() or get_safe_page() will eventually be released by swsusp_free(), no matter what happens.
Greetings,
Rafael
Re: [PATCH 2/3] swsusp: move snapshot-handling functions to snapshot.c
Hi!
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
This patch moves the snapshot-handling functions remaining in
swsusp.ctosnapshot.c(ie. it moves the code without changing the functionality).I'm sorry, but I acked this one too quickly. I'd prefer to keep "relocate" code where it is, and define "must not collide" as a part of interface.
That's doable, but frankly I don't like the idea.
Quoted 7 lines
Quoted 2 lines
That will keep
snapshot.csmaller/simpler, and I plan to eventually put responsibility for relocation to userspace.Please note that the relocating code uses the page flags to mark the allocated pages as well as to avoid the pages that should not be used. In my opinion no userspace process should be allowed to fiddle with the page flags.
Of course, userspace would have to use separate data structure. [Hash table?]
Quoted 5 lines
Moreover,
get_safe_page()is called directly by the arch code on x86-64, so it has to stay in the kernel and hence it should be insnapshot.c. OTOH the relocating code is nothing more than "if the page is not safe, useget_safe_page()to allocate one" kind of thing, so I don't see a point in taking it out of the kernel (in the future) too.
Well... for resume. If userspace does the allocation, it is:
userspace reads image
userspace relocates itsys_atomic_restore(image)
if something goes wrong, userspace is clearly responsible for freeing it.
How would you propose kernel<->user interface?
userspace reads pagedir sys_these_pages_are_forbidden(pagedir)
userspace reads restsys_atomic_restore(image)
if something goes wrong, userspace must dealocate pages _and_ clear forbidden flags?
Quoted 6 lines
Quoted 2 lines
That should simplify error handling at least: data structures needed for relocation can be kept in userspace memory,
Well, after the patches that are already in -mm we don't use any additional data structures for this purpose, so that's not a problem, I think. ;-)
Until someone will want to get page flag bits back ;-), ok.
Pavel
Signature · 1 line
Thanks, Sharp!
Re: [PATCH 2/3] swsusp: move snapshot-handling functions to snapshot.c
Hi,
Quoted 1 line · Pavel Machek
Hi!
}-- snip --{
Quoted 6 lines
Quoted 4 lines
Please note that the relocating code uses the page flags to mark the allocated pages as well as to avoid the pages that should not be used. In my opinion no userspace process should be allowed to fiddle with the page flags.
Of course, userspace would have to use separate data structure. [Hash table?]
IMO a bitmap could be used. Anyway in that case the x86-64 arch code would need to have access either to this structure or to the image metadata, because it must figure out which pages are not safe. I don't see any simple way of making this work ...
Quoted 14 lines
Quoted 5 lines
Moreover,
get_safe_page()is called directly by the arch code on x86-64, so it has to stay in the kernel and hence it should be insnapshot.c. OTOH the relocating code is nothing more than "if the page is not safe, useget_safe_page()to allocate one" kind of thing, so I don't see a point in taking it out of the kernel (in the future) too.Well... for resume. If userspace does the allocation, it is:
userspace reads image
userspace relocates itsys_atomic_restore(image)
if something goes wrong, userspace is clearly responsible for freeing it.
Quoted 8 lines
How would you propose kernel<->user interface?
userspace reads pagedir
sys_these_pages_are_forbidden(pagedir)
userspace reads restsys_atomic_restore(image)
if something goes wrong, userspace must dealocate pages _and_ clear forbidden flags?
Well, you have taken these things out of context. Namely, the userspace process cannot freeze the other tasks, suspend devices etc., so it has to call the kernel for these purposes anyway. Of course if something goes wrong it has to call the kernel to revert these steps too. Similarly it can call the kernel to allocate the image memory and to free it in case something's wrong. For example, if the userspace initiates the resume:
- if (image not found)
exit
- sys_freeze_processes /* this one will be tricky ;-) */
- sys_create_pagedir
- while (image data) {
sys_put_this_stuff_where_appropriate(image data);
/* Here the kernel will do the relocation etc. if necessary */
if (something's wrong)
goto Cleanup; }- sys_atomic_restore /* suspend devices, disable IRQs, restore */
Cleanup: /* certainly something's gone wrong */
- sys_destroy_pagedir /* that's it */
- sys_resume_devices
- sys_thaw_processes
Quoted 8 lines
Quoted 6 lines
Quoted 2 lines
That should simplify error handling at least: data structures needed for relocation can be kept in userspace memory,
Well, after the patches that are already in -mm we don't use any additional data structures for this purpose, so that's not a problem, I think. ;-)
Until someone will want to get page flag bits back ;-), ok.
In that case we'll have to redesign the snapshot part top-down anyway.
Greetings,
Rafael
Re: [PATCH 2/3] swsusp: move snapshot-handling functions to snapshot.c
Hi!
Quoted 11 lines
Quoted 6 lines
Quoted 4 lines
Please note that the relocating code uses the page flags to mark the allocated pages as well as to avoid the pages that should not be used. In my opinion no userspace process should be allowed to fiddle with the page flags.
Of course, userspace would have to use separate data structure. [Hash table?]
IMO a bitmap could be used. Anyway in that case the x86-64 arch code would need to have access either to this structure or to the image metadata, because it must figure out which pages are not safe. I don't see any simple way of making this work ...
Can you elaborate? resume is certainly going to get list of pbes...
Quoted 23 lines
Quoted 14 lines
Quoted 5 lines
Moreover,
get_safe_page()is called directly by the arch code on x86-64, so it has to stay in the kernel and hence it should be insnapshot.c. OTOH the relocating code is nothing more than "if the page is not safe, useget_safe_page()to allocate one" kind of thing, so I don't see a point in taking it out of the kernel (in the future) too.Well... for resume. If userspace does the allocation, it is:
userspace reads image
userspace relocates itsys_atomic_restore(image)
if something goes wrong, userspace is clearly responsible for freeing it.Quoted 8 lines
How would you propose kernel<->user interface?
userspace reads pagedir
sys_these_pages_are_forbidden(pagedir)
userspace reads restsys_atomic_restore(image)
if something goes wrong, userspace must dealocate pages _and_ clear forbidden flags?
Quoted 3 lines
Well, you have taken these things out of context. Namely, the userspace process cannot freeze the other tasks, suspend devices etc., so it has to
Yes, process freezing probably needs to be separate. Suspending devices can well be part of atomic_snapshot operation; userspace does not need to care.
Quoted 8 lines
call the kernel for these purposes anyway. Of course if something goes wrong it has to call the kernel to revert these steps too. Similarly it can call the kernel to allocate the image memory and to free it in case something's wrong. For example, if the userspace initiates the resume:
- if (image not found)
exit
-sys_freeze_processes/* this one will be tricky ;-) */
Why, I have it implemented? Just do not freeze the process calling you.
Quoted 1 line
-
sys_create_pagedir
Ugly...
Quoted 6 lines
- while (image data) { sys_put_this_stuff_where_appropriate(image data); /* Here the kernel will do the relocation etc. if necessary */ if (something's wrong) goto Cleanup; }-
sys_atomic_restore/* suspend devices, disable IRQs, restore */
Exactly. I'd like to go a
Quoted 3 lines
Cleanup: /* certainly something's gone wrong */
-sys_destroy_pagedir/* that's it */
-sys_resume_devices
You should not need to do this one. resuming devices is going to be integrated in atomic_restore, because suspending devices is there, too.
Here's how it looks... additionaly, I have ioctl for getting one usable page. It is true that I did not solve error paths, yet; I'll certainly need some way to free memory, too.
Pavel
intdo_resume(void)
{
kmem = open("/dev/kmem", O_RDWR | O_LARGEFILE);
image_fd = open(image, O_RDWR);
if (kmem < 0) {
fprintf(stderr, "Could not open /dev/kmem: %m\n");
return 1;
}
memset(&swsusp_info, 0, sizeof(swsusp_info));
read(image_fd, &swsusp_info, sizeof(swsusp_info));
resume.nr_copy_pages = swsusp_info.nr_copy_pages;
if (strcmp("swsusp3", swsusp_info.signature))
exit(0);
if (lseek(image_fd, 0, SEEK_SET) != 0) {
printf("Could not seek to kill sig: %m\n");
exit(1);
}
if (write(image_fd, &zeros, sizeof(swsusp_info)) != sizeof(swsusp_info)) {
printf("Could not write to kill sig: %m\n");
exit(1);
}
if (fsync(image_fd)) {
printf("Could not fsync to kill sig: %m\n");
exit(1);
}
printf("Got image, %d pages, signature [%s]\n", resume.nr_copy_pages, swsusp_info.signature);
alloc_pagedir(resume.nr_copy_pages);
printf("Verifying allocated pagedir: %d pages\n", walk_chain(&resume, NULL));
printf("swsusp: Reading pagedir ");
walk_pages_chain(&resume, (void *) read_pagedir_one);
printf("ok\n");
/* Need to be done twice; so that forbidden_pages comes into effect */
alloc_pagedir(resume.nr_copy_pages);
printf("Verifying allocated pagedir: %d pages\n", walk_chain(&resume, NULL));
printf("swsusp: Reading pagedir ");
walk_pages_chain(&resume, (void *) read_pagedir_one);
printf("ok\n");
printf("Verifying allocated pagedir: %d pages\n", walk_chain(&resume, NULL));
/* FIXME: Need to relocate pages */
mod = swsusp_info.nr_copy_pages / 100;
if (!mod)
mod = 1;
printf("swsusp: Reading image data (%d pages): ",
swsusp_info.nr_copy_pages);
walk_chain(&resume, data_read_one);
printf("\b\b\b\bdone\n");
if (ioctl(kmem, IOCTL_FREEZE, 0)) {
fprintf(stderr, "Could not freeze system: %m\n");
return 1;
}
if (ioctl(kmem, IOCTL_ATOMIC_RESTORE, &resume)) {
fprintf(stderr, "Could not restore system: %m\n");
}
/* Ouch, at this point we'll appear in ATOMIC_SNAPSHOT syscall, if
things went ok... */
return 0;
}Signature · 1 line
Thanks, Sharp!
Re: [PATCH 2/3] swsusp: move snapshot-handling functions to snapshot.c
Hi,
Quoted 7 lines · Pavel Machek
Hi!
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
Please note that the relocating code uses the page flags to mark the allocated pages as well as to avoid the pages that should not be used. In my opinion no userspace process should be allowed to fiddle with the page flags.
Quoted 8 lines
Quoted 6 lines
Quoted 1 line
Of course, userspace would have to use separate data structure. [Hash table?]
IMO a bitmap could be used. Anyway in that case the x86-64 arch code would need to have access either to this structure or to the image metadata, because it must figure out which pages are not safe. I don't see any simple way of making this work ...
Can you elaborate? resume is certainly going to get list of pbes...
OK
On x86-64 we have to allocate a few safe pages to put the temporary page tables on them. In principle I can imagine the following code for this:
do {
get a page;
walk the list of pbes to verify that the page is safe;
if (the page is not safe)
keep track of it;
} while (the page is not safe)but I'd rather not like to propose Andi to merge it. ;-) Currently the x86-64 arch code uses the same method of marking non-safe pages that is used by the rest of swsusp for efficiency and I think it should stay this way.
}-- snip --{
Quoted 14 lines
Quoted 4 lines
Well, you have taken these things out of context. Namely, the userspace process cannot freeze the other tasks, suspend devices etc., so it has to
Yes, process freezing probably needs to be separate. Suspending devices can well be part of
atomic_snapshotoperation; userspace does not need to care.Quoted 5 lines
call the kernel for these purposes anyway. Of course if something goes wrong it has to call the kernel to revert these steps too. Similarly it can call the kernel to allocate the image memory and to free it in case something's wrong. For example, if the userspace initiates the resume:
Quoted 5 lines
Quoted 3 lines
- if (image not found)
exit
-sys_freeze_processes/* this one will be tricky ;-) */Why, I have it implemented? Just do not freeze the process calling you.
"tricky" != "impossible" ;-)
Quoted 3 lines
Quoted 1 line
-
sys_create_pagedirUgly...
Oh, it can be done on-the-fly in sys_put_this_stuff_where_appropriate(image data) (at the expense of one redundant check per call).
Quoted 7 lines
Quoted 6 lines
- while (image data) { sys_put_this_stuff_where_appropriate(image data); /* Here the kernel will do the relocation etc. if necessary */ if (something's wrong) goto Cleanup; }-
sys_atomic_restore/* suspend devices, disable IRQs, restore */
Quoted 8 lines
Exactly. I'd like to go a
Quoted 3 lines
Cleanup: /* certainly something's gone wrong */
-sys_destroy_pagedir/* that's it */
-sys_resume_devicesYou should not need to do this one. resuming devices is going to be integrated in
atomic_restore, because suspending devices is there, too.
Yes, but I need to thaw processes anyway, so I can release memory as well. OTOH, if sys_atomic_restore fails because of the lack of memory, the memory should be freed _before_ resuming devices, since otherwise subsequent failures are almost certain to appear (I've seen what happens in that case). Now, if the memory is allocated by the kernel, I can easily put an emergency memory-freeing call in sys_atomic_restore (in that case sys_destroy_pagedir will be redundant, but so what?).
Quoted 3 lines
Here's how it looks... additionaly, I have ioctl for getting one usable page. It is true that I did not solve error paths, yet; I'll certainly need some way to free memory, too.
IMHO, these are important issues.
Greetings,
Rafael
Re: [PATCH 2/3] swsusp: move snapshot-handling functions to snapshot.c
Hi!
Quoted 13 lines
Quoted 1 line
Can you elaborate? resume is certainly going to get list of pbes...
OK
On x86-64 we have to allocate a few safe pages to put the temporary page tables on them. In principle I can imagine the following code for this:do { get a page; walk the list of pbes to verify that the page is safe; if (the page is not safe) keep track of it; } while (the page is not safe)
Quoted 4 lines
but I'd rather not like to propose Andi to merge it. ;-) Currently the x86-64 arch code uses the same method of marking non-safe pages that is used by the rest of swsusp for efficiency and I think it should stay this
way.
Ok, I see.
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
-
sys_create_pagedirUgly...
Oh, it can be done on-the-fly in
sys_put_this_stuff_where_appropriate(image data)(at the expense of one redundant check per call).
Yes, but it is still ugly, as you keep some context across the syscalls.
Quoted 7 lines
Quoted 6 lines
Quoted 3 lines
Cleanup: /* certainly something's gone wrong */
-sys_destroy_pagedir/* that's it */
-sys_resume_devicesYou should not need to do this one. resuming devices is going to be integrated in
atomic_restore, because suspending devices is there, too.
Quoted 7 lines
Yes, but I need to thaw processes anyway, so I can release memory as well. OTOH, if
sys_atomic_restorefails because of the lack of memory, the memory should be freed _before_ resuming devices, since otherwise subsequent failures are almost certain to appear (I've seen what happens in that case). Now, if the memory is allocated by the kernel, I can easily put an emergency memory-freeing call insys_atomic_restore(in that casesys_destroy_pagedirwill be redundant, but so what?).
Ugh, I'd say "don't care about this one too much". If resume is failing, we have bad problems anyway.
Quoted 5 lines
Quoted 3 lines
Here's how it looks... additionaly, I have ioctl for getting one usable page. It is true that I did not solve error paths, yet; I'll certainly need some way to free memory, too.
IMHO, these are important issues.
Yes, but I do not expect any problems while actually coding that...
Pavel
Signature · 1 line
Thanks, Sharp!
Re: [PATCH 2/3] swsusp: move snapshot-handling functions to snapshot.c
Hi,
On Monday, 31 of October 2005 22:59, Pavel Machek wrote:
}-- snip --{
Quoted 11 lines
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
-
sys_create_pagedirUgly...
Oh, it can be done on-the-fly in
sys_put_this_stuff_where_appropriate(image data)(at the expense of one redundant check per call).Yes, but it is still ugly, as you keep some context across the syscalls.
That depends on how you implement the interface. If you insist on using ioctls then yes, it's ugly. However, if it is a file in sysfs, for example, then you have well-defined open(), close(), read() and write() operations and it is assumed you will keep some context accross eg. write()s.
Quoted 15 lines
Quoted 7 lines
Quoted 6 lines
Quoted 3 lines
Cleanup: /* certainly something's gone wrong */
-sys_destroy_pagedir/* that's it */
-sys_resume_devicesYou should not need to do this one. resuming devices is going to be integrated in
atomic_restore, because suspending devices is there, too.Quoted 7 lines
Yes, but I need to thaw processes anyway, so I can release memory as well. OTOH, if
sys_atomic_restorefails because of the lack of memory, the memory should be freed _before_ resuming devices, since otherwise subsequent failures are almost certain to appear (I've seen what happens in that case). Now, if the memory is allocated by the kernel, I can easily put an emergency memory-freeing call insys_atomic_restore(in that casesys_destroy_pagedirwill be redundant, but so what?).
Quoted 2 lines
Ugh, I'd say "don't care about this one too much". If resume is failing, we have bad problems anyway.
We loose the saved system state, but the kernel that has just booted is supposed to continue, so we should make it possible. Alternatively, we can do something like a panic and force the user to reboot, in which case we can forget about the error paths, freeing memory etc. altogether.
Greetings,
Rafael
Re: [PATCH 2/3] swsusp: move snapshot-handling functions to snapshot.c
Hi!
Quoted 11 lines
Quoted 6 lines
Quoted 3 lines
Oh, it can be done on-the-fly in
sys_put_this_stuff_where_appropriate(image data)(at the expense of one redundant check per call).Yes, but it is still ugly, as you keep some context across the syscalls.
That depends on how you implement the interface. If you insist on using ioctls then yes, it's ugly. However, if it is a file in sysfs, for example, then you have well-defined
open(),close(),read()andwrite()operations and it is assumed you will keep some context accross eg. write()s.
I was trying to keep kernel code simple. Yes, if we do it sysfs based, that's probably not a problem. I'm not sure if nice sysfs interface can be done without excessive ammount of code.
Pavel
Signature · 1 line
Thanks, Sharp!
Re: [PATCH 2/3] swsusp: move snapshot-handling functions to snapshot.c
Hi,
Quoted 9 lines · Pavel Machek
Hi!
Quoted 7 lines
Quoted 6 lines
Quoted 3 lines
Oh, it can be done on-the-fly in
sys_put_this_stuff_where_appropriate(image data)(at the expense of one redundant check per call).Yes, but it is still ugly, as you keep some context across the syscalls.
Quoted 8 lines
Quoted 4 lines
That depends on how you implement the interface. If you insist on using ioctls then yes, it's ugly. However, if it is a file in sysfs, for example, then you have well-defined
open(),close(),read()andwrite()operations and it is assumed you will keep some context accross eg. write()s.I was trying to keep kernel code simple. Yes, if we do it sysfs based, that's probably not a problem. I'm not sure if nice sysfs interface can be done without excessive ammount of code.
I'm not sure either, but I'm going to try.
Still first I'd like to make swsusp free only as much memory as needed and not as much as possible which should improve its performance quite a bit.
Greetings,
Rafael
Re: [PATCH 2/3] swsusp: move snapshot-handling functions to snapshot.c
Hi!
Quoted 10 lines
Quoted 8 lines
Quoted 4 lines
That depends on how you implement the interface. If you insist on using ioctls then yes, it's ugly. However, if it is a file in sysfs, for example, then you have well-defined
open(),close(),read()andwrite()operations and it is assumed you will keep some context accross eg. write()s.I was trying to keep kernel code simple. Yes, if we do it sysfs based, that's probably not a problem. I'm not sure if nice sysfs interface can be done without excessive ammount of code.
I'm not sure either, but I'm going to try.
Ok, I'm looking forward. We still have my ugly ioctls as a fallback :-).
Quoted 3 lines
Still first I'd like to make swsusp free only as much memory as needed and not as much as possible which should improve its performance quite a bit.
Yes, I'd like that patch in. It will make many people happy.
Pavel
Signature · 1 line
Thanks, Sharp!
Re: [PATCH 2/3] swsusp: move snapshot-handling functions to snapshot.c
In reply to Pavel MachekHi,
Quoted 9 lines · Pavel Machek
Hi!
Quoted 3 lines
This patch moves the snapshot-handling functions remaining in
swsusp.ctosnapshot.c(ie. it moves the code without changing the functionality).I'm sorry, but I acked this one too quickly. I'd prefer to keep "relocate" code where it is, and define "must not collide" as a part of interface. That will keep
snapshot.csmaller/simpler,
Speaking of simplifications and having seen your code I hope you will agree with the appended patch against vanilla 2.6.14-git3 (it reduces the duplication of code, and replaces swsusp_pagedir_relocate with a simpler mechanism).
Greetings,
Rafael
kernel/power/power.h | 6 +- kernel/power/snapshot.c | 121 +++++++++++++++++++++++++++++++++-------- kernel/power/swsusp.c | 139 ++---------------------------------------------- 3 files changed, 109 insertions(+), 157 deletions(-)
kernel/power/power.h +5 -1
@@ -66,7 +66,11 @@ extern asmlinkage int swsusp_arch_resume(void);extern int restore_highmem (void ); -extern struct pbe *alloc_pagedir (unsigned nr_pages); +extern void free_pagedir (struct pbe *pblist); +extern struct pbe *alloc_pagedir (unsigned nr_pages,int need_safe);extern void create_pbe_list (struct pbe *pblist,unsigned nr_pages); +extern int alloc_data_pages (struct pbe *pblist,int need_safe);extern void swsusp_free (void );extern int enough_swap (unsigned nr_pages); +extern void mark_unsafe_pages (struct pbe *pblist); +extern void copy_page_backup_list (struct pbe *dst,struct pbe *src);
kernel/power/snapshot.c +97 -24
183 lines not on this page · raw message
kernel/power/swsusp.c +7 -132
166 lines not on this page · raw message
Re: [PATCH 2/3] swsusp: move snapshot-handling functions to snapshot.c
Hi!
Quoted 11 lines
Quoted 7 lines
Quoted 3 lines
This patch moves the snapshot-handling functions remaining in
swsusp.ctosnapshot.c(ie. it moves the code without changing the functionality).I'm sorry, but I acked this one too quickly. I'd prefer to keep "relocate" code where it is, and define "must not collide" as a part of interface. That will keep
snapshot.csmaller/simpler,Speaking of simplifications and having seen your code I hope you will agree with the appended patch against vanilla 2.6.14-git3 (it reduces the duplication of code, and replaces
swsusp_pagedir_relocatewith a simpler mechanism).
...and also moves stuff around in a way
a) I don't like
and
b) is almost impossible to review
:-). Can you keep "relocate" code in swsusp.c, just making it simpler?
Quoted 7 lines
kernel/power/swsusp.c +1
-1@@ -997,20 +870,22 @@int error =0 ;struct pbe *p; -if (!(p =alloc_pagedir (nr_copy_pages))) +if (!(p =alloc_pagedir (nr_copy_pages,0 )))return -ENOMEM ;
kernel/power/swsusp.c line 881
Quoted 10 lines
kernel/power/swsusp.c +2
-3if ((error =read_pagedir (p)))return error; -create_pbe_list (p, nr_copy_pages); - -if (!(pagedir_nosave =swsusp_pagedir_relocate (p))) +mark_unsafe_pages (p); +if (!(pagedir_nosave =alloc_pagedir (nr_copy_pages,1 )))return -ENOMEM ;
Okay, this is probably better approach than copying pagedir around...
Pavel
Signature · 1 line
Thanks, Sharp!
Re: [PATCH 2/3] swsusp: move snapshot-handling functions to snapshot.c
Hi,
Quoted 14 lines · Pavel Machek
Hi!
Quoted 11 lines
Quoted 7 lines
Quoted 3 lines
This patch moves the snapshot-handling functions remaining in
swsusp.ctosnapshot.c(ie. it moves the code without changing the functionality).I'm sorry, but I acked this one too quickly. I'd prefer to keep "relocate" code where it is, and define "must not collide" as a part of interface. That will keep
snapshot.csmaller/simpler,Speaking of simplifications and having seen your code I hope you will agree with the appended patch against vanilla 2.6.14-git3 (it reduces the duplication of code, and replaces
swsusp_pagedir_relocatewith a simpler mechanism).
Quoted 7 lines
...and also moves stuff around in a way
a) I don't like
and
b) is almost impossible to review
OK, I'll try to split it into two patches to make it cleaner.
Quoted 1 line
:-). Can you keep "relocate" code in
swsusp.c, just making it simpler?
If you mean mark_unsafe_pages() and copy_backup_list(), no problem. The rest is still there.
Quoted 9 lines
Quoted 9 lines
kernel/power/swsusp.c +1
-1@@ -997,20 +870,22 @@int error =0 ;struct pbe *p; -if (!(p =alloc_pagedir (nr_copy_pages))) +if (!(p =alloc_pagedir (nr_copy_pages,0 )))return -ENOMEM ;
Quoted 11 lines
kernel/power/swsusp.c line 881
Quoted 9 lines
kernel/power/swsusp.c +2
-3if ((error =read_pagedir (p)))return error; -create_pbe_list (p, nr_copy_pages); - -if (!(pagedir_nosave =swsusp_pagedir_relocate (p))) +mark_unsafe_pages (p); +if (!(pagedir_nosave =alloc_pagedir (nr_copy_pages,1 )))return -ENOMEM ;Okay, this is probably better approach than copying pagedir around...
It's nice you agree here. :-)
Greetings,
Rafael
PATCH 1/2 swsusp: reduce code duplication (was: Re: [PATCH 2/3] swsusp: move snapshot-handling functions to snapshot.c)
Hi,
On Tuesday, 1 of November 2005 13:57, Rafael J. Wysocki wrote:
}-- snip --{
Quoted 6 lines
Quoted 6 lines
Quoted 3 lines
Speaking of simplifications and having seen your code I hope you will agree with the appended patch against vanilla 2.6.14-git3 (it reduces the duplication of code, and replaces
swsusp_pagedir_relocatewith a simpler mechanism)....and also moves stuff around in a way
Quoted 7 lines
Quoted 5 lines
a) I don't like
and
b) is almost impossible to review
OK, I'll try to split it into two patches to make it cleaner.
The first patch is appended, the next one will be in the reply to this message.
The changes made by the appended patch are necessary for the relocation simplification in the next patch. Still, the changes allow us to drop check_pagedir() and make get_safe_page() be a one-line wrapper around alloc_image_page() (get_safe_page() goes to snapshot.c, because alloc_image_page() is static and it does not make sense to export it).
Greetings,
Rafael
kernel/power/power.h | 3 +- kernel/power/snapshot.c | 62 +++++++++++++++++++++++++++++++++++++----------- kernel/power/swsusp.c | 57 +------------------------------------------- 3 files changed, 52 insertions(+), 70 deletions(-)
kernel/power/power.h +2 -1
@@ -66,7 +66,8 @@ extern asmlinkage int swsusp_arch_resume(void);extern int restore_highmem (void ); -extern struct pbe *alloc_pagedir (unsigned nr_pages); +extern struct pbe *alloc_pagedir (unsigned nr_pages,gfp_t gfp_mask,int safe_needed);extern void create_pbe_list (struct pbe *pblist,unsigned nr_pages);extern void swsusp_free (void ); +extern int alloc_data_pages (struct pbe *pblist,gfp_t gfp_mask,int safe_needed);extern int enough_swap (unsigned nr_pages);
kernel/power/snapshot.c +48 -14
106 lines not on this page · raw message
kernel/power/swsusp.c +2 -55
75 lines not on this page · raw message
PATCH 2/2 swsusp: simplify pagedir relocation
The appended patch simplifies the relocation of the page backup list (aka pagedir) during resume.
kernel/power/power.h | 1 kernel/power/snapshot.c | 2 - kernel/power/swsusp.c | 78 ++++++++++++++++-------------------------------- 3 files changed, 28 insertions(+), 53 deletions(-)
kernel/power/swsusp.c +26 -52
@@ -636,74 +636,43 @@ }/** -* swsusp_pagedir_relocate - It is possible, that some memory pages -* occupied by the list of PBEs collide with pages where we're going to -* restore from the loaded pages later. We relocate them here. +* mark_unsafe_pages - mark the pages that cannot be used for storing +* the image during resume, because they conflict with the pages that +* had been used before suspend */ -static struct pbe *swsusp_pagedir_relocate (struct pbe *pblist) +static void mark_unsafe_pages (struct pbe *pblist) {struct zone *zone;unsigned long zone_pfn; -struct pbe *pbpage, *tail, *p; -void *m; -int rel =0 ; +struct pbe *p;if (!pblist)/* a sanity check */ -return NULL ; - -pr_debug ("swsusp: Relocating pagedir (%lu pages to check)\n" , - swsusp_info.pagedir_pages); +return ;/* Clear page flags */ -for_each_zone (zone) { -for (zone_pfn =0 ; zone_pfn < zone->spanned_pages; ++zone_pfn) -if (pfn_valid (zone_pfn + zone->zone_start_pfn)) -ClearPageNosaveFree (pfn_to_page (zone_pfn + +for (zone_pfn =0 ; zone_pfn < zone->spanned_pages; ++zone_pfn) +if (pfn_valid (zone_pfn + zone->zone_start_pfn)) +ClearPageNosaveFree (pfn_to_page (zone_pfn + zone->zone_start_pfn)); }/* Mark orig addresses */ - for_each_pbe (p, pblist)SetPageNosaveFree (virt_to_page (p->orig_address)); - tail = pblist +PB_PAGE_SKIP ; - -/* Relocate colliding pages */ - - for_each_pb_page (pbpage, pblist) { -if (PageNosaveFree (virt_to_page ((unsigned long )pbpage))) { - m = (void *)get_safe_page (GFP_ATOMIC | __GFP_COLD); -if (!m) -return NULL ; -memcpy (m, (void *)pbpage,PAGE_SIZE ); -if (pbpage == pblist) - pblist = (struct pbe *)m; -else - tail->next = (struct pbe *)m; - pbpage = (struct pbe *)m; - -/* We have to link the PBEs again */ -for (p = pbpage; p < pbpage +PB_PAGE_SKIP ; p++) -if (p->next)/* needed to save the end */ - p->next = p +1 ; - - rel++; - } - tail = pbpage +PB_PAGE_SKIP ; - } +} -/* This is for swsusp_free() */ - for_each_pb_page (pbpage, pblist) { -SetPageNosave (virt_to_page (pbpage)); -SetPageNosaveFree (virt_to_page (pbpage)); +static void copy_page_backup_list (struct pbe *dst,struct pbe *src) +{ +/* We assume both lists contain the same number of elements */ +while (src) { + dst->orig_address = src->orig_address; + dst->swap_address = src->swap_address; + dst = dst->next; + src = src->next; } - -printk ("swsusp: Relocated %d pages\n" , rel); - -return pblist; }/*
@@ -949,10 +918,15 @@if ((error =read_pagedir (p)))return error; -create_pbe_list (p, nr_copy_pages); - -if (!(pagedir_nosave =swsusp_pagedir_relocate (p))) +mark_unsafe_pages (p); + pagedir_nosave =alloc_pagedir (nr_copy_pages,GFP_ATOMIC ,1 ); +if (pagedir_nosave) { +create_pbe_list (pagedir_nosave, nr_copy_pages); +copy_page_backup_list (pagedir_nosave, p); + } +free_pagedir (p); +if (!pagedir_nosave)return -ENOMEM ;/* Allocate memory for the image and read the data from swap */
kernel/power/power.h +1 -0
@@ -66,6 +66,7 @@ extern asmlinkage int swsusp_arch_resume(void);extern int restore_highmem (void ); +extern void free_pagedir (struct pbe *pblist);extern struct pbe *alloc_pagedir (unsigned nr_pages,gfp_t gfp_mask,int safe_needed);extern void create_pbe_list (struct pbe *pblist,unsigned nr_pages);extern void swsusp_free (void );
kernel/power/snapshot.c +1 -1
@@ -217,7 +217,7 @@* free_pagedir - free pages allocated with alloc_pagedir() */ -static void free_pagedir (struct pbe *pblist) +void free_pagedir (struct pbe *pblist) {struct pbe *pbe;
Re: [PATCH 2/2] swsusp: simplify pagedir relocation
Quoted 3 lines
The appended patch simplifies the relocation of the page backup list (aka pagedir) during resume.
ACK and thanks for patience.
Pavel
Signature · 1 line
Thanks, Sharp!
Re: [PATCH 2/2] swsusp: simplify pagedir relocation
Quoted 5 lines · Pavel Machek
Quoted 3 lines
The appended patch simplifies the relocation of the page backup list (aka pagedir) during resume.
ACK and thanks for patience.
No big deal.
Greetings,
Rafael
Re: [PATCH 1/2] swsusp: reduce code duplication (was: Re: [PATCH 2/3] swsusp: move snapshot-handling functions to snapshot.c)
In reply to Rafael J. WysockiHi!
Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
Quoted 3 lines
Speaking of simplifications and having seen your code I hope you will agree with the appended patch against vanilla 2.6.14-git3 (it reduces the duplication of code, and replaces
swsusp_pagedir_relocatewith a simpler mechanism)....and also moves stuff around in a way
Quoted 7 lines
Quoted 5 lines
a) I don't like
and
b) is almost impossible to review
OK, I'll try to split it into two patches to make it cleaner.
Quoted 8 lines
The first patch is appended, the next one will be in the reply to this message.
The changes made by the appended patch are necessary for the relocation simplification in the next patch. Still, the changes allow us to drop
check_pagedir()and makeget_safe_page()be a one-line wrapper aroundalloc_image_page()(get_safe_page()goes tosnapshot.c, becausealloc_image_page()is static and it does not make sense to export it).
ACK.
Pavel
Signature · 1 line
Thanks, Sharp!
PATCH 3/3 swsusp: move swap check out of swsusp_suspend
In reply to Rafael J. WysockiThis patch moves the check for available swap out of swsusp_suspend(), which is necessary for separating the swap-handling functions in swsusp from the core code. No functionality changes.
kernel/power/swsusp.c | 13 +++++-------- 1 files changed, 5 insertions(+), 8 deletions(-)
kernel/power/swsusp.c +5 -8
@@ -567,12 +567,15 @@ {int error; +if ((error =swsusp_swap_check ())) { +printk (KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n" ); +return error; + }lock_swapdevices (); error =write_suspend_image ();/* This will unlock ignored swap devices since writing is finished */ lock_swapdevices ();return error; - }
@@ -595,11 +598,6 @@ goto Enable_irqs; } -if ((error =swsusp_swap_check ())) { -printk (KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n" ); - goto Power_up; - } -if ((error =save_highmem ())) {printk (KERN_ERR "swsusp: Not enough free pages for highmem\n" ); goto Restore_highmem;
@@ -612,7 +610,6 @@restore_processor_state (); Restore_highmem:restore_highmem (); -Power_up:device_power_up (); Enable_irqs:local_irq_enable ();
@@ -781,7 +778,7 @@* Reset swap signature now. */ error =bio_write_page (0 , &swsusp_header); - }else { + }else {return -EINVAL ; }if (!error)