--- mm/reserve.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) Index: linux-2.6/mm/reserve.c =================================================================== --- linux-2.6.orig/mm/reserve.c +++ linux-2.6/mm/reserve.c @@ -191,6 +191,10 @@ int mem_reserve_connect(struct mem_reser WARN_ON(!new_child->name); mutex_lock(&mem_reserve_mutex); + if (new_child->parent) { + ret = -EEXIST; + goto unlock; + } new_child->parent = node; list_add(&new_child->siblings, &node->children); ret = __mem_reserve_add(node, new_child->pages, new_child->limit); @@ -198,6 +202,7 @@ int mem_reserve_connect(struct mem_reser new_child->parent = NULL; list_del_init(&new_child->siblings); } +unlock: mutex_unlock(&mem_reserve_mutex); return ret; @@ -218,11 +223,16 @@ void mem_reserve_disconnect(struct mem_r BUG_ON(!node->parent); mutex_lock(&mem_reserve_mutex); + if (!node->parent) { + ret = -ENOENT; + goto unlock; + } ret = __mem_reserve_add(node->parent, -node->pages, -node->limit); if (!ret) { node->parent = NULL; list_del_init(&node->siblings); } +unlock: mutex_unlock(&mem_reserve_mutex); /* @@ -545,6 +555,7 @@ struct page *__alloc_pages_reserve(int n { struct page *page; gfp_t gfp; + long pages = 1 << order; gfp = flags | __GFP_NOMEMALLOC | __GFP_NOWARN; page = alloc_pages_node(node, gfp, order); @@ -552,16 +563,16 @@ struct page *__alloc_pages_reserve(int n if (page || !(gfp_to_alloc_flags(flags) & ALLOC_NO_WATERMARKS)) goto out; - if (res && !mem_reserve_pages_charge(res, 1 << order)) { + if (res && !mem_reserve_pages_charge(res, pages)) { if (!(flags & __GFP_WAIT)) goto out; wait_event(res->waitqueue, - mem_reserve_pages_charge(res, 1 << order)); + mem_reserve_pages_charge(res, pages)); page = alloc_pages_node(node, gfp, order); if (page) { - mem_reserve_pages_charge(res, -(1 << order)); + mem_reserve_pages_charge(res, -pages); goto out; } }