mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 21:51:40 +00:00
mm/swap: fix race on swap_info reuse between swapoff and swapon
swapoff clear swap_info's SWP_USED flag prematurely and free its resources after that. A concurrent swapon will reuse this swap_info while its previous resources are not cleared completely. These late freed resources are: - p->percpu_cluster - swap_cgroup_ctrl[type] - block_device setting - inode->i_flags &= ~S_SWAPFILE This patch clears the SWP_USED flag after all its resources are freed, so that swapon can reuse this swap_info by alloc_swap_info() safely. [akpm@linux-foundation.org: tidy up code comment] Signed-off-by: Weijie Yang <weijie.yang@samsung.com> Acked-by: Hugh Dickins <hughd@google.com> Cc: Krzysztof Kozlowski <k.kozlowski@samsung.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
579f82901f
commit
f893ab41e4
@ -1923,7 +1923,6 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
|
||||
p->swap_map = NULL;
|
||||
cluster_info = p->cluster_info;
|
||||
p->cluster_info = NULL;
|
||||
p->flags = 0;
|
||||
frontswap_map = frontswap_map_get(p);
|
||||
spin_unlock(&p->lock);
|
||||
spin_unlock(&swap_lock);
|
||||
@ -1949,6 +1948,16 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
}
|
||||
filp_close(swap_file, NULL);
|
||||
|
||||
/*
|
||||
* Clear the SWP_USED flag after all resources are freed so that swapon
|
||||
* can reuse this swap_info in alloc_swap_info() safely. It is ok to
|
||||
* not hold p->lock after we cleared its SWP_WRITEOK.
|
||||
*/
|
||||
spin_lock(&swap_lock);
|
||||
p->flags = 0;
|
||||
spin_unlock(&swap_lock);
|
||||
|
||||
err = 0;
|
||||
atomic_inc(&proc_poll_event);
|
||||
wake_up_interruptible(&proc_poll_wait);
|
||||
|
Loading…
Reference in New Issue
Block a user