Global total_swap_pages can indicate if usable swap deivice is present, use it instead of __has_usable_swap(). Signed-off-by: Baoquan He --- mm/swapfile.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/mm/swapfile.c b/mm/swapfile.c index 2bd8bd76ea28..5d71c748a2fe 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -3836,11 +3836,6 @@ static void free_swap_count_continuations(struct swap_info_struct *si) } #if defined(CONFIG_MEMCG) && defined(CONFIG_BLK_CGROUP) -static bool __has_usable_swap(void) -{ - return !plist_head_empty(&swap_active_head); -} - void __folio_throttle_swaprate(struct folio *folio, gfp_t gfp) { struct swap_info_struct *si, *next; @@ -3848,7 +3843,7 @@ void __folio_throttle_swaprate(struct folio *folio, gfp_t gfp) if (!(gfp & __GFP_IO)) return; - if (!__has_usable_swap()) + if (!total_swap_pages) return; if (!blk_cgroup_congested()) -- 2.41.0 Now, swap_active_head is only used to find a present swap device when trying to swapoff it. In fact, swap_info[] is a short array which is 32 at maximum, and usually the unused one can be reused, so the searching for target mostly only iterates the foremost several used slots. And swapoff is a rarely used operation, efficiency is not so important. Then it's unnecessary to get a plist to make it. Here go by iterating swap_info[] to find the swap device instead of iterating swap_active_head. Signed-off-by: Baoquan He --- mm/swapfile.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mm/swapfile.c b/mm/swapfile.c index 5d71c748a2fe..18b52cc20749 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -2641,6 +2641,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) struct inode *inode; struct filename *pathname; int err, found = 0; + unsigned int type; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -2658,7 +2659,8 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) mapping = victim->f_mapping; spin_lock(&swap_lock); - plist_for_each_entry(p, &swap_active_head, list) { + for (type = 0; type < nr_swapfiles; type++) { + p = swap_info[type]; if (p->flags & SWP_WRITEOK) { if (p->swap_file->f_mapping == mapping) { found = 1; -- 2.41.0 There's no user of swap_active_head, remove it now. Signed-off-by: Baoquan He --- include/linux/swap.h | 1 - mm/swapfile.c | 20 ++++---------------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/include/linux/swap.h b/include/linux/swap.h index 5b7a39b20f58..dfc0cc9fc166 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -296,7 +296,6 @@ struct swap_info_struct { struct percpu_ref users; /* indicate and keep swap device valid. */ unsigned long flags; /* SWP_USED etc: see above */ signed short prio; /* swap priority of this type */ - struct plist_node list; /* entry in swap_active_head */ signed char type; /* strange name for an index */ unsigned int max; /* extent of the swap_map */ unsigned char *swap_map; /* vmalloc'ed array of usage counts */ diff --git a/mm/swapfile.c b/mm/swapfile.c index 18b52cc20749..80b34dc86a95 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -85,17 +85,10 @@ static const char Bad_offset[] = "Bad swap offset entry "; static const char Unused_offset[] = "Unused swap offset entry "; /* - * all active swap_info_structs - * protected with swap_lock, and ordered by priority. - */ -static PLIST_HEAD(swap_active_head); - -/* - * all available (active, not full) swap_info_structs - * protected with swap_avail_lock, ordered by priority. - * This is used by folio_alloc_swap() instead of swap_active_head - * because swap_active_head includes all swap_info_structs, - * but folio_alloc_swap() doesn't need to look at full ones. + * All available (active, not full) swap_info_structs protected with + * swap_avail_lock, ordered by priority. + * This is used by folio_alloc_swap() because folio_alloc_swap() + * doesn't need to look at full ones. * This uses its own lock instead of swap_lock because when a * swap_info_struct changes between not-full/full, it needs to * add/remove itself to/from this list, but the swap_info_struct->lock @@ -2539,7 +2532,6 @@ static void setup_swap_info(struct swap_info_struct *si, int prio, * the plist prio is negated because plist ordering is * low-to-high, while swap ordering is high-to-low */ - si->list.prio = -si->prio; si->avail_list.prio = -si->prio; si->swap_map = swap_map; si->cluster_info = cluster_info; @@ -2553,8 +2545,6 @@ static void _enable_swap_info(struct swap_info_struct *si) assert_spin_locked(&swap_lock); - plist_add(&si->list, &swap_active_head); - /* Add back to available list */ add_to_avail_list(si, true); } @@ -2682,7 +2672,6 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) } spin_lock(&p->lock); del_from_avail_list(p, true); - plist_del(&p->list, &swap_active_head); atomic_long_sub(p->pages, &nr_swap_pages); total_swap_pages -= p->pages; spin_unlock(&p->lock); @@ -2958,7 +2947,6 @@ static struct swap_info_struct *alloc_swap_info(void) */ } p->swap_extent_root = RB_ROOT; - plist_node_init(&p->list, 0); plist_node_init(&p->avail_list, 0); p->flags = SWP_USED; spin_unlock(&swap_lock); -- 2.41.0