Merge tag 'vfio-v5.17-rc1' of git://github.com/awilliam/linux-vfio
[linux-2.6-microblaze.git] / include / linux / damon.h
index b4d4be3..5e1e3a1 100644 (file)
 #include <linux/mutex.h>
 #include <linux/time64.h>
 #include <linux/types.h>
+#include <linux/random.h>
 
 /* Minimal region size.  Every damon_region is aligned by this. */
 #define DAMON_MIN_REGION       PAGE_SIZE
 /* Max priority score for DAMON-based operation schemes */
 #define DAMOS_MAX_SCORE                (99)
 
+/* Get a random number in [l, r) */
+static inline unsigned long damon_rand(unsigned long l, unsigned long r)
+{
+       return l + prandom_u32_max(r - l);
+}
+
 /**
  * struct damon_addr_range - Represents an address region of [@start, @end).
  * @start:     Start address of the region (inclusive).
@@ -185,6 +192,22 @@ struct damos_watermarks {
        bool activated;
 };
 
+/**
+ * struct damos_stat - Statistics on a given scheme.
+ * @nr_tried:  Total number of regions that the scheme is tried to be applied.
+ * @sz_tried:  Total size of regions that the scheme is tried to be applied.
+ * @nr_applied:        Total number of regions that the scheme is applied.
+ * @sz_applied:        Total size of regions that the scheme is applied.
+ * @qt_exceeds: Total number of times the quota of the scheme has exceeded.
+ */
+struct damos_stat {
+       unsigned long nr_tried;
+       unsigned long sz_tried;
+       unsigned long nr_applied;
+       unsigned long sz_applied;
+       unsigned long qt_exceeds;
+};
+
 /**
  * struct damos - Represents a Data Access Monitoring-based Operation Scheme.
  * @min_sz_region:     Minimum size of target regions.
@@ -196,8 +219,7 @@ struct damos_watermarks {
  * @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.
- * @stat_count:                Total number of regions that this scheme is applied.
- * @stat_sz:           Total size of regions that this scheme is applied.
+ * @stat:              Statistics of this scheme.
  * @list:              List head for siblings.
  *
  * For each aggregation interval, DAMON finds regions which fit in the
@@ -228,8 +250,7 @@ struct damos {
        enum damos_action action;
        struct damos_quota quota;
        struct damos_watermarks wmarks;
-       unsigned long stat_count;
-       unsigned long stat_sz;
+       struct damos_stat stat;
        struct list_head list;
 };
 
@@ -274,7 +295,8 @@ struct damon_ctx;
  * as an integer in [0, &DAMOS_MAX_SCORE].
  * @apply_scheme is called from @kdamond when a region for user provided
  * DAMON-based operation scheme is found.  It should apply the scheme's action
- * to the region.  This is not used for &DAMON_ARBITRARY_TARGET case.
+ * to the region and return bytes of the region that the action is successfully
+ * applied.
  * @target_valid should check whether the target is still valid for the
  * monitoring.
  * @cleanup is called from @kdamond just before its termination.
@@ -288,8 +310,9 @@ struct damon_primitive {
        int (*get_scheme_score)(struct damon_ctx *context,
                        struct damon_target *t, struct damon_region *r,
                        struct damos *scheme);
-       int (*apply_scheme)(struct damon_ctx *context, struct damon_target *t,
-                       struct damon_region *r, struct damos *scheme);
+       unsigned long (*apply_scheme)(struct damon_ctx *context,
+                       struct damon_target *t, struct damon_region *r,
+                       struct damos *scheme);
        bool (*target_valid)(void *target);
        void (*cleanup)(struct damon_ctx *context);
 };
@@ -392,14 +415,20 @@ struct damon_ctx {
        struct list_head schemes;
 };
 
-#define damon_next_region(r) \
-       (container_of(r->list.next, struct damon_region, list))
+static inline struct damon_region *damon_next_region(struct damon_region *r)
+{
+       return container_of(r->list.next, struct damon_region, list);
+}
 
-#define damon_prev_region(r) \
-       (container_of(r->list.prev, struct damon_region, list))
+static inline struct damon_region *damon_prev_region(struct damon_region *r)
+{
+       return container_of(r->list.prev, struct damon_region, list);
+}
 
-#define damon_last_region(t) \
-       (list_last_entry(&t->regions_list, struct damon_region, list))
+static inline struct damon_region *damon_last_region(struct damon_target *t)
+{
+       return list_last_entry(&t->regions_list, struct damon_region, list);
+}
 
 #define damon_for_each_region(r, t) \
        list_for_each_entry(r, &t->regions_list, list)
@@ -422,9 +451,18 @@ struct damon_ctx {
 #ifdef CONFIG_DAMON
 
 struct damon_region *damon_new_region(unsigned long start, unsigned long end);
-inline void damon_insert_region(struct damon_region *r,
+
+/*
+ * Add a region between two other regions
+ */
+static inline void damon_insert_region(struct damon_region *r,
                struct damon_region *prev, struct damon_region *next,
-               struct damon_target *t);
+               struct damon_target *t)
+{
+       __list_add(&r->list, &prev->list, &next->list);
+       t->nr_regions++;
+}
+
 void damon_add_region(struct damon_region *r, struct damon_target *t);
 void damon_destroy_region(struct damon_region *r, struct damon_target *t);
 
@@ -461,34 +499,13 @@ int damon_stop(struct damon_ctx **ctxs, int nr_ctxs);
 #endif /* CONFIG_DAMON */
 
 #ifdef CONFIG_DAMON_VADDR
-
-/* Monitoring primitives for virtual memory address spaces */
-void damon_va_init(struct damon_ctx *ctx);
-void damon_va_update(struct damon_ctx *ctx);
-void damon_va_prepare_access_checks(struct damon_ctx *ctx);
-unsigned int damon_va_check_accesses(struct damon_ctx *ctx);
 bool damon_va_target_valid(void *t);
-void damon_va_cleanup(struct damon_ctx *ctx);
-int damon_va_apply_scheme(struct damon_ctx *context, struct damon_target *t,
-               struct damon_region *r, struct damos *scheme);
-int damon_va_scheme_score(struct damon_ctx *context, struct damon_target *t,
-               struct damon_region *r, struct damos *scheme);
 void damon_va_set_primitives(struct damon_ctx *ctx);
-
 #endif /* CONFIG_DAMON_VADDR */
 
 #ifdef CONFIG_DAMON_PADDR
-
-/* Monitoring primitives for the physical memory address space */
-void damon_pa_prepare_access_checks(struct damon_ctx *ctx);
-unsigned int damon_pa_check_accesses(struct damon_ctx *ctx);
 bool damon_pa_target_valid(void *t);
-int damon_pa_apply_scheme(struct damon_ctx *context, struct damon_target *t,
-               struct damon_region *r, struct damos *scheme);
-int damon_pa_scheme_score(struct damon_ctx *context, struct damon_target *t,
-               struct damon_region *r, struct damos *scheme);
 void damon_pa_set_primitives(struct damon_ctx *ctx);
-
 #endif /* CONFIG_DAMON_PADDR */
 
 #endif /* _DAMON_H */