static int kswapd_balance_pgdat(pg_data_t * pgdat) { int need_more_balance = 0, i; zone_t * zone; for (i = pgdat->nr_zones-1; i >= 0; i--) { zone = pgdat->node_zones + i; debug_lock_break(0); #ifndef CONFIG_PREEMPT if (unlikely(current->need_resched)) schedule(); #endif if (!zone->need_balance) continue; if (!try_to_free_pages(zone, GFP_KSWAPD, 0)) { zone->need_balance = 0; __set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ); continue; } if (check_classzone_need_balance(zone)) need_more_balance = 1; else zone->need_balance = 0; } return need_more_balance; }
static int kswapd_balance_pgdat(pg_data_t * pgdat) { int need_more_balance = 0, i; zone_t * zone; for (i = pgdat->nr_zones-1; i >= 0; i--) { zone = pgdat->node_zones + i; if (unlikely(current->need_resched)) schedule(); if (!zone->need_balance || !zone->size) continue; if (!try_to_free_pages_zone(zone, GFP_KSWAPD)) { zone->need_balance = 0; __set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ*5); continue; } if (check_classzone_need_balance(zone)) need_more_balance = 1; else zone->need_balance = 0; } return need_more_balance; }
static int kswapd_balance_pgdat(pg_data_t * pgdat) { int need_more_balance = 0, i; zone_t * zone; for (i = pgdat->nr_zones-1; i >= 0; i--) { zone = pgdat->node_zones + i; if (unlikely(current->need_resched)) schedule(); if (!zone->need_balance) continue; if (!try_to_free_pages_zone(zone, GFP_KSWAPD)) { zone->need_balance = 0; #ifndef CONFIG_CONTIGUOUS_PAGE_ALLOC /* we always want the memory now !! */ __set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ); #endif continue; } if (check_classzone_need_balance(zone)) need_more_balance = 1; else zone->need_balance = 0; } return need_more_balance; }
int try_to_free_pages_zone(zone_t *classzone, unsigned int gfp_mask) { gfp_mask = pf_gfp_mask(gfp_mask); for (;;) { int tries = vm_passes; int failed_swapout = !(gfp_mask & __GFP_IO); int nr_pages = SWAP_CLUSTER_MAX; do { nr_pages = shrink_caches(classzone, gfp_mask, nr_pages, &failed_swapout); if (nr_pages <= 0) return 1; shrink_dcache_memory(vm_vfs_scan_ratio, gfp_mask); shrink_icache_memory(vm_vfs_scan_ratio, gfp_mask); #ifdef CONFIG_QUOTA shrink_dqcache_memory(vm_vfs_scan_ratio, gfp_mask); #endif if (!failed_swapout) failed_swapout = !swap_out(classzone); } while (--tries); #ifdef CONFIG_OOM_KILLER out_of_memory(); #else if (likely(current->pid != 1)) break; if (!check_classzone_need_balance(classzone)) break; __set_current_state(TASK_RUNNING); yield(); #endif } return 0; }