OSDN Git Service

mm: swap_ratio: bail out if there aren't any other swap device
authorVinayak Menon <vinmenon@codeaurora.org>
Tue, 22 Mar 2016 09:11:57 +0000 (14:41 +0530)
committerKyle Yan <kyan@codeaurora.org>
Tue, 31 May 2016 22:23:38 +0000 (15:23 -0700)
It is pointless to calculate the swap ratio when there is only
one swap device in the group. Moreover the existing code would
result in a spinlock recursion because of not taking this into
consideration. Interestingly, this check is already performed
in swap_ratio_slow by this piece of code

if (&(*si)->avail_list == plist_last(&swap_avail_head)) {
/* just to make skip work */
n = *si;
ret = -ENODEV;
goto skip;
}

But there is window where we drop the swap_avail_lock before
invoking swap_ratio() and take it back again in swap_ratio_slow.
In this period the si can get removed from swap_avail_head,
resulting in the failure of above logic. So recheck again.

Similarly, bail out from swap_ratio() if the sysctl is disabled,
and thus avoiding overhead of taking unnecessary locks.

Change-Id: I81a9dd61d24b7da55d5341c48a1f71d2b4b1978d
Signed-off-by: Vinayak Menon <vinmenon@codeaurora.org>
mm/swap_ratio.c

index 3b4cf29..cf2a6e2 100644 (file)
@@ -88,6 +88,12 @@ static int swap_ratio_slow(struct swap_info_struct **si)
        n = plist_next_entry(&(*si)->avail_list,
                        struct swap_info_struct,
                        avail_list);
+       if (n == *si) {
+               /* No other swap device */
+               ret = -ENODEV;
+               goto skip;
+       }
+
        spin_unlock(&swap_avail_lock);
        spin_lock(&n->lock);
        spin_lock(&swap_avail_lock);
@@ -182,6 +188,9 @@ void setup_swap_ratio(struct swap_info_struct *p, int prio)
 
 int swap_ratio(struct swap_info_struct **si)
 {
+       if (!sysctl_swap_ratio_enable)
+               return -ENODEV;
+
        if (is_swap_ratio_group((*si)->prio))
                return swap_ratio_slow(si);
        else