Omar Sandoval <osandov@xxxxxxxxxxx> writes: > From: Omar Sandoval <osandov@xxxxxx> > > If swapon() fails after incrementing nr_rotate_swap, we don't decrement > it and thus effectively leak it. Make sure we decrement it if we > incremented it. > > Fixes: 81a0298bdfab ("mm, swap: don't use VMA based swap readahead if HDD is used as swap") > Signed-off-by: Omar Sandoval <osandov@xxxxxx> Good catch! Thanks! Reviewed-by: "Huang, Ying" <ying.huang@xxxxxxxxx> Best Regards, Huang, Ying > --- > Based on v4.17-rc5. > > mm/swapfile.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/mm/swapfile.c b/mm/swapfile.c > index cc2cf04d9018..78a015fcec3b 100644 > --- a/mm/swapfile.c > +++ b/mm/swapfile.c > @@ -3112,6 +3112,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) > unsigned long *frontswap_map = NULL; > struct page *page = NULL; > struct inode *inode = NULL; > + bool inced_nr_rotate_swap = false; > > if (swap_flags & ~SWAP_FLAGS_VALID) > return -EINVAL; > @@ -3215,8 +3216,10 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) > cluster = per_cpu_ptr(p->percpu_cluster, cpu); > cluster_set_null(&cluster->index); > } > - } else > + } else { > atomic_inc(&nr_rotate_swap); > + inced_nr_rotate_swap = true; > + } > > error = swap_cgroup_swapon(p->type, maxpages); > if (error) > @@ -3307,6 +3310,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) > vfree(swap_map); > kvfree(cluster_info); > kvfree(frontswap_map); > + if (inced_nr_rotate_swap) > + atomic_dec(&nr_rotate_swap); > if (swap_file) { > if (inode && S_ISREG(inode->i_mode)) { > inode_unlock(inode);