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 12 DEFINE_MUTEX(damon_sysfs_lock); 13 14 /* 15 * unsigned long range directory 16 */ 17 18 struct 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 34 static 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 43 static 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 59 static 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 68 static 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 84 void damon_sysfs_ul_range_release(struct kobject *kobj) 85 { 86 kfree(container_of(kobj, struct damon_sysfs_ul_range, kobj)); 87 } 88 89 static struct kobj_attribute damon_sysfs_ul_range_min_attr = 90 __ATTR_RW_MODE(min, 0600); 91 92 static struct kobj_attribute damon_sysfs_ul_range_max_attr = 93 __ATTR_RW_MODE(max, 0600); 94 95 static 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 }; 100 ATTRIBUTE_GROUPS(damon_sysfs_ul_range); 101 102 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