If the pages for a subpool are reserved, then the reservations have
already been accounted for in the global pool.  Therefore, when
requesting a new reservation (such as for a mapping) for the subpool
do not count again in global pool.  However, when actually allocating
a page for the subpool decrement gobal reserve count to correspond to
with decrement in global free pages.

Signed-off-by: Mike Kravetz <mike.krav...@oracle.com>
---
 mm/hugetlb.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index c6adf65..4ef8379 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -879,7 +879,7 @@ void free_huge_page(struct page *page)
        spin_lock(&hugetlb_lock);
        hugetlb_cgroup_uncharge_page(hstate_index(h),
                                     pages_per_huge_page(h), page);
-       if (restore_reserve)
+       if (restore_reserve || subpool_reserved(spool))
                h->resv_huge_pages++;
 
        if (h->surplus_huge_pages_node[nid]) {
@@ -2466,7 +2466,8 @@ static void hugetlb_vm_op_close(struct vm_area_struct 
*vma)
        kref_put(&resv->refs, resv_map_release);
 
        if (reserve) {
-               hugetlb_acct_memory(h, -reserve);
+               if (!subpool_reserved(spool))
+                       hugetlb_acct_memory(h, -reserve);
                hugepage_subpool_put_pages(spool, reserve);
        }
 }
@@ -3444,10 +3445,14 @@ int hugetlb_reserve_pages(struct inode *inode,
         * Check enough hugepages are available for the reservation.
         * Hand the pages back to the subpool if there are not
         */
-       ret = hugetlb_acct_memory(h, chg);
-       if (ret < 0) {
-               hugepage_subpool_put_pages(spool, chg);
-               goto out_err;
+       if (subpool_reserved(spool))
+               ret = 0;
+       else {
+               ret = hugetlb_acct_memory(h, chg);
+               if (ret < 0) {
+                       hugepage_subpool_put_pages(spool, chg);
+                       goto out_err;
+               }
        }
 
        /*
@@ -3483,7 +3488,8 @@ void hugetlb_unreserve_pages(struct inode *inode, long 
offset, long freed)
        inode->i_blocks -= (blocks_per_huge_page(h) * freed);
        spin_unlock(&inode->i_lock);
 
-       hugepage_subpool_put_pages(spool, (chg - freed));
+       if (!subpool_reserved(spool))
+               hugepage_subpool_put_pages(spool, (chg - freed));
        hugetlb_acct_memory(h, -(chg - freed));
 }
 
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to