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    [W:0.027 / U:61.284 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site