mm, oom: Try to online memory block before killing
Before killing a process first try to see if there are any offlined memory blocks, if there are try to online one of them. Change-Id: Ie97c8b69f0ba173c202a891a38a5c914869ddaae Signed-off-by: Liam Mark <lmark@codeaurora.org> [isaacm@codeaurora.org: Update walk_memory_range to walk_memory_blocks] Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
This commit is contained in:

committed by
Isaac J. Manjarres

parent
d62cabc403
commit
c5d41d1162
@@ -110,6 +110,7 @@ extern void __online_page_increment_counters(struct page *page);
|
|||||||
extern void __online_page_free(struct page *page);
|
extern void __online_page_free(struct page *page);
|
||||||
|
|
||||||
extern int try_online_node(int nid);
|
extern int try_online_node(int nid);
|
||||||
|
extern bool try_online_one_block(int nid);
|
||||||
|
|
||||||
extern int arch_add_memory(int nid, u64 start, u64 size,
|
extern int arch_add_memory(int nid, u64 start, u64 size,
|
||||||
struct mhp_restrictions *restrictions);
|
struct mhp_restrictions *restrictions);
|
||||||
@@ -269,6 +270,11 @@ static inline int try_online_node(int nid)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool try_online_one_block(int nid)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void get_online_mems(void) {}
|
static inline void get_online_mems(void) {}
|
||||||
static inline void put_online_mems(void) {}
|
static inline void put_online_mems(void) {}
|
||||||
|
|
||||||
|
@@ -999,6 +999,40 @@ int try_online_node(int nid)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int online_memory_one_block(struct memory_block *mem, void *arg)
|
||||||
|
{
|
||||||
|
bool *onlined_block = (bool *)arg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (*onlined_block || !is_memblock_offlined(mem))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = device_online(&mem->dev);
|
||||||
|
if (!ret)
|
||||||
|
*onlined_block = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool try_online_one_block(int nid)
|
||||||
|
{
|
||||||
|
struct zone *zone = &NODE_DATA(nid)->node_zones[ZONE_MOVABLE];
|
||||||
|
unsigned long zone_start, zone_size;
|
||||||
|
bool onlined_block = false;
|
||||||
|
int ret = lock_device_hotplug_sysfs();
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
zone_start = PFN_PHYS(zone->zone_start_pfn);
|
||||||
|
zone_size = zone->spanned_pages << PAGE_SHIFT;
|
||||||
|
walk_memory_blocks(zone_start, zone_size, &onlined_block,
|
||||||
|
online_memory_one_block);
|
||||||
|
|
||||||
|
unlock_device_hotplug();
|
||||||
|
return onlined_block;
|
||||||
|
}
|
||||||
|
|
||||||
static int check_hotplug_memory_range(u64 start, u64 size)
|
static int check_hotplug_memory_range(u64 start, u64 size)
|
||||||
{
|
{
|
||||||
/* memory range must be block size aligned */
|
/* memory range must be block size aligned */
|
||||||
|
@@ -43,6 +43,7 @@
|
|||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/mmu_notifier.h>
|
#include <linux/mmu_notifier.h>
|
||||||
#include <linux/show_mem_notifier.h>
|
#include <linux/show_mem_notifier.h>
|
||||||
|
#include <linux/memory_hotplug.h>
|
||||||
|
|
||||||
#include <asm/tlb.h>
|
#include <asm/tlb.h>
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
@@ -1066,6 +1067,12 @@ bool out_of_memory(struct oom_control *oc)
|
|||||||
if (oom_killer_disabled)
|
if (oom_killer_disabled)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (try_online_one_block(numa_node_id())) {
|
||||||
|
/* Got some memory back */
|
||||||
|
WARN(1, "OOM killer had to online a memory block\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_memcg_oom(oc)) {
|
if (!is_memcg_oom(oc)) {
|
||||||
blocking_notifier_call_chain(&oom_notify_list, 0, &freed);
|
blocking_notifier_call_chain(&oom_notify_list, 0, &freed);
|
||||||
if (freed > 0)
|
if (freed > 0)
|
||||||
|
Reference in New Issue
Block a user