Messages in this thread Patch in this message |  | | Date | Tue, 16 Oct 2001 16:07:29 -0200 (BRST) | From | Marcelo Tosatti <> | Subject | [UNTESTED PATCH] Throttle VM allocators |
| |
Hi,
The following patch will throttle VM allocators in case we are below a given threshold of free memory.
This will make hunger allocators throttle more page reclamation, giving us a (hopefully) fair system wrt memory.
Please test this. I'm specially interested in interactivity during heavy VM pressure.
Its against 2.4.12.
Thanks
diff -Nur linux.orig/mm/page_alloc.c linux/mm/page_alloc.c --- linux.orig/mm/page_alloc.c Thu Oct 11 16:04:56 2001 +++ linux/mm/page_alloc.c Thu Oct 11 16:03:36 2001 @@ -228,6 +228,22 @@ } #endif +static inline int vm_throttle(zone_t *classzone, unsigned int gfp_mask, unsigned int order) +{ + int progress; + if (in_interrupt()) + BUG(); + + current->allocation_order = order; + current->flags |= PF_MEMALLOC | PF_FREE_PAGES; + + progress = try_to_free_pages(classzone, gfp_mask, order); + + current->flags &= ~(PF_MEMALLOC | PF_FREE_PAGES); + + return progress; +} + static struct page * FASTCALL(balance_classzone(zone_t *, unsigned int, unsigned int, int *)); static struct page * balance_classzone(zone_t * classzone, unsigned int gfp_mask, unsigned int order, int * freed) { @@ -338,6 +354,16 @@ if (waitqueue_active(&kswapd_wait)) wake_up_interruptible(&kswapd_wait); + /* + * We're possibly going to eat memory from the min<->low + * "reversed" area. Throttling page reclamation using + * the allocators which reach this point will give us a + * fair system. + */ + + if ((gfp_mask & __GFP_WAIT)) + vm_throttle(classzone, gfp_mask, order); + zone = zonelist->zones; for (;;) { unsigned long min; @@ -386,7 +412,7 @@ if (!z) break; - if (zone_free_pages(z, order) > z->pages_min) { + if (zone_free_pages(z, order) > z->pages_low) { page = rmqueue(z, order); if (page) return page; @@ -394,7 +420,13 @@ } /* Don't let big-order allocations loop */ - if (order) + /* We have one special 1-order alloc user: fork(). + * It obviously cannot fail easily like other + * high order allocations. This could also be fixed + * by having a __GFP_LOOP flag to indicate that the + * high order allocation is "critical". + */ + if (order > 1) return NULL; /* Yield for kswapd, and try again */ diff -Nur linux.orig/mm/vmscan.c linux/mm/vmscan.c --- linux.orig/mm/vmscan.c Thu Oct 11 16:04:56 2001 +++ linux/mm/vmscan.c Thu Oct 11 15:52:36 2001 @@ -558,13 +558,14 @@ int priority = DEF_PRIORITY; int nr_pages = SWAP_CLUSTER_MAX; - do { - nr_pages = shrink_caches(priority, classzone, gfp_mask, nr_pages); - if (nr_pages <= 0) - return 1; + nr_pages = shrink_caches(priority, classzone, gfp_mask, nr_pages); + if (nr_pages <= 0) + return 1; + + ret = (nr_pages < SWAP_CLUSTER_MAX); + + ret |= swap_out(priority, classzone, gfp_mask, SWAP_CLUSTER_MAX << 2); - ret |= swap_out(priority, classzone, gfp_mask, SWAP_CLUSTER_MAX << 2); - } while (--priority); return ret; }
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |