1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * Out Of Memory (OOM) for MEMCG and CPUSET 3f08c3bdfSopenharmony_ci * 4f08c3bdfSopenharmony_ci * The program is designed to cope with unpredictable like amount and 5f08c3bdfSopenharmony_ci * system physical memory, swap size and other VMM technology like KSM, 6f08c3bdfSopenharmony_ci * memcg, memory hotplug and so on which may affect the OOM 7f08c3bdfSopenharmony_ci * behaviours. It simply increase the memory consumption 3G each time 8f08c3bdfSopenharmony_ci * until all the available memory is consumed and OOM is triggered. 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * Copyright (C) 2013-2017 Red Hat, Inc. 11f08c3bdfSopenharmony_ci * 12f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify 13f08c3bdfSopenharmony_ci * it under the terms of the GNU General Public License as published by 14f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or 15f08c3bdfSopenharmony_ci * (at your option) any later version. 16f08c3bdfSopenharmony_ci * 17f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful, 18f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 19f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 20f08c3bdfSopenharmony_ci * the GNU General Public License for more details. 21f08c3bdfSopenharmony_ci */ 22f08c3bdfSopenharmony_ci 23f08c3bdfSopenharmony_ci#include "config.h" 24f08c3bdfSopenharmony_ci#include <sys/types.h> 25f08c3bdfSopenharmony_ci#include <sys/stat.h> 26f08c3bdfSopenharmony_ci#include <errno.h> 27f08c3bdfSopenharmony_ci#include <fcntl.h> 28f08c3bdfSopenharmony_ci#include <stdio.h> 29f08c3bdfSopenharmony_ci#if HAVE_NUMA_H 30f08c3bdfSopenharmony_ci#include <numa.h> 31f08c3bdfSopenharmony_ci#endif 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_ci#include "lapi/abisize.h" 34f08c3bdfSopenharmony_ci#include "numa_helper.h" 35f08c3bdfSopenharmony_ci#include "mem.h" 36f08c3bdfSopenharmony_ci 37f08c3bdfSopenharmony_ci#ifdef HAVE_NUMA_V2 38f08c3bdfSopenharmony_ci 39f08c3bdfSopenharmony_cistatic void verify_oom(void) 40f08c3bdfSopenharmony_ci{ 41f08c3bdfSopenharmony_ci#ifdef TST_ABI32 42f08c3bdfSopenharmony_ci tst_brk(TCONF, "test is not designed for 32-bit system."); 43f08c3bdfSopenharmony_ci#endif 44f08c3bdfSopenharmony_ci 45f08c3bdfSopenharmony_ci tst_res(TINFO, "OOM on CPUSET & MEMCG..."); 46f08c3bdfSopenharmony_ci testoom(0, 0, ENOMEM, 1); 47f08c3bdfSopenharmony_ci 48f08c3bdfSopenharmony_ci /* 49f08c3bdfSopenharmony_ci * Under NUMA system, the migration of cpuset's memory 50f08c3bdfSopenharmony_ci * is in charge of cpuset.memory_migrate, we can write 51f08c3bdfSopenharmony_ci * 1 to cpuset.memory_migrate to enable the migration. 52f08c3bdfSopenharmony_ci */ 53f08c3bdfSopenharmony_ci if (is_numa(NULL, NH_MEMS, 2) && 54f08c3bdfSopenharmony_ci SAFE_CG_HAS(tst_cg, "cpuset.memory_migrate")) { 55f08c3bdfSopenharmony_ci SAFE_CG_PRINT(tst_cg, "cpuset.memory_migrate", "1"); 56f08c3bdfSopenharmony_ci tst_res(TINFO, "OOM on CPUSET & MEMCG with " 57f08c3bdfSopenharmony_ci "cpuset.memory_migrate=1"); 58f08c3bdfSopenharmony_ci testoom(0, 0, ENOMEM, 1); 59f08c3bdfSopenharmony_ci } 60f08c3bdfSopenharmony_ci 61f08c3bdfSopenharmony_ci if (SAFE_CG_HAS(tst_cg, "memory.swap.max")) { 62f08c3bdfSopenharmony_ci tst_res(TINFO, "OOM on CPUSET & MEMCG with " 63f08c3bdfSopenharmony_ci "special memswap limitation:"); 64f08c3bdfSopenharmony_ci if (!TST_CG_VER_IS_V1(tst_cg, "memory")) 65f08c3bdfSopenharmony_ci SAFE_CG_PRINTF(tst_cg, "memory.swap.max", "%lu", MB); 66f08c3bdfSopenharmony_ci else 67f08c3bdfSopenharmony_ci SAFE_CG_PRINTF(tst_cg, "memory.swap.max", "%lu", TESTMEM + MB); 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_ci testoom(0, 1, ENOMEM, 1); 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_ci tst_res(TINFO, "OOM on CPUSET & MEMCG with " 72f08c3bdfSopenharmony_ci "disabled memswap limitation:"); 73f08c3bdfSopenharmony_ci if (TST_CG_VER_IS_V1(tst_cg, "memory")) 74f08c3bdfSopenharmony_ci SAFE_CG_PRINTF(tst_cg, "memory.swap.max", "%lu", ~0UL); 75f08c3bdfSopenharmony_ci else 76f08c3bdfSopenharmony_ci SAFE_CG_PRINT(tst_cg, "memory.swap.max", "max"); 77f08c3bdfSopenharmony_ci testoom(0, 0, ENOMEM, 1); 78f08c3bdfSopenharmony_ci } 79f08c3bdfSopenharmony_ci} 80f08c3bdfSopenharmony_ci 81f08c3bdfSopenharmony_civoid setup(void) 82f08c3bdfSopenharmony_ci{ 83f08c3bdfSopenharmony_ci int ret, memnode; 84f08c3bdfSopenharmony_ci 85f08c3bdfSopenharmony_ci if (!is_numa(NULL, NH_MEMS, 1)) 86f08c3bdfSopenharmony_ci tst_brk(TCONF, "requires NUMA with at least 1 node"); 87f08c3bdfSopenharmony_ci 88f08c3bdfSopenharmony_ci /* 89f08c3bdfSopenharmony_ci * Some nodes do not contain memory, so use 90f08c3bdfSopenharmony_ci * get_allowed_nodes(NH_MEMS) to get a memory 91f08c3bdfSopenharmony_ci * node. This operation also applies to Non-NUMA 92f08c3bdfSopenharmony_ci * systems. 93f08c3bdfSopenharmony_ci */ 94f08c3bdfSopenharmony_ci ret = get_allowed_nodes(NH_MEMS, 1, &memnode); 95f08c3bdfSopenharmony_ci if (ret < 0) 96f08c3bdfSopenharmony_ci tst_brk(TBROK, "Failed to get a memory node " 97f08c3bdfSopenharmony_ci "using get_allowed_nodes()"); 98f08c3bdfSopenharmony_ci 99f08c3bdfSopenharmony_ci write_cpusets(tst_cg, memnode); 100f08c3bdfSopenharmony_ci SAFE_CG_PRINTF(tst_cg, "cgroup.procs", "%d", getpid()); 101f08c3bdfSopenharmony_ci SAFE_CG_PRINTF(tst_cg, "memory.max", "%lu", TESTMEM); 102f08c3bdfSopenharmony_ci} 103f08c3bdfSopenharmony_ci 104f08c3bdfSopenharmony_cistatic struct tst_test test = { 105f08c3bdfSopenharmony_ci .needs_root = 1, 106f08c3bdfSopenharmony_ci .forks_child = 1, 107f08c3bdfSopenharmony_ci .max_runtime = TST_UNLIMITED_RUNTIME, 108f08c3bdfSopenharmony_ci .setup = setup, 109f08c3bdfSopenharmony_ci .test_all = verify_oom, 110f08c3bdfSopenharmony_ci .needs_cgroup_ctrls = (const char *const []){ 111f08c3bdfSopenharmony_ci "memory", "cpuset", NULL 112f08c3bdfSopenharmony_ci }, 113f08c3bdfSopenharmony_ci .save_restore = (const struct tst_path_val[]) { 114f08c3bdfSopenharmony_ci {"/proc/sys/vm/overcommit_memory", "1", TST_SR_TBROK}, 115f08c3bdfSopenharmony_ci {} 116f08c3bdfSopenharmony_ci }, 117f08c3bdfSopenharmony_ci}; 118f08c3bdfSopenharmony_ci 119f08c3bdfSopenharmony_ci#else 120f08c3bdfSopenharmony_ci TST_TEST_TCONF(NUMA_ERROR_MSG); 121f08c3bdfSopenharmony_ci#endif 122