From nobody Sat Jul 25 03:20:31 2026 Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0B03E2F0673 for ; Mon, 20 Jul 2026 03:03:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784516628; cv=none; b=VGOaSMWGQ+40WpwlVJJFnnYinBWV2LM1uiWbDq5UuVs9hyWtXYfPDHODD/f0xWMRLgCgTLduqADad9oMqa9KBlRdguW+Qa1MELOttrnTs+bKCbJL5zX5V5WVNZGgBbRL56HGPz5mLPIA4cfsRcF00+LhtFYFhNlaaKYH5c9QkLo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784516628; c=relaxed/simple; bh=DUin7ncN2wE53OSsMptOjCA0tzO+DsIg+Rek0OLve6A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HeFrdi3Jj9eL22Pw833Bos7c6RU6+YTEbOMXPaSUZ1KfxQfpuwM2LsWCgWChcejMu4cvBcny3Lwi+HGD60cTFxuh8r7RyKbcUsHzElD+faMATZLYpWoKVXDbHG2D+nl7eTRjD1acgi7WaqAOh6p1oyJsH//Kyj/FCTGnovCuSa0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=rggULqmo; arc=none smtp.client-ip=209.85.214.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="rggULqmo" Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-2cad4170e8eso129899555ad.3 for ; Sun, 19 Jul 2026 20:03:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784516626; x=1785121426; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=69Ct5gp9rT21SAwaHS4XMcVk/1fLHoPDTQLb0SWSnDU=; b=rggULqmo8lZ6oZ+g+/g7IDVc8XZl0nXDN/swvyBUVj55XO1kM1AvpMzAqrYHciqfdN Nbjl8AxUDWCJD4FgFGPG57O5n59xAsWx+xU7HSCf7mZ8PCKQx0u2U+Mg6mt0IqxIbVqz kiFyXwxac4vTWpKts3ewEybUu+wun4q3zoDKCwG+RmAXzTOCkT2tHh0RATPyXwDyViYI QTYik1K6LY3goa42dIWwz8gCdnohkGPlFHAyP1S0A4YiEgv6dgahDMFJM8D/mo6yR0Hl aEnsyfnLhKLGAs0uR2VEnddUAvSXDGgKi9JL3Rii7WSruuF8w07yL5+rBDP6VHQBGyCi WMuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784516626; x=1785121426; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=69Ct5gp9rT21SAwaHS4XMcVk/1fLHoPDTQLb0SWSnDU=; b=XS7xwGRvdXS/Xo+fQ8X2+oKgG7fHN6YTTp3c7ShpiJJ2NEpge7rCib39vWFjqjqOwi Mibv+ktY0yWCCl74iJSOJsTwj9zAonOEFbyxQvtOxNXnsWUzECtRexsree0F4jRm8bY1 KP1F1tRiiCENqKquZ5p3+kQOH5+Ettp8JIFpO82w2hNvG+2Mabuwmu5htoqtqSBDS+tP 0iJwuhEwjSQnTcUufvGSCNLeVqcRc6bVOHuXXj3kPcDT2P4FObvZD/sqCd7w/RGMWdLX oREyBs8ym8KyYyfn/377Gq1xoc5/KbjSUeF8GrFOOuAJSxlhylPvDxOpYkrqrfGYWrq8 AhKA== X-Forwarded-Encrypted: i=1; AHgh+RqmaAqW6jKzvPrwwwm29Uf2GOmi4MfqXwei0qgUK81s7dhhCwwCdMqNwl8E8HzIdZGx8fMIAhGtOKJTspU=@vger.kernel.org X-Gm-Message-State: AOJu0Yw5zkfIMdq8sCbY2bBbw3tHA08+JXQe6D57SFhUGvE3IQmBmHRP Pj+pCLbgKCaNi964BN8CgKC34v2p719B58o4nxZyXoJSlNTnd5bbvB/p X-Gm-Gg: AfdE7ckzlvTb5nkz+EKPstKF21L8tXuOwrPzuXgOKv6/wRUQbi1BIm4N2/hVcAC6I8C Iar78e9Sslkdb1MpLVWDozxq7TOORlGTaw+9jnnTcoxBZXuhawyc80egTkMyDTERH2bNv4m9sBu 9SgN43hDz1JwTvU1HJhqXkSQu08AwZweOdk0WTXvFoGoFg0YCB3Mmo9MGHJilbsj54zvEyJUrOS VBMY3oD+DtTT8pQV1238zsckYIhFj3NR7INYTJhcbWOOZ+68Bm0l68Kpva8DvDwus/WFOMDmnyu WjHxGGkGAU4/aCHfU8Qcmwg1xdNk4NrMMeTRfR/iq6Z8VmcR5srPeFpGXLBoRfoE7krgFzbEtvO S1L1Vr09W/pJMnyINCNH7Ak/16vAPazRA5vcMOBytrlHK/eLvvmDqxporS9Ob6XyQt2CZ7FiB7F fL7gAfV6c7+CnSt17xBzbcUwSyv6c= X-Received: by 2002:a17:902:fc85:b0:2c9:bd37:ae76 with SMTP id d9443c01a7336-2cf34a3ef59mr139624465ad.47.1784516626163; Sun, 19 Jul 2026 20:03:46 -0700 (PDT) Received: from localhost.localdomain ([112.65.87.25]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2cf344d80e6sm47783065ad.29.2026.07.19.20.03.39 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 19 Jul 2026 20:03:45 -0700 (PDT) From: Lian Wang To: damon@lists.linux.dev, linux-mm@kvack.org Cc: sj@kernel.org, akpm@linux-foundation.org, linux-kernel@vger.kernel.org, david@kernel.org, ljs@kernel.org, liam@infradead.org, vbabka@kernel.org, rppt@kernel.org, surenb@google.com, mhocko@suse.com, npache@redhat.com, ziy@nvidia.com, baolin.wang@linux.alibaba.com, ryan.roberts@arm.com, daichaobing@sangfor.com.cn, wangkefeng.wang@huawei.com, gutierrez.asier@huawei-partners.com, zengheng4@huawei.com, kasong@tencent.com, corbet@lwn.net, skhan@linuxfoundation.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, lianux.mm@gmail.com, lianux.wang@processmission.com, kunwu.chan@linux.dev Subject: [RFC PATCH v3 1/3] mm/damon: introduce DAMOS_SPLIT action Date: Mon, 20 Jul 2026 11:03:25 +0800 Message-ID: <20260720030327.80153-2-lianux.mm@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260720030327.80153-1-lianux.mm@gmail.com> References: <20260720030327.80153-1-lianux.mm@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a new DAMOS action, DAMOS_SPLIT, that splits large folios in the target region down to a smaller order. A new per-scheme field and sysfs file, target_order, selects the split target: 0 for order-0 base pages, or 2..HPAGE_PMD_ORDER-1 for a smaller mTHP order (order-1 is rejected at store time since anonymous THPs cannot be split to order-1). Unlike DAMOS_COLLAPSE which builds large folios, splitting only dismantles them; it allocates nothing, copies nothing, and no THP admission policy applies. khugepaged deliberately refuses to collapse a folio to a smaller order, leaving the shrink direction to callers like this one. This patch adds the DAMOS_SPLIT action, the ``order`` field (placed in the existing union alongside target_nid and migrate_dests), its sysfs interface, and documentation. The vaddr operations set handler is added in the next patch. Link: https://lore.kernel.org/20260605161422.213817-9-npache@redhat.com/ ("mm/khugepaged: skip collapsing mTHP to smaller orders") Co-developed-by: Kunwu Chan Signed-off-by: Kunwu Chan Signed-off-by: Lian Wang (Processmission) --- .../ABI/testing/sysfs-kernel-mm-damon | 7 +++ Documentation/mm/damon/design.rst | 5 ++ include/linux/damon.h | 15 ++++-- mm/damon/core.c | 2 + mm/damon/sysfs-schemes.c | 48 +++++++++++++++++++ tools/testing/selftests/damon/sysfs.py | 11 +++-- 6 files changed, 79 insertions(+), 9 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-kernel-mm-damon b/Documentatio= n/ABI/testing/sysfs-kernel-mm-damon index 907a504fb64c..ee8e260a631c 100644 --- a/Documentation/ABI/testing/sysfs-kernel-mm-damon +++ b/Documentation/ABI/testing/sysfs-kernel-mm-damon @@ -265,6 +265,13 @@ Contact: SJ Park Description: Action's target NUMA node id. Supported by only relevant actions. =20 +What: /sys/kernel/mm/damon/admin/kdamonds//contexts//schemes//ta= rget_order +Date: Jul 2026 +Contact: SJ Park +Description: Target folio order for the ``split`` action. Large folios in + the target region are split down to this order. Valid values + are 0 (order-0 base pages) and 2..HPAGE_PMD_ORDER-1. + What: /sys/kernel/mm/damon/admin/kdamonds//contexts//schemes//ap= ply_interval_us Date: Sep 2023 Contact: SJ Park diff --git a/Documentation/mm/damon/design.rst b/Documentation/mm/damon/des= ign.rst index aed6cb1cf483..87a801954b1b 100644 --- a/Documentation/mm/damon/design.rst +++ b/Documentation/mm/damon/design.rst @@ -549,6 +549,11 @@ that supports each action are as below. Supported by ``vaddr`` and ``fvaddr`` operations set. When TRANSPARENT_HUGEPAGE is disabled, the application of the action will ju= st fail. + - ``split``: Split each large folio in the region down to the order speci= fied + by the scheme's ``target_order`` (``0`` for order-0 base pages, or + ``2..HPAGE_PMD_ORDER-1``). Supported by ``vaddr`` and ``fvaddr`` opera= tions + set. When TRANSPARENT_HUGEPAGE is disabled, the application of the acti= on + will just fail. - ``lru_prio``: Prioritize the region on its LRU lists. Supported by ``paddr`` operations set. - ``lru_deprio``: Deprioritize the region on its LRU lists. diff --git a/include/linux/damon.h b/include/linux/damon.h index f69442a9d431..88b61b900a36 100644 --- a/include/linux/damon.h +++ b/include/linux/damon.h @@ -110,6 +110,7 @@ struct damon_target { * @DAMOS_HUGEPAGE: Call ``madvise()`` for the region with MADV_HUGEPAGE. * @DAMOS_NOHUGEPAGE: Call ``madvise()`` for the region with MADV_NOHUGEPA= GE. * @DAMOS_COLLAPSE: Call ``madvise()`` for the region with MADV_COLLAPSE. + * @DAMOS_SPLIT: Split each large folio in the region to a smaller order. * @DAMOS_LRU_PRIO: Prioritize the region on its LRU lists. * @DAMOS_LRU_DEPRIO: Deprioritize the region on its LRU lists. * @DAMOS_MIGRATE_HOT: Migrate the regions prioritizing warmer regions. @@ -130,6 +131,7 @@ enum damos_action { DAMOS_HUGEPAGE, DAMOS_NOHUGEPAGE, DAMOS_COLLAPSE, + DAMOS_SPLIT, DAMOS_LRU_PRIO, DAMOS_LRU_DEPRIO, DAMOS_MIGRATE_HOT, @@ -582,10 +584,15 @@ struct damos { struct damos_quota quota; struct damos_watermarks wmarks; union { - struct { - int target_nid; - struct damos_migrate_dests migrate_dests; - }; + int target_nid; + struct damos_migrate_dests migrate_dests; + /* + * @order: target folio order for DAMOS_SPLIT. + * Split large folios down to this order. 0 for + * order-0 base pages, 2..HPAGE_PMD_ORDER-1 for + * smaller mTHP. Order-1 is rejected. + */ + unsigned int order; }; struct list_head core_filters; struct list_head ops_filters; diff --git a/mm/damon/core.c b/mm/damon/core.c index 806a67d02a6e..394c62455ad5 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -693,6 +693,7 @@ struct damos *damon_new_scheme(struct damos_access_patt= ern *pattern, return NULL; scheme->pattern =3D *pattern; scheme->action =3D action; + scheme->order =3D 0; scheme->apply_interval_us =3D apply_interval_us; /* * next_apply_sis will be set when kdamond starts. While kdamond is @@ -1446,6 +1447,7 @@ static int damos_commit(struct damos *dst, struct dam= os *src) =20 dst->pattern =3D src->pattern; dst->action =3D src->action; + dst->order =3D src->order; dst->apply_interval_us =3D src->apply_interval_us; =20 err =3D damos_commit_quota(&dst->quota, &src->quota); diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c index 32f495a96b17..725ed81ccf6c 100644 --- a/mm/damon/sysfs-schemes.c +++ b/mm/damon/sysfs-schemes.c @@ -4,7 +4,9 @@ */ =20 #include +#include #include +#include =20 #include "sysfs-common.h" =20 @@ -2260,6 +2262,7 @@ struct damon_sysfs_scheme { struct damon_sysfs_stats *stats; struct damon_sysfs_scheme_regions *tried_regions; int target_nid; + unsigned int target_order; struct damos_sysfs_dests *dests; }; =20 @@ -2293,6 +2296,10 @@ static struct damos_sysfs_action_name damos_sysfs_ac= tion_names[] =3D { .action =3D DAMOS_COLLAPSE, .name =3D "collapse", }, + { + .action =3D DAMOS_SPLIT, + .name =3D "split", + }, { .action =3D DAMOS_LRU_PRIO, .name =3D "lru_prio", @@ -2326,6 +2333,7 @@ static struct damon_sysfs_scheme *damon_sysfs_scheme_= alloc( scheme->action =3D action; scheme->apply_interval_us =3D apply_interval_us; scheme->target_nid =3D NUMA_NO_NODE; + scheme->target_order =3D 0; return scheme; } =20 @@ -2645,6 +2653,40 @@ static ssize_t target_nid_store(struct kobject *kobj, return err ? err : count; } =20 +static ssize_t target_order_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct damon_sysfs_scheme *scheme =3D container_of(kobj, + struct damon_sysfs_scheme, kobj); + + return sysfs_emit(buf, "%u\n", scheme->target_order); +} + +static ssize_t target_order_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + struct damon_sysfs_scheme *scheme =3D container_of(kobj, + struct damon_sysfs_scheme, kobj); + unsigned int val; + int err; + + err =3D kstrtouint(buf, 0, &val); + if (err) + return err; + +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + /* Valid split targets: 0 (order-0 base pages) or 2..HPAGE_PMD_ORDER-1. */ + if (val !=3D 0 && (val < 2 || val >=3D HPAGE_PMD_ORDER)) + return -EINVAL; +#else + if (val !=3D 0) + return -EINVAL; +#endif + + scheme->target_order =3D val; + return count; +} + static void damon_sysfs_scheme_release(struct kobject *kobj) { kfree(container_of(kobj, struct damon_sysfs_scheme, kobj)); @@ -2659,10 +2701,14 @@ static struct kobj_attribute damon_sysfs_scheme_app= ly_interval_us_attr =3D static struct kobj_attribute damon_sysfs_scheme_target_nid_attr =3D __ATTR_RW_MODE(target_nid, 0600); =20 +static struct kobj_attribute damon_sysfs_scheme_target_order_attr =3D + __ATTR_RW_MODE(target_order, 0600); + static struct attribute *damon_sysfs_scheme_attrs[] =3D { &damon_sysfs_scheme_action_attr.attr, &damon_sysfs_scheme_apply_interval_us_attr.attr, &damon_sysfs_scheme_target_nid_attr.attr, + &damon_sysfs_scheme_target_order_attr.attr, NULL, }; ATTRIBUTE_GROUPS(damon_sysfs_scheme); @@ -3011,6 +3057,8 @@ static struct damos *damon_sysfs_mk_scheme( if (!scheme) return NULL; =20 + scheme->order =3D sysfs_scheme->target_order; + err =3D damos_sysfs_add_quota_score(sysfs_quotas->goals, &scheme->quota); if (err) { damon_destroy_scheme(scheme); diff --git a/tools/testing/selftests/damon/sysfs.py b/tools/testing/selftes= ts/damon/sysfs.py index 3ffa054b6386..49d3c319dfd8 100755 --- a/tools/testing/selftests/damon/sysfs.py +++ b/tools/testing/selftests/damon/sysfs.py @@ -131,11 +131,12 @@ def assert_scheme_committed(scheme, dump): 'hugepage': 3, 'nohugepage': 4, 'collapse': 5, - 'lru_prio': 6, - 'lru_deprio': 7, - 'migrate_hot': 8, - 'migrate_cold': 9, - 'stat': 10, + 'split': 6, + 'lru_prio': 7, + 'lru_deprio': 8, + 'migrate_hot': 9, + 'migrate_cold': 10, + 'stat': 11, } assert_true(dump['action'] =3D=3D action_val[scheme.action], 'action',= dump) assert_true(dump['apply_interval_us'] =3D=3D scheme. apply_interval_us, From nobody Sat Jul 25 03:20:31 2026 Received: from mail-pl1-f181.google.com (mail-pl1-f181.google.com [209.85.214.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 981E7233D9E for ; Mon, 20 Jul 2026 03:03:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784516636; cv=none; b=b8hy0C2AsbYT6p0YuFPRyUTa67RDsVZYgDbI4MNooIrOey9wrpIxz+mf4zX4Ii0zVGIctI5sWDEJhPo0NNrKxK06LSwcEFZwBsqDVFjtgIuJ96WCQW+oSYezhy7UJ4uYbBiovA4qDf3vJnm8c0EBEqx8giVU3V6upVgcunoRWuo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784516636; c=relaxed/simple; bh=nS+ihT8yiDs312RlqRcd39KPDyY9S4PRM4guYmebc9g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pcCnxUkv7DOJRy5CWOA3iz657Qqqbj0ucus79NaQcopzIflhQ+9p41IGEnwKcSyF0HmWGL4eB7z4DV2ziqjRclqLxIYvu6nVAkGJUCmmEsKYV3EtmfpOP+w4aF7H2REpijVIwksI29XAestZLUVWbaP3e/dH9kXhlbrn/o/senQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ZVuhkggL; arc=none smtp.client-ip=209.85.214.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ZVuhkggL" Received: by mail-pl1-f181.google.com with SMTP id d9443c01a7336-2cc891373e0so117080155ad.2 for ; Sun, 19 Jul 2026 20:03:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784516634; x=1785121434; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=X+CN3F8GNJ49+wMCUtm6B3zkpBPb78+r1IbCrOzeLVY=; b=ZVuhkggLQeTrrcQo7xuaVftVKlVfYYI5NrbIaDUVtEkotIODt39SjBSVg1t1K9PImy nWp3qHDKz4AxCDiMxvdLhW48mFZlf6xS5varigeAgoSNeLeILOQfDkWcUfHX5JTFhnf4 Jm0mLNnsbuxbAaOiDVI7MAQrhjNLB/HGnDIklSx43/0AGrZElQAXUtrRS5c0y7dx7VnW FyfREacoYQPgTFVtphHRyYFpjAUW2Vvqkv9HRhAerq9xLBwX119BonlZ3p4c0gs2KDsR 7GWXBWUYcOdPfQkIi4DEdSKGdmt/2zDA0V6SknulidkOfQevEQIOUmFZD9Sc6RJHYVAr ZUrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784516634; x=1785121434; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=X+CN3F8GNJ49+wMCUtm6B3zkpBPb78+r1IbCrOzeLVY=; b=gr7mTSGmj1l/JPtppVUOtDF7L8VUj70+aOWOQ7G0zUOSylsVYd0n6Zlp+lYHBtQDbO NXskOLgeV3YxGvBKVr9J0AIdz2bxdsFZT3wREg6gKegIt0GDTDyBcioiofSz3P3Y6Gc5 5LTW+HhmPidjj62FUVbSl+DeDV7i+uFGgEKUEWLsmA4EtY/sRkERR1J30ALEB2RZTJhG 0UsPJnPU0PYXqtmLXjpV2vEsNMdDY8QMxOd9OOAKeJH6ZzTNfJOdHDDTzE+ingWLlnyw A4UsVrnEQNMzD4+3GYdUFHvm1p+psqnOGoqNfMapj97aIltYSj34bNA/VmCPYaMKfD/o VRmw== X-Forwarded-Encrypted: i=1; AHgh+RrF2XWWcSdUyVdxM5FMnfsqWrCqdnItafVGZPWogK1Kyfl9TEmOQTqE2wKk6TvNWhrIY0TgvkfWMb2dJ6A=@vger.kernel.org X-Gm-Message-State: AOJu0Yw5kKIgk1JYP9Zre5Qnh/Ee/cNfcLjCnPNB28eZViiaDxNvbDDN N4PkYm5U5AZhV2Vn4z4sE3w+drT2vTUVKFeT006Qm892bpZyjNDOh5D5 X-Gm-Gg: AfdE7clDMCRHi43qra2SBRGgFf89SGHlWWwKC6ZDs3RpqmSlXqA3qjhtIytgyvshdR6 hjzRfXNMkdanlliMHAgVLTnrBvHsITtBgC9TobgKn7f9+QyabwQOTSAoD8waonR2gJhi1JDzx4U gKybs3LNJQ/TttU2k34DBTM1CTgqImH4XEkBA1ZFxbaptzyArmp+Pt9LpHXFEUrpg7+uiSU7qsY MB4DtiLe/vXMPo8MNbl2zx5MggmCD0sQfWpcDYF3xG+uRKHb9QqtHYsJp8KB6SwFVhz09J+9lt2 8cwQTDUGB/KP2uK9Hiq6jwIFcQwbXW+5lG3B41u/g4/mmDM4Xhlbl65ihnUl9nQetj/NAEVftfw nCR5Lk9gNL8QPWbeXe+CZrJHLyajZ+wqKmQPcLTeIlZ9A54hzS/WhGWbTIrHnrxqMy9QBZZUsri eXIfB6Xd5q18FD5wWh/4njsDhNh7U= X-Received: by 2002:a17:902:e54b:b0:2c9:b48c:fdec with SMTP id d9443c01a7336-2cf348547d0mr141397945ad.12.1784516633659; Sun, 19 Jul 2026 20:03:53 -0700 (PDT) Received: from localhost.localdomain ([112.65.87.25]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2cf344d80e6sm47783065ad.29.2026.07.19.20.03.46 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 19 Jul 2026 20:03:53 -0700 (PDT) From: Lian Wang To: damon@lists.linux.dev, linux-mm@kvack.org Cc: sj@kernel.org, akpm@linux-foundation.org, linux-kernel@vger.kernel.org, david@kernel.org, ljs@kernel.org, liam@infradead.org, vbabka@kernel.org, rppt@kernel.org, surenb@google.com, mhocko@suse.com, npache@redhat.com, ziy@nvidia.com, baolin.wang@linux.alibaba.com, ryan.roberts@arm.com, daichaobing@sangfor.com.cn, wangkefeng.wang@huawei.com, gutierrez.asier@huawei-partners.com, zengheng4@huawei.com, kasong@tencent.com, corbet@lwn.net, skhan@linuxfoundation.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, lianux.mm@gmail.com, lianux.wang@processmission.com, kunwu.chan@linux.dev Subject: [RFC PATCH v3 2/3] mm/damon/vaddr: implement DAMOS_SPLIT handler Date: Mon, 20 Jul 2026 11:03:26 +0800 Message-ID: <20260720030327.80153-3-lianux.mm@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260720030327.80153-1-lianux.mm@gmail.com> References: <20260720030327.80153-1-lianux.mm@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Implement DAMOS_SPLIT for the vaddr and fvaddr operations sets. For each large folio in the target region whose order exceeds the scheme's order, split it down using split_folio_to_order() -- the same helper used by truncation, migration, ksm and shmem. No new core-mm code or exported symbols are introduced. split_folio_to_order() must not run under the page table lock, so the folio is pinned (folio_trylock + folio_get), the walk is ended to drop the page table lock, and the split runs while holding only mmap_read_lock. The scheme's operations-layer filters are honoured, and the amount of memory that passed those filters is reported via sz_filter_passed. Co-developed-by: Kunwu Chan Signed-off-by: Kunwu Chan Signed-off-by: Lian Wang (Processmission) --- mm/damon/vaddr.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/mm/damon/vaddr.c b/mm/damon/vaddr.c index d10b8042adb5..a8607448584d 100644 --- a/mm/damon/vaddr.c +++ b/mm/damon/vaddr.c @@ -6,6 +6,7 @@ #define pr_fmt(fmt) "damon-va: " fmt =20 #include +#include #include #include #include @@ -896,6 +897,111 @@ static unsigned long damos_va_stat(struct damon_targe= t *target, return 0; } =20 +/* + * damos_va_split() - Split large folios in a region down to @target_order + * using the existing split_folio_to_order(). + * + * Locking: folio_walk_start() returns the folio with the page table lock + * held. split_folio_to_order() must not run under the page table lock, + * so we pin the folio (reference + lock), end the walk to drop the page + * table lock, and split while holding only mmap_read_lock. + * split_folio_to_order() returns -EBUSY for a raced or pinned folio; + * we skip such folios. + */ +static unsigned long damos_va_split(struct damon_target *target, + struct damon_region *r, struct damos *s, + unsigned long *sz_filter_passed) +{ + unsigned int target_order =3D s->order; + unsigned long addr =3D ALIGN_DOWN(r->ar.start, PAGE_SIZE); + unsigned long end =3D r->ar.end; + unsigned long applied =3D 0; + struct mm_struct *mm; + + mm =3D damon_get_mm(target); + if (!mm) + return 0; + + while (addr < end) { + struct vm_area_struct *vma; + struct folio *folio; + struct folio_walk fw; + unsigned long folio_sz =3D 0; + + if (mmap_read_lock_killable(mm)) + break; + + vma =3D vma_lookup(mm, addr); + if (!vma) { + /* Skip the gap to the next VMA, if any. */ + vma =3D find_vma(mm, addr); + mmap_read_unlock(mm); + if (!vma || vma->vm_start >=3D end) + break; + addr =3D vma->vm_start; + continue; + } + + /* Folios in these VMAs are not our business. */ + if (vma->vm_flags & (VM_HUGETLB | VM_MIXEDMAP)) { + addr =3D vma->vm_end; + mmap_read_unlock(mm); + continue; + } + + folio =3D folio_walk_start(&fw, vma, addr, 0); + if (!folio) { + mmap_read_unlock(mm); + addr +=3D PAGE_SIZE; + continue; + } + + folio_sz =3D folio_size(folio); + + /* + * For file-backed folios, @target_order may be below the + * filesystem's minimum folio order (mapping_min_folio_order()). + * split_folio_to_order() will simply fail in that case and + * we skip the folio. This is a safe no-op; future work can + * adjust target_order upward like split_huge_pages_in_pid() + * does when a specific filesystem needs it. + */ + + /* Honour the scheme's operations-layer filters. */ + if (damos_ops_has_filter(s)) { + if (damos_va_filter_out(s, folio, vma, addr, + fw.level =3D=3D FW_LEVEL_PTE ? fw.ptep : NULL, + fw.level =3D=3D FW_LEVEL_PMD ? fw.pmdp : NULL)) { + folio_walk_end(&fw, vma); + mmap_read_unlock(mm); + goto next; + } + *sz_filter_passed +=3D folio_sz; + } + + if (folio_order(folio) > target_order && folio_trylock(folio)) { + folio_get(folio); + /* Drop the page table lock before splitting. */ + folio_walk_end(&fw, vma); + + if (!split_folio_to_order(folio, target_order)) + applied +=3D folio_sz; + + folio_unlock(folio); + folio_put(folio); + } else { + folio_walk_end(&fw, vma); + } + mmap_read_unlock(mm); +next: + addr =3D ALIGN_DOWN(addr, folio_sz) + folio_sz; + cond_resched(); + } + + mmput(mm); + return applied; +} + static unsigned long damon_va_apply_scheme(struct damon_ctx *ctx, struct damon_target *t, struct damon_region *r, struct damos *scheme, unsigned long *sz_filter_passed) @@ -926,6 +1032,8 @@ static unsigned long damon_va_apply_scheme(struct damo= n_ctx *ctx, return damos_va_migrate(t, r, scheme, sz_filter_passed); case DAMOS_STAT: return damos_va_stat(t, r, scheme, sz_filter_passed); + case DAMOS_SPLIT: + return damos_va_split(t, r, scheme, sz_filter_passed); default: /* * DAMOS actions that are not yet supported by 'vaddr'. From nobody Sat Jul 25 03:20:31 2026 Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2EC85388899 for ; Mon, 20 Jul 2026 03:04:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784516644; cv=none; b=cnKg0VcQvxRQ2qgo14Q+5X+b1fvPdiEA/5FfclyXp/+38/ErByftfVlM8KMRY16xGQgfrXN8K6Y/2SiPcRaxlt1v2pr2LD6GpIycF97+NeGN/7kVYEgiJTIJYtiz1GNm2qONwtiWTQ9bm1qPl2O1NAQ0g82GCtDnvBveqs1rxlw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784516644; c=relaxed/simple; bh=YLKc+POCNITKfz5Zq68JdFxIzpDDqljeDs2WwwuKzhM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ITOqTlAHtO6qfmfY9PIQXUKZhqWUScU9Wen41IfrXgbVItUbnkfQbZWwyDSVVTk4WTDuh1FI+sI1SsDkUB/08FlVzDfGycyUMDak3ZQAo49H8+EFyer71Dap05DhMizo2CMPhTLiIy9uF+C2bbZtcMv+u56FNaECtrpfeMYCro8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=HrLK/q8P; arc=none smtp.client-ip=209.85.214.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="HrLK/q8P" Received: by mail-pl1-f175.google.com with SMTP id d9443c01a7336-2cad4170e8eso129901625ad.3 for ; Sun, 19 Jul 2026 20:04:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784516641; x=1785121441; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Zbv8c6XPjklVCkXRSa81M3HIzY/Ff3msBnn5ibeFm/4=; b=HrLK/q8PRfkyVvzkhP3WYDphKKdTqg+kPAESMle/XLoss56Fq/z/JhH8oip4g7opsW X17Va7UNupTcCsqjhvGTvSa8ZQR0XKfTOCJmMOPxpX9jU+vSrAJqgejtGvA+Dgl6DAaC j9RN4JM2H2MboYy6bONjPodBLX7O2QEpSDY4DqzC+3Zl0hD2ERoNZNjJQ3+9GnbP+ZM4 UzOQ3JTfdySNdnp5Z0fuecsMGVkA8aQCKlASegbbmEoGashAEEeN/BSLTB4V1HPQpxA0 Dap/tGMKdb/qlhpOaypm6ADn8pGxx/aDeMH85CqSaDqJCWUY1gi2/mlMAnrBdPT+CsWn sbeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784516641; x=1785121441; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Zbv8c6XPjklVCkXRSa81M3HIzY/Ff3msBnn5ibeFm/4=; b=kBueEQyHIZY3g2V45/DJYzbmcMM28WHwK8fzjCu/bzlnCYZWdwYcaYhj+8Iett/srM szta9ykwG0bYVLxMSiEegmXE7prwESOC+2qGgt7/RFlVLioZgqRH0gMwbyTtAfB1GxIq /lLJ1R5zZ9gjd2Blyt4zGEVK+ramRQbAwbGywpEmESaLPX3t902/80YmaEOQvF9hDXTv +TvSoDbb+4xalsbHDW/DXw3A3spQk5rkjxkXA37v/liy9dusF6/Q85rCjXaE9YnscFqQ k9Ebtuzn24Kto3RI7OgBBuo4p0CJzojIfM3PZrZRdUNByKUhwAjF099fE9EYkS9moHMD CVfQ== X-Forwarded-Encrypted: i=1; AHgh+RpRQpHeBtDHUpD/x/x40Ec0INFVVNWYNYYZ799soCGgTgZhifxYsM1jJCEk7ulw1xQizyVy6cGpzIoODPM=@vger.kernel.org X-Gm-Message-State: AOJu0Yza34CqqekM07ZvPak/whbmCgJmyr4i1JYi7+dAeyTxAqYyzBfw 06Fyy4Pb0WY6N704+ijMVq5bz8MCD+dfh+ZBd0+gvONaNvKlZtJ1fbbU X-Gm-Gg: AfdE7cmol1RT2WmRALriifDrTPa501YpefGv0No9uqsmTtcHwjdJJLJBL8uhE7u9I6+ m5udhaFn49qaik0SScp+1xLf8TP0rZKQl2ntH1eW/oJDoGCbIToQDQ7ziXhcy5dAC/4EOWs88Jp zLh/5ha9FxsvtpA1lwx3Wc7ecQGyaNk0VLiZOHiz5piP3CwavDqwPjfjEJY4+aL93cs9XCrOc0D 2BjTU/nt+4Mu89xA1QuB5L7wS9z/SAbTQIImBWePV95gP4/pqteOWIu7r//N26yMtryHnA3W3Qo Jv2+9Crw0p2IXjcUIcCZPXnRnZmSWZtiLGlZ6Q8ceXg8GIep2CbqnSjhBlEk6SmXg6pFFlnTIta iypARhsK5b2H4J7WLPxlDxJn/iSK5lz/gpaPk3CCnuZsFnlethK9VA3YUyg6rWTPTfM/w1R14GJ BC8eAg14a01Wi4cNJ3XBhAuMVwhYU= X-Received: by 2002:a17:902:d4cc:b0:2c9:e9db:8167 with SMTP id d9443c01a7336-2cf348193f5mr133308615ad.7.1784516641437; Sun, 19 Jul 2026 20:04:01 -0700 (PDT) Received: from localhost.localdomain ([112.65.87.25]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2cf344d80e6sm47783065ad.29.2026.07.19.20.03.54 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 19 Jul 2026 20:04:01 -0700 (PDT) From: Lian Wang To: damon@lists.linux.dev, linux-mm@kvack.org Cc: sj@kernel.org, akpm@linux-foundation.org, linux-kernel@vger.kernel.org, david@kernel.org, ljs@kernel.org, liam@infradead.org, vbabka@kernel.org, rppt@kernel.org, surenb@google.com, mhocko@suse.com, npache@redhat.com, ziy@nvidia.com, baolin.wang@linux.alibaba.com, ryan.roberts@arm.com, daichaobing@sangfor.com.cn, wangkefeng.wang@huawei.com, gutierrez.asier@huawei-partners.com, zengheng4@huawei.com, kasong@tencent.com, corbet@lwn.net, skhan@linuxfoundation.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, lianux.mm@gmail.com, lianux.wang@processmission.com, kunwu.chan@linux.dev Subject: [RFC PATCH v3 3/3] selftests/damon: add functional test for DAMOS_SPLIT Date: Mon, 20 Jul 2026 11:03:27 +0800 Message-ID: <20260720030327.80153-4-lianux.mm@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260720030327.80153-1-lianux.mm@gmail.com> References: <20260720030327.80153-1-lianux.mm@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add damos_split.py, which allocates a MADV_HUGEPAGE-backed region in a child process and runs a DAMON/DAMOS scheme with action 'split' and target_order 0 against it, then verifies the huge pages are split into base pages (the child's AnonHugePages drops). Extend the _damon_sysfs.py Damos helper with the target_order parameter so a scheme's split target can be expressed. Co-developed-by: Kunwu Chan Signed-off-by: Kunwu Chan Signed-off-by: Lian Wang (Processmission) --- tools/testing/selftests/damon/Makefile | 1 + tools/testing/selftests/damon/_damon_sysfs.py | 9 +- tools/testing/selftests/damon/damos_split.py | 125 ++++++++++++++++++ 3 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/damon/damos_split.py diff --git a/tools/testing/selftests/damon/Makefile b/tools/testing/selftes= ts/damon/Makefile index ece244e5c5b9..a623c271355f 100644 --- a/tools/testing/selftests/damon/Makefile +++ b/tools/testing/selftests/damon/Makefile @@ -12,6 +12,7 @@ TEST_PROGS +=3D sysfs.sh TEST_PROGS +=3D sysfs.py TEST_PROGS +=3D sysfs_update_schemes_tried_regions_wss_estimation.py TEST_PROGS +=3D damos_quota.py damos_quota_goal.py damos_apply_interval.py +TEST_PROGS +=3D damos_split.py TEST_PROGS +=3D damos_tried_regions.py damon_nr_regions.py TEST_PROGS +=3D sysfs_refresh.py TEST_PROGS +=3D reclaim.sh lru_sort.sh diff --git a/tools/testing/selftests/damon/_damon_sysfs.py b/tools/testing/= selftests/damon/_damon_sysfs.py index e6a2265d721e..5a01f31ad9f2 100644 --- a/tools/testing/selftests/damon/_damon_sysfs.py +++ b/tools/testing/selftests/damon/_damon_sysfs.py @@ -419,6 +419,7 @@ class Damos: filters =3D None apply_interval_us =3D None target_nid =3D None + target_order =3D None dests =3D None idx =3D None context =3D None @@ -429,7 +430,7 @@ class Damos: def __init__(self, action=3D'stat', access_pattern=3DDamosAccessPatter= n(), quota=3DDamosQuota(), watermarks=3DDamosWatermarks(), core_filters=3D[], ops_filters=3D[], filters=3D[], target= _nid=3D0, - dests=3DDamosDests(), apply_interval_us=3D0): + target_order=3D0, dests=3DDamosDests(), apply_interval_us= =3D0): self.action =3D action self.access_pattern =3D access_pattern self.access_pattern.scheme =3D self @@ -448,6 +449,7 @@ class Damos: self.filters.scheme =3D self =20 self.target_nid =3D target_nid + self.target_order =3D target_order self.dests =3D dests self.dests.scheme =3D self =20 @@ -492,6 +494,11 @@ class Damos: if err is not None: return err =20 + err =3D write_file(os.path.join(self.sysfs_dir(), 'target_order'),= '%d' % + self.target_order) + if err is not None: + return err + err =3D self.dests.stage() if err is not None: return err diff --git a/tools/testing/selftests/damon/damos_split.py b/tools/testing/s= elftests/damon/damos_split.py new file mode 100644 index 000000000000..089fbe0f0d4d --- /dev/null +++ b/tools/testing/selftests/damon/damos_split.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 +# +# Functional test for the DAMOS_SPLIT action. +# +# A child process allocates a MADV_HUGEPAGE-backed anonymous region and +# faults it in so that it is backed by (m)THPs. The parent then runs a +# DAMON/DAMOS scheme with action 'split' and target_order 0 against the +# child and checks that the huge pages are split into base pages, i.e. the +# child's AnonHugePages (as reported by /proc//smaps) drops. + +import ctypes +import os +import signal +import sys +import time + +import _damon_sysfs + +PMD_SIZE =3D 2 * 1024 * 1024 +MADV_HUGEPAGE =3D 14 +PROT_READ_WRITE =3D 0x1 | 0x2 +MAP_PRIVATE_ANON =3D 0x2 | 0x20 +REGION_SIZE =3D 32 * PMD_SIZE + +def child_workload(): + '''Allocate a PMD-aligned, THP-backed region, fault it in, then idle.'= '' + libc =3D ctypes.CDLL('libc.so.6', use_errno=3DTrue) + libc.mmap.restype =3D ctypes.c_void_p + libc.mmap.argtypes =3D [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_int, + ctypes.c_int, ctypes.c_int, ctypes.c_long] + libc.madvise.argtypes =3D [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_= int] + + # Over-allocate so that a PMD-aligned window is available. + raw =3D libc.mmap(None, REGION_SIZE + PMD_SIZE, PROT_READ_WRITE, + MAP_PRIVATE_ANON, -1, 0) + if raw is None or raw =3D=3D ctypes.c_void_p(-1).value: + os._exit(2) + base =3D (raw + PMD_SIZE - 1) & ~(PMD_SIZE - 1) + libc.madvise(ctypes.c_void_p(base), REGION_SIZE, MADV_HUGEPAGE) + + buf =3D (ctypes.c_char * REGION_SIZE).from_address(base) + for off in range(0, REGION_SIZE, 4096): + buf[off] =3D 1 + + # Ready; idle until the parent tears us down. + signal.pause() + +def anon_huge_kb(pid): + total =3D 0 + try: + with open('/proc/%d/smaps' % pid) as f: + for line in f: + if line.startswith('AnonHugePages:'): + total +=3D int(line.split()[1]) + except FileNotFoundError: + return -1 + return total + +def main(): + if not os.path.exists('/sys/kernel/mm/transparent_hugepage/enabled'): + print('SKIP: transparent hugepage is not available') + exit(0) + + pid =3D os.fork() + if pid =3D=3D 0: + child_workload() + os._exit(0) + + try: + # Give the child time to fault in its huge pages. + time.sleep(2) + before =3D anon_huge_kb(pid) + if before <=3D 0: + print('SKIP: workload did not get any THP (AnonHugePages=3D%d)' + % before) + os.kill(pid, signal.SIGKILL) + exit(0) + + # Split every large folio in the target down to order-0 base pages. + kdamonds =3D _damon_sysfs.Kdamonds([_damon_sysfs.Kdamond( + contexts=3D[_damon_sysfs.DamonCtx( + ops=3D'vaddr', + targets=3D[_damon_sysfs.DamonTarget(pid=3Dpid)], + schemes=3D[_damon_sysfs.Damos( + action=3D'split', + target_order=3D0, + # match every region regardless of access/age/size, so + # the ARM64 stale-TLB blind spot cannot mask the target + access_pattern=3D_damon_sysfs.DamosAccessPattern( + size=3D[0, 2**64 - 1], + nr_accesses=3D[0, 2**64 - 1], + age=3D[0, 2**64 - 1]), + apply_interval_us=3D0)])])]) + err =3D kdamonds.start() + if err is not None: + print('kdamonds start failed: %s' % err) + os.kill(pid, signal.SIGKILL) + exit(1) + + # Let the scheme find and split the regions. + after =3D before + for _ in range(50): + time.sleep(0.2) + after =3D anon_huge_kb(pid) + if after =3D=3D 0: + break + + kdamonds.stop() + os.kill(pid, signal.SIGKILL) + + if after >=3D before: + print('FAIL: AnonHugePages did not shrink: before=3D%d KiB ' + 'after=3D%d KiB' % (before, after)) + exit(1) + print('PASS: AnonHugePages %d KiB -> %d KiB after DAMOS_SPLIT' + % (before, after)) + finally: + try: + os.kill(pid, signal.SIGKILL) + except ProcessLookupError: + pass + +if __name__ =3D=3D '__main__': + main()