Skip to contentSkip to conversation

rmap 15a for 2.4.20-rc2-ac3

RFC PATCH In review Paul P Komkoff Jr 2 participants 2 messages Nov 26, 2002

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

RFC PATCH 1/1 rmap 15a for 2.4.20-rc2-ac3

The subject clearly described the patch.

The only thing I'm unsure about is current->mm->... etc in kernel/sched.c

Enjoy.

fs/buffer.c +25 -0
diff -Nru a/fs/buffer.c b/fs/buffer.c
@@ -2915,6 +2915,30 @@
 	}
 }
 
+
+/*
+ * Do some IO post-processing here!!!
+ */
+void do_io_postprocessing(void)
+{
+	int i;
+	struct buffer_head *bh, *next;
+
+	spin_lock(&lru_list_lock);
+	bh = lru_list[BUF_LOCKED];
+	if (bh) {
+		for (i = nr_buffers_type[BUF_LOCKED]; i-- > 0; bh = next) {
+			next = bh->b_next_free;
+
+			if (!buffer_locked(bh)) 
+				__refile_buffer(bh);
+			else 
+				break;
+		}
+	}
+	spin_unlock(&lru_list_lock);
+}
+
 /*
  * This is the kernel update daemon. It was used to live in userspace
  * but since it's need to run safely we want it unkillable by mistake.
@@ -2966,6 +2990,7 @@
 #ifdef DEBUG
 		printk(KERN_DEBUG "kupdate() activated...\n");
 #endif
+		do_io_postprocessing();
 		sync_old_buffers();
 		run_task_queue(&tq_disk);
 	}
fs/proc/proc_misc.c +9 -3
diff -Nru a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
@@ -191,7 +191,10 @@
 		"Cached:       %8lu kB\n"
 		"SwapCached:   %8lu kB\n"
 		"Active:       %8u kB\n"
+		"ActiveAnon:   %8u kB\n"
+		"ActiveCache:  %8u kB\n"
 		"Inact_dirty:  %8u kB\n"
+		"Inact_laundry:%8u kB\n"
 		"Inact_clean:  %8u kB\n"
 		"Inact_target: %8u kB\n"
 		"HighTotal:    %8lu kB\n"
@@ -207,9 +210,12 @@
 		K(i.bufferram),
 		K(pg_size - swapper_space.nrpages),
 		K(swapper_space.nrpages),
-		K(nr_active_pages),
-		K(nr_inactive_dirty_pages),
-		K(nr_inactive_clean_pages),
+		K(nr_active_anon_pages()) + K(nr_active_cache_pages()),
+		K(nr_active_anon_pages()),
+		K(nr_active_cache_pages()),
+		K(nr_inactive_dirty_pages()),
+		K(nr_inactive_laundry_pages()),
+		K(nr_inactive_clean_pages()),
 		K(inactive_target()),
 		K(i.totalhigh),
 		K(i.freehigh),
include/linux/brlock.h +2 -0
diff -Nru a/include/linux/brlock.h b/include/linux/brlock.h
@@ -37,6 +37,8 @@
 	BR_GLOBALIRQ_LOCK,
 	BR_NETPROTO_LOCK,
 	BR_LLC_LOCK,
+	BR_LRU_LOCK,
+
 	__BR_END
 };
 
include/linux/list.h +1 -2
diff -Nru a/include/linux/list.h b/include/linux/list.h
@@ -137,8 +137,7 @@
 	return head->next == head;
 }
 
-static inline void __list_splice(struct list_head *list,
-				 struct list_head *head)
+static inline void __list_splice(struct list_head *list, struct list_head *head)
 {
 	struct list_head *first = list->next;
 	struct list_head *last = list->prev;
include/linux/mm.h +49 -18

97 lines not on this page · raw message

include/linux/mm_inline.h +178 -18

268 lines not on this page · raw message

include/linux/mmzone.h +13 -6
diff -Nru a/include/linux/mmzone.h b/include/linux/mmzone.h
@@ -13,11 +13,7 @@
  * Free memory management - zoned buddy allocator.
  */
 
-#ifndef CONFIG_FORCE_MAX_ZONEORDER
 #define MAX_ORDER 10
