Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm/damon/sysfs-schemes: add target_nid on sysfs-schemes

This patch adds target_nid under
/sys/kernel/mm/damon/admin/kdamonds/<N>/contexts/<N>/schemes/<N>/

The 'target_nid' can be used as the destination node for DAMOS actions
such as DAMOS_MIGRATE_{HOT,COLD} in the follow up patches.

[sj@kernel.org: document target_nid file]
Link: https://lkml.kernel.org/r/20240618213630.84846-3-sj@kernel.org
Link: https://lkml.kernel.org/r/20240614030010.751-4-honggyu.kim@sk.com
Signed-off-by: Hyeongtak Ji <hyeongtak.ji@sk.com>
Signed-off-by: Honggyu Kim <honggyu.kim@sk.com>
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Gregory Price <gregory.price@memverge.com>
Cc: Hyeonggon Yoo <42.hyeyoo@gmail.com>
Cc: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Rakie Kim <rakie.kim@sk.com>
Cc: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Hyeongtak Ji and committed by
Andrew Morton
e36287c6 8f75267d

+57 -6
+6
Documentation/ABI/testing/sysfs-kernel-mm-damon
··· 155 155 Description: Writing to and reading from this file sets and gets the action 156 156 of the scheme. 157 157 158 + What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/target_nid 159 + Date: Jun 2024 160 + Contact: SeongJae Park <sj@kernel.org> 161 + Description: Action's target NUMA node id. Supported by only relevant 162 + actions. 163 + 158 164 What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/apply_interval_us 159 165 Date: Sep 2023 160 166 Contact: SeongJae Park <sj@kernel.org>
+10 -1
include/linux/damon.h
··· 374 374 * @apply_interval_us: The time between applying the @action. 375 375 * @quota: Control the aggressiveness of this scheme. 376 376 * @wmarks: Watermarks for automated (in)activation of this scheme. 377 + * @target_nid: Destination node if @action is "migrate_{hot,cold}". 377 378 * @filters: Additional set of &struct damos_filter for &action. 378 379 * @stat: Statistics of this scheme. 379 380 * @list: List head for siblings. ··· 389 388 * system situations using &wmarks. If all schemes that registered to the 390 389 * monitoring context are inactive, DAMON stops monitoring either, and just 391 390 * repeatedly checks the watermarks. 391 + * 392 + * @target_nid is used to set the migration target node for migrate_hot or 393 + * migrate_cold actions, which means it's only meaningful when @action is either 394 + * "migrate_hot" or "migrate_cold". 392 395 * 393 396 * Before applying the &action to a memory region, &struct damon_operations 394 397 * implementation could check pages of the region and skip &action to respect ··· 415 410 /* public: */ 416 411 struct damos_quota quota; 417 412 struct damos_watermarks wmarks; 413 + union { 414 + int target_nid; 415 + }; 418 416 struct list_head filters; 419 417 struct damos_stat stat; 420 418 struct list_head list; ··· 734 726 enum damos_action action, 735 727 unsigned long apply_interval_us, 736 728 struct damos_quota *quota, 737 - struct damos_watermarks *wmarks); 729 + struct damos_watermarks *wmarks, 730 + int target_nid); 738 731 void damon_add_scheme(struct damon_ctx *ctx, struct damos *s); 739 732 void damon_destroy_scheme(struct damos *s); 740 733
+4 -1
mm/damon/core.c
··· 354 354 enum damos_action action, 355 355 unsigned long apply_interval_us, 356 356 struct damos_quota *quota, 357 - struct damos_watermarks *wmarks) 357 + struct damos_watermarks *wmarks, 358 + int target_nid) 358 359 { 359 360 struct damos *scheme; 360 361 ··· 381 380 382 381 scheme->wmarks = *wmarks; 383 382 scheme->wmarks.activated = true; 383 + 384 + scheme->target_nid = target_nid; 384 385 385 386 return scheme; 386 387 }
+1 -1
mm/damon/dbgfs.c
··· 281 281 282 282 pos += parsed; 283 283 scheme = damon_new_scheme(&pattern, action, 0, &quota, 284 - &wmarks); 284 + &wmarks, NUMA_NO_NODE); 285 285 if (!scheme) 286 286 goto fail; 287 287
+2 -1
mm/damon/lru_sort.c
··· 163 163 /* under the quota. */ 164 164 &quota, 165 165 /* (De)activate this according to the watermarks. */ 166 - &damon_lru_sort_wmarks); 166 + &damon_lru_sort_wmarks, 167 + NUMA_NO_NODE); 167 168 } 168 169 169 170 /* Create a DAMON-based operation scheme for hot memory regions */
+2 -1
mm/damon/reclaim.c
··· 177 177 /* under the quota. */ 178 178 &damon_reclaim_quota, 179 179 /* (De)activate this according to the watermarks. */ 180 - &damon_reclaim_wmarks); 180 + &damon_reclaim_wmarks, 181 + NUMA_NO_NODE); 181 182 } 182 183 183 184 static void damon_reclaim_copy_quota_status(struct damos_quota *dst,
+32 -1
mm/damon/sysfs-schemes.c
··· 6 6 */ 7 7 8 8 #include <linux/slab.h> 9 + #include <linux/numa.h> 9 10 10 11 #include "sysfs-common.h" 11 12 ··· 1446 1445 struct damon_sysfs_scheme_filters *filters; 1447 1446 struct damon_sysfs_stats *stats; 1448 1447 struct damon_sysfs_scheme_regions *tried_regions; 1448 + int target_nid; 1449 1449 }; 1450 1450 1451 1451 /* This should match with enum damos_action */ ··· 1472 1470 scheme->kobj = (struct kobject){}; 1473 1471 scheme->action = action; 1474 1472 scheme->apply_interval_us = apply_interval_us; 1473 + scheme->target_nid = NUMA_NO_NODE; 1475 1474 return scheme; 1476 1475 } 1477 1476 ··· 1695 1692 return err ? err : count; 1696 1693 } 1697 1694 1695 + static ssize_t target_nid_show(struct kobject *kobj, 1696 + struct kobj_attribute *attr, char *buf) 1697 + { 1698 + struct damon_sysfs_scheme *scheme = container_of(kobj, 1699 + struct damon_sysfs_scheme, kobj); 1700 + 1701 + return sysfs_emit(buf, "%d\n", scheme->target_nid); 1702 + } 1703 + 1704 + static ssize_t target_nid_store(struct kobject *kobj, 1705 + struct kobj_attribute *attr, const char *buf, size_t count) 1706 + { 1707 + struct damon_sysfs_scheme *scheme = container_of(kobj, 1708 + struct damon_sysfs_scheme, kobj); 1709 + int err = 0; 1710 + 1711 + /* TODO: error handling for target_nid range. */ 1712 + err = kstrtoint(buf, 0, &scheme->target_nid); 1713 + 1714 + return err ? err : count; 1715 + } 1716 + 1698 1717 static void damon_sysfs_scheme_release(struct kobject *kobj) 1699 1718 { 1700 1719 kfree(container_of(kobj, struct damon_sysfs_scheme, kobj)); ··· 1728 1703 static struct kobj_attribute damon_sysfs_scheme_apply_interval_us_attr = 1729 1704 __ATTR_RW_MODE(apply_interval_us, 0600); 1730 1705 1706 + static struct kobj_attribute damon_sysfs_scheme_target_nid_attr = 1707 + __ATTR_RW_MODE(target_nid, 0600); 1708 + 1731 1709 static struct attribute *damon_sysfs_scheme_attrs[] = { 1732 1710 &damon_sysfs_scheme_action_attr.attr, 1733 1711 &damon_sysfs_scheme_apply_interval_us_attr.attr, 1712 + &damon_sysfs_scheme_target_nid_attr.attr, 1734 1713 NULL, 1735 1714 }; 1736 1715 ATTRIBUTE_GROUPS(damon_sysfs_scheme); ··· 2060 2031 }; 2061 2032 2062 2033 scheme = damon_new_scheme(&pattern, sysfs_scheme->action, 2063 - sysfs_scheme->apply_interval_us, &quota, &wmarks); 2034 + sysfs_scheme->apply_interval_us, &quota, &wmarks, 2035 + sysfs_scheme->target_nid); 2064 2036 if (!scheme) 2065 2037 return NULL; 2066 2038 ··· 2098 2068 2099 2069 scheme->action = sysfs_scheme->action; 2100 2070 scheme->apply_interval_us = sysfs_scheme->apply_interval_us; 2071 + scheme->target_nid = sysfs_scheme->target_nid; 2101 2072 2102 2073 scheme->quota.ms = sysfs_quotas->ms; 2103 2074 scheme->quota.sz = sysfs_quotas->sz;