From patchwork Tue Apr 19 14:34:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liang Li X-Patchwork-Id: 8881061 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E5E9A9F39A for ; Tue, 19 Apr 2016 14:44:54 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 20CCD201D3 for ; Tue, 19 Apr 2016 14:44:54 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5EDAF20117 for ; Tue, 19 Apr 2016 14:44:53 +0000 (UTC) Received: from localhost ([::1]:59443 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1asWtY-0003Ww-Mi for patchwork-qemu-devel@patchwork.kernel.org; Tue, 19 Apr 2016 10:44:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51720) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1asWtE-00034L-5s for qemu-devel@nongnu.org; Tue, 19 Apr 2016 10:44:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1asWt8-0007Ba-AX for qemu-devel@nongnu.org; Tue, 19 Apr 2016 10:44:32 -0400 Received: from mga02.intel.com ([134.134.136.20]:34078) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1asWt8-0007BL-0a for qemu-devel@nongnu.org; Tue, 19 Apr 2016 10:44:26 -0400 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga101.jf.intel.com with ESMTP; 19 Apr 2016 07:43:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,506,1455004800"; d="scan'208";a="688779638" Received: from ll.sh.intel.com (HELO localhost) ([10.239.13.27]) by FMSMGA003.fm.intel.com with ESMTP; 19 Apr 2016 07:43:41 -0700 From: Liang Li To: mst@redhat.com, viro@zeniv.linux.org.uk, linux-kernel@vger.kernel.org, quintela@redhat.com, amit.shah@redhat.com, pbonzini@redhat.com, dgilbert@redhat.com Date: Tue, 19 Apr 2016 22:34:33 +0800 Message-Id: <1461076474-3864-2-git-send-email-liang.z.li@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1461076474-3864-1-git-send-email-liang.z.li@intel.com> References: <1461076474-3864-1-git-send-email-liang.z.li@intel.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 134.134.136.20 Subject: [Qemu-devel] [PATCH kernel 1/2] mm: add the related functions to build the free page bitmap X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kvm@vger.kernel.org, borntraeger@de.ibm.com, Liang Li , qemu-devel@nongnu.org, agraf@suse.de, linux-mm@kvack.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The free page bitmap will be sent to QEMU through virtio interface and used for live migration optimization. Drop the cache before building the free page bitmap can get more free pages. Whether dropping the cache is decided by user. Signed-off-by: Liang Li --- fs/drop_caches.c | 22 ++++++++++++++-------- include/linux/fs.h | 1 + mm/page_alloc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 8 deletions(-) diff --git a/fs/drop_caches.c b/fs/drop_caches.c index d72d52b..f488086 100644 --- a/fs/drop_caches.c +++ b/fs/drop_caches.c @@ -50,14 +50,8 @@ int drop_caches_sysctl_handler(struct ctl_table *table, int write, if (write) { static int stfu; - if (sysctl_drop_caches & 1) { - iterate_supers(drop_pagecache_sb, NULL); - count_vm_event(DROP_PAGECACHE); - } - if (sysctl_drop_caches & 2) { - drop_slab(); - count_vm_event(DROP_SLAB); - } + drop_cache(sysctl_drop_caches); + if (!stfu) { pr_info("%s (%d): drop_caches: %d\n", current->comm, task_pid_nr(current), @@ -67,3 +61,15 @@ int drop_caches_sysctl_handler(struct ctl_table *table, int write, } return 0; } + +void drop_cache(int drop_ctl) +{ + if (drop_ctl & 1) { + iterate_supers(drop_pagecache_sb, NULL); + count_vm_event(DROP_PAGECACHE); + } + if (drop_ctl & 2) { + drop_slab(); + count_vm_event(DROP_SLAB); + } +} diff --git a/include/linux/fs.h b/include/linux/fs.h index 70e61b5..b8a0bc0 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2864,6 +2864,7 @@ extern void drop_super(struct super_block *sb); extern void iterate_supers(void (*)(struct super_block *, void *), void *); extern void iterate_supers_type(struct file_system_type *, void (*)(struct super_block *, void *), void *); +extern void drop_cache(int drop_ctl); extern int dcache_dir_open(struct inode *, struct file *); extern int dcache_dir_close(struct inode *, struct file *); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 59de90d..4799983 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -63,6 +63,7 @@ #include #include #include +#include #include #include @@ -4029,6 +4030,51 @@ void show_free_areas(unsigned int filter) show_swap_cache_info(); } +static void mark_free_pages_bitmap(struct zone *zone, + unsigned long *bitmap, unsigned long len) +{ + unsigned long pfn, flags, i, limit; + unsigned int order, t; + struct list_head *curr; + + if (zone_is_empty(zone)) + return; + + spin_lock_irqsave(&zone->lock, flags); + + limit = min(len, max_pfn); + for_each_migratetype_order(order, t) { + list_for_each(curr, &zone->free_area[order].free_list[t]) { + pfn = page_to_pfn(list_entry(curr, struct page, lru)); + for (i = 0; i < (1UL << order); i++) { + if ((pfn + i) < limit) + set_bit_le(pfn + i, bitmap); + else + break; + } + } + } + + spin_unlock_irqrestore(&zone->lock, flags); +} + +unsigned long get_max_pfn(void) +{ + return max_pfn; +} +EXPORT_SYMBOL(get_max_pfn); + +void get_free_pages(unsigned long *bitmap, unsigned long len, int drop) +{ + struct zone *zone; + + drop_cache(drop); + + for_each_populated_zone(zone) + mark_free_pages_bitmap(zone, bitmap, len); +} +EXPORT_SYMBOL(get_free_pages); + static void zoneref_set_zone(struct zone *zone, struct zoneref *zoneref) { zoneref->zone = zone;