@@ -113,6 +113,189 @@ static struct kobj_type damon_sysfs_ul_range_ktype = {
113113 .default_groups = damon_sysfs_ul_range_groups ,
114114};
115115
116+ /*
117+ * watermarks directory
118+ */
119+
120+ struct damon_sysfs_watermarks {
121+ struct kobject kobj ;
122+ enum damos_wmark_metric metric ;
123+ unsigned long interval_us ;
124+ unsigned long high ;
125+ unsigned long mid ;
126+ unsigned long low ;
127+ };
128+
129+ static struct damon_sysfs_watermarks * damon_sysfs_watermarks_alloc (
130+ enum damos_wmark_metric metric , unsigned long interval_us ,
131+ unsigned long high , unsigned long mid , unsigned long low )
132+ {
133+ struct damon_sysfs_watermarks * watermarks = kmalloc (
134+ sizeof (* watermarks ), GFP_KERNEL );
135+
136+ if (!watermarks )
137+ return NULL ;
138+ watermarks -> kobj = (struct kobject ){};
139+ watermarks -> metric = metric ;
140+ watermarks -> interval_us = interval_us ;
141+ watermarks -> high = high ;
142+ watermarks -> mid = mid ;
143+ watermarks -> low = low ;
144+ return watermarks ;
145+ }
146+
147+ /* Should match with enum damos_wmark_metric */
148+ static const char * const damon_sysfs_wmark_metric_strs [] = {
149+ "none" ,
150+ "free_mem_rate" ,
151+ };
152+
153+ static ssize_t metric_show (struct kobject * kobj , struct kobj_attribute * attr ,
154+ char * buf )
155+ {
156+ struct damon_sysfs_watermarks * watermarks = container_of (kobj ,
157+ struct damon_sysfs_watermarks , kobj );
158+
159+ return sysfs_emit (buf , "%s\n" ,
160+ damon_sysfs_wmark_metric_strs [watermarks -> metric ]);
161+ }
162+
163+ static ssize_t metric_store (struct kobject * kobj , struct kobj_attribute * attr ,
164+ const char * buf , size_t count )
165+ {
166+ struct damon_sysfs_watermarks * watermarks = container_of (kobj ,
167+ struct damon_sysfs_watermarks , kobj );
168+ enum damos_wmark_metric metric ;
169+
170+ for (metric = 0 ; metric < NR_DAMOS_WMARK_METRICS ; metric ++ ) {
171+ if (sysfs_streq (buf , damon_sysfs_wmark_metric_strs [metric ])) {
172+ watermarks -> metric = metric ;
173+ return count ;
174+ }
175+ }
176+ return - EINVAL ;
177+ }
178+
179+ static ssize_t interval_us_show (struct kobject * kobj ,
180+ struct kobj_attribute * attr , char * buf )
181+ {
182+ struct damon_sysfs_watermarks * watermarks = container_of (kobj ,
183+ struct damon_sysfs_watermarks , kobj );
184+
185+ return sysfs_emit (buf , "%lu\n" , watermarks -> interval_us );
186+ }
187+
188+ static ssize_t interval_us_store (struct kobject * kobj ,
189+ struct kobj_attribute * attr , const char * buf , size_t count )
190+ {
191+ struct damon_sysfs_watermarks * watermarks = container_of (kobj ,
192+ struct damon_sysfs_watermarks , kobj );
193+ int err = kstrtoul (buf , 0 , & watermarks -> interval_us );
194+
195+ if (err )
196+ return - EINVAL ;
197+ return count ;
198+ }
199+
200+ static ssize_t high_show (struct kobject * kobj ,
201+ struct kobj_attribute * attr , char * buf )
202+ {
203+ struct damon_sysfs_watermarks * watermarks = container_of (kobj ,
204+ struct damon_sysfs_watermarks , kobj );
205+
206+ return sysfs_emit (buf , "%lu\n" , watermarks -> high );
207+ }
208+
209+ static ssize_t high_store (struct kobject * kobj ,
210+ struct kobj_attribute * attr , const char * buf , size_t count )
211+ {
212+ struct damon_sysfs_watermarks * watermarks = container_of (kobj ,
213+ struct damon_sysfs_watermarks , kobj );
214+ int err = kstrtoul (buf , 0 , & watermarks -> high );
215+
216+ if (err )
217+ return - EINVAL ;
218+ return count ;
219+ }
220+
221+ static ssize_t mid_show (struct kobject * kobj ,
222+ struct kobj_attribute * attr , char * buf )
223+ {
224+ struct damon_sysfs_watermarks * watermarks = container_of (kobj ,
225+ struct damon_sysfs_watermarks , kobj );
226+
227+ return sysfs_emit (buf , "%lu\n" , watermarks -> mid );
228+ }
229+
230+ static ssize_t mid_store (struct kobject * kobj ,
231+ struct kobj_attribute * attr , const char * buf , size_t count )
232+ {
233+ struct damon_sysfs_watermarks * watermarks = container_of (kobj ,
234+ struct damon_sysfs_watermarks , kobj );
235+ int err = kstrtoul (buf , 0 , & watermarks -> mid );
236+
237+ if (err )
238+ return - EINVAL ;
239+ return count ;
240+ }
241+
242+ static ssize_t low_show (struct kobject * kobj ,
243+ struct kobj_attribute * attr , char * buf )
244+ {
245+ struct damon_sysfs_watermarks * watermarks = container_of (kobj ,
246+ struct damon_sysfs_watermarks , kobj );
247+
248+ return sysfs_emit (buf , "%lu\n" , watermarks -> low );
249+ }
250+
251+ static ssize_t low_store (struct kobject * kobj ,
252+ struct kobj_attribute * attr , const char * buf , size_t count )
253+ {
254+ struct damon_sysfs_watermarks * watermarks = container_of (kobj ,
255+ struct damon_sysfs_watermarks , kobj );
256+ int err = kstrtoul (buf , 0 , & watermarks -> low );
257+
258+ if (err )
259+ return - EINVAL ;
260+ return count ;
261+ }
262+
263+ static void damon_sysfs_watermarks_release (struct kobject * kobj )
264+ {
265+ kfree (container_of (kobj , struct damon_sysfs_watermarks , kobj ));
266+ }
267+
268+ static struct kobj_attribute damon_sysfs_watermarks_metric_attr =
269+ __ATTR_RW_MODE (metric , 0600 );
270+
271+ static struct kobj_attribute damon_sysfs_watermarks_interval_us_attr =
272+ __ATTR_RW_MODE (interval_us , 0600 );
273+
274+ static struct kobj_attribute damon_sysfs_watermarks_high_attr =
275+ __ATTR_RW_MODE (high , 0600 );
276+
277+ static struct kobj_attribute damon_sysfs_watermarks_mid_attr =
278+ __ATTR_RW_MODE (mid , 0600 );
279+
280+ static struct kobj_attribute damon_sysfs_watermarks_low_attr =
281+ __ATTR_RW_MODE (low , 0600 );
282+
283+ static struct attribute * damon_sysfs_watermarks_attrs [] = {
284+ & damon_sysfs_watermarks_metric_attr .attr ,
285+ & damon_sysfs_watermarks_interval_us_attr .attr ,
286+ & damon_sysfs_watermarks_high_attr .attr ,
287+ & damon_sysfs_watermarks_mid_attr .attr ,
288+ & damon_sysfs_watermarks_low_attr .attr ,
289+ NULL ,
290+ };
291+ ATTRIBUTE_GROUPS (damon_sysfs_watermarks );
292+
293+ static struct kobj_type damon_sysfs_watermarks_ktype = {
294+ .release = damon_sysfs_watermarks_release ,
295+ .sysfs_ops = & kobj_sysfs_ops ,
296+ .default_groups = damon_sysfs_watermarks_groups ,
297+ };
298+
116299/*
117300 * scheme/weights directory
118301 */
@@ -469,6 +652,7 @@ struct damon_sysfs_scheme {
469652 enum damos_action action ;
470653 struct damon_sysfs_access_pattern * access_pattern ;
471654 struct damon_sysfs_quotas * quotas ;
655+ struct damon_sysfs_watermarks * watermarks ;
472656};
473657
474658/* This should match with enum damos_action */
@@ -541,6 +725,24 @@ static int damon_sysfs_scheme_set_quotas(struct damon_sysfs_scheme *scheme)
541725 return err ;
542726}
543727
728+ static int damon_sysfs_scheme_set_watermarks (struct damon_sysfs_scheme * scheme )
729+ {
730+ struct damon_sysfs_watermarks * watermarks =
731+ damon_sysfs_watermarks_alloc (DAMOS_WMARK_NONE , 0 , 0 , 0 , 0 );
732+ int err ;
733+
734+ if (!watermarks )
735+ return - ENOMEM ;
736+ err = kobject_init_and_add (& watermarks -> kobj ,
737+ & damon_sysfs_watermarks_ktype , & scheme -> kobj ,
738+ "watermarks" );
739+ if (err )
740+ kobject_put (& watermarks -> kobj );
741+ else
742+ scheme -> watermarks = watermarks ;
743+ return err ;
744+ }
745+
544746static int damon_sysfs_scheme_add_dirs (struct damon_sysfs_scheme * scheme )
545747{
546748 int err ;
@@ -551,8 +753,14 @@ static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme)
551753 err = damon_sysfs_scheme_set_quotas (scheme );
552754 if (err )
553755 goto put_access_pattern_out ;
756+ err = damon_sysfs_scheme_set_watermarks (scheme );
757+ if (err )
758+ goto put_quotas_access_pattern_out ;
554759 return 0 ;
555760
761+ put_quotas_access_pattern_out :
762+ kobject_put (& scheme -> quotas -> kobj );
763+ scheme -> quotas = NULL ;
556764put_access_pattern_out :
557765 kobject_put (& scheme -> access_pattern -> kobj );
558766 scheme -> access_pattern = NULL ;
@@ -565,6 +773,7 @@ static void damon_sysfs_scheme_rm_dirs(struct damon_sysfs_scheme *scheme)
565773 kobject_put (& scheme -> access_pattern -> kobj );
566774 damon_sysfs_quotas_rm_dirs (scheme -> quotas );
567775 kobject_put (& scheme -> quotas -> kobj );
776+ kobject_put (& scheme -> watermarks -> kobj );
568777}
569778
570779static ssize_t action_show (struct kobject * kobj , struct kobj_attribute * attr ,
@@ -1805,6 +2014,7 @@ static struct damos *damon_sysfs_mk_scheme(
18052014 sysfs_scheme -> access_pattern ;
18062015 struct damon_sysfs_quotas * sysfs_quotas = sysfs_scheme -> quotas ;
18072016 struct damon_sysfs_weights * sysfs_weights = sysfs_quotas -> weights ;
2017+ struct damon_sysfs_watermarks * sysfs_wmarks = sysfs_scheme -> watermarks ;
18082018 struct damos_quota quota = {
18092019 .ms = sysfs_quotas -> ms ,
18102020 .sz = sysfs_quotas -> sz ,
@@ -1814,11 +2024,11 @@ static struct damos *damon_sysfs_mk_scheme(
18142024 .weight_age = sysfs_weights -> age ,
18152025 };
18162026 struct damos_watermarks wmarks = {
1817- .metric = DAMOS_WMARK_NONE ,
1818- .interval = 0 ,
1819- .high = 0 ,
1820- .mid = 0 ,
1821- .low = 0 ,
2027+ .metric = sysfs_wmarks -> metric ,
2028+ .interval = sysfs_wmarks -> interval_us ,
2029+ .high = sysfs_wmarks -> high ,
2030+ .mid = sysfs_wmarks -> mid ,
2031+ .low = sysfs_wmarks -> low ,
18222032 };
18232033
18242034 return damon_new_scheme (pattern -> sz -> min , pattern -> sz -> max ,
0 commit comments