| From: luofei <luofei@unicloud.com> |
| Subject: hugetlb: fix comments about avoiding atomic allocation of vmemmap pages |
| |
| Since there is no longer an atomic allocation of vmemmap pages, but a |
| fixed flag(GFP_KERNEL | __GFP_NORETRY | __GFP_THISNODE) is used. The |
| description of atomicity here is some what inappropriate. |
| |
| And the atomic parameter naming of update_and_free_page() may be |
| misleading, add a comment here. |
| |
| Link: https://lkml.kernel.org/r/20220316031602.377452-1-luofei@unicloud.com |
| Signed-off-by: luofei <luofei@unicloud.com> |
| Reviewed-by: Muchun Song <songmuchun@bytedance.com> |
| Cc: Mike Kravetz <mike.kravetz@oracle.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| mm/hugetlb.c | 17 ++++++++++++----- |
| 1 file changed, 12 insertions(+), 5 deletions(-) |
| |
| --- a/mm/hugetlb.c~hugetlb-fix-comments-about-avoiding-atomic-allocation-of-vmemmap-pages |
| +++ a/mm/hugetlb.c |
| @@ -1567,10 +1567,12 @@ static void __update_and_free_page(struc |
| } |
| |
| /* |
| - * As update_and_free_page() can be called under any context, so we cannot |
| - * use GFP_KERNEL to allocate vmemmap pages. However, we can defer the |
| - * actual freeing in a workqueue to prevent from using GFP_ATOMIC to allocate |
| - * the vmemmap pages. |
| + * Freeing hugetlb pages in done in update_and_free_page(). When freeing |
| + * a hugetlb page, vmemmap pages may need to be allocated. The routine |
| + * alloc_huge_page_vmemmap() can possibly sleep as it uses GFP_KERNEL. |
| + * However, update_and_free_page() can be called under any context. To |
| + * avoid the possibility of sleeping in a context where sleeping is not |
| + * allowed, defer the actual freeing in a workqueue where sleeping is allowed. |
| * |
| * free_hpage_workfn() locklessly retrieves the linked list of pages to be |
| * freed and frees them one-by-one. As the page->mapping pointer is going |
| @@ -1614,6 +1616,10 @@ static inline void flush_free_hpage_work |
| flush_work(&free_hpage_work); |
| } |
| |
| +/* |
| + * atomic == true indicates called from a context where sleeping is |
| + * not allowed. |
| + */ |
| static void update_and_free_page(struct hstate *h, struct page *page, |
| bool atomic) |
| { |
| @@ -1623,7 +1629,8 @@ static void update_and_free_page(struct |
| } |
| |
| /* |
| - * Defer freeing to avoid using GFP_ATOMIC to allocate vmemmap pages. |
| + * Defer freeing to avoid possible sleeping when allocating |
| + * vmemmap pages. |
| * |
| * Only call schedule_work() if hpage_freelist is previously |
| * empty. Otherwise, schedule_work() had been called but the workfn |
| _ |