Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp2949734imm; Thu, 24 May 2018 19:43:21 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrhTk56NUEw1jND2JIRnP/BO2hSQhX1WLXDJWoaad/++id2DYUXubzXYWt6bSmQ4gWFo4FH X-Received: by 2002:a17:902:5a03:: with SMTP id q3-v6mr621142pli.300.1527216201348; Thu, 24 May 2018 19:43:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527216201; cv=none; d=google.com; s=arc-20160816; b=0zP0esRyQBGm/ZtNdeG9DcVnOjwbtuDjoaddYG80IrRp+z0seJkS+enjm2dpr9TtOf KnYLpb3hUkQ4WZFhSRpc+xWFcd7JBTSQsgaq25oUsffPPY3E/lFYCjgjlN2BtviHqqmH rVjAiDS8r8LzHkaFEUm929pkCNubeZ8jnV8IdbZg/dXK3+h2GSKoi2zw42kLfeiXfAP+ 1Hboh+9M1t+EJyMRMQtGRK/Xgh+0CUU0KUZNfr963UWxgm6WS2N+0NrWv9z4YbrDtiOB 8moHPGKoYdOAhcH45PPtfN2xYhCe0TuhCXiLogUuQU2HKYvibfsWzdk/pXHihhQZ+qQ/ EfiA== 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 :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dkim-signature :arc-authentication-results; bh=k2gbYRBKCJ6D/yBfJUOge/9MWfahWtnQ/hw0lDjkyYI=; b=MdID66Gu9d2inukdAQIAGymBYQ1UVz/cH6Kw61OdMsKkQ8dmwCSG3lXcfTYzKREzsa jSL9+mt00Bo4y+rbvEG4ygdzLxCXBhmc1xKFi2bhncub9bvfRBa1VnnVGJIDkqFFwVFj NSrgycmr+jHfPFL9WQBmJmUmDtNLCisJx5HIQtNSBMcD2UzX6JZ3jV8e7o8njghcHtJl i8CCShhw6/NtNOpK5qq0Ztgs7JPPUfrxT4Jf4Oyehl2w9P0irYcfpkKRnD2CNWefIprK pxmG48WxDFAaILsvZi3/845kh0cAaKeYx66JAUpN0zA4IU+DGZGpzCE/+OOcLQpNGKNX 2pZg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@oracle.com header.s=corp-2017-10-26 header.b=MdIDA21+; 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=NONE dis=NONE) header.from=oracle.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b5-v6si21264219plm.202.2018.05.24.19.43.07; Thu, 24 May 2018 19:43:21 -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=@oracle.com header.s=corp-2017-10-26 header.b=MdIDA21+; 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=NONE dis=NONE) header.from=oracle.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S971523AbeEXU41 (ORCPT + 99 others); Thu, 24 May 2018 16:56:27 -0400 Received: from aserp2130.oracle.com ([141.146.126.79]:49546 "EHLO aserp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S969064AbeEXU4Y (ORCPT ); Thu, 24 May 2018 16:56:24 -0400 Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.22/8.16.0.22) with SMTP id w4OKp2t5063673; Thu, 24 May 2018 20:55:51 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : to : cc : references : from : message-id : date : mime-version : in-reply-to : content-type : content-transfer-encoding; s=corp-2017-10-26; bh=k2gbYRBKCJ6D/yBfJUOge/9MWfahWtnQ/hw0lDjkyYI=; b=MdIDA21+LBYvyxRSw2k48VynD6TAtPvwKj1m7Ia6QnR0BitV2gEa/CX5LrbqXJaV0FGD J/EOZtZjHyWLwrg5K6AAFOjzBHhnFQNJyD9dIjP16245EyOmGRUbdsn3av0LIZOqaTml wV2f2b/aJ2eUfrAcZzz2mqCuHC7Y4iLbZD5y9RKgMimnoGEt5HsBFyQzpVEvYEvbwOzJ hr83HwZmTV1sfvW91A8VFf2Takj4QUJkPUaYjngw25UbOzipTe+sfHRVNc0CafGGpd0U 4C9RDT5SRBGPCw4Ya3jg2kjMr9P/fLveV9IEhGdN9IC+pUyu8tS9sMd9/4DtFRwjzyy8 IA== Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp2130.oracle.com with ESMTP id 2j62sw8kyj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 24 May 2018 20:55:51 +0000 Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id w4OKtoxO026912 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 24 May 2018 20:55:50 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id w4OKtohQ031422; Thu, 24 May 2018 20:55:50 GMT Received: from [192.168.1.164] (/50.38.38.67) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 24 May 2018 13:55:50 -0700 Subject: Re: [PATCH -V2 -mm 1/4] mm, clear_huge_page: Move order algorithm into a separate function To: "Huang, Ying" , Andrew Morton Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Andi Kleen , Jan Kara , Michal Hocko , Andrea Arcangeli , "Kirill A. Shutemov" , Matthew Wilcox , Hugh Dickins , Minchan Kim , Shaohua Li , Christopher Lameter References: <20180524005851.4079-1-ying.huang@intel.com> <20180524005851.4079-2-ying.huang@intel.com> From: Mike Kravetz Message-ID: <4569310c-ae07-2353-8276-f9cba3011ea5@oracle.com> Date: Thu, 24 May 2018 13:55:48 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.5.2 MIME-Version: 1.0 In-Reply-To: <20180524005851.4079-2-ying.huang@intel.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8903 signatures=668700 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1805240236 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 05/23/2018 05:58 PM, Huang, Ying wrote: > From: Huang Ying > > In commit c79b57e462b5d ("mm: hugetlb: clear target sub-page last when > clearing huge page"), to keep the cache lines of the target subpage > hot, the order to clear the subpages in the huge page in > clear_huge_page() is changed to clearing the subpage which is furthest > from the target subpage firstly, and the target subpage last. This > optimization could be applied to copying huge page too with the same > order algorithm. To avoid code duplication and reduce maintenance > overhead, in this patch, the order algorithm is moved out of > clear_huge_page() into a separate function: process_huge_page(). So > that we can use it for copying huge page too. > > This will change the direct calls to clear_user_highpage() into the > indirect calls. But with the proper inline support of the compilers, > the indirect call will be optimized to be the direct call. Our tests > show no performance change with the patch. > > This patch is a code cleanup without functionality change. > > Signed-off-by: "Huang, Ying" > Suggested-by: Mike Kravetz Thanks for doing this. The extra level of indirection does make this a bit more difficult to read. However, I believe this is offset by the reuse of the algorithm in subsequent copy_huge_page support. > Cc: Andi Kleen > Cc: Jan Kara > Cc: Michal Hocko > Cc: Andrea Arcangeli > Cc: "Kirill A. Shutemov" > Cc: Matthew Wilcox > Cc: Hugh Dickins > Cc: Minchan Kim > Cc: Shaohua Li > Cc: Christopher Lameter > --- > mm/memory.c | 90 ++++++++++++++++++++++++++++++++++++++----------------------- > 1 file changed, 56 insertions(+), 34 deletions(-) > > diff --git a/mm/memory.c b/mm/memory.c > index 14578158ed20..b9f573a81bbd 100644 > --- a/mm/memory.c > +++ b/mm/memory.c > @@ -4569,71 +4569,93 @@ EXPORT_SYMBOL(__might_fault); > #endif > > #if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLBFS) > -static void clear_gigantic_page(struct page *page, > - unsigned long addr, > - unsigned int pages_per_huge_page) > -{ > - int i; > - struct page *p = page; > - > - might_sleep(); > - for (i = 0; i < pages_per_huge_page; > - i++, p = mem_map_next(p, page, i)) { > - cond_resched(); > - clear_user_highpage(p, addr + i * PAGE_SIZE); > - } > -} > -void clear_huge_page(struct page *page, > - unsigned long addr_hint, unsigned int pages_per_huge_page) > +/* > + * Process all subpages of the specified huge page with the specified > + * operation. The target subpage will be processed last to keep its > + * cache lines hot. > + */ > +static inline void process_huge_page( > + unsigned long addr_hint, unsigned int pages_per_huge_page, > + void (*process_subpage)(unsigned long addr, int idx, void *arg), > + void *arg) There could be a bit more information in the comment about the function. But it is not a requirement, unless patch needs to be redone for some other reason. Reviewed-by: Mike Kravetz -- Mike Kravetz > { > int i, n, base, l; > unsigned long addr = addr_hint & > ~(((unsigned long)pages_per_huge_page << PAGE_SHIFT) - 1); > > - if (unlikely(pages_per_huge_page > MAX_ORDER_NR_PAGES)) { > - clear_gigantic_page(page, addr, pages_per_huge_page); > - return; > - } > - > - /* Clear sub-page to access last to keep its cache lines hot */ > + /* Process target subpage last to keep its cache lines hot */ > might_sleep(); > n = (addr_hint - addr) / PAGE_SIZE; > if (2 * n <= pages_per_huge_page) { > - /* If sub-page to access in first half of huge page */ > + /* If target subpage in first half of huge page */ > base = 0; > l = n; > - /* Clear sub-pages at the end of huge page */ > + /* Process subpages at the end of huge page */ > for (i = pages_per_huge_page - 1; i >= 2 * n; i--) { > cond_resched(); > - clear_user_highpage(page + i, addr + i * PAGE_SIZE); > + process_subpage(addr + i * PAGE_SIZE, i, arg); > } > } else { > - /* If sub-page to access in second half of huge page */ > + /* If target subpage in second half of huge page */ > base = pages_per_huge_page - 2 * (pages_per_huge_page - n); > l = pages_per_huge_page - n; > - /* Clear sub-pages at the begin of huge page */ > + /* Process subpages at the begin of huge page */ > for (i = 0; i < base; i++) { > cond_resched(); > - clear_user_highpage(page + i, addr + i * PAGE_SIZE); > + process_subpage(addr + i * PAGE_SIZE, i, arg); > } > } > /* > - * Clear remaining sub-pages in left-right-left-right pattern > - * towards the sub-page to access > + * Process remaining subpages in left-right-left-right pattern > + * towards the target subpage > */ > for (i = 0; i < l; i++) { > int left_idx = base + i; > int right_idx = base + 2 * l - 1 - i; > > cond_resched(); > - clear_user_highpage(page + left_idx, > - addr + left_idx * PAGE_SIZE); > + process_subpage(addr + left_idx * PAGE_SIZE, left_idx, arg); > cond_resched(); > - clear_user_highpage(page + right_idx, > - addr + right_idx * PAGE_SIZE); > + process_subpage(addr + right_idx * PAGE_SIZE, right_idx, arg); > } > } > > +static void clear_gigantic_page(struct page *page, > + unsigned long addr, > + unsigned int pages_per_huge_page) > +{ > + int i; > + struct page *p = page; > + > + might_sleep(); > + for (i = 0; i < pages_per_huge_page; > + i++, p = mem_map_next(p, page, i)) { > + cond_resched(); > + clear_user_highpage(p, addr + i * PAGE_SIZE); > + } > +} > + > +static void clear_subpage(unsigned long addr, int idx, void *arg) > +{ > + struct page *page = arg; > + > + clear_user_highpage(page + idx, addr); > +} > + > +void clear_huge_page(struct page *page, > + unsigned long addr_hint, unsigned int pages_per_huge_page) > +{ > + unsigned long addr = addr_hint & > + ~(((unsigned long)pages_per_huge_page << PAGE_SHIFT) - 1); > + > + if (unlikely(pages_per_huge_page > MAX_ORDER_NR_PAGES)) { > + clear_gigantic_page(page, addr, pages_per_huge_page); > + return; > + } > + > + process_huge_page(addr_hint, pages_per_huge_page, clear_subpage, page); > +} > + > static void copy_user_gigantic_page(struct page *dst, struct page *src, > unsigned long addr, > struct vm_area_struct *vma, >