Commit cadcd419 authored by Liu Shixin's avatar Liu Shixin
Browse files

mm/swapfile: fix infinite loop in get_swap_pages after set memory.swapfile

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I9QRNR


CVE: NA

--------------------------------

In get_swap_pages(), we select the swap device based on the priority by
default. If two or more devices have the same priority, their positions
in the avail_lists will move in a circle in plist_requeue(). After set
memory.swapfile in a memory cgroup and the priority of the matched swap
is less than the priority of these swap, the loop will be confined to
these swaps with same priority and can't select the specified swap forever.

Fix the infinite loop by skip the unmatched swap before plist_requeue().

Fixes: 682fc25d ("mm/swapfile: introduce per-memcg swapfile control")
Signed-off-by: default avatarLiu Shixin <liushixin2@huawei.com>
parent 55b1bcbb
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -1173,15 +1173,13 @@ int get_swap_pages(int n_goal, swp_entry_t swp_entries[], int entry_size,
start_over:
	node = numa_node_id();
	plist_for_each_entry_safe(si, next, &swap_avail_heads[node], avail_lists[node]) {
		if (should_skip_swap_type(si->type, type))
			goto nextsi;

		/* requeue si to after same-priority siblings */
		plist_requeue(&si->avail_lists[node], &swap_avail_heads[node]);
		spin_unlock(&swap_avail_lock);
		spin_lock(&si->lock);
		if (should_skip_swap_type(si->type, type)) {
			spin_unlock(&si->lock);
			spin_lock(&swap_avail_lock);
			goto nextsi;
		}
		if (!si->highest_bit || !(si->flags & SWP_WRITEOK)) {
			spin_lock(&swap_avail_lock);
			if (plist_node_empty(&si->avail_lists[node])) {