mm/damon: update comments in damon.h for damon_attrs
[linux-block.git] / include / linux / damon.h
index ad15a5b88e3a499cf0f1c2ffd1a6773a843fad25..d5d4d19928e0ac97df6a4ccf5c0c38c3d7358b71 100644 (file)
@@ -8,6 +8,7 @@
 #ifndef _DAMON_H_
 #define _DAMON_H_
 
+#include <linux/memcontrol.h>
 #include <linux/mutex.h>
 #include <linux/time64.h>
 #include <linux/types.h>
@@ -90,6 +91,12 @@ struct damon_target {
  * @DAMOS_LRU_DEPRIO:  Deprioritize the region on its LRU lists.
  * @DAMOS_STAT:                Do nothing but count the stat.
  * @NR_DAMOS_ACTIONS:  Total number of DAMOS actions
+ *
+ * The support of each action is up to running &struct damon_operations.
+ * &enum DAMON_OPS_VADDR and &enum DAMON_OPS_FVADDR supports all actions except
+ * &enum DAMOS_LRU_PRIO and &enum DAMOS_LRU_DEPRIO.  &enum DAMON_OPS_PADDR
+ * supports only &enum DAMOS_PAGEOUT, &enum DAMOS_LRU_PRIO, &enum
+ * DAMOS_LRU_DEPRIO, and &DAMOS_STAT.
  */
 enum damos_action {
        DAMOS_WILLNEED,
@@ -215,6 +222,44 @@ struct damos_stat {
        unsigned long qt_exceeds;
 };
 
+/**
+ * enum damos_filter_type - Type of memory for &struct damos_filter
+ * @DAMOS_FILTER_TYPE_ANON:    Anonymous pages.
+ * @DAMOS_FILTER_TYPE_MEMCG:   Specific memcg's pages.
+ * @NR_DAMOS_FILTER_TYPES:     Number of filter types.
+ *
+ * The support of each filter type is up to running &struct damon_operations.
+ * &enum DAMON_OPS_PADDR is supporting all filter types, while
+ * &enum DAMON_OPS_VADDR and &enum DAMON_OPS_FVADDR are not supporting any
+ * filter types.
+ */
+enum damos_filter_type {
+       DAMOS_FILTER_TYPE_ANON,
+       DAMOS_FILTER_TYPE_MEMCG,
+       NR_DAMOS_FILTER_TYPES,
+};
+
+/**
+ * struct damos_filter - DAMOS action target memory filter.
+ * @type:      Type of the page.
+ * @matching:  If the matching page should filtered out or in.
+ * @memcg_id:  Memcg id of the question if @type is DAMOS_FILTER_MEMCG.
+ * @list:      List head for siblings.
+ *
+ * Before applying the &damos->action to a memory region, DAMOS checks if each
+ * page of the region matches to this and avoid applying the action if so.
+ * Note that the check support is up to &struct damon_operations
+ * implementation.
+ */
+struct damos_filter {
+       enum damos_filter_type type;
+       bool matching;
+       union {
+               unsigned short memcg_id;
+       };
+       struct list_head list;
+};
+
 /**
  * struct damos_access_pattern - Target access pattern of the given scheme.
  * @min_sz_region:     Minimum size of target regions.
@@ -239,6 +284,7 @@ struct damos_access_pattern {
  * @action:            &damo_action to be applied to the target regions.
  * @quota:             Control the aggressiveness of this scheme.
  * @wmarks:            Watermarks for automated (in)activation of this scheme.
+ * @filters:           Additional set of &struct damos_filter for &action.
  * @stat:              Statistics of this scheme.
  * @list:              List head for siblings.
  *
@@ -254,6 +300,10 @@ struct damos_access_pattern {
  * If all schemes that registered to a &struct damon_ctx are inactive, DAMON
  * stops monitoring and just repeatedly checks the watermarks.
  *
+ * Before applying the &action to a memory region, &struct damon_operations
+ * implementation could check pages of the region and skip &action to respect
+ * &filters
+ *
  * After applying the &action to each region, &stat_count and &stat_sz is
  * updated to reflect the number of regions and total size of regions that the
  * &action is applied.
@@ -263,6 +313,7 @@ struct damos {
        enum damos_action action;
        struct damos_quota quota;
        struct damos_watermarks wmarks;
+       struct list_head filters;
        struct damos_stat stat;
        struct list_head list;
 };
@@ -303,10 +354,10 @@ struct damon_ctx;
  * users should register the low level operations for their target address
  * space and usecase via the &damon_ctx.ops.  Then, the monitoring thread
  * (&damon_ctx.kdamond) calls @init and @prepare_access_checks before starting
- * the monitoring, @update after each &damon_ctx.ops_update_interval, and
+ * the monitoring, @update after each &damon_attrs.ops_update_interval, and
  * @check_accesses, @target_valid and @prepare_access_checks after each
- * &damon_ctx.sample_interval.  Finally, @reset_aggregated is called after each
- * &damon_ctx.aggr_interval.
+ * &damon_attrs.sample_interval.  Finally, @reset_aggregated is called after
+ * each &damon_attrs.aggr_interval.
  *
  * Each &struct damon_operations instance having valid @id can be registered
  * via damon_register_ops() and selected by damon_select_ops() later.
@@ -516,6 +567,12 @@ static inline unsigned long damon_sz_region(struct damon_region *r)
 #define damon_for_each_scheme_safe(s, next, ctx) \
        list_for_each_entry_safe(s, next, &(ctx)->schemes, list)
 
+#define damos_for_each_filter(f, scheme) \
+       list_for_each_entry(f, &(scheme)->filters, list)
+
+#define damos_for_each_filter_safe(f, next, scheme) \
+       list_for_each_entry_safe(f, next, &(scheme)->filters, list)
+
 #ifdef CONFIG_DAMON
 
 struct damon_region *damon_new_region(unsigned long start, unsigned long end);
@@ -536,6 +593,11 @@ void damon_destroy_region(struct damon_region *r, struct damon_target *t);
 int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges,
                unsigned int nr_ranges);
 
+struct damos_filter *damos_new_filter(enum damos_filter_type type,
+               bool matching);
+void damos_add_filter(struct damos *s, struct damos_filter *f);
+void damos_destroy_filter(struct damos_filter *f);
+
 struct damos *damon_new_scheme(struct damos_access_pattern *pattern,
                        enum damos_action action, struct damos_quota *quota,
                        struct damos_watermarks *wmarks);