Skip to contentSkip to conversation

mm: frontswap: core swap subsystem hooks and headers

PATCH In review Dan Magenheimer 1 participant 1 message Sep 15, 2011

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH v10 2/6 mm: frontswap: core swap subsystem hooks and headers

From: Dan Magenheimer <[email protected]>
Subject: [PATCH V10 2/6] mm: frontswap: core swap subsystem hooks and headers

(Note to earlier reviewers: This patchset has been reorganized due to feedback from Kame Hiroyuki and Andrew Morton. This patch combines patch 1of4 and patch 3of4 from the previous series.)

This second patch of six in the frontswap series contains the changes to the core swap subsystem. This includes:

(1) makes available core swap data structures (swap_lock, swap_list and swap_info) that are needed by frontswap.c but we don't need to expose them to the dozens of files that include swap.h so we create a new swapfile.h just to extern-ify these and modify their declarations to non-static

(2) adds frontswap-related elements to swap_info_struct. Frontswap_map points to vzalloc'ed one-bit-per-swap-page metadata that indicates whether the swap page is in frontswap or in the device and frontswap_pages counts how many pages are in frontswap.

(3) adds hooks in the swap subsystem and extends try_to_unuse so that frontswap_shrink can do a "partial swapoff".

Note that a failed frontswap_map allocation is safe... failure is noted by lack of "FS" in the subsequent printk.

[v10: no change]
[v9: [email protected]: mark some statics __read_mostly]
[v9: [email protected]: add clarifying comments]
[v9: [email protected]: no need to loop repeating try_to_unuse]
[v9: [email protected]: remove superfluous check for NULL]
[v8: rebase to 3.0-rc4]
[v8: [email protected]: change counter to atomic_t to avoid races]
[v8: [email protected]: comment to clarify informational counters]
[v7: rebase to 3.0-rc3]
[v7: [email protected]: add new swap struct elements only if config'd]
[v6: rebase to 3.0-rc1]
[v6: [email protected]: fix null pointer deref if vzalloc fails]
[v6: [email protected]: various checks and code clarifications/comments]
[v5: no change from v4]
[v4: rebase to 2.6.39]
Cc Jeremy Fitzhardinge <[email protected]>
Cc Hugh Dickins <[email protected]>
Cc Johannes Weiner <[email protected]>
Cc Nitin Gupta <[email protected]>
Cc Matthew Wilcox <[email protected]>
Cc Chris Mason <[email protected]>
Cc Rik Riel <[email protected]>
Cc Andrew Morton <[email protected]>

---

Diffstat:

 include/linux/swap.h                     |    4 +
 include/linux/swapfile.h                 |   13 ++++
 mm/page_io.c                             |   12 +++
 mm/swapfile.c                            |   64 ++++++++++++++++-----
 4 files changed, 80 insertions(+), 13 deletions(-)
include/linux/swapfile.h +13 -0
@@ -0,0 +1,13 @@
+#ifndef _LINUX_SWAPFILE_H
+#define _LINUX_SWAPFILE_H
+
+/*
+ * these were static in swapfile.c but frontswap.c needs them and we don't
+ * want to expose them to the dozens of source files that include swap.h
+ */
+extern spinlock_t swap_lock;
+extern struct swap_list_t swap_list;
+extern struct swap_info_struct *swap_info[];
+extern int try_to_unuse(unsigned int, bool, unsigned long);
+
+#endif /* _LINUX_SWAPFILE_H */
include/linux/swap.h +4 -0
@@ -194,6 +194,10 @@ struct swap_info_struct {
 	struct block_device *bdev;	/* swap device or bdev of swap file */
 	struct file *swap_file;		/* seldom referenced */
 	unsigned int old_block_size;	/* seldom referenced */
+#ifdef CONFIG_FRONTSWAP
+	unsigned long *frontswap_map;	/* frontswap in-use, one bit per page */
+	atomic_t frontswap_pages;	/* frontswap pages in-use counter */
+#endif
 };
 
 struct swap_list_t {
mm/swapfile.c +51 -13

203 lines not on this page · raw message

mm/page_io.c +12 -0
@@ -18,6 +18,7 @@
 #include <linux/bio.h>
 #include <linux/swapops.h>
 #include <linux/writeback.h>
+#include <linux/frontswap.h>
 #include <asm/pgtable.h>
 
 static struct bio *get_swap_bio(gfp_t gfp_flags,
@@ -98,6 +99,12 @@ int swap_writepage(struct page *page, st
 		unlock_page(page);
 		goto out;
 	}
+	if (frontswap_put_page(page) == 0) {
+		set_page_writeback(page);
+		unlock_page(page);
+		end_page_writeback(page);
+		goto out;
+	}
 	bio = get_swap_bio(GFP_NOIO, page, end_swap_bio_write);
 	if (bio == NULL) {
 		set_page_dirty(page);
@@ -122,6 +129,11 @@ int swap_readpage(struct page *page)
 
 	VM_BUG_ON(!PageLocked(page));
 	VM_BUG_ON(PageUptodate(page));
+	if (frontswap_get_page(page) == 0) {
+		SetPageUptodate(page);
+		unlock_page(page);
+		goto out;
+	}
 	bio = get_swap_bio(GFP_KERNEL, page, end_swap_bio_read);
 	if (bio == NULL) {
 		unlock_page(page);

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>