Commit a833a69
mm: hugetlb: fix incorrect fallback for subpool
During our testing with hugetlb subpool enabled, we observe that
hstate->resv_huge_pages may underflow into negative values. Root cause
analysis reveals a race condition in subpool reservation fallback handling
as follow:
hugetlb_reserve_pages()
/* Attempt subpool reservation */
gbl_reserve = hugepage_subpool_get_pages(spool, chg);
/* Global reservation may fail after subpool allocation */
if (hugetlb_acct_memory(h, gbl_reserve) < 0)
goto out_put_pages;
out_put_pages:
/* This incorrectly restores reservation to subpool */
hugepage_subpool_put_pages(spool, chg);
When hugetlb_acct_memory() fails after subpool allocation, the current
implementation over-commits subpool reservations by returning the full
'chg' value instead of the actual allocated 'gbl_reserve' amount. This
discrepancy propagates to global reservations during subsequent releases,
eventually causing resv_huge_pages underflow.
This problem can be trigger easily with the following steps:
1. reverse hugepage for hugeltb allocation
2. mount hugetlbfs with min_size to enable hugetlb subpool
3. alloc hugepages with two task(make sure the second will fail due to
insufficient amount of hugepages)
4. with for a few seconds and repeat step 3 which will make
hstate->resv_huge_pages to go below zero.
To fix this problem, return corrent amount of pages to subpool during the
fallback after hugepage_subpool_get_pages is called.
Link: https://lkml.kernel.org/r/20250410062633.3102457-1-mawupeng1@huawei.com
Fixes: 1c5ecae ("hugetlbfs: add minimum size accounting to subpools")
Signed-off-by: Wupeng Ma <mawupeng1@huawei.com>
Tested-by: Joshua Hahn <joshua.hahnjy@gmail.com>
Reviewed-by: Oscar Salvador <osalvador@suse.de>
Cc: David Hildenbrand <david@redhat.com>
Cc: Ma Wupeng <mawupeng1@huawei.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>1 parent 82f2b0b commit a833a69
1 file changed
+22
-6
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3010 | 3010 | | |
3011 | 3011 | | |
3012 | 3012 | | |
3013 | | - | |
| 3013 | + | |
3014 | 3014 | | |
3015 | 3015 | | |
3016 | 3016 | | |
| |||
3163 | 3163 | | |
3164 | 3164 | | |
3165 | 3165 | | |
3166 | | - | |
3167 | | - | |
| 3166 | + | |
| 3167 | + | |
| 3168 | + | |
| 3169 | + | |
| 3170 | + | |
| 3171 | + | |
| 3172 | + | |
| 3173 | + | |
| 3174 | + | |
| 3175 | + | |
3168 | 3176 | | |
3169 | 3177 | | |
3170 | 3178 | | |
| |||
7239 | 7247 | | |
7240 | 7248 | | |
7241 | 7249 | | |
7242 | | - | |
| 7250 | + | |
7243 | 7251 | | |
7244 | 7252 | | |
7245 | 7253 | | |
| |||
7374 | 7382 | | |
7375 | 7383 | | |
7376 | 7384 | | |
7377 | | - | |
7378 | | - | |
| 7385 | + | |
| 7386 | + | |
| 7387 | + | |
| 7388 | + | |
| 7389 | + | |
| 7390 | + | |
| 7391 | + | |
| 7392 | + | |
| 7393 | + | |
| 7394 | + | |
7379 | 7395 | | |
7380 | 7396 | | |
7381 | 7397 | | |
| |||
0 commit comments