-#else
-#define MAX_ORDER CONFIG_FORCE_MAX_ZONEORDER
-#endif
 
 typedef struct free_area_struct {
 	struct list_head	free_list;
@@ -29,6 +25,9 @@
 
 #define MAX_CHUNKS_PER_NODE 8
 
+#define MAX_AGE 15
+#define INITIAL_AGE 3
+
 #define MAX_PER_CPU_PAGES 512
 typedef struct per_cpu_pages_s {
 	int			nr_pages, max_nr_pages;
@@ -50,19 +49,27 @@
 	per_cpu_t		cpu_pages[NR_CPUS];
 	spinlock_t		lock;
 	unsigned long		free_pages;
-	unsigned long		active_pages;
+	unsigned long		active_anon_pages;
+	unsigned long		active_cache_pages;
 	unsigned long		inactive_dirty_pages;
+	unsigned long		inactive_laundry_pages;
 	unsigned long		inactive_clean_pages;
 	unsigned long		pages_min, pages_low, pages_high, pages_plenty;
 	int			need_balance;
+	int			need_scan;
+	int			active_anon_count[MAX_AGE+1];
+	int			active_cache_count[MAX_AGE+1];
 
 	/*
 	 * free areas of different sizes
 	 */
-	struct list_head	active_list;
+	struct list_head	active_anon_list[MAX_AGE+1];
+	struct list_head	active_cache_list[MAX_AGE+1];
 	struct list_head	inactive_dirty_list;
+	struct list_head	inactive_laundry_list;
 	struct list_head	inactive_clean_list;
 	free_area_t		free_area[MAX_ORDER];
+	spinlock_t		lru_lock;
 
 	/*
 	 * wait_table           -- the array holding the hash table
include/linux/module.h +4 -1
diff -Nru a/include/linux/module.h b/include/linux/module.h
@@ -287,6 +287,9 @@
 static const char __module_license[] __attribute__((section(".modinfo"))) =   \
 "license=" license
 
+#define GPL_HEADER() \
+static const char cpyright="This software may be freely redistributed under the terms of the GNU General Public License.";
+
 /* Define the module variable, and usage macros.  */
 extern struct module __this_module;
 
@@ -302,7 +305,6 @@
 static const char __module_using_checksums[] __attribute__((section(".modinfo"))) =
 "using_checksums=1";
 #endif
-
 #else /* MODULE */
 
 #define MODULE_AUTHOR(name)
@@ -311,6 +313,7 @@
 #define MODULE_SUPPORTED_DEVICE(name)
 #define MODULE_PARM(var,type)
 #define MODULE_PARM_DESC(var,desc)
+#define GPL_HEADER()
 
 /* Create a dummy reference to the table to suppress gcc unused warnings.  Put
  * the reference in the .data.exit section which is discarded when code is built
include/linux/pagemap.h +9 -4
diff -Nru a/include/linux/pagemap.h b/include/linux/pagemap.h
@@ -70,10 +70,6 @@
 
 #define page_hash(mapping,index) (page_hash_table+_page_hashfn(mapping,index))
 
-extern struct page * __find_get_page(struct address_space *mapping,
-				unsigned long index, struct page **hash);
-#define find_get_page(mapping, index) \
-	__find_get_page(mapping, index, page_hash(mapping, index))
 extern struct page * __find_lock_page (struct address_space * mapping,
 				unsigned long index, struct page **hash);
 extern struct page * find_or_create_page(struct address_space *mapping,
@@ -90,6 +86,15 @@
 extern int add_to_page_cache_unique(struct page * page, struct address_space *mapping, unsigned long index, struct page **hash);
 
 extern void ___wait_on_page(struct page *);
+extern int wait_on_page_timeout(struct page *page, int timeout);
+
+
+extern struct page * __find_pagecache_page(struct address_space *mapping,
+				unsigned long index, struct page **hash);
+#define find_pagecache_page(mapping, index) \
+	__find_pagecache_page(mapping, index, page_hash(mapping, index))
+#define find_get_page(mapping, index) \
+	__find_pagecache_page(mapping, index, page_hash(mapping, index))
 
 static inline void wait_on_page(struct page * page)
 {
include/linux/sched.h +1 -0
diff -Nru a/include/linux/sched.h b/include/linux/sched.h
@@ -260,6 +260,7 @@
 	unsigned long def_flags;
 	unsigned long cpu_vm_mask;
 	unsigned long rlimit_rss;
+	unsigned long last_run;
 
 	unsigned dumpable:1;
 
include/linux/swap.h +13 -7
diff -Nru a/include/linux/swap.h b/include/linux/swap.h
@@ -85,9 +85,11 @@
 
 extern unsigned int nr_free_pages(void);
 extern unsigned int nr_free_buffer_pages(void);
-extern int nr_active_pages;
-extern int nr_inactive_dirty_pages;
-extern int nr_inactive_clean_pages;
+extern unsigned int nr_active_anon_pages(void);
+extern unsigned int nr_active_cache_pages(void);
+extern unsigned int nr_inactive_dirty_pages(void);
+extern unsigned int nr_inactive_laundry_pages(void);
+extern unsigned int nr_inactive_clean_pages(void);
 extern atomic_t page_cache_size;
 extern atomic_t buffermem_pages;
 extern spinlock_cacheline_t pagecache_lock_cacheline;
@@ -115,6 +117,7 @@
 
 /* linux/mm/swap.c */
 extern void FASTCALL(lru_cache_add(struct page *));
+extern void FASTCALL(lru_cache_add_dirty(struct page *));
 extern void FASTCALL(__lru_cache_del(struct page *));
 extern void FASTCALL(lru_cache_del(struct page *));
 
@@ -130,6 +133,7 @@
 extern wait_queue_head_t kswapd_wait;
 extern struct page * FASTCALL(reclaim_page(zone_t *));
 extern int FASTCALL(try_to_free_pages(unsigned int gfp_mask));
+extern int rebalance_laundry_zone(struct zone_struct *, int, unsigned int);
 extern void wakeup_kswapd(unsigned int);
 extern void rss_free_pages(unsigned int);
 
@@ -175,8 +179,6 @@
 asmlinkage long sys_swapoff(const char *);
 asmlinkage long sys_swapon(const char *, int);
 
-extern spinlock_cacheline_t pagemap_lru_lock_cacheline;
-#define pagemap_lru_lock pagemap_lru_lock_cacheline.lock
 
 extern void FASTCALL(mark_page_accessed(struct page *));
 
@@ -191,13 +193,17 @@
 
 /*
  * List add/del helper macros. These must be called
- * with the pagemap_lru_lock held!
+ * with the lru lock held!
  */
 #define DEBUG_LRU_PAGE(page)			\
 do {						\
-	if (PageActive(page))			\
+	if (PageActiveAnon(page))		\
+		BUG();				\
+	if (PageActiveCache(page))		\
 		BUG();				\
 	if (PageInactiveDirty(page))		\
+		BUG();				\
+	if (PageInactiveLaundry(page))		\
 		BUG();				\
 	if (PageInactiveClean(page))		\
 		BUG();				\
kernel/ksyms.c +0 -1
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
@@ -262,7 +262,6 @@
 EXPORT_SYMBOL(__pollwait);
 EXPORT_SYMBOL(poll_freewait);
 EXPORT_SYMBOL(ROOT_DEV);
-EXPORT_SYMBOL(__find_get_page);
 EXPORT_SYMBOL(__find_lock_page);
 EXPORT_SYMBOL(find_or_create_page);
 EXPORT_SYMBOL(grab_cache_page_nowait);
kernel/sched.c +2 -0
diff -Nru a/kernel/sched.c b/kernel/sched.c
@@ -971,6 +971,8 @@
 	reacquire_kernel_lock(current);
 	if (need_resched())
 		goto need_resched;
+	if (current->mm)
+		current->mm->last_run = jiffies;
 }
 
 /*
mm/filemap.c +61 -33

176 lines not on this page · raw message

mm/page_alloc.c +70 -30

167 lines not on this page · raw message

mm/rmap.c +10 -6
diff -Nru a/mm/rmap.c b/mm/rmap.c
@@ -14,7 +14,7 @@
 /*
  * Locking:
  * - the page->pte_chain is protected by the PG_chainlock bit,
- *   which nests within the pagemap_lru_lock, then the
+ *   which nests within the lru lock, then the
  *   mm->page_table_lock, and then the page lock.
  * - because swapout locking is opposite to the locking order
  *   in the page fault path, the swapout path uses trylocks
@@ -68,7 +68,7 @@
  */
 int page_referenced(struct page * page, int * rsslimit)
 {
-	int referenced = 0, under_rsslimit = 0;
+	int referenced = 0, under_rsslimit = 0, active_process = 0;
 	struct mm_struct * mm;
 	struct pte_chain * pc;
 
@@ -85,13 +85,17 @@
 		mm = ptep_to_mm(ptep);
 		if (mm->rss < mm->rlimit_rss)
 			under_rsslimit++;
+
+		if (time_before(jiffies, mm->last_run + 5 * HZ))
+			active_process++;
 	}
 
 	/*
 	 * We're only over the RSS limit if all the processes sharing the
-	 * page are.
+	 * page are, or if none of the processes has been active for 5
+	 * seconds.
 	 */
-	*rsslimit = !under_rsslimit;
+	*rsslimit = !(under_rsslimit && active_process);
 
 	return referenced;
 }
@@ -195,7 +199,7 @@
  * table entry mapping a page. Because locking order here is opposite
  * to the locking order used by the page fault path, we use trylocks.
  * Locking:
- *	pagemap_lru_lock		page_launder()
+ *	   lru lock			page_launder()
  *	    page lock			page_launder(), trylock
  *		pte_chain_lock		page_launder()
  *		    mm->page_table_lock	try_to_unmap_one(), trylock
@@ -263,7 +267,7 @@
  * @page: the page to get unmapped
  *
  * Tries to remove all the page table entries which are mapping this
- * page, used in the pageout path.  Caller must hold pagemap_lru_lock
+ * page, used in the pageout path.  Caller must hold lru lock
  * and the page lock.  Return values are:
  *
  * SWAP_SUCCESS	- we succeeded in removing all mappings
mm/shmem.c +1 -1
diff -Nru a/mm/shmem.c b/mm/shmem.c
@@ -581,7 +581,7 @@
 	 * cache and swap cache.  We need to recheck the page cache
 	 * under the protection of the info->lock spinlock. */
 
-	page = find_get_page(mapping, idx);
+	page = find_pagecache_page(mapping, idx);
 	if (page) {
 		if (TryLockPage(page))
 			goto wait_retry;
mm/swap.c +75 -27

183 lines not on this page · raw message

mm/swap_state.c +3 -3
diff -Nru a/mm/swap_state.c b/mm/swap_state.c
@@ -196,7 +196,7 @@
 {
 	struct page *found;
 
-	found = find_get_page(&swapper_space, entry.val);
+	found = find_pagecache_page(&swapper_space, entry.val);
 	/*
 	 * Unsafe to assert PageSwapCache and mapping on page found:
 	 * if SMP nothing prevents swapoff from deleting this page from
@@ -224,10 +224,10 @@
 		/*
 		 * First check the swap cache.  Since this is normally
 		 * called after lookup_swap_cache() failed, re-calling
-		 * that would confuse statistics: use find_get_page()
+		 * that would confuse statistics: use find_pagecache_page()
 		 * directly.
 		 */
-		found_page = find_get_page(&swapper_space, entry.val);
+		found_page = find_pagecache_page(&swapper_space, entry.val);
 		if (found_page)
 			break;
 
mm/vmscan.c +684 -391

1,278 lines not on this page · raw message

Signature · 2 lines
Paul P 'Stingray' Komkoff 'Greatest' Jr /// (icq)23200764 /// (http)stingr.net
  When you're invisible, the only one really watching you is you (my keychain)
#1 lore raw
Quoted 4 lines · Paul P Komkoff Jr

The subject clearly described the patch.

The only thing I'm unsure about is current->mm->... etc in kernel/sched.c

That code shouldn't be there at all. It's not in any of my rmap patches and shouldn't be on bkbits.net either...

Rik

Signature · 3 lines
Bravely reimplemented by the knights who say "NIH".
http://www.surriel.com/		http://guru.conectiva.com/
Current spamtrap:  <a href=mailto:"[email protected]">[email protected]</a>