From 371be5e48749529d5c5a019c7227fbd85aa050f0 Mon Sep 17 00:00:00 2001 From: Naveen Ramaraj Date: Mon, 14 Nov 2011 17:21:14 -0800 Subject: [PATCH] lowmemorykiller: Account for ZONE_MOVABLE during hotplug. When a memory section is offlined, lmk would be invoked to create room to migrate pages if required. When this happens lmk should discount any free memory in the section being offlined for its heuristics. Change-Id: I79d8e332451cbb6d51735836b6a19bded01dfad9 Signed-off-by: Naveen Ramaraj --- drivers/staging/android/lowmemorykiller.c | 45 +++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index 86d51959b29..70131fa03c6 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -35,6 +35,8 @@ #include #include #include +#include +#include static uint32_t lowmem_debug_level = 2; static int lowmem_adj[6] = { @@ -52,6 +54,7 @@ static size_t lowmem_minfree[6] = { }; static int lowmem_minfree_size = 4; +static unsigned int offlining; static struct task_struct *lowmem_deathpending; static unsigned long lowmem_deathpending_timeout; @@ -79,6 +82,32 @@ task_notify_func(struct notifier_block *self, unsigned long val, void *data) return NOTIFY_OK; } +#ifdef CONFIG_MEMORY_HOTPLUG +static int lmk_hotplug_callback(struct notifier_block *self, + unsigned long cmd, void *data) +{ + switch (cmd) { + /* Don't care LMK cases */ + case MEM_ONLINE: + case MEM_OFFLINE: + case MEM_CANCEL_ONLINE: + case MEM_CANCEL_OFFLINE: + case MEM_GOING_ONLINE: + offlining = 0; + lowmem_print(4, "lmk in normal mode\n"); + break; + /* LMK should account for movable zone */ + case MEM_GOING_OFFLINE: + offlining = 1; + lowmem_print(4, "lmk in hotplug mode\n"); + break; + } + return NOTIFY_DONE; +} +#endif + + + static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) { struct task_struct *p; @@ -93,7 +122,20 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) int other_free = global_page_state(NR_FREE_PAGES); int other_file = global_page_state(NR_FILE_PAGES) - global_page_state(NR_SHMEM); + struct zone *zone; + if (offlining) { + /* Discount all free space in the section being offlined */ + for_each_zone(zone) { + if (zone_idx(zone) == ZONE_MOVABLE) { + other_free -= zone_page_state(zone, + NR_FREE_PAGES); + lowmem_print(4, "lowmem_shrink discounted " + "%lu pages in movable zone\n", + zone_page_state(zone, NR_FREE_PAGES)); + } + } + } /* * If we already have a death outstanding, then * bail out right away; indicating to vmscan @@ -190,6 +232,9 @@ static int __init lowmem_init(void) { task_free_register(&task_nb); register_shrinker(&lowmem_shrinker); +#ifdef CONFIG_MEMORY_HOTPLUG + hotplug_memory_notifier(lmk_hotplug_callback, 0); +#endif return 0; }