1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Common Primitives for DAMON Sysfs Interface 4 * 5 * Author: SeongJae Park <sj@kernel.org> 6 */ 7 8#include <linux/slab.h> 9 10#include "sysfs-common.h" 11 12DEFINE_MUTEX(damon_sysfs_lock); 13 14/* 15 * unsigned long range directory 16 */ 17 18struct damon_sysfs_ul_range *damon_sysfs_ul_range_alloc( 19 unsigned long min, 20 unsigned long max) 21{ 22 struct damon_sysfs_ul_range *range = kmalloc(sizeof(*range), 23 GFP_KERNEL); 24 25 if (!range) 26 return NULL; 27 range->kobj = (struct kobject){}; 28 range->min = min; 29 range->max = max; 30 31 return range; 32} 33 34static ssize_t min_show(struct kobject *kobj, struct kobj_attribute *attr, 35 char *buf) 36{ 37 struct damon_sysfs_ul_range *range = container_of(kobj, 38 struct damon_sysfs_ul_range, kobj); 39 40 return sysfs_emit(buf, "%lu\n", range->min); 41} 42 43static ssize_t min_store(struct kobject *kobj, struct kobj_attribute *attr, 44 const char *buf, size_t count) 45{ 46 struct damon_sysfs_ul_range *range = container_of(kobj, 47 struct damon_sysfs_ul_range, kobj); 48 unsigned long min; 49 int err; 50 51 err = kstrtoul(buf, 0, &min); 52 if (err) 53 return err; 54 55 range->min = min; 56 return count; 57} 58 59static ssize_t max_show(struct kobject *kobj, struct kobj_attribute *attr, 60 char *buf) 61{ 62 struct damon_sysfs_ul_range *range = container_of(kobj, 63 struct damon_sysfs_ul_range, kobj); 64 65 return sysfs_emit(buf, "%lu\n", range->max); 66} 67 68static ssize_t max_store(struct kobject *kobj, struct kobj_attribute *attr, 69 const char *buf, size_t count) 70{ 71 struct damon_sysfs_ul_range *range = container_of(kobj, 72 struct damon_sysfs_ul_range, kobj); 73 unsigned long max; 74 int err; 75 76 err = kstrtoul(buf, 0, &max); 77 if (err) 78 return err; 79 80 range->max = max; 81 return count; 82} 83 84void damon_sysfs_ul_range_release(struct kobject *kobj) 85{ 86 kfree(container_of(kobj, struct damon_sysfs_ul_range, kobj)); 87} 88 89static struct kobj_attribute damon_sysfs_ul_range_min_attr = 90 __ATTR_RW_MODE(min, 0600); 91 92static struct kobj_attribute damon_sysfs_ul_range_max_attr = 93 __ATTR_RW_MODE(max, 0600); 94 95static struct attribute *damon_sysfs_ul_range_attrs[] = { 96 &damon_sysfs_ul_range_min_attr.attr, 97 &damon_sysfs_ul_range_max_attr.attr, 98 NULL, 99}; 100ATTRIBUTE_GROUPS(damon_sysfs_ul_range); 101 102const struct kobj_type damon_sysfs_ul_range_ktype = { 103 .release = damon_sysfs_ul_range_release, 104 .sysfs_ops = &kobj_sysfs_ops, 105 .default_groups = damon_sysfs_ul_range_groups, 106}; 107 108