NR_DAMOS_ACTIONS,
};
+/**
+ * enum damos_quota_goal_metric - Represents the metric to be used as the goal
+ *
+ * @DAMOS_QUOTA_USER_INPUT: User-input value.
+ * @NR_DAMOS_QUOTA_GOAL_METRICS: Number of DAMOS quota goal metrics.
+ *
+ * Metrics equal to larger than @NR_DAMOS_QUOTA_GOAL_METRICS are unsupported.
+ */
+enum damos_quota_goal_metric {
+ DAMOS_QUOTA_USER_INPUT,
+ NR_DAMOS_QUOTA_GOAL_METRICS,
+};
+
/**
* struct damos_quota_goal - DAMOS scheme quota auto-tuning goal.
- * @target_value: Target value to achieve with the tuning.
- * @current_value: Current value that achieving with the tuning.
+ * @metric: Metric to be used for representing the goal.
+ * @target_value: Target value of @metric to achieve with the tuning.
+ * @current_value: Current value of @metric.
* @list: List head for siblings.
*
* Data structure for getting the current score of the quota tuning goal. The
* score is calculated by how close @current_value and @target_value are. Then
* the score is entered to DAMON's internal feedback loop mechanism to get the
* auto-tuned quota.
+ *
+ * If @metric is DAMOS_QUOTA_USER_INPUT, @current_value should be manually
+ * entered by the user, probably inside the kdamond callbacks. Otherwise,
+ * DAMON sets @current_value with self-measured value of @metric.
*/
struct damos_quota_goal {
+ enum damos_quota_goal_metric metric;
unsigned long target_value;
unsigned long current_value;
struct list_head list;
void damos_destroy_filter(struct damos_filter *f);
struct damos_quota_goal *damos_new_quota_goal(
- unsigned long target_value, unsigned long current_value);
+ enum damos_quota_goal_metric metric,
+ unsigned long target_value);
void damos_add_quota_goal(struct damos_quota *q, struct damos_quota_goal *g);
void damos_destroy_quota_goal(struct damos_quota_goal *goal);
}
struct damos_quota_goal *damos_new_quota_goal(
- unsigned long target_value, unsigned long current_value)
+ enum damos_quota_goal_metric metric,
+ unsigned long target_value)
{
struct damos_quota_goal *goal;
goal = kmalloc(sizeof(*goal), GFP_KERNEL);
if (!goal)
return NULL;
+ goal->metric = metric;
goal->target_value = target_value;
- goal->current_value = current_value;
INIT_LIST_HEAD(&goal->list);
return goal;
}
return min_input;
}
+static void damos_set_quota_goal_current_value(struct damos_quota_goal *goal)
+{
+ u64 now_psi_total;
+
+ switch (goal->metric) {
+ case DAMOS_QUOTA_USER_INPUT:
+ /* User should already set goal->current_value */
+ break;
+ default:
+ break;
+ }
+}
+
/* Return the highest score since it makes schemes least aggressive */
static unsigned long damos_quota_score(struct damos_quota *quota)
{
struct damos_quota_goal *goal;
unsigned long highest_score = 0;
- damos_for_each_quota_goal(goal, quota)
+ damos_for_each_quota_goal(goal, quota) {
+ damos_set_quota_goal_current_value(goal);
highest_score = max(highest_score,
goal->current_value * 10000 /
goal->target_value);
+ }
return highest_score;
}
if (!sysfs_goal->target_value)
continue;
- goal = damos_new_quota_goal(sysfs_goal->target_value,
- sysfs_goal->current_value);
+ goal = damos_new_quota_goal(DAMOS_QUOTA_USER_INPUT,
+ sysfs_goal->target_value);
if (!goal)
return -ENOMEM;
+ goal->current_value = sysfs_goal->current_value;
damos_add_quota_goal(quota, goal);
}
return 0;