From patchwork Fri Jun 23 07:12:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Ying" X-Patchwork-Id: 9805815 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D5F9B600C5 for ; Fri, 23 Jun 2017 07:14:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C5E2B2870D for ; Fri, 23 Jun 2017 07:14:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BAB0F2872C; Fri, 23 Jun 2017 07:14:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 603D82870D for ; Fri, 23 Jun 2017 07:14:57 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 12C4521CA3598; Fri, 23 Jun 2017 00:13:28 -0700 (PDT) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 3B63121BBC43A for ; Fri, 23 Jun 2017 00:13:27 -0700 (PDT) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga104.jf.intel.com with ESMTP; 23 Jun 2017 00:14:53 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.39,376,1493708400"; d="scan'208";a="116565879" Received: from yhuang-dev.sh.intel.com ([10.239.13.13]) by orsmga005.jf.intel.com with ESMTP; 23 Jun 2017 00:14:20 -0700 From: "Huang, Ying" To: Andrew Morton Subject: [PATCH -mm -v2 07/12] mm, THP, swap: Support to split THP for THP swapped out Date: Fri, 23 Jun 2017 15:12:58 +0800 Message-Id: <20170623071303.13469-8-ying.huang@intel.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170623071303.13469-1-ying.huang@intel.com> References: <20170623071303.13469-1-ying.huang@intel.com> X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrea Arcangeli , Rik van Riel , linux-nvdimm@lists.01.org, Huang Ying , Hugh Dickins , linux-kernel@vger.kernel.org, linux-mm@kvack.org, Johannes Weiner , Minchan Kim , Shaohua Li , "Kirill A . Shutemov" MIME-Version: 1.0 Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP From: Huang Ying After adding swapping out support for THP (Transparent Huge Page), it is possible that a THP in swap cache (partly swapped out) need to be split. To split such a THP, the swap cluster backing the THP need to be split too, that is, the CLUSTER_FLAG_HUGE flag need to be cleared for the swap cluster. The patch implemented this. And because the THP swap writing needs the THP keeps as huge page during writing. The PageWriteback flag is checked before splitting. Signed-off-by: "Huang, Ying" Cc: Johannes Weiner Cc: Minchan Kim Cc: Hugh Dickins Cc: Shaohua Li Cc: Rik van Riel Cc: Andrea Arcangeli Cc: "Kirill A . Shutemov" --- include/linux/swap.h | 9 +++++++++ mm/huge_memory.c | 10 +++++++++- mm/swapfile.c | 15 +++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/include/linux/swap.h b/include/linux/swap.h index 3cd9cfe76422..186015622062 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -526,6 +526,15 @@ static inline swp_entry_t get_swap_page(struct page *page) #endif /* CONFIG_SWAP */ +#ifdef CONFIG_THP_SWAP +extern int split_swap_cluster(swp_entry_t entry); +#else +static inline int split_swap_cluster(swp_entry_t entry) +{ + return 0; +} +#endif + #ifdef CONFIG_MEMCG static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg) { diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 08cb43c1088f..e88e121f80ac 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2452,6 +2452,9 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) VM_BUG_ON_PAGE(!PageLocked(page), page); VM_BUG_ON_PAGE(!PageCompound(page), page); + if (PageWriteback(page)) + return -EBUSY; + if (PageAnon(head)) { /* * The caller does not necessarily hold an mmap_sem that would @@ -2529,7 +2532,12 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) __dec_node_page_state(page, NR_SHMEM_THPS); spin_unlock(&pgdata->split_queue_lock); __split_huge_page(page, list, flags); - ret = 0; + if (PageSwapCache(head)) { + swp_entry_t entry = { .val = page_private(head) }; + + ret = split_swap_cluster(entry); + } else + ret = 0; } else { if (IS_ENABLED(CONFIG_DEBUG_VM) && mapcount) { pr_alert("total_mapcount: %u, page_count(): %u\n", diff --git a/mm/swapfile.c b/mm/swapfile.c index d3329b209d12..d8a95dc5a63d 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -1216,6 +1216,21 @@ static void swapcache_free_cluster(swp_entry_t entry) } } } + +int split_swap_cluster(swp_entry_t entry) +{ + struct swap_info_struct *si; + struct swap_cluster_info *ci; + unsigned long offset = swp_offset(entry); + + si = _swap_info_get(entry); + if (!si) + return -EBUSY; + ci = lock_cluster(si, offset); + cluster_clear_huge(ci); + unlock_cluster(ci); + return 0; +} #else static inline void swapcache_free_cluster(swp_entry_t entry) {