From: Ravi Jonnalagadda <ravis.opensrc@gmail.com>
To: sj@kernel.org, akinobu.mita@gmail.com, damon@lists.linux.dev,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
linux-doc@vger.kernel.org
Cc: akpm@linux-foundation.org, corbet@lwn.net, bijan311@gmail.com,
ajayjoshi@micron.com, honggyu.kim@sk.com, yunjeong.mun@sk.com,
ravis.opensrc@gmail.com
Subject: [RFC PATCH 2/6] mm/damon/sysfs-sample: expose perf_events configuration via sysfs
Date: Fri, 29 May 2026 09:56:36 -0700 [thread overview]
Message-ID: <20260529165640.820-3-ravis.opensrc@gmail.com> (raw)
In-Reply-To: <20260529165640.820-1-ravis.opensrc@gmail.com>
Add a perf_events/ subdirectory under each context's sample/ directory.
Each numbered entry maps to one damon_perf_event and exposes its raw
PMU attr, addressing flags, and period/delivery knobs.
Defaults match Intel PEBS L3-miss; userspace overrides them for other
PMUs. sample_weight_struct defaults off because PMUs that do not
advertise PERF_SAMPLE_WEIGHT_STRUCT (e.g. AMD IBS Op) reject events
that request it with -EOPNOTSUPP.
Signed-off-by: Ravi Jonnalagadda <ravis.opensrc@gmail.com>
---
mm/damon/sysfs-sample.c | 579 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 579 insertions(+)
diff --git a/mm/damon/sysfs-sample.c b/mm/damon/sysfs-sample.c
index ffc9c85455474..0570d27a47b1c 100644
--- a/mm/damon/sysfs-sample.c
+++ b/mm/damon/sysfs-sample.c
@@ -452,6 +452,520 @@ static const struct kobj_type damon_sysfs_primitives_ktype = {
.default_groups = damon_sysfs_primitives_groups,
};
+/*
+ * perf_event_attr directory
+ */
+
+struct damon_sysfs_perf_event_attr {
+ struct kobject kobj;
+ u32 type;
+ u64 config;
+ u64 config1;
+ u64 config2;
+ bool sample_phys_addr;
+ bool sample_weight_struct;
+ bool exclude_kernel;
+ bool exclude_hv;
+ bool freq;
+ u64 sample_freq;
+ u64 sample_period;
+ u32 wakeup_events;
+ u32 precise_ip;
+};
+
+static struct damon_sysfs_perf_event_attr *
+damon_sysfs_perf_event_attr_alloc(void)
+{
+ struct damon_sysfs_perf_event_attr *attr =
+ kzalloc(sizeof(*attr), GFP_KERNEL);
+
+ if (!attr)
+ return NULL;
+ attr->wakeup_events = 1;
+ attr->precise_ip = 2;
+ attr->freq = true;
+ attr->exclude_kernel = true;
+ attr->exclude_hv = true;
+ return attr;
+}
+
+static ssize_t attr_type_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+
+ return sysfs_emit(buf, "0x%x\n", perf_event_attr->type);
+}
+
+static ssize_t attr_type_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+ int err = kstrtou32(buf, 0, &perf_event_attr->type);
+
+ if (err)
+ return -EINVAL;
+ return count;
+}
+
+static ssize_t config_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+
+ return sysfs_emit(buf, "0x%llx\n", perf_event_attr->config);
+}
+
+static ssize_t config_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+ int err = kstrtou64(buf, 0, &perf_event_attr->config);
+
+ if (err)
+ return -EINVAL;
+ return count;
+}
+
+static ssize_t config1_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+
+ return sysfs_emit(buf, "0x%llx\n", perf_event_attr->config1);
+}
+
+static ssize_t config1_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+ int err = kstrtou64(buf, 0, &perf_event_attr->config1);
+
+ if (err)
+ return -EINVAL;
+ return count;
+}
+
+static ssize_t config2_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+
+ return sysfs_emit(buf, "0x%llx\n", perf_event_attr->config2);
+}
+
+static ssize_t config2_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+ int err = kstrtou64(buf, 0, &perf_event_attr->config2);
+
+ if (err)
+ return -EINVAL;
+ return count;
+}
+
+static ssize_t sample_phys_addr_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+
+ return sysfs_emit(buf, "%d\n", perf_event_attr->sample_phys_addr);
+}
+
+static ssize_t sample_phys_addr_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+ bool sample_phys_addr;
+ int err = kstrtobool(buf, &sample_phys_addr);
+
+ if (err)
+ return -EINVAL;
+
+ perf_event_attr->sample_phys_addr = sample_phys_addr;
+ return count;
+}
+
+static ssize_t sample_weight_struct_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+
+ return sysfs_emit(buf, "%d\n", perf_event_attr->sample_weight_struct);
+}
+
+static ssize_t sample_weight_struct_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+ bool sample_weight_struct;
+ int err = kstrtobool(buf, &sample_weight_struct);
+
+ if (err)
+ return -EINVAL;
+
+ perf_event_attr->sample_weight_struct = sample_weight_struct;
+ return count;
+}
+
+static ssize_t sample_freq_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+
+ return sysfs_emit(buf, "%llu\n", perf_event_attr->sample_freq);
+}
+
+static ssize_t sample_freq_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+ int err = kstrtou64(buf, 0, &perf_event_attr->sample_freq);
+
+ if (err)
+ return -EINVAL;
+ return count;
+}
+
+static ssize_t wakeup_events_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+
+ return sysfs_emit(buf, "%u\n", perf_event_attr->wakeup_events);
+}
+
+static ssize_t wakeup_events_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+ int err = kstrtou32(buf, 0, &perf_event_attr->wakeup_events);
+
+ if (err)
+ return -EINVAL;
+ return count;
+}
+
+static ssize_t precise_ip_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+
+ return sysfs_emit(buf, "%u\n", perf_event_attr->precise_ip);
+}
+
+static ssize_t precise_ip_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+ int err = kstrtou32(buf, 0, &perf_event_attr->precise_ip);
+
+ if (err)
+ return -EINVAL;
+ return count;
+}
+
+static ssize_t freq_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+
+ return sysfs_emit(buf, "%d\n", perf_event_attr->freq);
+}
+
+static ssize_t freq_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+ bool freq;
+ int err = kstrtobool(buf, &freq);
+
+ if (err)
+ return -EINVAL;
+ perf_event_attr->freq = freq;
+ return count;
+}
+
+static ssize_t sample_period_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+
+ return sysfs_emit(buf, "%llu\n", perf_event_attr->sample_period);
+}
+
+static ssize_t sample_period_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+ int err = kstrtou64(buf, 0, &perf_event_attr->sample_period);
+
+ if (err)
+ return -EINVAL;
+ return count;
+}
+
+static ssize_t exclude_kernel_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+
+ return sysfs_emit(buf, "%d\n", perf_event_attr->exclude_kernel);
+}
+
+static ssize_t exclude_kernel_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+ bool v;
+ int err = kstrtobool(buf, &v);
+
+ if (err)
+ return -EINVAL;
+ perf_event_attr->exclude_kernel = v;
+ return count;
+}
+
+static ssize_t exclude_hv_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+
+ return sysfs_emit(buf, "%d\n", perf_event_attr->exclude_hv);
+}
+
+static ssize_t exclude_hv_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_perf_event_attr *perf_event_attr = container_of(kobj,
+ struct damon_sysfs_perf_event_attr, kobj);
+ bool v;
+ int err = kstrtobool(buf, &v);
+
+ if (err)
+ return -EINVAL;
+ perf_event_attr->exclude_hv = v;
+ return count;
+}
+
+static void damon_sysfs_perf_event_attr_release(struct kobject *kobj)
+{
+ kfree(container_of(kobj, struct damon_sysfs_perf_event_attr, kobj));
+}
+
+static struct kobj_attribute damon_sysfs_perf_event_attr_type_attr =
+ __ATTR(type, 0600, attr_type_show, attr_type_store);
+
+static struct kobj_attribute damon_sysfs_perf_event_attr_config_attr =
+ __ATTR_RW_MODE(config, 0600);
+
+static struct kobj_attribute damon_sysfs_perf_event_attr_config1_attr =
+ __ATTR_RW_MODE(config1, 0600);
+
+static struct kobj_attribute damon_sysfs_perf_event_attr_config2_attr =
+ __ATTR_RW_MODE(config2, 0600);
+
+static struct kobj_attribute damon_sysfs_perf_event_attr_sample_phys_addr_attr =
+ __ATTR_RW_MODE(sample_phys_addr, 0600);
+
+static struct kobj_attribute
+ damon_sysfs_perf_event_attr_sample_weight_struct_attr =
+ __ATTR_RW_MODE(sample_weight_struct, 0600);
+
+static struct kobj_attribute damon_sysfs_perf_event_attr_sample_freq_attr =
+ __ATTR_RW_MODE(sample_freq, 0600);
+
+static struct kobj_attribute damon_sysfs_perf_event_attr_wakeup_events_attr =
+ __ATTR_RW_MODE(wakeup_events, 0600);
+
+static struct kobj_attribute damon_sysfs_perf_event_attr_precise_ip_attr =
+ __ATTR_RW_MODE(precise_ip, 0600);
+
+static struct kobj_attribute damon_sysfs_perf_event_attr_freq_attr =
+ __ATTR_RW_MODE(freq, 0600);
+
+static struct kobj_attribute damon_sysfs_perf_event_attr_sample_period_attr =
+ __ATTR_RW_MODE(sample_period, 0600);
+
+static struct kobj_attribute damon_sysfs_perf_event_attr_exclude_kernel_attr =
+ __ATTR_RW_MODE(exclude_kernel, 0600);
+
+static struct kobj_attribute damon_sysfs_perf_event_attr_exclude_hv_attr =
+ __ATTR_RW_MODE(exclude_hv, 0600);
+
+static struct attribute *damon_sysfs_perf_event_attr_attrs[] = {
+ &damon_sysfs_perf_event_attr_type_attr.attr,
+ &damon_sysfs_perf_event_attr_config_attr.attr,
+ &damon_sysfs_perf_event_attr_config1_attr.attr,
+ &damon_sysfs_perf_event_attr_config2_attr.attr,
+ &damon_sysfs_perf_event_attr_sample_phys_addr_attr.attr,
+ &damon_sysfs_perf_event_attr_sample_weight_struct_attr.attr,
+ &damon_sysfs_perf_event_attr_freq_attr.attr,
+ &damon_sysfs_perf_event_attr_sample_freq_attr.attr,
+ &damon_sysfs_perf_event_attr_sample_period_attr.attr,
+ &damon_sysfs_perf_event_attr_wakeup_events_attr.attr,
+ &damon_sysfs_perf_event_attr_precise_ip_attr.attr,
+ &damon_sysfs_perf_event_attr_exclude_kernel_attr.attr,
+ &damon_sysfs_perf_event_attr_exclude_hv_attr.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(damon_sysfs_perf_event_attr);
+
+static const struct kobj_type damon_sysfs_perf_event_attr_ktype = {
+ .release = damon_sysfs_perf_event_attr_release,
+ .sysfs_ops = &kobj_sysfs_ops,
+ .default_groups = damon_sysfs_perf_event_attr_groups,
+};
+
+/*
+ * perf_events directory
+ */
+
+/*
+ * Cap on the number of perf events per damon_ctx, to bound the sysfs
+ * kobject footprint and prevent unbounded allocations from a careless
+ * write to nr_perf_events.
+ */
+#define DAMON_SYSFS_PERF_EVENTS_MAX 64
+
+struct damon_sysfs_perf_events {
+ struct kobject kobj;
+ struct damon_sysfs_perf_event_attr **attrs_arr;
+ int nr;
+};
+
+static struct damon_sysfs_perf_events *damon_sysfs_perf_events_alloc(void)
+{
+ return kzalloc(sizeof(struct damon_sysfs_perf_events), GFP_KERNEL);
+}
+
+static void damon_sysfs_perf_events_rm_dirs(
+ struct damon_sysfs_perf_events *events)
+{
+ struct damon_sysfs_perf_event_attr **attrs_arr = events->attrs_arr;
+ int i;
+
+ for (i = 0; i < events->nr; i++)
+ kobject_put(&attrs_arr[i]->kobj);
+ events->nr = 0;
+ kfree(attrs_arr);
+ events->attrs_arr = NULL;
+}
+
+static int damon_sysfs_perf_events_add_dirs(
+ struct damon_sysfs_perf_events *events, int nr_events)
+{
+ struct damon_sysfs_perf_event_attr **attrs_arr, *attr;
+ int err, i;
+
+ damon_sysfs_perf_events_rm_dirs(events);
+ if (!nr_events)
+ return 0;
+
+ attrs_arr = kmalloc_array(nr_events, sizeof(*attrs_arr), GFP_KERNEL);
+ if (!attrs_arr)
+ return -ENOMEM;
+ events->attrs_arr = attrs_arr;
+
+ for (i = 0; i < nr_events; i++) {
+ attr = damon_sysfs_perf_event_attr_alloc();
+ if (!attr) {
+ damon_sysfs_perf_events_rm_dirs(events);
+ return -ENOMEM;
+ }
+
+ err = kobject_init_and_add(&attr->kobj,
+ &damon_sysfs_perf_event_attr_ktype, &events->kobj,
+ "%d", i);
+ if (err) {
+ kobject_put(&attr->kobj);
+ damon_sysfs_perf_events_rm_dirs(events);
+ return err;
+ }
+ attrs_arr[i] = attr;
+ events->nr++;
+ }
+ return 0;
+}
+
+static ssize_t nr_perf_events_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_perf_events *events = container_of(kobj,
+ struct damon_sysfs_perf_events, kobj);
+
+ return sysfs_emit(buf, "%d\n", events->nr);
+}
+
+static ssize_t nr_perf_events_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_perf_events *events;
+ int nr, err = kstrtoint(buf, 0, &nr);
+
+ if (err)
+ return err;
+ if (nr < 0 || nr > DAMON_SYSFS_PERF_EVENTS_MAX)
+ return -EINVAL;
+
+ events = container_of(kobj, struct damon_sysfs_perf_events, kobj);
+
+ if (!mutex_trylock(&damon_sysfs_lock))
+ return -EBUSY;
+ err = damon_sysfs_perf_events_add_dirs(events, nr);
+ mutex_unlock(&damon_sysfs_lock);
+ if (err)
+ return err;
+
+ return count;
+}
+
+static void damon_sysfs_perf_events_release(struct kobject *kobj)
+{
+ kfree(container_of(kobj, struct damon_sysfs_perf_events, kobj));
+}
+
+static struct kobj_attribute damon_sysfs_perf_events_nr_attr =
+ __ATTR_RW_MODE(nr_perf_events, 0600);
+
+static struct attribute *damon_sysfs_perf_events_attrs[] = {
+ &damon_sysfs_perf_events_nr_attr.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(damon_sysfs_perf_events);
+
+static const struct kobj_type damon_sysfs_perf_events_ktype = {
+ .release = damon_sysfs_perf_events_release,
+ .sysfs_ops = &kobj_sysfs_ops,
+ .default_groups = damon_sysfs_perf_events_groups,
+};
+
/*
* sample directory
*/
@@ -471,6 +985,7 @@ int damon_sysfs_sample_add_dirs(struct damon_sysfs_sample *sample)
{
struct damon_sysfs_primitives *primitives;
struct damon_sysfs_sample_filters *filters;
+ struct damon_sysfs_perf_events *perf_events;
int err;
primitives = damon_sysfs_primitives_alloc(true, false);
@@ -494,7 +1009,23 @@ int damon_sysfs_sample_add_dirs(struct damon_sysfs_sample *sample)
if (err)
goto put_filters_out;
sample->filters = filters;
+
+ perf_events = damon_sysfs_perf_events_alloc();
+ if (!perf_events) {
+ err = -ENOMEM;
+ goto put_filters_out;
+ }
+ err = kobject_init_and_add(&perf_events->kobj,
+ &damon_sysfs_perf_events_ktype, &sample->kobj,
+ "perf_events");
+ if (err)
+ goto put_perf_events_out;
+ sample->perf_events = perf_events;
+
return 0;
+put_perf_events_out:
+ kobject_put(&perf_events->kobj);
+ sample->perf_events = NULL;
put_filters_out:
kobject_put(&filters->kobj);
sample->filters = NULL;
@@ -512,6 +1043,10 @@ void damon_sysfs_sample_rm_dirs(struct damon_sysfs_sample *sample)
damon_sysfs_sample_filters_rm_dirs(sample->filters);
kobject_put(&sample->filters->kobj);
}
+ if (sample->perf_events) {
+ damon_sysfs_perf_events_rm_dirs(sample->perf_events);
+ kobject_put(&sample->perf_events->kobj);
+ }
}
void damon_sysfs_sample_release(struct kobject *kobj)
@@ -596,3 +1131,47 @@ int damon_sysfs_set_sample_control(
return damon_sysfs_set_sample_filters(control,
sysfs_sample->filters);
}
+
+static int damon_sysfs_add_perf_event(
+ struct damon_sysfs_perf_event_attr *sys_attr,
+ struct damon_ctx *ctx)
+{
+ struct damon_perf_event *event = kzalloc(sizeof(*event), GFP_KERNEL);
+
+ if (!event)
+ return -ENOMEM;
+
+ event->attr.type = sys_attr->type;
+ event->attr.config = sys_attr->config;
+ event->attr.config1 = sys_attr->config1;
+ event->attr.config2 = sys_attr->config2;
+ event->attr.sample_phys_addr = sys_attr->sample_phys_addr;
+ event->attr.sample_weight_struct = sys_attr->sample_weight_struct;
+ event->attr.freq = sys_attr->freq;
+ event->attr.sample_freq = sys_attr->sample_freq;
+ event->attr.sample_period = sys_attr->sample_period;
+ event->attr.wakeup_events = sys_attr->wakeup_events;
+ event->attr.precise_ip = sys_attr->precise_ip;
+ event->attr.exclude_kernel = sys_attr->exclude_kernel;
+ event->attr.exclude_hv = sys_attr->exclude_hv;
+
+ list_add_tail(&event->list, &ctx->perf_events);
+ return 0;
+}
+
+int damon_sysfs_add_perf_events(struct damon_ctx *ctx,
+ struct damon_sysfs_sample *sysfs_sample)
+{
+ struct damon_sysfs_perf_events *events = sysfs_sample->perf_events;
+ int i, err;
+
+ if (!events)
+ return 0;
+
+ for (i = 0; i < events->nr; i++) {
+ err = damon_sysfs_add_perf_event(events->attrs_arr[i], ctx);
+ if (err)
+ return err;
+ }
+ return 0;
+}
--
2.43.0
next prev parent reply other threads:[~2026-05-29 16:57 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-29 16:56 [RFC PATCH 0/6] mm/damon: hardware-sampled access reports Ravi Jonnalagadda
2026-05-29 16:56 ` [RFC PATCH 1/6] mm/damon: add struct damon_perf_event{,_attr} and per-ctx perf_events list Ravi Jonnalagadda
2026-05-29 16:56 ` Ravi Jonnalagadda [this message]
2026-05-29 16:56 ` [RFC PATCH 3/6] mm/damon/sysfs: install perf_events on apply Ravi Jonnalagadda
2026-05-29 16:56 ` [RFC PATCH 4/6] mm/damon/core: per-CPU SPSC ring drain and damon_perf_event lifecycle Ravi Jonnalagadda
2026-05-29 16:56 ` [RFC PATCH 5/6] mm/damon/vaddr: implement perf-event access check Ravi Jonnalagadda
2026-05-29 16:56 ` [RFC PATCH 6/6] mm/damon: add damos_node_eligible_mem_bp tracepoint Ravi Jonnalagadda
2026-05-30 0:04 ` [RFC PATCH 0/6] mm/damon: hardware-sampled access reports SeongJae Park
2026-05-30 3:01 ` Akinobu Mita
2026-05-30 5:03 ` Ravi Jonnalagadda
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260529165640.820-3-ravis.opensrc@gmail.com \
--to=ravis.opensrc@gmail.com \
--cc=ajayjoshi@micron.com \
--cc=akinobu.mita@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=bijan311@gmail.com \
--cc=corbet@lwn.net \
--cc=damon@lists.linux.dev \
--cc=honggyu.kim@sk.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=sj@kernel.org \
--cc=yunjeong.mun@sk.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox