From patchwork Thu Oct 28 22:40:13 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Balbir Singh X-Patchwork-Id: 288932 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o9SMeN14032516 for ; Thu, 28 Oct 2010 22:40:23 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756334Ab0J1WkT (ORCPT ); Thu, 28 Oct 2010 18:40:19 -0400 Received: from e28smtp06.in.ibm.com ([122.248.162.6]:36908 "EHLO e28smtp06.in.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757173Ab0J1WkR (ORCPT ); Thu, 28 Oct 2010 18:40:17 -0400 Received: from d28relay03.in.ibm.com (d28relay03.in.ibm.com [9.184.220.60]) by e28smtp06.in.ibm.com (8.14.4/8.13.1) with ESMTP id o9SMeFp8010382 for ; Fri, 29 Oct 2010 04:10:15 +0530 Received: from d28av03.in.ibm.com (d28av03.in.ibm.com [9.184.220.65]) by d28relay03.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id o9SMeEAg4284668 for ; Fri, 29 Oct 2010 04:10:14 +0530 Received: from d28av03.in.ibm.com (loopback [127.0.0.1]) by d28av03.in.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id o9SMeEGC032093 for ; Fri, 29 Oct 2010 09:40:14 +1100 Received: from localhost.localdomain ([9.77.203.69]) by d28av03.in.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id o9SMeDnn032088; Fri, 29 Oct 2010 09:40:14 +1100 From: Balbir Singh To: kvm@vger.kernel.org Cc: linux-mm@kvack.org, Balbir Singh , qemu-devel@nongnu.org Date: Fri, 29 Oct 2010 04:10:13 +0530 Message-Id: <20101028224013.32626.42073.sendpatchset@localhost.localdomain> In-Reply-To: <20101028224002.32626.13015.sendpatchset@localhost.localdomain> References: <20101028224002.32626.13015.sendpatchset@localhost.localdomain> Subject: [RFC][PATCH 2/3] Linux/Guest cooperative unmapped page cache control Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Thu, 28 Oct 2010 22:40:23 +0000 (UTC) diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 0f1da45..70f97ea 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -99,12 +99,24 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq) static void fill_balloon(struct virtio_balloon *vb, size_t num) { + u32 reclaim_cache_first; + int err; + gfp_t mask = GFP_HIGHUSER | __GFP_NORETRY | __GFP_NOMEMALLOC | + __GFP_NOWARN; + + err = virtio_config_val(vb->vdev, VIRTIO_BALLOON_F_BALLOON_HINT, + offsetof(struct virtio_balloon_config, + reclaim_cache_first), + &reclaim_cache_first); + + if (!err && reclaim_cache_first) + mask |= __GFP_FREE_CACHE; + /* We can only do one array worth at a time. */ num = min(num, ARRAY_SIZE(vb->pfns)); for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { - struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY | - __GFP_NOMEMALLOC | __GFP_NOWARN); + struct page *page = alloc_page(mask); if (!page) { if (printk_ratelimit()) dev_printk(KERN_INFO, &vb->vdev->dev, @@ -358,6 +370,7 @@ static void __devexit virtballoon_remove(struct virtio_device *vdev) static unsigned int features[] = { VIRTIO_BALLOON_F_MUST_TELL_HOST, VIRTIO_BALLOON_F_STATS_VQ, + VIRTIO_BALLOON_F_BALLOON_HINT, }; static struct virtio_driver virtio_balloon_driver = { diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 975609c..9048259 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -61,12 +61,18 @@ struct vm_area_struct; #endif /* + * While allocating pages, try to free cache pages first. Note the + * heavy dependency on zone_reclaim_mode logic + */ +#define __GFP_FREE_CACHE ((__force gfp_t)0x400000u) /* Free cache first */ + +/* * This may seem redundant, but it's a way of annotating false positives vs. * allocations that simply cannot be supported (e.g. page tables). */ #define __GFP_NOTRACK_FALSE_POSITIVE (__GFP_NOTRACK) -#define __GFP_BITS_SHIFT 22 /* Room for 22 __GFP_FOO bits */ +#define __GFP_BITS_SHIFT 23 /* Room for 22 __GFP_FOO bits */ #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) /* This equals 0, but use constants in case they ever change */ diff --git a/include/linux/swap.h b/include/linux/swap.h index 5d29097..e77db75 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -254,16 +254,13 @@ extern long vm_total_pages; extern bool should_balance_unmapped_pages(struct zone *zone); extern int sysctl_min_unmapped_ratio; -#ifdef CONFIG_NUMA -extern int zone_reclaim_mode; extern int sysctl_min_slab_ratio; extern int zone_reclaim(struct zone *, gfp_t, unsigned int); + +#ifdef CONFIG_NUMA +extern int zone_reclaim_mode; #else #define zone_reclaim_mode 0 -static inline int zone_reclaim(struct zone *z, gfp_t mask, unsigned int order) -{ - return 0; -} #endif extern int page_evictable(struct page *page, struct vm_area_struct *vma); diff --git a/include/linux/virtio_balloon.h b/include/linux/virtio_balloon.h index a50ecd1..6e405b4 100644 --- a/include/linux/virtio_balloon.h +++ b/include/linux/virtio_balloon.h @@ -8,6 +8,7 @@ /* The feature bitmap for virtio balloon */ #define VIRTIO_BALLOON_F_MUST_TELL_HOST 0 /* Tell before reclaiming pages */ #define VIRTIO_BALLOON_F_STATS_VQ 1 /* Memory Stats virtqueue */ +#define VIRTIO_BALLOON_F_BALLOON_HINT 2 /* Reclaim hint */ /* Size of a PFN in the balloon interface. */ #define VIRTIO_BALLOON_PFN_SHIFT 12 @@ -18,6 +19,8 @@ struct virtio_balloon_config __le32 num_pages; /* Number of pages we've actually got in balloon. */ __le32 actual; + /* Hint, should we reclaim cached pages first? */ + __le32 reclaim_cache_first; }; #define VIRTIO_BALLOON_S_SWAP_IN 0 /* Amount of memory swapped in */ diff --git a/mm/page_alloc.c b/mm/page_alloc.c index d8fe29f..2cdf4a9 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1650,7 +1650,8 @@ zonelist_scan: classzone_idx, alloc_flags)) goto try_this_zone; - if (zone_reclaim_mode == 0) + if (zone_reclaim_mode == 0 && + !(gfp_mask & __GFP_FREE_CACHE)) goto this_zone_full; ret = zone_reclaim(zone, gfp_mask, order); diff --git a/mm/vmscan.c b/mm/vmscan.c index 02346ad..9a11e5a 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2705,6 +2705,7 @@ module_init(kswapd_init) * the watermarks. */ int zone_reclaim_mode __read_mostly; +#endif /* * If the number of slab pages in a zone grows beyond this percentage then @@ -2870,7 +2871,6 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) return ret; } -#endif /* * page_evictable - test whether a page is evictable