@@ -113,6 +113,105 @@ static struct kobj_type damon_sysfs_ul_range_ktype = {
113
113
.default_groups = damon_sysfs_ul_range_groups ,
114
114
};
115
115
116
+ /*
117
+ * schemes/stats directory
118
+ */
119
+
120
+ struct damon_sysfs_stats {
121
+ struct kobject kobj ;
122
+ unsigned long nr_tried ;
123
+ unsigned long sz_tried ;
124
+ unsigned long nr_applied ;
125
+ unsigned long sz_applied ;
126
+ unsigned long qt_exceeds ;
127
+ };
128
+
129
+ static struct damon_sysfs_stats * damon_sysfs_stats_alloc (void )
130
+ {
131
+ return kzalloc (sizeof (struct damon_sysfs_stats ), GFP_KERNEL );
132
+ }
133
+
134
+ static ssize_t nr_tried_show (struct kobject * kobj , struct kobj_attribute * attr ,
135
+ char * buf )
136
+ {
137
+ struct damon_sysfs_stats * stats = container_of (kobj ,
138
+ struct damon_sysfs_stats , kobj );
139
+
140
+ return sysfs_emit (buf , "%lu\n" , stats -> nr_tried );
141
+ }
142
+
143
+ static ssize_t sz_tried_show (struct kobject * kobj , struct kobj_attribute * attr ,
144
+ char * buf )
145
+ {
146
+ struct damon_sysfs_stats * stats = container_of (kobj ,
147
+ struct damon_sysfs_stats , kobj );
148
+
149
+ return sysfs_emit (buf , "%lu\n" , stats -> sz_tried );
150
+ }
151
+
152
+ static ssize_t nr_applied_show (struct kobject * kobj ,
153
+ struct kobj_attribute * attr , char * buf )
154
+ {
155
+ struct damon_sysfs_stats * stats = container_of (kobj ,
156
+ struct damon_sysfs_stats , kobj );
157
+
158
+ return sysfs_emit (buf , "%lu\n" , stats -> nr_applied );
159
+ }
160
+
161
+ static ssize_t sz_applied_show (struct kobject * kobj ,
162
+ struct kobj_attribute * attr , char * buf )
163
+ {
164
+ struct damon_sysfs_stats * stats = container_of (kobj ,
165
+ struct damon_sysfs_stats , kobj );
166
+
167
+ return sysfs_emit (buf , "%lu\n" , stats -> sz_applied );
168
+ }
169
+
170
+ static ssize_t qt_exceeds_show (struct kobject * kobj ,
171
+ struct kobj_attribute * attr , char * buf )
172
+ {
173
+ struct damon_sysfs_stats * stats = container_of (kobj ,
174
+ struct damon_sysfs_stats , kobj );
175
+
176
+ return sysfs_emit (buf , "%lu\n" , stats -> qt_exceeds );
177
+ }
178
+
179
+ static void damon_sysfs_stats_release (struct kobject * kobj )
180
+ {
181
+ kfree (container_of (kobj , struct damon_sysfs_stats , kobj ));
182
+ }
183
+
184
+ static struct kobj_attribute damon_sysfs_stats_nr_tried_attr =
185
+ __ATTR_RO_MODE (nr_tried , 0400 );
186
+
187
+ static struct kobj_attribute damon_sysfs_stats_sz_tried_attr =
188
+ __ATTR_RO_MODE (sz_tried , 0400 );
189
+
190
+ static struct kobj_attribute damon_sysfs_stats_nr_applied_attr =
191
+ __ATTR_RO_MODE (nr_applied , 0400 );
192
+
193
+ static struct kobj_attribute damon_sysfs_stats_sz_applied_attr =
194
+ __ATTR_RO_MODE (sz_applied , 0400 );
195
+
196
+ static struct kobj_attribute damon_sysfs_stats_qt_exceeds_attr =
197
+ __ATTR_RO_MODE (qt_exceeds , 0400 );
198
+
199
+ static struct attribute * damon_sysfs_stats_attrs [] = {
200
+ & damon_sysfs_stats_nr_tried_attr .attr ,
201
+ & damon_sysfs_stats_sz_tried_attr .attr ,
202
+ & damon_sysfs_stats_nr_applied_attr .attr ,
203
+ & damon_sysfs_stats_sz_applied_attr .attr ,
204
+ & damon_sysfs_stats_qt_exceeds_attr .attr ,
205
+ NULL ,
206
+ };
207
+ ATTRIBUTE_GROUPS (damon_sysfs_stats );
208
+
209
+ static struct kobj_type damon_sysfs_stats_ktype = {
210
+ .release = damon_sysfs_stats_release ,
211
+ .sysfs_ops = & kobj_sysfs_ops ,
212
+ .default_groups = damon_sysfs_stats_groups ,
213
+ };
214
+
116
215
/*
117
216
* watermarks directory
118
217
*/
@@ -653,6 +752,7 @@ struct damon_sysfs_scheme {
653
752
struct damon_sysfs_access_pattern * access_pattern ;
654
753
struct damon_sysfs_quotas * quotas ;
655
754
struct damon_sysfs_watermarks * watermarks ;
755
+ struct damon_sysfs_stats * stats ;
656
756
};
657
757
658
758
/* This should match with enum damos_action */
@@ -743,6 +843,22 @@ static int damon_sysfs_scheme_set_watermarks(struct damon_sysfs_scheme *scheme)
743
843
return err ;
744
844
}
745
845
846
+ static int damon_sysfs_scheme_set_stats (struct damon_sysfs_scheme * scheme )
847
+ {
848
+ struct damon_sysfs_stats * stats = damon_sysfs_stats_alloc ();
849
+ int err ;
850
+
851
+ if (!stats )
852
+ return - ENOMEM ;
853
+ err = kobject_init_and_add (& stats -> kobj , & damon_sysfs_stats_ktype ,
854
+ & scheme -> kobj , "stats" );
855
+ if (err )
856
+ kobject_put (& stats -> kobj );
857
+ else
858
+ scheme -> stats = stats ;
859
+ return err ;
860
+ }
861
+
746
862
static int damon_sysfs_scheme_add_dirs (struct damon_sysfs_scheme * scheme )
747
863
{
748
864
int err ;
@@ -756,8 +872,14 @@ static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme)
756
872
err = damon_sysfs_scheme_set_watermarks (scheme );
757
873
if (err )
758
874
goto put_quotas_access_pattern_out ;
875
+ err = damon_sysfs_scheme_set_stats (scheme );
876
+ if (err )
877
+ goto put_watermarks_quotas_access_pattern_out ;
759
878
return 0 ;
760
879
880
+ put_watermarks_quotas_access_pattern_out :
881
+ kobject_put (& scheme -> watermarks -> kobj );
882
+ scheme -> watermarks = NULL ;
761
883
put_quotas_access_pattern_out :
762
884
kobject_put (& scheme -> quotas -> kobj );
763
885
scheme -> quotas = NULL ;
@@ -774,6 +896,7 @@ static void damon_sysfs_scheme_rm_dirs(struct damon_sysfs_scheme *scheme)
774
896
damon_sysfs_quotas_rm_dirs (scheme -> quotas );
775
897
kobject_put (& scheme -> quotas -> kobj );
776
898
kobject_put (& scheme -> watermarks -> kobj );
899
+ kobject_put (& scheme -> stats -> kobj );
777
900
}
778
901
779
902
static ssize_t action_show (struct kobject * kobj , struct kobj_attribute * attr ,
@@ -2141,6 +2264,31 @@ static int damon_sysfs_turn_damon_off(struct damon_sysfs_kdamond *kdamond)
2141
2264
*/
2142
2265
}
2143
2266
2267
+ static int damon_sysfs_update_schemes_stats (struct damon_sysfs_kdamond * kdamond )
2268
+ {
2269
+ struct damon_ctx * ctx = kdamond -> damon_ctx ;
2270
+ struct damos * scheme ;
2271
+ int schemes_idx = 0 ;
2272
+
2273
+ if (!ctx )
2274
+ return - EINVAL ;
2275
+ mutex_lock (& ctx -> kdamond_lock );
2276
+ damon_for_each_scheme (scheme , ctx ) {
2277
+ struct damon_sysfs_schemes * sysfs_schemes ;
2278
+ struct damon_sysfs_stats * sysfs_stats ;
2279
+
2280
+ sysfs_schemes = kdamond -> contexts -> contexts_arr [0 ]-> schemes ;
2281
+ sysfs_stats = sysfs_schemes -> schemes_arr [schemes_idx ++ ]-> stats ;
2282
+ sysfs_stats -> nr_tried = scheme -> stat .nr_tried ;
2283
+ sysfs_stats -> sz_tried = scheme -> stat .sz_tried ;
2284
+ sysfs_stats -> nr_applied = scheme -> stat .nr_applied ;
2285
+ sysfs_stats -> sz_applied = scheme -> stat .sz_applied ;
2286
+ sysfs_stats -> qt_exceeds = scheme -> stat .qt_exceeds ;
2287
+ }
2288
+ mutex_unlock (& ctx -> kdamond_lock );
2289
+ return 0 ;
2290
+ }
2291
+
2144
2292
static ssize_t state_store (struct kobject * kobj , struct kobj_attribute * attr ,
2145
2293
const char * buf , size_t count )
2146
2294
{
@@ -2154,6 +2302,8 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
2154
2302
ret = damon_sysfs_turn_damon_on (kdamond );
2155
2303
else if (sysfs_streq (buf , "off" ))
2156
2304
ret = damon_sysfs_turn_damon_off (kdamond );
2305
+ else if (sysfs_streq (buf , "update_schemes_stats" ))
2306
+ ret = damon_sysfs_update_schemes_stats (kdamond );
2157
2307
else
2158
2308
ret = - EINVAL ;
2159
2309
mutex_unlock (& damon_sysfs_lock );
0 commit comments