Re: Fix memory leak in swsusp

From: Herbert Xu
Date: Fri Jun 11 2004 - 06:05:16 EST


On Fri, Jun 11, 2004 at 12:23:27PM +0200, Pavel Machek wrote:
>
> If you want more cleanups, copy_pagedir() should be probably replaced
> by simple memset...

Yes that's a great idea. Here is the patch to do that. Again it
relies on all the previous patches in this thread.

Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@xxxxxxxxxxxxxxxxxxx>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
===== kernel/power/pmdisk.c 1.86 vs edited =====
--- 1.86/kernel/power/pmdisk.c 2004-06-11 18:23:44 +10:00
+++ edited/kernel/power/pmdisk.c 2004-06-11 21:01:41 +10:00
@@ -732,19 +732,6 @@

/* More restore stuff */

-/* FIXME: Why not memcpy(to, from, 1<<pagedir_order*PAGE_SIZE)? */
-static void __init copy_pagedir(suspend_pagedir_t *to, suspend_pagedir_t *from)
-{
- int i;
- char *topointer=(char *)to, *frompointer=(char *)from;
-
- for(i=0; i < 1 << pagedir_order; i++) {
- copy_page(topointer, frompointer);
- topointer += PAGE_SIZE;
- frompointer += PAGE_SIZE;
- }
-}
-
#define does_collide(addr) does_collide_order(pm_pagedir_nosave, addr, 0)

/*
@@ -792,7 +779,7 @@
* We have to avoid recursion (not to overflow kernel stack),
* and that's why code looks pretty cryptic
*/
- suspend_pagedir_t *new_pagedir, *old_pagedir = pm_pagedir_nosave;
+ suspend_pagedir_t *old_pagedir = pm_pagedir_nosave;
void **eaten_memory = NULL;
void **c = eaten_memory, *m, *f;
int err;
@@ -808,8 +795,9 @@
while ((m = (void *) __get_free_pages(GFP_ATOMIC, pagedir_order))) {
if (!does_collide_order(old_pagedir, (unsigned long)m,
pagedir_order)) {
- pm_pagedir_nosave = new_pagedir = m;
- copy_pagedir(new_pagedir, old_pagedir);
+ pm_pagedir_nosave =
+ memcpy(m, old_pagedir,
+ PAGE_SIZE << pagedir_order);
err = 0;
break;
}
--- linux-2.5/kernel/power/swsusp.c.orig 2004-06-11 20:54:24.000000000 +1000
+++ linux-2.5/kernel/power/swsusp.c 2004-06-11 21:02:22.000000000 +1000
@@ -863,19 +863,6 @@

/* More restore stuff */

-/* FIXME: Why not memcpy(to, from, 1<<pagedir_order*PAGE_SIZE)? */
-static void copy_pagedir(suspend_pagedir_t *to, suspend_pagedir_t *from)
-{
- int i;
- char *topointer=(char *)to, *frompointer=(char *)from;
-
- for(i=0; i < 1 << pagedir_order; i++) {
- copy_page(topointer, frompointer);
- topointer += PAGE_SIZE;
- frompointer += PAGE_SIZE;
- }
-}
-
#define does_collide(addr) does_collide_order(pagedir_nosave, addr, 0)

/*
@@ -923,7 +910,7 @@
* We have to avoid recursion (not to overflow kernel stack),
* and that's why code looks pretty cryptic
*/
- suspend_pagedir_t *new_pagedir, *old_pagedir = pagedir_nosave;
+ suspend_pagedir_t *old_pagedir = pagedir_nosave;
void **eaten_memory = NULL;
void **c = eaten_memory, *m, *f;
int ret = 0;
@@ -948,8 +935,8 @@
printk("out of memory\n");
ret = -ENOMEM;
} else {
- pagedir_nosave = new_pagedir = m;
- copy_pagedir(new_pagedir, old_pagedir);
+ pagedir_nosave =
+ memcpy(m, old_pagedir, PAGE_SIZE << pagedir_order);
}

c = eaten_memory;