Commit e679b26
mm: swap: correctly use maxpages in swapon syscall to avoid potential deadloop
commit 255116c upstream.
We use maxpages from read_swap_header() to initialize swap_info_struct,
however the maxpages might be reduced in setup_swap_extents() and the
si->max is assigned with the reduced maxpages from the
setup_swap_extents().
Obviously, this could lead to memory waste as we allocated memory based on
larger maxpages, besides, this could lead to a potential deadloop as
following:
1) When calling setup_clusters() with larger maxpages, unavailable
pages within range [si->max, larger maxpages) are not accounted with
inc_cluster_info_page(). As a result, these pages are assumed
available but can not be allocated. The cluster contains these pages
can be moved to frag_clusters list after it's all available pages were
allocated.
2) When the cluster mentioned in 1) is the only cluster in
frag_clusters list, cluster_alloc_swap_entry() assume order 0
allocation will never failed and will enter a deadloop by keep trying
to allocate page from the only cluster in frag_clusters which contains
no actually available page.
Call setup_swap_extents() to get the final maxpages before
swap_info_struct initialization to fix the issue.
After this change, span will include badblocks and will become large
value which I think is correct value:
In summary, there are two kinds of swapfile_activate operations.
1. Filesystem style: Treat all blocks logical continuity and find
usable physical extents in logical range. In this way, si->pages will
be actual usable physical blocks and span will be "1 + highest_block -
lowest_block".
2. Block device style: Treat all blocks physically continue and only
one single extent is added. In this way, si->pages will be si->max and
span will be "si->pages - 1". Actually, si->pages and si->max is only
used in block device style and span value is set with si->pages. As a
result, span value in block device style will become a larger value as
you mentioned.
I think larger value is correct based on:
1. Span value in filesystem style is "1 + highest_block -
lowest_block" which is the range cover all possible phisical blocks
including the badblocks.
2. For block device style, si->pages is the actual usable block number
and is already in pr_info. The original span value before this patch
is also refer to usable block number which is redundant in pr_info.
[shikemeng@huaweicloud.com: ensure si->pages == si->max - 1 after setup_swap_extents()]
Link: https://lkml.kernel.org/r/20250522122554.12209-3-shikemeng@huaweicloud.com
Link: https://lkml.kernel.org/r/20250718065139.61989-1-shikemeng@huaweicloud.com
Link: https://lkml.kernel.org/r/20250522122554.12209-3-shikemeng@huaweicloud.com
Fixes: 661383c ("mm: swap: relaim the cached parts that got scanned")
Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
Reviewed-by: Baoquan He <bhe@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Kairui Song <kasong@tencent.com>
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 9128ecb commit e679b26
1 file changed
Lines changed: 26 additions & 27 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3138 | 3138 | | |
3139 | 3139 | | |
3140 | 3140 | | |
3141 | | - | |
3142 | | - | |
3143 | | - | |
3144 | | - | |
3145 | | - | |
| 3141 | + | |
| 3142 | + | |
| 3143 | + | |
| 3144 | + | |
3146 | 3145 | | |
3147 | | - | |
3148 | 3146 | | |
3149 | | - | |
3150 | | - | |
3151 | | - | |
3152 | 3147 | | |
| 3148 | + | |
3153 | 3149 | | |
3154 | 3150 | | |
3155 | 3151 | | |
3156 | 3152 | | |
3157 | 3153 | | |
3158 | 3154 | | |
3159 | | - | |
| 3155 | + | |
3160 | 3156 | | |
3161 | 3157 | | |
3162 | 3158 | | |
3163 | | - | |
3164 | | - | |
3165 | | - | |
3166 | | - | |
3167 | | - | |
3168 | | - | |
3169 | | - | |
3170 | | - | |
3171 | | - | |
3172 | | - | |
| 3159 | + | |
3173 | 3160 | | |
3174 | 3161 | | |
3175 | 3162 | | |
3176 | 3163 | | |
3177 | | - | |
| 3164 | + | |
3178 | 3165 | | |
3179 | 3166 | | |
3180 | 3167 | | |
| |||
3214 | 3201 | | |
3215 | 3202 | | |
3216 | 3203 | | |
3217 | | - | |
| 3204 | + | |
3218 | 3205 | | |
3219 | 3206 | | |
3220 | 3207 | | |
| |||
3360 | 3347 | | |
3361 | 3348 | | |
3362 | 3349 | | |
| 3350 | + | |
| 3351 | + | |
| 3352 | + | |
| 3353 | + | |
| 3354 | + | |
| 3355 | + | |
| 3356 | + | |
| 3357 | + | |
| 3358 | + | |
| 3359 | + | |
| 3360 | + | |
| 3361 | + | |
| 3362 | + | |
| 3363 | + | |
| 3364 | + | |
3363 | 3365 | | |
3364 | 3366 | | |
3365 | 3367 | | |
| |||
3371 | 3373 | | |
3372 | 3374 | | |
3373 | 3375 | | |
3374 | | - | |
3375 | | - | |
3376 | | - | |
3377 | | - | |
| 3376 | + | |
| 3377 | + | |
3378 | 3378 | | |
3379 | | - | |
3380 | 3379 | | |
3381 | 3380 | | |
3382 | 3381 | | |
| |||
0 commit comments