@@ -113,6 +113,189 @@ static struct kobj_type damon_sysfs_ul_range_ktype = {
113
113
.default_groups = damon_sysfs_ul_range_groups ,
114
114
};
115
115
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
+
116
299
/*
117
300
* scheme/weights directory
118
301
*/
@@ -469,6 +652,7 @@ struct damon_sysfs_scheme {
469
652
enum damos_action action ;
470
653
struct damon_sysfs_access_pattern * access_pattern ;
471
654
struct damon_sysfs_quotas * quotas ;
655
+ struct damon_sysfs_watermarks * watermarks ;
472
656
};
473
657
474
658
/* This should match with enum damos_action */
@@ -541,6 +725,24 @@ static int damon_sysfs_scheme_set_quotas(struct damon_sysfs_scheme *scheme)
541
725
return err ;
542
726
}
543
727
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
+
544
746
static int damon_sysfs_scheme_add_dirs (struct damon_sysfs_scheme * scheme )
545
747
{
546
748
int err ;
@@ -551,8 +753,14 @@ static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme)
551
753
err = damon_sysfs_scheme_set_quotas (scheme );
552
754
if (err )
553
755
goto put_access_pattern_out ;
756
+ err = damon_sysfs_scheme_set_watermarks (scheme );
757
+ if (err )
758
+ goto put_quotas_access_pattern_out ;
554
759
return 0 ;
555
760
761
+ put_quotas_access_pattern_out :
762
+ kobject_put (& scheme -> quotas -> kobj );
763
+ scheme -> quotas = NULL ;
556
764
put_access_pattern_out :
557
765
kobject_put (& scheme -> access_pattern -> kobj );
558
766
scheme -> access_pattern = NULL ;
@@ -565,6 +773,7 @@ static void damon_sysfs_scheme_rm_dirs(struct damon_sysfs_scheme *scheme)
565
773
kobject_put (& scheme -> access_pattern -> kobj );
566
774
damon_sysfs_quotas_rm_dirs (scheme -> quotas );
567
775
kobject_put (& scheme -> quotas -> kobj );
776
+ kobject_put (& scheme -> watermarks -> kobj );
568
777
}
569
778
570
779
static ssize_t action_show (struct kobject * kobj , struct kobj_attribute * attr ,
@@ -1805,6 +2014,7 @@ static struct damos *damon_sysfs_mk_scheme(
1805
2014
sysfs_scheme -> access_pattern ;
1806
2015
struct damon_sysfs_quotas * sysfs_quotas = sysfs_scheme -> quotas ;
1807
2016
struct damon_sysfs_weights * sysfs_weights = sysfs_quotas -> weights ;
2017
+ struct damon_sysfs_watermarks * sysfs_wmarks = sysfs_scheme -> watermarks ;
1808
2018
struct damos_quota quota = {
1809
2019
.ms = sysfs_quotas -> ms ,
1810
2020
.sz = sysfs_quotas -> sz ,
@@ -1814,11 +2024,11 @@ static struct damos *damon_sysfs_mk_scheme(
1814
2024
.weight_age = sysfs_weights -> age ,
1815
2025
};
1816
2026
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 ,
1822
2032
};
1823
2033
1824
2034
return damon_new_scheme (pattern -> sz -> min , pattern -> sz -> max ,
0 commit comments