changeset 1:be7e3e4b76b7

attempt 2
author Josef "Jeff" Sipek <jsipek@cs.sunysb.edu>
date Sun, 29 Jul 2007 01:16:05 -0400
parents c4fbdb46d162
children 818e80678261
files multiple-inactive_lists remove_assfail series xfs-save-buf-reference-count-as-page-weight
diffstat 4 files changed, 281 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multiple-inactive_lists	Sun Jul 29 01:16:05 2007 -0400
@@ -0,0 +1,155 @@
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index a5c4518..fd79561 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -221,6 +221,9 @@ struct inode;
+ #define page_private(page)		((page)->private)
+ #define set_page_private(page, v)	((page)->private = (v))
+ 
++#define page_weight(page)		((page)->weight)
++#define set_page_weight(page, v)	((page)->weight = (v))
++
+ /*
+  * FIXME: take this include out, include page-flags.h in
+  * files which need it (119 of them)
+diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
+index 895bc4e..781417d 100644
+--- a/include/linux/mm_inline.h
++++ b/include/linux/mm_inline.h
+@@ -8,7 +8,8 @@ add_page_to_active_list(struct zone *zone, struct page *page)
+ static inline void
+ add_page_to_inactive_list(struct zone *zone, struct page *page)
+ {
+-	list_add(&page->lru, &zone->inactive_list);
++	VM_BUG_ON(page_weight(page) >= NR_INACTIVE_LISTS);
++	list_add(&page->lru, &zone->inactive_lists[page_weight(page)]);
+ 	__inc_zone_state(zone, NR_INACTIVE);
+ }
+ 
+diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
+index d5bb179..b9510b6 100644
+--- a/include/linux/mm_types.h
++++ b/include/linux/mm_types.h
+@@ -61,6 +61,7 @@ struct page {
+ 		pgoff_t index;		/* Our offset within mapping. */
+ 		void *freelist;		/* SLUB: freelist req. slab lock */
+ 	};
++	int weight;
+ 	struct list_head lru;		/* Pageout list, eg. active_list
+ 					 * protected by zone->lru_lock !
+ 					 */
+diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
+index da8eb8a..e75a39c 100644
+--- a/include/linux/mmzone.h
++++ b/include/linux/mmzone.h
+@@ -189,6 +189,8 @@ enum zone_type {
+ #endif
+ #undef __ZONE_COUNT
+ 
++#define NR_INACTIVE_LISTS	2
++
+ struct zone {
+ 	/* Fields commonly accessed by the page allocator */
+ 	unsigned long		pages_min, pages_low, pages_high;
+@@ -229,7 +231,7 @@ struct zone {
+ 	/* Fields commonly accessed by the page reclaim scanner */
+ 	spinlock_t		lru_lock;	
+ 	struct list_head	active_list;
+-	struct list_head	inactive_list;
++	struct list_head	inactive_lists[NR_INACTIVE_LISTS];
+ 	unsigned long		nr_scan_active;
+ 	unsigned long		nr_scan_inactive;
+ 	unsigned long		pages_scanned;	   /* since last reclaim */
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index e2a10b9..4da3f97 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -620,6 +620,7 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags)
+ 	page->flags &= ~(1 << PG_uptodate | 1 << PG_error |
+ 			1 << PG_referenced | 1 << PG_arch_1 |
+ 			1 << PG_owner_priv_1 | 1 << PG_mappedtodisk);
++	set_page_weight(page, 0);
+ 	set_page_private(page, 0);
+ 	set_page_refcounted(page);
+ 
+@@ -2899,6 +2900,7 @@ static void __meminit free_area_init_core(struct pglist_data *pgdat,
+ 		unsigned long *zones_size, unsigned long *zholes_size)
+ {
+ 	enum zone_type j;
++	int weight;
+ 	int nid = pgdat->node_id;
+ 	unsigned long zone_start_pfn = pgdat->node_start_pfn;
+ 	int ret;
+@@ -2961,7 +2963,10 @@ static void __meminit free_area_init_core(struct pglist_data *pgdat,
+ 
+ 		zone_pcp_init(zone);
+ 		INIT_LIST_HEAD(&zone->active_list);
+-		INIT_LIST_HEAD(&zone->inactive_list);
++
++		for (weight = 0; weight < NR_INACTIVE_LISTS; weight++)
++			INIT_LIST_HEAD(&zone->inactive_lists[weight]);
++
+ 		zone->nr_scan_active = 0;
+ 		zone->nr_scan_inactive = 0;
+ 		zap_zone_vm_stats(zone);
+diff --git a/mm/swap.c b/mm/swap.c
+index d3cb966..07d7e72 100644
+--- a/mm/swap.c
++++ b/mm/swap.c
+@@ -125,7 +125,7 @@ int rotate_reclaimable_page(struct page *page)
+ 	zone = page_zone(page);
+ 	spin_lock_irqsave(&zone->lru_lock, flags);
+ 	if (PageLRU(page) && !PageActive(page)) {
+-		list_move_tail(&page->lru, &zone->inactive_list);
++		list_move_tail(&page->lru, &zone->inactive_lists[page_weight(page)]);
+ 		__count_vm_event(PGROTATED);
+ 	}
+ 	if (!test_clear_page_writeback(page))
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index d419e10..c236999 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -759,6 +759,7 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
+ 	struct pagevec pvec;
+ 	unsigned long nr_scanned = 0;
+ 	unsigned long nr_reclaimed = 0;
++	int weight = 0;
+ 
+ 	pagevec_init(&pvec, 1);
+ 
+@@ -772,7 +773,7 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
+ 		unsigned long nr_active;
+ 
+ 		nr_taken = isolate_lru_pages(sc->swap_cluster_max,
+-			     &zone->inactive_list,
++			     &zone->inactive_lists[weight],
+ 			     &page_list, &nr_scan, sc->order,
+ 			     (sc->order > PAGE_ALLOC_COSTLY_ORDER)?
+ 					     ISOLATE_BOTH : ISOLATE_INACTIVE);
+@@ -795,8 +796,15 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
+ 			__count_zone_vm_events(PGSCAN_DIRECT, zone, nr_scan);
+ 		__count_zone_vm_events(PGSTEAL, zone, nr_freed);
+ 
+-		if (nr_taken == 0)
+-			goto done;
++		if (nr_taken == 0) {
++			/*
++			 * The current inactive list is empty, let's move
++			 * onto the next one - one with higher weight pages
++			 */
++			weight++;
++			if (weight == NR_INACTIVE_LISTS)
++				goto done;
++		}
+ 
+ 		spin_lock(&zone->lru_lock);
+ 		/*
+@@ -956,7 +964,7 @@ force_reclaim_mapped:
+ 		VM_BUG_ON(!PageActive(page));
+ 		ClearPageActive(page);
+ 
+-		list_move(&page->lru, &zone->inactive_list);
++		list_move(&page->lru, &zone->inactive_lists[page_weight(page)]);
+ 		pgmoved++;
+ 		if (!pagevec_add(&pvec, page)) {
+ 			__mod_zone_page_state(zone, NR_INACTIVE, pgmoved);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/remove_assfail	Sun Jul 29 01:16:05 2007 -0400
@@ -0,0 +1,37 @@
+XFS: Removed a useless wrapper: assfail
+
+Cc: xfs-masters@oss.sgi.com
+Cc: xfs@oss.sgi.com
+Signed-off-by: Josef 'Jeff' Sipek <jsipek@cs.sunysb.edu>
+
+diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
+index f45a49f..fafc048 100644
+--- a/fs/xfs/support/debug.c
++++ b/fs/xfs/support/debug.c
+@@ -74,10 +74,3 @@ icmn_err(register int level, char *fmt, va_list ap)
+ 	spin_unlock_irqrestore(&xfs_err_lock,flags);
+ 	BUG_ON(level == CE_PANIC);
+ }
+-
+-void
+-assfail(char *expr, char *file, int line)
+-{
+-	printk("Assertion failed: %s, file: %s, line: %d\n", expr, file, line);
+-	BUG();
+-}
+diff --git a/fs/xfs/support/debug.h b/fs/xfs/support/debug.h
+index a27a7c8..86c5103 100644
+--- a/fs/xfs/support/debug.h
++++ b/fs/xfs/support/debug.h
+@@ -31,10 +31,8 @@ extern void icmn_err(int, char *, va_list)
+ 	__attribute__ ((format (printf, 2, 0)));
+ extern void cmn_err(int, char *, ...)
+ 	__attribute__ ((format (printf, 2, 3)));
+-extern void assfail(char *expr, char *f, int l);
+ 
+-#define ASSERT_ALWAYS(expr)	\
+-	(unlikely((expr) != 0) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
++#define ASSERT_ALWAYS(expr)	BUG_ON(!(expr))
+ 
+ #ifndef DEBUG
+ # define ASSERT(expr)	((void)0)
--- a/series	Wed Jul 25 09:44:40 2007 -0400
+++ b/series	Sun Jul 29 01:16:05 2007 -0400
@@ -1,3 +1,21 @@
-version
+#
+# Linus messed up my compile & install script
+#
+#version
+
+#
+# Priority page reclaim
+#
+multiple-inactive_lists
 rename-B_FS-flags
-save-xfs_buf_set_vtype_ref-value
+xfs-save-buf-reference-count-as-page-weight
+
+#
+# Previous attempt
+# 
+#save-xfs_buf_set_vtype_ref-value
+
+#
+# Misc cleanup
+#
+remove_assfail
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xfs-save-buf-reference-count-as-page-weight	Sun Jul 29 01:16:05 2007 -0400
@@ -0,0 +1,69 @@
+XFS: Save buffer type and references count
+
+Save values passed to XFS_BUF_SET_{VTYPE,REF,VTYPE_REF} inside the xfs_buf_t
+struct.
+
+Signed-off-by: Josef 'Jeff' Sipek <jsipek@cs.sunysb.edu>
+
+diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
+index b5908a3..99099d0 100644
+--- a/fs/xfs/linux-2.6/xfs_buf.h
++++ b/fs/xfs/linux-2.6/xfs_buf.h
+@@ -31,6 +31,19 @@
+  *	Base types
+  */
+ 
++typedef enum {
++	XFS_B_FS_NONE,
++	XFS_B_FS_INO,
++	XFS_B_FS_INOMAP,
++	XFS_B_FS_DIR_BTREE,
++	XFS_B_FS_MAP,
++	XFS_B_FS_ATTR_BTREE,
++	XFS_B_FS_AGI,
++	XFS_B_FS_AGF,
++	XFS_B_FS_AGFL,
++	XFS_B_FS_DQUOT
++} xfs_bvtype_t;
++
+ #define XFS_BUF_DADDR_NULL	((xfs_daddr_t) (-1LL))
+ 
+ #define xfs_buf_ctob(pp)	((pp) * PAGE_CACHE_SIZE)
+@@ -123,6 +136,7 @@ typedef struct xfs_buf {
+ 	atomic_t		b_pin_count;	/* pin count */
+ 	wait_queue_head_t	b_waiters;	/* unpin waiters */
+ 	struct list_head	b_list;
++	xfs_bvtype_t		b_type;		/* buffer type */
+ 	xfs_buf_flags_t		b_flags;	/* status flags */
+ 	struct list_head	b_hash_list;	/* hash table list */
+ 	xfs_bufhash_t		*b_hash;	/* hash table list start */
+@@ -324,9 +338,26 @@ extern void xfs_buf_trace(xfs_buf_t *, char *, void *, void *);
+ #define XFS_BUF_SIZE(bp)		((bp)->b_buffer_length)
+ #define XFS_BUF_SET_SIZE(bp, cnt)	((bp)->b_buffer_length = (cnt))
+ 
+-#define XFS_BUF_SET_VTYPE_REF(bp, type, ref)	do { } while (0)
+-#define XFS_BUF_SET_VTYPE(bp, type)		do { } while (0)
+-#define XFS_BUF_SET_REF(bp, ref)		do { } while (0)
++static inline void XFS_BUF_SET_VTYPE(xfs_buf_t *bp, xfs_bvtype_t type)
++{
++	bp->b_type = type;
++}
++
++static inline void XFS_BUF_SET_REF(xfs_buf_t *bp, char ref)
++{
++	int i;
++	int weight = !!(ref-1);
++
++	for (i = 0; i < XFS_BUF_SIZE(bp); i++)
++		set_page_weight(bp->b_pages, weight);
++}
++
++static inline void XFS_BUF_SET_VTYPE_REF(xfs_buf_t *bp, xfs_bvtype_t type,
++					 char ref)
++{
++	XFS_BUF_SET_VTYPE(bp, type);
++	XFS_BUF_SET_REF(bp, ref);
++}
+ 
+ #define XFS_BUF_ISPINNED(bp)	xfs_buf_ispin(bp)
+