the following patch adds support for machines where swap is
smaller than ram by conditionally freeing up swap space at
swapin time when our swap area is getting full.
The main part of the patch is this:
+ if (vm_swap_full() && exclusive_swap_page(page)) {
+ delete_from_swap_cache_nolock(page);
+ pte = pte_mkwrite(pte_mkdirty(pte));
+ }
The rest is trivial support code, mostly optimised for
readability.
Please apply for the next -pre version.
thanks,
Rik
-- Executive summary of a recent Microsoft press release: "we are concerned about the GNU General Public License (GPL)"http://www.surriel.com/ http://www.conectiva.com/ http://distro.conectiva.com/
--- linux-2.4.7-ac7/mm/memory.c.orig Mon Aug 6 12:23:33 2001 +++ linux-2.4.7-ac7/mm/memory.c Tue Aug 7 14:20:11 2001 @@ -1147,6 +1147,20 @@ swap_free(entry); if (write_access && exclusive_swap_page(page)) pte = pte_mkwrite(pte_mkdirty(pte)); + + /* + * If swap space is getting low and we were the last user + * of this piece of swap space, we free this space so + * somebody else can be swapped out. + * + * We are protected against try_to_swap_out() because the + * page is locked and against do_fork() because we have + * read_lock(&mm->mmap_sem). + */ + if (vm_swap_full() && exclusive_swap_page(page)) { + delete_from_swap_cache_nolock(page); + pte = pte_mkwrite(pte_mkdirty(pte)); + } UnlockPage(page);
flush_page_to_ram(page); --- linux-2.4.7-ac7/mm/swapfile.c.orig Mon Aug 6 12:23:33 2001 +++ linux-2.4.7-ac7/mm/swapfile.c Tue Aug 7 11:55:18 2001 @@ -19,11 +19,34 @@
spinlock_t swaplock = SPIN_LOCK_UNLOCKED; unsigned int nr_swapfiles; +int total_swap_pages;
struct swap_list_t swap_list = {-1, -1};
struct swap_info_struct swap_info[MAX_SWAPFILES];
+/* + * When swap space gets filled up, we will set this flag. + * This will make do_swap_page(), in the page fault path, + * free swap entries on swapin so we'll reclaim swap space + * in order to be able to swap something out. + * + * At the moment we start reclaiming when swap usage goes + * over 80% of swap space and we continue reclaiming until + * the amount of occupied swap drops to less than 75%. + * XXX: these are random numbers, fixme. + */ +#define SWAP_FULL_PCT 80 +int vm_swap_full (void) { + int full = 0; + int swap_used = total_swap_pages - nr_swap_pages; + + if (swap_used * 100 > total_swap_pages * SWAP_FULL_PCT) + full = 1; + + return full; +} + #define SWAPFILE_CLUSTER 256
static inline int scan_swap_map(struct swap_info_struct *si, unsigned short count) @@ -469,6 +492,7 @@ swap_list.next = swap_list.head; } nr_swap_pages -= p->pages; + total_swap_pages -= p->pages; swap_list_unlock(); p->flags = SWP_USED; err = try_to_unuse(type); @@ -484,6 +508,7 @@ else swap_info[prev].next = p - swap_info; nr_swap_pages += p->pages; + total_swap_pages += p->pages; swap_list_unlock(); p->flags = SWP_WRITEOK; goto out_dput; @@ -771,6 +796,7 @@ p->pages = nr_good_pages; swap_list_lock(); nr_swap_pages += nr_good_pages; + total_swap_pages += nr_good_pages; printk(KERN_INFO "Adding Swap: %dk swap-space (priority %d)\n", nr_good_pages<<(PAGE_SHIFT-10), p->prio);
--- linux-2.4.7-ac7/include/linux/swap.h.orig Mon Aug 6 12:33:35 2001 +++ linux-2.4.7-ac7/include/linux/swap.h Mon Aug 6 20:08:44 2001 @@ -158,6 +158,7 @@ extern void free_page_and_swap_cache(struct page *page);
/* linux/mm/swapfile.c */ +extern int vm_swap_full(void); extern unsigned int nr_swapfiles; extern struct swap_info_struct swap_info[]; extern int is_swap_partition(kdev_t);
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/