};
 
 /**
- * struct damon_ctx - Represents a context for each monitoring.  This is the
- * main interface that allows users to set the attributes and get the results
- * of the monitoring.
+ * struct damon_attrs - Monitoring attributes for accuracy/overhead control.
  *
  * @sample_interval:           The time between access samplings.
  * @aggr_interval:             The time between monitor results aggregations.
  * @ops_update_interval:       The time between monitoring operations updates.
+ * @min_nr_regions:            The minimum number of adaptive monitoring
+ *                             regions.
+ * @max_nr_regions:            The maximum number of adaptive monitoring
+ *                             regions.
  *
  * For each @sample_interval, DAMON checks whether each region is accessed or
  * not.  It aggregates and keeps the access information (number of accesses to
  * @ops_update_interval.  All time intervals are in micro-seconds.
  * Please refer to &struct damon_operations and &struct damon_callback for more
  * detail.
+ */
+struct damon_attrs {
+       unsigned long sample_interval;
+       unsigned long aggr_interval;
+       unsigned long ops_update_interval;
+       unsigned long min_nr_regions;
+       unsigned long max_nr_regions;
+};
+
+/**
+ * struct damon_ctx - Represents a context for each monitoring.  This is the
+ * main interface that allows users to set the attributes and get the results
+ * of the monitoring.
  *
+ * @attrs:             Monitoring attributes for accuracy/overhead control.
  * @kdamond:           Kernel thread who does the monitoring.
  * @kdamond_lock:      Mutex for the synchronizations with @kdamond.
  *
  * @ops:       Set of monitoring operations for given use cases.
  * @callback:  Set of callbacks for monitoring events notifications.
  *
- * @min_nr_regions:    The minimum number of adaptive monitoring regions.
- * @max_nr_regions:    The maximum number of adaptive monitoring regions.
  * @adaptive_targets:  Head of monitoring targets (&damon_target) list.
  * @schemes:           Head of schemes (&damos) list.
  */
 struct damon_ctx {
-       unsigned long sample_interval;
-       unsigned long aggr_interval;
-       unsigned long ops_update_interval;
+       struct damon_attrs attrs;
 
 /* private: internal use only */
        struct timespec64 last_aggregation;
        struct damon_operations ops;
        struct damon_callback callback;
 
-       unsigned long min_nr_regions;
-       unsigned long max_nr_regions;
        struct list_head adaptive_targets;
        struct list_head schemes;
 };
 
        if (!ctx)
                return NULL;
 
-       ctx->sample_interval = 5 * 1000;
-       ctx->aggr_interval = 100 * 1000;
-       ctx->ops_update_interval = 60 * 1000 * 1000;
+       ctx->attrs.sample_interval = 5 * 1000;
+       ctx->attrs.aggr_interval = 100 * 1000;
+       ctx->attrs.ops_update_interval = 60 * 1000 * 1000;
 
        ktime_get_coarse_ts64(&ctx->last_aggregation);
        ctx->last_ops_update = ctx->last_aggregation;
 
        mutex_init(&ctx->kdamond_lock);
 
-       ctx->min_nr_regions = 10;
-       ctx->max_nr_regions = 1000;
+       ctx->attrs.min_nr_regions = 10;
+       ctx->attrs.max_nr_regions = 1000;
 
        INIT_LIST_HEAD(&ctx->adaptive_targets);
        INIT_LIST_HEAD(&ctx->schemes);
        if (min_nr_reg > max_nr_reg)
                return -EINVAL;
 
-       ctx->sample_interval = sample_int;
-       ctx->aggr_interval = aggr_int;
-       ctx->ops_update_interval = ops_upd_int;
-       ctx->min_nr_regions = min_nr_reg;
-       ctx->max_nr_regions = max_nr_reg;
+       ctx->attrs.sample_interval = sample_int;
+       ctx->attrs.aggr_interval = aggr_int;
+       ctx->attrs.ops_update_interval = ops_upd_int;
+       ctx->attrs.min_nr_regions = min_nr_reg;
+       ctx->attrs.max_nr_regions = max_nr_reg;
 
        return 0;
 }
                        sz += r->ar.end - r->ar.start;
        }
 
-       if (ctx->min_nr_regions)
-               sz /= ctx->min_nr_regions;
+       if (ctx->attrs.min_nr_regions)
+               sz /= ctx->attrs.min_nr_regions;
        if (sz < DAMON_MIN_REGION)
                sz = DAMON_MIN_REGION;
 
 static bool kdamond_aggregate_interval_passed(struct damon_ctx *ctx)
 {
        return damon_check_reset_time_interval(&ctx->last_aggregation,
-                       ctx->aggr_interval);
+                       ctx->attrs.aggr_interval);
 }
 
 /*
        damon_for_each_target(t, ctx)
                nr_regions += damon_nr_regions(t);
 
-       if (nr_regions > ctx->max_nr_regions / 2)
+       if (nr_regions > ctx->attrs.max_nr_regions / 2)
                return;
 
        /* Maybe the middle of the region has different access frequency */
        if (last_nr_regions == nr_regions &&
-                       nr_regions < ctx->max_nr_regions / 3)
+                       nr_regions < ctx->attrs.max_nr_regions / 3)
                nr_subregions = 3;
 
        damon_for_each_target(t, ctx)
 static bool kdamond_need_update_operations(struct damon_ctx *ctx)
 {
        return damon_check_reset_time_interval(&ctx->last_ops_update,
-                       ctx->ops_update_interval);
+                       ctx->attrs.ops_update_interval);
 }
 
 /*
                        continue;
                }
 
-               kdamond_usleep(ctx->sample_interval);
+               kdamond_usleep(ctx->attrs.sample_interval);
 
                if (ctx->ops.check_accesses)
                        max_nr_accesses = ctx->ops.check_accesses(ctx);
 
 
        mutex_lock(&ctx->kdamond_lock);
        ret = scnprintf(kbuf, ARRAY_SIZE(kbuf), "%lu %lu %lu %lu %lu\n",
-                       ctx->sample_interval, ctx->aggr_interval,
-                       ctx->ops_update_interval, ctx->min_nr_regions,
-                       ctx->max_nr_regions);
+                       ctx->attrs.sample_interval, ctx->attrs.aggr_interval,
+                       ctx->attrs.ops_update_interval,
+                       ctx->attrs.min_nr_regions, ctx->attrs.max_nr_regions);
        mutex_unlock(&ctx->kdamond_lock);
 
        return simple_read_from_buffer(buf, count, ppos, kbuf, ret);
 
        unsigned int age_weight = s->quota.weight_age;
        int hotness;
 
-       max_nr_accesses = c->aggr_interval / c->sample_interval;
+       max_nr_accesses = c->attrs.aggr_interval / c->attrs.sample_interval;
        freq_subscore = r->nr_accesses * DAMON_MAX_SUBSCORE / max_nr_accesses;
 
-       age_in_sec = (unsigned long)r->age * c->aggr_interval / 1000000;
+       age_in_sec = (unsigned long)r->age * c->attrs.aggr_interval / 1000000;
        for (age_in_log = 0; age_in_log < DAMON_MAX_AGE_IN_LOG && age_in_sec;
                        age_in_log++, age_in_sec >>= 1)
                ;
 
 
        for (i = 0; i < 3; i++)
                sz += regions[i].end - regions[i].start;
-       if (ctx->min_nr_regions)
-               sz /= ctx->min_nr_regions;
+       if (ctx->attrs.min_nr_regions)
+               sz /= ctx->attrs.min_nr_regions;
        if (sz < DAMON_MIN_REGION)
                sz = DAMON_MIN_REGION;