Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp9890701ybi; Wed, 24 Jul 2019 11:48:17 -0700 (PDT) X-Google-Smtp-Source: APXvYqz12960HhOaKk+AMbcbMf49ANVMXPuDtJbc6GR2UsGb+J7UNSC7cAPbKi0aAQS7VavhPccW X-Received: by 2002:a17:90a:d151:: with SMTP id t17mr88056296pjw.60.1563994097434; Wed, 24 Jul 2019 11:48:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1563994097; cv=none; d=google.com; s=arc-20160816; b=TnSoSXztawS4DyJuRmgNoujwIBQLPg/5abubA8pBrTMss8glK0XXn0uT7Mjd1M8Dm4 xEyXwfjfCqLu4vFRLJQwx+b251NYaFlpj8/vsvzDU5Pn5LEgaL1emB0sYXPaPUFR7VPy vWxFUhYb3xc4Gu8rXCX5Y4mbAZHuK8Up5DEJTkevAzqMon2aoHoXmS+4X95daE3njjvZ eWMFBiAdGGHNC63Xxl0qfgPxinI+WFDfvRLs+qsCQkxrqm3pTD3hLQxKbwiurYKOBm48 ovdCwibqowrV8s2nM4sdOkZdyzXCu3/mnF6J2ij1UjcE5TOxnS+tHuRDaAQ51ujftFYT 4uuw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:cc:to:from :subject:dkim-signature; bh=wYHYz2CAMv2i0hd4mcN2CYyNrF3b9BU8TFbZbdGIzOs=; b=uZDagH+j2Hg1yHqvh3RvUNzMuvFr83mXIlCpfgRSy7nWiUs+R7HgQZviUHuWPx16Vz oJ4FNOFMiSxehZ/Msxv/57fvBHIyEk0Njaghan3amjMmxK1wEMXSIbP2gOfIuE8V2ovu SOiPXAfk46MxB5p4tM+HCz7tNVKeFgEqZiaQ6X/4ffKBHYKHLMJFv/MI1dYl4kwIWAUY lcW8LNuPrTdp8fktTIkR5QeJ8+4RDrDTzKtkZd0FAGPyMJLkcFh/IcSdJbnwmkwZHloc mbhDDbtlOEcPuUDrK6mWBrNBI6c0sckQHW7n7WxyvOAORK1xSSYIiJ+CUY4z1dadyeTB uViw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=uY1ehjWR; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s23si13825330plq.81.2019.07.24.11.48.03; Wed, 24 Jul 2019 11:48:17 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=uY1ehjWR; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728351AbfGXQ61 (ORCPT + 99 others); Wed, 24 Jul 2019 12:58:27 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:33395 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726282AbfGXQ60 (ORCPT ); Wed, 24 Jul 2019 12:58:26 -0400 Received: by mail-io1-f65.google.com with SMTP id z3so91149672iog.0; Wed, 24 Jul 2019 09:58:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:from:to:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=wYHYz2CAMv2i0hd4mcN2CYyNrF3b9BU8TFbZbdGIzOs=; b=uY1ehjWR6BNqfQDttxnJ2nwMmBN8h3DMwSIIAOAYu7j+1U9hWxIKRCWsDilAvtulS7 jqHJXC90O93P97yw9YGdgSrzEUbp/ZLwkCT8Yc0LOVtg7XtoHzdwigcsAacCSXhT9E6V beqzvXL7IVwvTdXLU3GOtLQearf9QMNAH8y0xURecTQLtawiDMebQFFl5jX3uHtZ+F9c ikP//AaeOHroRE4+hUvKBROEkcq166E16z8wfjtJtzRhaXSVsUpd49066HnG3q72ZGj8 LdvAH/t8xfq00R+pV9kgkHyBHNwpH45MFLV/9Our+I1qQxPvHjK9Ty+dkBWr4Kwu2ZzO j4qw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=wYHYz2CAMv2i0hd4mcN2CYyNrF3b9BU8TFbZbdGIzOs=; b=Tm6vzWa02x4/fs9Y4JaA6t2Wo7/RX1QUQRU1iuOZ2dHTjOI+aQkOY4X0Ytuto1DmIi fdDvQQQt0m65J7CvzHdNX6QQs7YXeq5mUImjKng7IWvGap03RfAD4h1sowJWmZlg/Zzz a1+N45He0BTV3YpcT26hMPRVUJgb/ZqAJ3nF/61Ts4FpsfeqlARwXK5PAE83gEFcR4VJ AU2+eRbleLuf4BA5Jz5zSMoFaPXLBqctVzkBLksXzkVFdRvxPM8H6VzWKeXOc270d0GP 3ef3VGkyy24SUwDYFSwnMtbydsxGpxvlOu80+jauMwboqeZW80G70OvSXfy31YUpboxT 8CmQ== X-Gm-Message-State: APjAAAU6mAomsI5d5ddigFtx2CvNMtlqLI/1TfbwZQn32ekS3DPhYaSR DJNxSdFKzWWI0LkFNvpl+Mg= X-Received: by 2002:a6b:ef06:: with SMTP id k6mr4646761ioh.70.1563987505511; Wed, 24 Jul 2019 09:58:25 -0700 (PDT) Received: from localhost.localdomain (50-39-177-61.bvtn.or.frontiernet.net. [50.39.177.61]) by smtp.gmail.com with ESMTPSA id q13sm42436508ioh.36.2019.07.24.09.58.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 24 Jul 2019 09:58:25 -0700 (PDT) Subject: [PATCH v2 1/5] mm: Adjust shuffle code to allow for future coalescing From: Alexander Duyck To: nitesh@redhat.com, kvm@vger.kernel.org, david@redhat.com, mst@redhat.com, dave.hansen@intel.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, akpm@linux-foundation.org Cc: yang.zhang.wz@gmail.com, pagupta@redhat.com, riel@surriel.com, konrad.wilk@oracle.com, lcapitulino@redhat.com, wei.w.wang@intel.com, aarcange@redhat.com, pbonzini@redhat.com, dan.j.williams@intel.com, alexander.h.duyck@linux.intel.com Date: Wed, 24 Jul 2019 09:56:16 -0700 Message-ID: <20190724165615.6685.24289.stgit@localhost.localdomain> In-Reply-To: <20190724165158.6685.87228.stgit@localhost.localdomain> References: <20190724165158.6685.87228.stgit@localhost.localdomain> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Alexander Duyck This patch is meant to move the head/tail adding logic out of the shuffle code and into the __free_one_page function since ultimately that is where it is really needed anyway. By doing this we should be able to reduce the overhead and can consolidate all of the list addition bits in one spot. Signed-off-by: Alexander Duyck --- include/linux/mmzone.h | 12 -------- mm/page_alloc.c | 70 +++++++++++++++++++++++++++--------------------- mm/shuffle.c | 24 ---------------- mm/shuffle.h | 32 ++++++++++++++++++++++ 4 files changed, 71 insertions(+), 67 deletions(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index d77d717c620c..738e9c758135 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -116,18 +116,6 @@ static inline void add_to_free_area_tail(struct page *page, struct free_area *ar area->nr_free++; } -#ifdef CONFIG_SHUFFLE_PAGE_ALLOCATOR -/* Used to preserve page allocation order entropy */ -void add_to_free_area_random(struct page *page, struct free_area *area, - int migratetype); -#else -static inline void add_to_free_area_random(struct page *page, - struct free_area *area, int migratetype) -{ - add_to_free_area(page, area, migratetype); -} -#endif - /* Used for pages which are on another list */ static inline void move_to_free_area(struct page *page, struct free_area *area, int migratetype) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 272c6de1bf4e..1c4644b6cdc3 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -877,6 +877,36 @@ static inline struct capture_control *task_capc(struct zone *zone) #endif /* CONFIG_COMPACTION */ /* + * If this is not the largest possible page, check if the buddy + * of the next-highest order is free. If it is, it's possible + * that pages are being freed that will coalesce soon. In case, + * that is happening, add the free page to the tail of the list + * so it's less likely to be used soon and more likely to be merged + * as a higher order page + */ +static inline bool +buddy_merge_likely(unsigned long pfn, unsigned long buddy_pfn, + struct page *page, unsigned int order) +{ + struct page *higher_page, *higher_buddy; + unsigned long combined_pfn; + + if (order >= MAX_ORDER - 2) + return false; + + if (!pfn_valid_within(buddy_pfn)) + return false; + + combined_pfn = buddy_pfn & pfn; + higher_page = page + (combined_pfn - pfn); + buddy_pfn = __find_buddy_pfn(combined_pfn, order + 1); + higher_buddy = higher_page + (buddy_pfn - combined_pfn); + + return pfn_valid_within(buddy_pfn) && + page_is_buddy(higher_page, higher_buddy, order + 1); +} + +/* * Freeing function for a buddy system allocator. * * The concept of a buddy system is to maintain direct-mapped table @@ -905,11 +935,12 @@ static inline void __free_one_page(struct page *page, struct zone *zone, unsigned int order, int migratetype) { - unsigned long combined_pfn; + struct capture_control *capc = task_capc(zone); unsigned long uninitialized_var(buddy_pfn); - struct page *buddy; + unsigned long combined_pfn; + struct free_area *area; unsigned int max_order; - struct capture_control *capc = task_capc(zone); + struct page *buddy; max_order = min_t(unsigned int, MAX_ORDER, pageblock_order + 1); @@ -978,35 +1009,12 @@ static inline void __free_one_page(struct page *page, done_merging: set_page_order(page, order); - /* - * If this is not the largest possible page, check if the buddy - * of the next-highest order is free. If it is, it's possible - * that pages are being freed that will coalesce soon. In case, - * that is happening, add the free page to the tail of the list - * so it's less likely to be used soon and more likely to be merged - * as a higher order page - */ - if ((order < MAX_ORDER-2) && pfn_valid_within(buddy_pfn) - && !is_shuffle_order(order)) { - struct page *higher_page, *higher_buddy; - combined_pfn = buddy_pfn & pfn; - higher_page = page + (combined_pfn - pfn); - buddy_pfn = __find_buddy_pfn(combined_pfn, order + 1); - higher_buddy = higher_page + (buddy_pfn - combined_pfn); - if (pfn_valid_within(buddy_pfn) && - page_is_buddy(higher_page, higher_buddy, order + 1)) { - add_to_free_area_tail(page, &zone->free_area[order], - migratetype); - return; - } - } - - if (is_shuffle_order(order)) - add_to_free_area_random(page, &zone->free_area[order], - migratetype); + area = &zone->free_area[order]; + if (is_shuffle_order(order) ? shuffle_add_to_tail() : + buddy_merge_likely(pfn, buddy_pfn, page, order)) + add_to_free_area_tail(page, area, migratetype); else - add_to_free_area(page, &zone->free_area[order], migratetype); - + add_to_free_area(page, area, migratetype); } /* diff --git a/mm/shuffle.c b/mm/shuffle.c index 3ce12481b1dc..55d592e62526 100644 --- a/mm/shuffle.c +++ b/mm/shuffle.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include "internal.h" #include "shuffle.h" @@ -182,26 +181,3 @@ void __meminit __shuffle_free_memory(pg_data_t *pgdat) for (z = pgdat->node_zones; z < pgdat->node_zones + MAX_NR_ZONES; z++) shuffle_zone(z); } - -void add_to_free_area_random(struct page *page, struct free_area *area, - int migratetype) -{ - static u64 rand; - static u8 rand_bits; - - /* - * The lack of locking is deliberate. If 2 threads race to - * update the rand state it just adds to the entropy. - */ - if (rand_bits == 0) { - rand_bits = 64; - rand = get_random_u64(); - } - - if (rand & 1) - add_to_free_area(page, area, migratetype); - else - add_to_free_area_tail(page, area, migratetype); - rand_bits--; - rand >>= 1; -} diff --git a/mm/shuffle.h b/mm/shuffle.h index 777a257a0d2f..add763cc0995 100644 --- a/mm/shuffle.h +++ b/mm/shuffle.h @@ -3,6 +3,7 @@ #ifndef _MM_SHUFFLE_H #define _MM_SHUFFLE_H #include +#include /* * SHUFFLE_ENABLE is called from the command line enabling path, or by @@ -43,6 +44,32 @@ static inline bool is_shuffle_order(int order) return false; return order >= SHUFFLE_ORDER; } + +static inline bool shuffle_add_to_tail(void) +{ + static u64 rand; + static u8 rand_bits; + u64 rand_old; + + /* + * The lack of locking is deliberate. If 2 threads race to + * update the rand state it just adds to the entropy. + */ + if (rand_bits-- == 0) { + rand_bits = 64; + rand = get_random_u64(); + } + + /* + * Test highest order bit while shifting our random value. This + * should result in us testing for the carry flag following the + * shift. + */ + rand_old = rand; + rand <<= 1; + + return rand < rand_old; +} #else static inline void shuffle_free_memory(pg_data_t *pgdat) { @@ -60,5 +87,10 @@ static inline bool is_shuffle_order(int order) { return false; } + +static inline bool shuffle_add_to_tail(void) +{ + return false; +} #endif #endif /* _MM_SHUFFLE_H */