From mboxrd@z Thu Jan 1 00:00:00 1970 Subject: [PATCH] Memoryless nodes: use "node_memory_map" for cpuset mems_allowed validation From: Lee Schermerhorn In-Reply-To: References: <20070711182219.234782227@sgi.com> <20070711182250.005856256@sgi.com> Content-Type: text/plain Date: Fri, 20 Jul 2007 16:49:24 -0400 Message-Id: <1184964564.9651.66.camel@localhost> Mime-Version: 1.0 Content-Transfer-Encoding: 7bit Sender: owner-linux-mm@kvack.org Return-Path: To: Christoph Lameter , Paul Jackson Cc: akpm@linux-foundation.org, kxr@sgi.com, linux-mm@kvack.org, Nishanth Aravamudan , KAMEZAWA Hiroyuki List-ID: This fixes a problem I encountered testing Christoph's memoryless nodes series. Applies atop that series. Other than this, series holds up under what testing I've been able to do this week. Memoryless Nodes: use "node_memory_map" for cpusets mems_allowed validation cpusets try to ensure that any node added to a cpuset's mems_allowed is on-line and contains memory. The assumption was that online nodes contained memory. Thus, it is possible to add memoryless nodes to a cpuset and then add tasks to this cpuset. This results in continuous series of oom-kill and other console stack traces and apparent system hang. Change cpusets to use node_states[N_MEMORY] [a.k.a. node_memory_map] in place of node_online_map when vetting memories. Return error if admin attempts to write a non-empty mems_allowed node mask containing only memoryless-nodes. Signed-off-by: Lee Schermerhorn kernel/cpuset.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) Index: Linux/kernel/cpuset.c =================================================================== --- Linux.orig/kernel/cpuset.c 2007-07-20 16:02:01.000000000 -0400 +++ Linux/kernel/cpuset.c 2007-07-20 16:27:46.000000000 -0400 @@ -316,26 +316,26 @@ static void guarantee_online_cpus(const /* * Return in *pmask the portion of a cpusets's mems_allowed that - * are online. If none are online, walk up the cpuset hierarchy - * until we find one that does have some online mems. If we get - * all the way to the top and still haven't found any online mems, - * return node_online_map. + * are online, with memory. If none are online with memory, walk + * up the cpuset hierarchy until we find one that does have some + * online mems. If we get all the way to the top and still haven't + * found any online mems, return node_states[N_MEMORY]. * * One way or another, we guarantee to return some non-empty subset - * of node_online_map. + * of node_states[N_MEMORY]. * * Call with callback_mutex held. */ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask) { - while (cs && !nodes_intersects(cs->mems_allowed, node_online_map)) + while (cs && !nodes_intersects(cs->mems_allowed, node_states[N_MEMORY])) cs = cs->parent; if (cs) - nodes_and(*pmask, cs->mems_allowed, node_online_map); + nodes_and(*pmask, cs->mems_allowed, node_states[N_MEMORY]); else - *pmask = node_online_map; - BUG_ON(!nodes_intersects(*pmask, node_online_map)); + *pmask = node_states[N_MEMORY]; + BUG_ON(!nodes_intersects(*pmask, node_states[N_MEMORY])); } /** @@ -623,8 +623,21 @@ static int update_nodemask(struct cpuset retval = nodelist_parse(buf, trialcs.mems_allowed); if (retval < 0) goto done; + if (!nodes_intersects(trialcs.mems_allowed, + node_states[N_MEMORY])) { + /* + * error if only memoryless nodes specified. + */ + retval = -ENOSPC; + goto done; + } } - nodes_and(trialcs.mems_allowed, trialcs.mems_allowed, node_online_map); + /* + * Exclude memoryless nodes. We know that trialcs.mems_allowed + * contains at least one node with memory. + */ + nodes_and(trialcs.mems_allowed, trialcs.mems_allowed, + node_states[N_MEMORY]); oldmem = cs->mems_allowed; if (nodes_equal(oldmem, trialcs.mems_allowed)) { retval = 0; /* Too easy - nothing to do */ -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org