mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-22 07:27:12 +08:00
mm, swap: split locked entry duplicating into a standalone helper
No feature change, split the common logic into a stand alone helper to be reused later. Link: https://lkml.kernel.org/r/20251220-swap-table-p2-v5-11-8862a265a033@tencent.com Signed-off-by: Kairui Song <kasong@tencent.com> Reviewed-by: Baoquan He <bhe@redhat.com> Cc: Baolin Wang <baolin.wang@linux.alibaba.com> Cc: Barry Song <baohua@kernel.org> Cc: Chris Li <chrisl@kernel.org> Cc: Nhat Pham <nphamcs@gmail.com> Cc: Rafael J. Wysocki (Intel) <rafael@kernel.org> Cc: Yosry Ahmed <yosry.ahmed@linux.dev> Cc: Deepanshu Kartikey <kartikey406@gmail.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Kairui Song <ryncsn@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
committed by
Andrew Morton
parent
cda2504c51
commit
78d6a12dd9
@@ -3667,26 +3667,14 @@ void si_swapinfo(struct sysinfo *val)
|
||||
* - swap-cache reference is requested but the entry is not used. -> ENOENT
|
||||
* - swap-mapped reference requested but needs continued swap count. -> ENOMEM
|
||||
*/
|
||||
static int __swap_duplicate(swp_entry_t entry, unsigned char usage, int nr)
|
||||
static int swap_dup_entries(struct swap_info_struct *si,
|
||||
struct swap_cluster_info *ci,
|
||||
unsigned long offset,
|
||||
unsigned char usage, int nr)
|
||||
{
|
||||
struct swap_info_struct *si;
|
||||
struct swap_cluster_info *ci;
|
||||
unsigned long offset;
|
||||
unsigned char count;
|
||||
unsigned char has_cache;
|
||||
int err, i;
|
||||
int i;
|
||||
unsigned char count, has_cache;
|
||||
|
||||
si = swap_entry_to_info(entry);
|
||||
if (WARN_ON_ONCE(!si)) {
|
||||
pr_err("%s%08lx\n", Bad_file, entry.val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
offset = swp_offset(entry);
|
||||
VM_WARN_ON(nr > SWAPFILE_CLUSTER - offset % SWAPFILE_CLUSTER);
|
||||
ci = swap_cluster_lock(si, offset);
|
||||
|
||||
err = 0;
|
||||
for (i = 0; i < nr; i++) {
|
||||
count = si->swap_map[offset + i];
|
||||
|
||||
@@ -3694,25 +3682,20 @@ static int __swap_duplicate(swp_entry_t entry, unsigned char usage, int nr)
|
||||
* For swapin out, allocator never allocates bad slots. for
|
||||
* swapin, readahead is guarded by swap_entry_swapped.
|
||||
*/
|
||||
if (WARN_ON(swap_count(count) == SWAP_MAP_BAD)) {
|
||||
err = -ENOENT;
|
||||
goto unlock_out;
|
||||
}
|
||||
if (WARN_ON(swap_count(count) == SWAP_MAP_BAD))
|
||||
return -ENOENT;
|
||||
|
||||
has_cache = count & SWAP_HAS_CACHE;
|
||||
count &= ~SWAP_HAS_CACHE;
|
||||
|
||||
if (!count && !has_cache) {
|
||||
err = -ENOENT;
|
||||
return -ENOENT;
|
||||
} else if (usage == SWAP_HAS_CACHE) {
|
||||
if (has_cache)
|
||||
err = -EEXIST;
|
||||
return -EEXIST;
|
||||
} else if ((count & ~COUNT_CONTINUED) > SWAP_MAP_MAX) {
|
||||
err = -EINVAL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (err)
|
||||
goto unlock_out;
|
||||
}
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
@@ -3731,14 +3714,31 @@ static int __swap_duplicate(swp_entry_t entry, unsigned char usage, int nr)
|
||||
* Don't need to rollback changes, because if
|
||||
* usage == 1, there must be nr == 1.
|
||||
*/
|
||||
err = -ENOMEM;
|
||||
goto unlock_out;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
WRITE_ONCE(si->swap_map[offset + i], count | has_cache);
|
||||
}
|
||||
|
||||
unlock_out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __swap_duplicate(swp_entry_t entry, unsigned char usage, int nr)
|
||||
{
|
||||
int err;
|
||||
struct swap_info_struct *si;
|
||||
struct swap_cluster_info *ci;
|
||||
unsigned long offset = swp_offset(entry);
|
||||
|
||||
si = swap_entry_to_info(entry);
|
||||
if (WARN_ON_ONCE(!si)) {
|
||||
pr_err("%s%08lx\n", Bad_file, entry.val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
VM_WARN_ON(nr > SWAPFILE_CLUSTER - offset % SWAPFILE_CLUSTER);
|
||||
ci = swap_cluster_lock(si, offset);
|
||||
err = swap_dup_entries(si, ci, offset, usage, nr);
|
||||
swap_cluster_unlock(ci);
|
||||
return err;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user