[patch] shm swap deallocation for 2.0.35

Andrea Arcangeli (arcangeli@mbox.queen.it)
Thu, 27 Aug 1998 15:09:35 +0200 (CEST)


I backported the swap deallocation code needed to run swapoff without
going in troubles to 2.0.35. I tested it a bit and seems to work.

Andrea[s] Arcangeli

--- linux-2.0.35/CREDITS Tue Aug 11 02:09:19 1998
+++ linux/CREDITS Thu Aug 27 15:05:49 1998
@@ -37,9 +37,11 @@

N: Andrea Arcangeli
E: arcangeli@mbox.queen.it
-W: http://www.cs.unibo.it/~arcangel/
+W: http://e-mind.com/~andrea/
P: 1024/CB4660B9 CC A0 71 81 F4 A0 63 AC C0 4B 81 1D 8C 15 C8 E5
D: Fixed a 2.0.33 mm bug that corrupts memory in linux/mm/vmalloc.c
+D: Author of lil (Linux Interrupt Latency benchmark)
+D: Fixed the shm swap deallocation at swapoff time
S: Via Ciaclini 26
S: Imola 40026
S: Italy
--- linux/mm/swapfile.c.orig Thu Jun 18 23:48:22 1998
+++ linux/mm/swapfile.c Thu Aug 27 14:20:47 1998
@@ -17,6 +17,7 @@
#include <linux/fs.h>
#include <linux/swapctl.h>
#include <linux/blkdev.h> /* for blk_size */
+#include <linux/shm.h>

#include <asm/dma.h>
#include <asm/system.h> /* for cli()/sti() */
@@ -313,6 +314,7 @@
nr++;
}
free_page(page);
+ shm_unuse(type);
return 0;
}

--- linux/ipc/shm.c.orig Thu Jun 18 23:48:21 1998
+++ linux/ipc/shm.c Thu Aug 27 14:59:32 1998
@@ -3,6 +3,7 @@
* Copyright (C) 1992, 1993 Krishna Balasubramanian
* Many improvements/fixes by Bruno Haible.
* Replaced `struct shm_desc' by `struct vm_area_struct', July 1994.
+ * Fixed the shm swap deallocation (shm_unuse()), August 1998 Andrea Arcangeli.
*/

#include <linux/errno.h>
@@ -803,4 +804,66 @@
shm_swp++;
shm_rss--;
return 1;
+}
+
+/*
+ * Free the swap entry and set the new pte for the shm page.
+ */
+static void shm_unuse_page(struct shmid_ds *shp, unsigned long idx,
+ unsigned long type)
+{
+ pte_t pte = __pte(shp->shm_pages[idx]);
+ unsigned long page, entry = shp->shm_pages[idx];
+
+ if (pte_none(pte))
+ return;
+ if (pte_present(pte))
+ {
+ /*
+ * Security check. Should be not needed...
+ */
+ unsigned long page_nr = MAP_NR(pte_page(pte));
+ if (page_nr >= MAP_NR(high_memory))
+ {
+ printk("shm page mapped in virtual memory\n");
+ return;
+ }
+ if (!in_swap_cache(page_nr))
+ return;
+ if (SWP_TYPE(in_swap_cache(page_nr)) != type)
+ return;
+ printk("shm page in swap cache, trying to remove it!\n");
+ delete_from_swap_cache(page_nr);
+
+ shp->shm_pages[idx] = pte_val(pte_mkdirty(pte));
+ return;
+ }
+
+ if (SWP_TYPE(pte_val(pte)) != type)
+ return;
+
+ /*
+ * Here we must swapin the pte and free the swap.
+ */
+ page = get_free_page(GFP_KERNEL);
+ read_swap_page(pte_val(pte), (char *) page);
+ pte = pte_mkdirty(mk_pte(page, PAGE_SHARED));
+ shp->shm_pages[idx] = pte_val(pte);
+ shm_rss++;
+
+ swap_free(entry);
+ shm_swp--;
+}
+
+/*
+ * unuse_shm() search for an eventually swapped out shm page.
+ */
+void shm_unuse(unsigned int type)
+{
+ int i, n;
+
+ for (i = 0; i < SHMMNI; i++)
+ if (shm_segs[i] != IPC_UNUSED && shm_segs[i] != IPC_NOID)
+ for (n = 0; n < shm_segs[i]->shm_npages; n++)
+ shm_unuse_page(shm_segs[i], n, type);
}
--- linux/include/linux/shm.h.orig Tue Oct 8 18:45:42 1996
+++ linux/include/linux/shm.h Thu Aug 27 14:35:04 1998
@@ -63,6 +63,7 @@
asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *addr);
asmlinkage int sys_shmdt (char *shmaddr);
asmlinkage int sys_shmctl (int shmid, int cmd, struct shmid_ds *buf);
+extern void shm_unuse(unsigned int type);

#endif /* __KERNEL__ */

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html