Intruduce a new flag to make page-cluster fine-grained discards while swapping
conditional, as they can be considered detrimental to some setups. However,
keep allowing batched discards at sys_swapon() time, when enabled by the
system administrator. 

Signed-off-by: Rafael Aquini <aqu...@redhat.com>
---
 include/linux/swap.h |  8 +++++---
 mm/swapfile.c        | 12 ++++++++----
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index 1701ce4..ab2e742 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -19,10 +19,11 @@ struct bio;
 #define SWAP_FLAG_PREFER       0x8000  /* set if swap priority specified */
 #define SWAP_FLAG_PRIO_MASK    0x7fff
 #define SWAP_FLAG_PRIO_SHIFT   0
-#define SWAP_FLAG_DISCARD      0x10000 /* discard swap cluster after use */
+#define SWAP_FLAG_DISCARD      0x10000 /* enable discard for swap areas */
+#define SWAP_FLAG_DISCARD_CLUSTER 0x20000 /* discard swap clusters after use */
 
 #define SWAP_FLAGS_VALID       (SWAP_FLAG_PRIO_MASK | SWAP_FLAG_PREFER | \
-                                SWAP_FLAG_DISCARD)
+                                SWAP_FLAG_DISCARD | SWAP_FLAG_DISCARD_CLUSTER)
 
 static inline int current_is_kswapd(void)
 {
@@ -152,8 +153,9 @@ enum {
        SWP_CONTINUED   = (1 << 5),     /* swap_map has count continuation */
        SWP_BLKDEV      = (1 << 6),     /* its a block device */
        SWP_FILE        = (1 << 7),     /* set after swap_activate success */
+       SWP_CLUSTERDISCARD = (1 << 8),  /* discard swap cluster after usage */
                                        /* add others here before... */
-       SWP_SCANNING    = (1 << 8),     /* refcount in scan_swap_map */
+       SWP_SCANNING    = (1 << 9),     /* refcount in scan_swap_map */
 };
 
 #define SWAP_CLUSTER_MAX 32UL
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 6c340d9..197461f 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -212,7 +212,7 @@ static unsigned long scan_swap_map(struct swap_info_struct 
*si,
                        si->cluster_nr = SWAPFILE_CLUSTER - 1;
                        goto checks;
                }
-               if (si->flags & SWP_DISCARDABLE) {
+               if (si->flags & SWP_CLUSTERDISCARD) {
                        /*
                         * Start range check on racing allocations, in case
                         * they overlap the cluster we eventually decide on
@@ -322,7 +322,7 @@ checks:
 
        if (si->lowest_alloc) {
                /*
-                * Only set when SWP_DISCARDABLE, and there's a scan
+                * Only set when SWP_CLUSTERDISCARD, and there's a scan
                 * for a free cluster in progress or just completed.
                 */
                if (found_free_cluster) {
@@ -2123,8 +2123,11 @@ SYSCALL_DEFINE2(swapon, const char __user *, 
specialfile, int, swap_flags)
                        p->flags |= SWP_SOLIDSTATE;
                        p->cluster_next = 1 + (prandom_u32() % p->highest_bit);
                }
-               if ((swap_flags & SWAP_FLAG_DISCARD) && discard_swap(p) == 0)
+               if ((swap_flags & SWAP_FLAG_DISCARD) && discard_swap(p) == 0) {
                        p->flags |= SWP_DISCARDABLE;
+                       if (swap_flags & SWAP_FLAG_DISCARD_CLUSTER)
+                               p->flags |= SWP_CLUSTERDISCARD;
+               }
        }
 
        mutex_lock(&swapon_mutex);
@@ -2135,11 +2138,12 @@ SYSCALL_DEFINE2(swapon, const char __user *, 
specialfile, int, swap_flags)
        enable_swap_info(p, prio, swap_map, frontswap_map);
 
        printk(KERN_INFO "Adding %uk swap on %s.  "
-                       "Priority:%d extents:%d across:%lluk %s%s%s\n",
+                       "Priority:%d extents:%d across:%lluk %s%s%s%s\n",
                p->pages<<(PAGE_SHIFT-10), name->name, p->prio,
                nr_extents, (unsigned long long)span<<(PAGE_SHIFT-10),
                (p->flags & SWP_SOLIDSTATE) ? "SS" : "",
                (p->flags & SWP_DISCARDABLE) ? "D" : "",
+               (p->flags & SWP_CLUSTERDISCARD) ? "C" : "",
                (frontswap_map) ? "FS" : "");
 
        mutex_unlock(&swapon_mutex);
-- 
1.7.11.7

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to