Commit adb5c2e
mm: hugetlb: fix incorrect fallback for subpool
commit a833a69 upstream.
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>1 parent a1ebbe0 commit adb5c2e
1 file changed
Lines changed: 22 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2987 | 2987 | | |
2988 | 2988 | | |
2989 | 2989 | | |
2990 | | - | |
| 2990 | + | |
2991 | 2991 | | |
2992 | 2992 | | |
2993 | 2993 | | |
| |||
3140 | 3140 | | |
3141 | 3141 | | |
3142 | 3142 | | |
3143 | | - | |
3144 | | - | |
| 3143 | + | |
| 3144 | + | |
| 3145 | + | |
| 3146 | + | |
| 3147 | + | |
| 3148 | + | |
| 3149 | + | |
| 3150 | + | |
| 3151 | + | |
| 3152 | + | |
3145 | 3153 | | |
3146 | 3154 | | |
3147 | 3155 | | |
| |||
6949 | 6957 | | |
6950 | 6958 | | |
6951 | 6959 | | |
6952 | | - | |
| 6960 | + | |
6953 | 6961 | | |
6954 | 6962 | | |
6955 | 6963 | | |
| |||
7084 | 7092 | | |
7085 | 7093 | | |
7086 | 7094 | | |
7087 | | - | |
7088 | | - | |
| 7095 | + | |
| 7096 | + | |
| 7097 | + | |
| 7098 | + | |
| 7099 | + | |
| 7100 | + | |
| 7101 | + | |
| 7102 | + | |
| 7103 | + | |
| 7104 | + | |
7089 | 7105 | | |
7090 | 7106 | | |
7091 | 7107 | | |
| |||
0 commit comments