summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/proc/task_mmu.c3
-rw-r--r--mm/hugetlb.c9
-rw-r--r--mm/page_alloc.c17
3 files changed, 22 insertions, 7 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index dd3b5cf9f0b7..d7d52e259055 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -780,7 +780,7 @@ static int do_procmap_query(struct mm_struct *mm, void __user *uarg)
} else {
if (karg.build_id_size < build_id_sz) {
err = -ENAMETOOLONG;
- goto out;
+ goto out_file;
}
karg.build_id_size = build_id_sz;
}
@@ -808,6 +808,7 @@ static int do_procmap_query(struct mm_struct *mm, void __user *uarg)
out:
query_vma_teardown(&lock_ctx);
mmput(mm);
+out_file:
if (vm_file)
fput(vm_file);
kfree(name_buf);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 0b005e944ee3..90182724d4cf 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -6723,6 +6723,15 @@ out_put_pages:
*/
hugetlb_acct_memory(h, -gbl_resv);
}
+ /* Restore used_hpages for pages that failed global reservation */
+ if (gbl_reserve && spool) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&spool->lock, flags);
+ if (spool->max_hpages != -1)
+ spool->used_hpages -= gbl_reserve;
+ unlock_or_release_subpool(spool, flags);
+ }
out_uncharge_cgroup:
hugetlb_cgroup_uncharge_cgroup_rsvd(hstate_index(h),
chg * pages_per_huge_page(h), h_cg);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 5fd9e4a03a4d..167d4b710786 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1339,8 +1339,8 @@ static inline void pgalloc_tag_sub_pages(struct alloc_tag *tag, unsigned int nr)
#endif /* CONFIG_MEM_ALLOC_PROFILING */
-__always_inline bool free_pages_prepare(struct page *page,
- unsigned int order)
+__always_inline bool __free_pages_prepare(struct page *page,
+ unsigned int order, fpi_t fpi_flags)
{
int bad = 0;
bool skip_kasan_poison = should_skip_kasan_poison(page);
@@ -1433,7 +1433,7 @@ __always_inline bool free_pages_prepare(struct page *page,
page_table_check_free(page, order);
pgalloc_tag_sub(page, 1 << order);
- if (!PageHighMem(page)) {
+ if (!PageHighMem(page) && !(fpi_flags & FPI_TRYLOCK)) {
debug_check_no_locks_freed(page_address(page),
PAGE_SIZE << order);
debug_check_no_obj_freed(page_address(page),
@@ -1472,6 +1472,11 @@ __always_inline bool free_pages_prepare(struct page *page,
return true;
}
+bool free_pages_prepare(struct page *page, unsigned int order)
+{
+ return __free_pages_prepare(page, order, FPI_NONE);
+}
+
/*
* Frees a number of pages from the PCP lists
* Assumes all pages on list are in same zone.
@@ -1605,7 +1610,7 @@ static void __free_pages_ok(struct page *page, unsigned int order,
unsigned long pfn = page_to_pfn(page);
struct zone *zone = page_zone(page);
- if (free_pages_prepare(page, order))
+ if (__free_pages_prepare(page, order, fpi_flags))
free_one_page(zone, page, pfn, order, fpi_flags);
}
@@ -2969,7 +2974,7 @@ static void __free_frozen_pages(struct page *page, unsigned int order,
return;
}
- if (!free_pages_prepare(page, order))
+ if (!__free_pages_prepare(page, order, fpi_flags))
return;
/*
@@ -3031,7 +3036,7 @@ void free_unref_folios(struct folio_batch *folios)
unsigned long pfn = folio_pfn(folio);
unsigned int order = folio_order(folio);
- if (!free_pages_prepare(&folio->page, order))
+ if (!__free_pages_prepare(&folio->page, order, FPI_NONE))
continue;
/*
* Free orders not handled on the PCP directly to the