@@ -113,6 +113,105 @@ static struct kobj_type damon_sysfs_ul_range_ktype = {
113113 .default_groups = damon_sysfs_ul_range_groups ,
114114};
115115
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+
116215/*
117216 * watermarks directory
118217 */
@@ -653,6 +752,7 @@ struct damon_sysfs_scheme {
653752 struct damon_sysfs_access_pattern * access_pattern ;
654753 struct damon_sysfs_quotas * quotas ;
655754 struct damon_sysfs_watermarks * watermarks ;
755+ struct damon_sysfs_stats * stats ;
656756};
657757
658758/* This should match with enum damos_action */
@@ -743,6 +843,22 @@ static int damon_sysfs_scheme_set_watermarks(struct damon_sysfs_scheme *scheme)
743843 return err ;
744844}
745845
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+
746862static int damon_sysfs_scheme_add_dirs (struct damon_sysfs_scheme * scheme )
747863{
748864 int err ;
@@ -756,8 +872,14 @@ static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme)
756872 err = damon_sysfs_scheme_set_watermarks (scheme );
757873 if (err )
758874 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 ;
759878 return 0 ;
760879
880+ put_watermarks_quotas_access_pattern_out :
881+ kobject_put (& scheme -> watermarks -> kobj );
882+ scheme -> watermarks = NULL ;
761883put_quotas_access_pattern_out :
762884 kobject_put (& scheme -> quotas -> kobj );
763885 scheme -> quotas = NULL ;
@@ -774,6 +896,7 @@ static void damon_sysfs_scheme_rm_dirs(struct damon_sysfs_scheme *scheme)
774896 damon_sysfs_quotas_rm_dirs (scheme -> quotas );
775897 kobject_put (& scheme -> quotas -> kobj );
776898 kobject_put (& scheme -> watermarks -> kobj );
899+ kobject_put (& scheme -> stats -> kobj );
777900}
778901
779902static 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)
21412264 */
21422265}
21432266
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+
21442292static ssize_t state_store (struct kobject * kobj , struct kobj_attribute * attr ,
21452293 const char * buf , size_t count )
21462294{
@@ -2154,6 +2302,8 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
21542302 ret = damon_sysfs_turn_damon_on (kdamond );
21552303 else if (sysfs_streq (buf , "off" ))
21562304 ret = damon_sysfs_turn_damon_off (kdamond );
2305+ else if (sysfs_streq (buf , "update_schemes_stats" ))
2306+ ret = damon_sysfs_update_schemes_stats (kdamond );
21572307 else
21582308 ret = - EINVAL ;
21592309 mutex_unlock (& damon_sysfs_lock );
0 commit comments