Received: by 2002:a05:6a10:7420:0:0:0:0 with SMTP id hk32csp636442pxb; Wed, 16 Feb 2022 00:33:39 -0800 (PST) X-Google-Smtp-Source: ABdhPJwx6KXewfwI3IeacFhjhpSbjXjUOqxF9jGuzA/2Phdep3B3K7JHL9tEcowofR3LsA44CZyS X-Received: by 2002:a63:ed4c:0:b0:373:1bea:2711 with SMTP id m12-20020a63ed4c000000b003731bea2711mr1387954pgk.178.1645000418945; Wed, 16 Feb 2022 00:33:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1645000418; cv=none; d=google.com; s=arc-20160816; b=cKmPju7JB+y4Z1cAWD3G/O6SJ414RnJ5UNCxtZkbTJYnR9+kw51X38azm3N0RPKsTN LteZRfyIxh+sTbev/ITtADiixksShw+3rNoDCg1RWwpOq46pz36at5JGZxEXO0i+bvD1 s3MQNekTRVjZViLPTYHQF0k9/uZDqPLQce4KSM2r6NRfKeY8rHhyHL68w9MqVVJIRsUD 2gh5UG0bJ/UxMTpO24WRBFpBqLMkvgMbb1dOOQq4YQwJ+E1g+D2UwlT5JJHzVcNQwc/K lelYSosjfNSarIRSH3x9PS7YtAQsPcRJMkeni8TuAi1CxQCjscPuTwz68pwnXWl5Ylg/ 1tpw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=gHU8Rb7XmOCAV3r7uY4NdIQYHBa2gDSPm2KtYVDkbZ8=; b=wDo2hScjRDj5UWBD/UEkYKUT1JaL3wQxHvBeXVy2TiXu4qUgL2imMz+TVzbQYmIP8a 5VmsDWOaGHvYPO0NduSmJvzZLoK0VXRMPvkJrLlOKyjPqrWdd9zjA40a7bmmxkb7lkxn wCK+JIw/iSLAtseTwITfNqZnllDZLu5eivst6VrBSDEIeyxm7d7Z34LYPbWhm3Twwf4k gxMgrMDZsaHI1SDx1ok0tP21h/2mMoMuEAub4QC8PS0Mw8xIG5e3oJ33mFNlhs+Yz7iD 1bjJaeW/23cPq+sx2dmChnrYisP2UKSN/+OBOD11f/YozVHMEt7rXdJIbWmF+egEeHzu fsnA== ARC-Authentication-Results: i=1; mx.google.com; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=alibaba.com Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id v14si5014650pgk.382.2022.02.16.00.33.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Feb 2022 00:33:38 -0800 (PST) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=alibaba.com Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 50B0E2A4A35; Wed, 16 Feb 2022 00:31:05 -0800 (PST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230189AbiBPIbH (ORCPT + 99 others); Wed, 16 Feb 2022 03:31:07 -0500 Received: from gmail-smtp-in.l.google.com ([23.128.96.19]:34978 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229526AbiBPIbA (ORCPT ); Wed, 16 Feb 2022 03:31:00 -0500 Received: from out30-56.freemail.mail.aliyun.com (out30-56.freemail.mail.aliyun.com [115.124.30.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 97AB821E31 for ; Wed, 16 Feb 2022 00:30:48 -0800 (PST) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R191e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04395;MF=xhao@linux.alibaba.com;NM=1;PH=DS;RN=6;SR=0;TI=SMTPD_---0V4cXjyl_1645000245; Received: from localhost.localdomain(mailfrom:xhao@linux.alibaba.com fp:SMTPD_---0V4cXjyl_1645000245) by smtp.aliyun-inc.com(127.0.0.1); Wed, 16 Feb 2022 16:30:46 +0800 From: Xin Hao To: sj@kernel.org Cc: xhao@linux.alibaba.com, rongwei.wang@linux.alibaba.com, akpm@linux-foundation.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH V1 2/5] mm/damon: Add 'damon_region' NUMA fault simulation support Date: Wed, 16 Feb 2022 16:30:38 +0800 Message-Id: <35c8c45267c6f2f5b6ec3559592342685106d39e.1645024354.git.xhao@linux.alibaba.com> X-Mailer: git-send-email 2.31.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RDNS_NONE, SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE,UNPARSEABLE_RELAY autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org These codes development here refers to NUMA balance code, it will cause a page_fault, in do_numa_page(), we will count 'damon_region' NUMA local and remote values. Signed-off-by: Xin Hao Signed-off-by: Rongwei Wang --- mm/damon/paddr.c | 23 +++++++++++++++++---- mm/damon/prmtv-common.c | 44 +++++++++++++++++++++++++++++++++++++++++ mm/damon/prmtv-common.h | 3 +++ mm/damon/vaddr.c | 32 +++++++++++++++++++++--------- 4 files changed, 89 insertions(+), 13 deletions(-) diff --git a/mm/damon/paddr.c b/mm/damon/paddr.c index 5e8244f65a1a..b8feacf15592 100644 --- a/mm/damon/paddr.c +++ b/mm/damon/paddr.c @@ -16,9 +16,10 @@ #include "../internal.h" #include "prmtv-common.h" -static bool __damon_pa_mkold(struct page *page, struct vm_area_struct *vma, +static bool __damon_pa_mk_set(struct page *page, struct vm_area_struct *vma, unsigned long addr, void *arg) { + bool result = false; struct page_vma_mapped_walk pvmw = { .page = page, .vma = vma, @@ -27,10 +28,24 @@ static bool __damon_pa_mkold(struct page *page, struct vm_area_struct *vma, while (page_vma_mapped_walk(&pvmw)) { addr = pvmw.address; - if (pvmw.pte) + if (pvmw.pte) { damon_ptep_mkold(pvmw.pte, vma->vm_mm, addr); - else + if (nr_online_nodes > 1) { + result = damon_ptep_mknone(pvmw.pte, vma, addr); + if (result) + flush_tlb_page(vma, addr); + } + } else { damon_pmdp_mkold(pvmw.pmd, vma->vm_mm, addr); + if (nr_online_nodes > 1) { + result = damon_pmdp_mknone(pvmw.pmd, vma, addr); + if (result) { + unsigned long haddr = addr & HPAGE_PMD_MASK; + + flush_tlb_range(vma, haddr, haddr + HPAGE_PMD_SIZE); + } + } + } } return true; } @@ -39,7 +54,7 @@ static void damon_pa_mkold(unsigned long paddr) { struct page *page = damon_get_page(PHYS_PFN(paddr)); struct rmap_walk_control rwc = { - .rmap_one = __damon_pa_mkold, + .rmap_one = __damon_pa_mk_set, .anon_lock = page_lock_anon_vma_read, }; bool need_lock; diff --git a/mm/damon/prmtv-common.c b/mm/damon/prmtv-common.c index 92a04f5831d6..35ac50fdf7b6 100644 --- a/mm/damon/prmtv-common.c +++ b/mm/damon/prmtv-common.c @@ -12,6 +12,50 @@ #include "prmtv-common.h" +bool damon_ptep_mknone(pte_t *pte, struct vm_area_struct *vma, unsigned long addr) +{ + pte_t oldpte, ptent; + bool preserve_write; + + oldpte = *pte; + if (pte_protnone(oldpte)) + return false; + + if (pte_present(oldpte)) { + preserve_write = pte_write(oldpte); + oldpte = ptep_modify_prot_start(vma, addr, pte); + ptent = pte_modify(oldpte, PAGE_NONE); + + if (preserve_write) + ptent = pte_mk_savedwrite(ptent); + + ptep_modify_prot_commit(vma, addr, pte, oldpte, ptent); + return true; + } + return false; +} + +bool damon_pmdp_mknone(pmd_t *pmd, struct vm_area_struct *vma, unsigned long addr) +{ + bool preserve_write; + pmd_t entry = *pmd; + + if (is_huge_zero_pmd(entry) || pmd_protnone(entry)) + return false; + + if (pmd_present(entry)) { + preserve_write = pmd_write(entry); + entry = pmdp_invalidate(vma, addr, pmd); + entry = pmd_modify(entry, PAGE_NONE); + if (preserve_write) + entry = pmd_mk_savedwrite(entry); + + set_pmd_at(vma->vm_mm, addr, pmd, entry); + return true; + } + return false; +} + /* * Get an online page for a pfn if it's in the LRU list. Otherwise, returns * NULL. diff --git a/mm/damon/prmtv-common.h b/mm/damon/prmtv-common.h index e790cb5f8fe0..002a308facd0 100644 --- a/mm/damon/prmtv-common.h +++ b/mm/damon/prmtv-common.h @@ -7,6 +7,9 @@ #include +bool damon_ptep_mknone(pte_t *pte, struct vm_area_struct *vma, unsigned long addr); +bool damon_pmdp_mknone(pmd_t *pmd, struct vm_area_struct *vma, unsigned long addr); + struct page *damon_get_page(unsigned long pfn); void damon_ptep_mkold(pte_t *pte, struct mm_struct *mm, unsigned long addr); diff --git a/mm/damon/vaddr.c b/mm/damon/vaddr.c index 89b6468da2b9..732b41ed134c 100644 --- a/mm/damon/vaddr.c +++ b/mm/damon/vaddr.c @@ -367,9 +367,10 @@ static void damon_va_update(struct damon_ctx *ctx) } } -static int damon_mkold_pmd_entry(pmd_t *pmd, unsigned long addr, +static int damon_va_pmd_entry(pmd_t *pmd, unsigned long addr, unsigned long next, struct mm_walk *walk) { + bool result = false; pte_t *pte; spinlock_t *ptl; @@ -377,7 +378,14 @@ static int damon_mkold_pmd_entry(pmd_t *pmd, unsigned long addr, ptl = pmd_lock(walk->mm, pmd); if (pmd_huge(*pmd)) { damon_pmdp_mkold(pmd, walk->mm, addr); + if (nr_online_nodes > 1) + result = damon_pmdp_mknone(pmd, walk->vma, addr); spin_unlock(ptl); + if (result) { + unsigned long haddr = addr & HPAGE_PMD_MASK; + + flush_tlb_range(walk->vma, haddr, haddr + HPAGE_PMD_SIZE); + } return 0; } spin_unlock(ptl); @@ -386,11 +394,17 @@ static int damon_mkold_pmd_entry(pmd_t *pmd, unsigned long addr, if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) return 0; pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl); - if (!pte_present(*pte)) - goto out; + if (!pte_present(*pte)) { + pte_unmap_unlock(pte, ptl); + return 0; + } damon_ptep_mkold(pte, walk->mm, addr); -out: + if (nr_online_nodes > 1) + result = damon_ptep_mknone(pte, walk->vma, addr); pte_unmap_unlock(pte, ptl); + if (result) + flush_tlb_page(walk->vma, addr); + return 0; } @@ -450,15 +464,15 @@ static int damon_mkold_hugetlb_entry(pte_t *pte, unsigned long hmask, #define damon_mkold_hugetlb_entry NULL #endif /* CONFIG_HUGETLB_PAGE */ -static const struct mm_walk_ops damon_mkold_ops = { - .pmd_entry = damon_mkold_pmd_entry, +static const struct mm_walk_ops damon_va_ops = { + .pmd_entry = damon_va_pmd_entry, .hugetlb_entry = damon_mkold_hugetlb_entry, }; -static void damon_va_mkold(struct mm_struct *mm, unsigned long addr) +static void damon_va_check(struct mm_struct *mm, unsigned long addr) { mmap_read_lock(mm); - walk_page_range(mm, addr, addr + 1, &damon_mkold_ops, NULL); + walk_page_range(mm, addr, addr + 1, &damon_va_ops, NULL); mmap_read_unlock(mm); } @@ -471,7 +485,7 @@ static void __damon_va_prepare_access_check(struct damon_ctx *ctx, { r->sampling_addr = damon_rand(r->ar.start, r->ar.end); - damon_va_mkold(mm, r->sampling_addr); + damon_va_check(mm, r->sampling_addr); } static void damon_va_prepare_access_checks(struct damon_ctx *ctx) -- 2.27.0