lkml.org 
[lkml]   [1998]   [Jul]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subjectpatch to trim page table cache
The current kernel has no provision to drain down the page table cache
when the system needs memory, which is not good for fragmentation and
probably counterproductive for performance as well. The attached patch
redefines the check_pgt_cache() routine and passes an argument to
specify whether to drain the cache or keep it between the watermarks.

I've placed a call to trim_pgt_cache(1) in do_try_to_free_page() so that
the page table cache drains gradually when the system starts swapping.

The patch also corrects an apparent kernel locking problem in
arch/i386/kernel/process.c. The SMP version of sys_idle() doesn't get
the kernel lock before calling check_pgt_cache(), but since the pgt
quicklists don't have spinlock protection, the kernel lock is necessary
for SMP safety. I've moved the kernel lock upwards to cover it.

Tested lightly and seems to work OK.

Regards,
Bill--- linux-2.1.109/include/linux/mm.h.old Fri Jul 17 09:34:42 1998
+++ linux-2.1.109/include/linux/mm.h Fri Jul 17 21:03:39 1998
@@ -277,7 +281,8 @@

extern void vmtruncate(struct inode * inode, unsigned long offset);
extern void handle_mm_fault(struct task_struct *tsk,struct vm_area_struct *vma, unsigned long address, int write_access);
-extern void check_pgt_cache(void);
+extern void trim_pgt_cache(int);
+#define check_pgt_cache() trim_pgt_cache(0)
extern void make_pages_present(unsigned long addr, unsigned long end);

extern unsigned long paging_init(unsigned long start_mem, unsigned long end_mem);
--- linux-2.1.109/mm/memory.c.old Fri Jul 3 10:33:11 1998
+++ linux-2.1.109/mm/memory.c Fri Jul 17 21:10:47 1998
@@ -939,9 +954,9 @@
*/
int pgt_cache_water[2] = { 25, 50 };

-void check_pgt_cache(void)
+void trim_pgt_cache(int must_free)
{
- if(pgtable_cache_size > pgt_cache_water[0]) {
+ if(pgtable_cache_size > (must_free ? 0 : pgt_cache_water[0])) {
do {
if(pgd_quicklist)
free_pgd_slow(get_pgd_fast());
--- linux-2.1.109/mm/vmscan.c.old Fri Jul 17 09:10:45 1998
+++ linux-2.1.109/mm/vmscan.c Fri Jul 17 20:34:57 1998
@@ -453,6 +453,9 @@
/* Always trim SLAB caches when memory gets low. */
kmem_cache_reap(gfp_mask);

+ /* Trim back the page table cache. */
+ trim_pgt_cache(1);
+
/* We try harder if we are waiting .. */
stop = 3;
if (gfp_mask & __GFP_WAIT)
@@ -533,7 +536,6 @@
add_wait_queue(&kswapd_wait, &wait);
while (1) {
int tries;
- int tried = 0;

current->state = TASK_INTERRUPTIBLE;
flush_signals(current);
--- linux-2.1.109/arch/i386/kernel/process.c.old Fri Jul 17 09:10:28 1998
+++ linux-2.1.109/arch/i386/kernel/process.c Fri Jul 17 20:35:13 1998
@@ -158,16 +158,18 @@
if(current_cpu_data.hlt_works_ok &&
!hlt_counter && !need_resched)
__asm("hlt");
+
+ lock_kernel();
+ /* Need the kernel lock for this ... */
check_pgt_cache();
/*
* tq_scheduler currently assumes we're running in a process
* context (ie that we hold the kernel lock..)
*/
if (tq_scheduler) {
- lock_kernel();
run_task_queue(&tq_scheduler);
- unlock_kernel();
}
+ unlock_kernel();
/* endless idle loop with no priority at all */
current->counter = -100;
schedule();
\
 
 \ /
  Last update: 2005-03-22 13:43    [from the cache]
©2003-2011 Jasper Spaans