A patch for smaller systems (32, 24, 16MB and less) lowmem.patch-2.1.110.gz with the following changes:
In linux/include/linux/pagemap.h touch_page() is used instead of the fixed limit PAGE_AGE_VALUE.
In linux/ipc/shm.c and linux/mm/page_alloc.c recently swapped in pages get a better start due a higher age. This should avoid that the page will be swapped out on the next cycle without getting a chance to reach a higher age.
In linux/fs/buffer.c the buffer head are allocated in get_unused_buffer_head() with SLAB_BUFFER because the swapping code knows how to handle pages which should not do I/O. This forces __get_free_pages() in linux/mm/page_alloc.c to call try_to_free_pages and avoids going down with the number of free pages under heavy I/O.
For non-async pages use SLAB_ATOMIC if SLAB_BUFFER fails.
Change gfp priority of buffer pages to __GFP_MED in linux/include/linux/mm.h to make sure that we get I/O buffer page even if the system is highly stressed.
In linux/mm/vmscan.c do not swap out dirty pages in try_to_swap_out() if a free buffer page is needed.
Call shrink_dcache_memory() in do_try_to_free_page() in linux/mm/vmscan.c if the dcache is not in balance.
Make swap_out() more aggressive if gfp level forces waiting and we've reached higher priorities.
Make do_try_to_free_page() more throughout if the system is down with free pages even if we have not to wait.
Run disk task queue in try_to_free_page() if gfp level does not include waiting.