/* 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) */ staticinlineunsignedlong damon_rand(unsignedlong l, unsignedlong r)
{ return l + get_random_u32_below(r - l);
}
/** * struct damon_addr_range - Represents an address region of [@start, @end). * @start: Start address of the region (inclusive). * @end: End address of the region (exclusive).
*/ struct damon_addr_range { unsignedlong start; unsignedlong end;
};
/** * struct damon_size_range - Represents size for filter to operate on [@min, @max]. * @min: Min size (inclusive). * @max: Max size (inclusive).
*/ struct damon_size_range { unsignedlong min; unsignedlong max;
};
/** * struct damon_region - Represents a monitoring target region. * @ar: The address range of the region. * @sampling_addr: Address of the sample for the next access check. * @nr_accesses: Access frequency of this region. * @nr_accesses_bp: @nr_accesses in basis point (0.01%) that updated for * each sampling interval. * @list: List head for siblings. * @age: Age of this region. * * @nr_accesses is reset to zero for every &damon_attrs->aggr_interval and be * increased for every &damon_attrs->sample_interval if an access to the region * during the last sampling interval is found. The update of this field should * not be done with direct access but with the helper function, * damon_update_region_access_rate(). * * @nr_accesses_bp is another representation of @nr_accesses in basis point * (1 in 10,000) that updated for every &damon_attrs->sample_interval in a * manner similar to moving sum. By the algorithm, this value becomes * @nr_accesses * 10000 for every &struct damon_attrs->aggr_interval. This can * be used when the aggregation interval is too huge and therefore cannot wait * for it before getting the access monitoring results. * * @age is initially zero, increased for each aggregation interval, and reset * to zero again if the access frequency is significantly changed. If two * regions are merged into a new region, both @nr_accesses and @age of the new * region are set as region size-weighted average of those of the two regions.
*/ struct damon_region { struct damon_addr_range ar; unsignedlong sampling_addr; unsignedint nr_accesses; unsignedint nr_accesses_bp; struct list_head list;
unsignedint age; /* private: Internal value for age calculation. */ unsignedint last_nr_accesses;
};
/** * struct damon_target - Represents a monitoring target. * @pid: The PID of the virtual address space to monitor. * @nr_regions: Number of monitoring target regions of this target. * @regions_list: Head of the monitoring target regions of this target. * @list: List head for siblings. * * Each monitoring context could have multiple targets. For example, a context * for virtual memory address spaces could have multiple target processes. The * @pid should be set for appropriate &struct damon_operations including the * virtual address spaces monitoring operations.
*/ struct damon_target { struct pid *pid; unsignedint nr_regions; struct list_head regions_list; struct list_head list;
};
/** * enum damos_action - Represents an action of a Data Access Monitoring-based * Operation Scheme. * * @DAMOS_WILLNEED: Call ``madvise()`` for the region with MADV_WILLNEED. * @DAMOS_COLD: Call ``madvise()`` for the region with MADV_COLD. * @DAMOS_PAGEOUT: Call ``madvise()`` for the region with MADV_PAGEOUT. * @DAMOS_HUGEPAGE: Call ``madvise()`` for the region with MADV_HUGEPAGE. * @DAMOS_NOHUGEPAGE: Call ``madvise()`` for the region with MADV_NOHUGEPAGE. * @DAMOS_LRU_PRIO: Prioritize the region on its LRU lists. * @DAMOS_LRU_DEPRIO: Deprioritize the region on its LRU lists. * @DAMOS_MIGRATE_HOT: Migrate the regions prioritizing warmer regions. * @DAMOS_MIGRATE_COLD: Migrate the regions prioritizing colder regions. * @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,
DAMOS_COLD,
DAMOS_PAGEOUT,
DAMOS_HUGEPAGE,
DAMOS_NOHUGEPAGE,
DAMOS_LRU_PRIO,
DAMOS_LRU_DEPRIO,
DAMOS_MIGRATE_HOT,
DAMOS_MIGRATE_COLD,
DAMOS_STAT, /* Do nothing but only record the stat */
NR_DAMOS_ACTIONS,
};
/** * enum damos_quota_goal_metric - Represents the metric to be used as the goal * * @DAMOS_QUOTA_USER_INPUT: User-input value. * @DAMOS_QUOTA_SOME_MEM_PSI_US: System level some memory PSI in us. * @DAMOS_QUOTA_NODE_MEM_USED_BP: MemUsed ratio of a node. * @DAMOS_QUOTA_NODE_MEM_FREE_BP: MemFree ratio of a node. * @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,
DAMOS_QUOTA_SOME_MEM_PSI_US,
DAMOS_QUOTA_NODE_MEM_USED_BP,
DAMOS_QUOTA_NODE_MEM_FREE_BP,
NR_DAMOS_QUOTA_GOAL_METRICS,
};
/** * struct damos_quota_goal - DAMOS scheme quota auto-tuning goal. * @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. * @last_psi_total: Last measured total PSI * @nid: Node id. * @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; unsignedlong target_value; unsignedlong current_value; /* metric-dependent fields */ union {
u64 last_psi_total; int nid;
}; struct list_head list;
};
/** * struct damos_quota - Controls the aggressiveness of the given scheme. * @reset_interval: Charge reset interval in milliseconds. * @ms: Maximum milliseconds that the scheme can use. * @sz: Maximum bytes of memory that the action can be applied. * @goals: Head of quota tuning goals (&damos_quota_goal) list. * @esz: Effective size quota in bytes. * * @weight_sz: Weight of the region's size for prioritization. * @weight_nr_accesses: Weight of the region's nr_accesses for prioritization. * @weight_age: Weight of the region's age for prioritization. * * To avoid consuming too much CPU time or IO resources for applying the * &struct damos->action to large memory, DAMON allows users to set time and/or * size quotas. The quotas can be set by writing non-zero values to &ms and * &sz, respectively. If the time quota is set, DAMON tries to use only up to * &ms milliseconds within &reset_interval for applying the action. If the * size quota is set, DAMON tries to apply the action only up to &sz bytes * within &reset_interval. * * To convince the different types of quotas and goals, DAMON internally * converts those into one single size quota called "effective quota". DAMON * internally uses it as the only one real quota. The conversion is made as * follows. * * The time quota is transformed to a size quota using estimated throughput of * the scheme's action. DAMON then compares it against &sz and uses smaller * one as the effective quota. * * If @goals is not empty, DAMON calculates yet another size quota based on the * goals using its internal feedback loop algorithm, for every @reset_interval. * Then, if the new size quota is smaller than the effective quota, it uses the * new size quota as the effective quota. * * The resulting effective size quota in bytes is set to @esz. * * For selecting regions within the quota, DAMON prioritizes current scheme's * target memory regions using the &struct damon_operations->get_scheme_score. * You could customize the prioritization logic by setting &weight_sz, * &weight_nr_accesses, and &weight_age, because monitoring operations are * encouraged to respect those.
*/ struct damos_quota { unsignedlong reset_interval; unsignedlong ms; unsignedlong sz; struct list_head goals; unsignedlong esz;
/* For charging the quota */ unsignedlong charged_sz; unsignedlong charged_from; struct damon_target *charge_target_from; unsignedlong charge_addr_from;
/* For prioritization */ unsignedint min_score;
/* For feedback loop */ unsignedlong esz_bp;
};
/** * enum damos_wmark_metric - Represents the watermark metric. * * @DAMOS_WMARK_NONE: Ignore the watermarks of the given scheme. * @DAMOS_WMARK_FREE_MEM_RATE: Free memory rate of the system in [0,1000]. * @NR_DAMOS_WMARK_METRICS: Total number of DAMOS watermark metrics
*/ enum damos_wmark_metric {
DAMOS_WMARK_NONE,
DAMOS_WMARK_FREE_MEM_RATE,
NR_DAMOS_WMARK_METRICS,
};
/** * struct damos_watermarks - Controls when a given scheme should be activated. * @metric: Metric for the watermarks. * @interval: Watermarks check time interval in microseconds. * @high: High watermark. * @mid: Middle watermark. * @low: Low watermark. * * If &metric is &DAMOS_WMARK_NONE, the scheme is always active. Being active * means DAMON does monitoring and applying the action of the scheme to * appropriate memory regions. Else, DAMON checks &metric of the system for at * least every &interval microseconds and works as below. * * If &metric is higher than &high, the scheme is inactivated. If &metric is * between &mid and &low, the scheme is activated. If &metric is lower than * &low, the scheme is inactivated.
*/ struct damos_watermarks { enum damos_wmark_metric metric; unsignedlong interval; unsignedlong high; unsignedlong mid; unsignedlong low;
/* private: */ 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. * @sz_ops_filter_passed: * Total bytes that passed ops layer-handled DAMOS filters. * @qt_exceeds: Total number of times the quota of the scheme has exceeded. * * "Tried an action to a region" in this context means the DAMOS core logic * determined the region as eligible to apply the action. The access pattern * (&struct damos_access_pattern), quotas (&struct damos_quota), watermarks * (&struct damos_watermarks) and filters (&struct damos_filter) that handled * on core logic can affect this. The core logic asks the operation set * (&struct damon_operations) to apply the action to the region. * * "Applied an action to a region" in this context means the operation set * (&struct damon_operations) successfully applied the action to the region, at * least to a part of the region. The filters (&struct damos_filter) that * handled on operation set layer and type of the action and pages of the * region can affect this. For example, if a filter is set to exclude * anonymous pages and the region has only anonymous pages, the region will be * failed at applying the action. If the action is &DAMOS_PAGEOUT and all * pages of the region are already paged out, the region will be failed at * applying the action.
*/ struct damos_stat { unsignedlong nr_tried; unsignedlong sz_tried; unsignedlong nr_applied; unsignedlong sz_applied; unsignedlong sz_ops_filter_passed; unsignedlong qt_exceeds;
};
/** * enum damos_filter_type - Type of memory for &struct damos_filter * @DAMOS_FILTER_TYPE_ANON: Anonymous pages. * @DAMOS_FILTER_TYPE_ACTIVE: Active pages. * @DAMOS_FILTER_TYPE_MEMCG: Specific memcg's pages. * @DAMOS_FILTER_TYPE_YOUNG: Recently accessed pages. * @DAMOS_FILTER_TYPE_HUGEPAGE_SIZE: Page is part of a hugepage. * @DAMOS_FILTER_TYPE_UNMAPPED: Unmapped pages. * @DAMOS_FILTER_TYPE_ADDR: Address range. * @DAMOS_FILTER_TYPE_TARGET: Data Access Monitoring target. * @NR_DAMOS_FILTER_TYPES: Number of filter types. * * The anon pages type and memcg type filters are handled by underlying * &struct damon_operations as a part of scheme action trying, and therefore * accounted as 'tried'. In contrast, other types are handled by core layer * before trying of the action and therefore not accounted as 'tried'. * * The support of the filters that handled by &struct damon_operations depend * on the running &struct damon_operations. * &enum DAMON_OPS_PADDR supports both anon pages type and memcg type filters, * while &enum DAMON_OPS_VADDR and &enum DAMON_OPS_FVADDR don't support any of * the two types.
*/ enum damos_filter_type {
DAMOS_FILTER_TYPE_ANON,
DAMOS_FILTER_TYPE_ACTIVE,
DAMOS_FILTER_TYPE_MEMCG,
DAMOS_FILTER_TYPE_YOUNG,
DAMOS_FILTER_TYPE_HUGEPAGE_SIZE,
DAMOS_FILTER_TYPE_UNMAPPED,
DAMOS_FILTER_TYPE_ADDR,
DAMOS_FILTER_TYPE_TARGET,
NR_DAMOS_FILTER_TYPES,
};
/** * struct damos_filter - DAMOS action target memory filter. * @type: Type of the target memory. * @matching: Whether this is for @type-matching memory. * @allow: Whether to include or exclude the @matching memory. * @memcg_id: Memcg id of the question if @type is DAMOS_FILTER_MEMCG. * @addr_range: Address range if @type is DAMOS_FILTER_TYPE_ADDR. * @target_idx: Index of the &struct damon_target of * &damon_ctx->adaptive_targets if @type is * DAMOS_FILTER_TYPE_TARGET. * @sz_range: Size range if @type is DAMOS_FILTER_TYPE_HUGEPAGE_SIZE. * @list: List head for siblings. * * Before applying the &damos->action to a memory region, DAMOS checks if each * byte of the region matches to this given condition and avoid applying the * action if so. Support of each filter type depends on the running &struct * damon_operations and the type. Refer to &enum damos_filter_type for more * details.
*/ struct damos_filter { enum damos_filter_type type; bool matching; bool allow; union { unsignedshort memcg_id; struct damon_addr_range addr_range; int target_idx; struct damon_size_range sz_range;
}; struct list_head list;
};
struct damon_ctx; struct damos;
/** * struct damos_walk_control - Control damos_walk(). * * @walk_fn: Function to be called back for each region. * @data: Data that will be passed to walk functions. * * Control damos_walk(), which requests specific kdamond to invoke the given * function to each region that eligible to apply actions of the kdamond's * schemes. Refer to damos_walk() for more details.
*/ struct damos_walk_control { void (*walk_fn)(void *data, struct damon_ctx *ctx, struct damon_target *t, struct damon_region *r, struct damos *s, unsignedlong sz_filter_passed); void *data; /* private: internal use only */ /* informs if the kdamond finished handling of the walk request */ struct completion completion; /* informs if the walk is canceled. */ bool canceled;
};
/** * struct damos_access_pattern - Target access pattern of the given scheme. * @min_sz_region: Minimum size of target regions. * @max_sz_region: Maximum size of target regions. * @min_nr_accesses: Minimum ``->nr_accesses`` of target regions. * @max_nr_accesses: Maximum ``->nr_accesses`` of target regions. * @min_age_region: Minimum age of target regions. * @max_age_region: Maximum age of target regions.
*/ struct damos_access_pattern { unsignedlong min_sz_region; unsignedlong max_sz_region; unsignedint min_nr_accesses; unsignedint max_nr_accesses; unsignedint min_age_region; unsignedint max_age_region;
};
/** * struct damos_migrate_dests - Migration destination nodes and their weights. * @node_id_arr: Array of migration destination node ids. * @weight_arr: Array of migration weights for @node_id_arr. * @nr_dests: Length of the @node_id_arr and @weight_arr arrays. * * @node_id_arr is an array of the ids of migration destination nodes. * @weight_arr is an array of the weights for those. The weights in * @weight_arr are for nodes in @node_id_arr of same array index.
*/ struct damos_migrate_dests { unsignedint *node_id_arr; unsignedint *weight_arr;
size_t nr_dests;
};
/** * struct damos - Represents a Data Access Monitoring-based Operation Scheme. * @pattern: Access pattern of target regions. * @action: &damos_action to be applied to the target regions. * @apply_interval_us: The time between applying the @action. * @quota: Control the aggressiveness of this scheme. * @wmarks: Watermarks for automated (in)activation of this scheme. * @migrate_dests: Destination nodes if @action is "migrate_{hot,cold}". * @target_nid: Destination node if @action is "migrate_{hot,cold}". * @filters: Additional set of &struct damos_filter for &action. * @ops_filters: ops layer handling &struct damos_filter objects list. * @last_applied: Last @action applied ops-managing entity. * @stat: Statistics of this scheme. * @list: List head for siblings. * * For each @apply_interval_us, DAMON finds regions which fit in the * &pattern and applies &action to those. To avoid consuming too much * CPU time or IO resources for the &action, "a is used. * * If @apply_interval_us is zero, &damon_attrs->aggr_interval is used instead. * * To do the work only when needed, schemes can be activated for specific * system situations using &wmarks. If all schemes that registered to the * monitoring context are inactive, DAMON stops monitoring either, and just * repeatedly checks the watermarks. * * @migrate_dests specifies multiple migration target nodes with different * weights for migrate_hot or migrate_cold actions. @target_nid is ignored if * this is set. * * @target_nid is used to set the migration target node for migrate_hot or * migrate_cold actions, and @migrate_dests is unset. * * Before applying the &action to a memory region, &struct damon_operations * implementation could check pages of the region and skip &action to respect * &filters * * The minimum entity that @action can be applied depends on the underlying * &struct damon_operations. Since it may not be aligned with the core layer * abstract, namely &struct damon_region, &struct damon_operations could apply * @action to same entity multiple times. Large folios that underlying on * multiple &struct damon region objects could be such examples. The &struct * damon_operations can use @last_applied to avoid that. DAMOS core logic * unsets @last_applied when each regions walking for applying the scheme is * finished. * * 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.
*/ struct damos { struct damos_access_pattern pattern; enum damos_action action; unsignedlong apply_interval_us; /* private: internal use only */ /* * number of sample intervals that should be passed before applying * @action
*/ unsignedlong next_apply_sis; /* informs if ongoing DAMOS walk for this scheme is finished */ bool walk_completed; /* * If the current region in the filtering stage is allowed by core * layer-handled filters. If true, operations layer allows it, too.
*/ bool core_filters_allowed; /* whether to reject core/ops filters umatched regions */ bool core_filters_default_reject; bool ops_filters_default_reject; /* public: */ struct damos_quota quota; struct damos_watermarks wmarks; union { struct { int target_nid; struct damos_migrate_dests migrate_dests;
};
}; struct list_head filters; struct list_head ops_filters; void *last_applied; struct damos_stat stat; struct list_head list;
};
/** * enum damon_ops_id - Identifier for each monitoring operations implementation * * @DAMON_OPS_VADDR: Monitoring operations for virtual address spaces * @DAMON_OPS_FVADDR: Monitoring operations for only fixed ranges of virtual * address spaces * @DAMON_OPS_PADDR: Monitoring operations for the physical address space * @NR_DAMON_OPS: Number of monitoring operations implementations
*/ enum damon_ops_id {
DAMON_OPS_VADDR,
DAMON_OPS_FVADDR,
DAMON_OPS_PADDR,
NR_DAMON_OPS,
};
/** * struct damon_operations - Monitoring operations for given use cases. * * @id: Identifier of this operations set. * @init: Initialize operations-related data structures. * @update: Update operations-related data structures. * @prepare_access_checks: Prepare next access check of target regions. * @check_accesses: Check the accesses to target regions. * @get_scheme_score: Get the score of a region for a scheme. * @apply_scheme: Apply a DAMON-based operation scheme. * @target_valid: Determine if the target is valid. * @cleanup_target: Clean up each target before deallocation. * @cleanup: Clean up the context. * * DAMON can be extended for various address spaces and usages. For this, * 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_attrs.ops_update_interval, and * @check_accesses, @target_valid and @prepare_access_checks after each * &damon_attrs.sample_interval. * * Each &struct damon_operations instance having valid @id can be registered * via damon_register_ops() and selected by damon_select_ops() later. * @init should initialize operations-related data structures. For example, * this could be used to construct proper monitoring target regions and link * those to @damon_ctx.adaptive_targets. * @update should update the operations-related data structures. For example, * this could be used to update monitoring target regions for current status. * @prepare_access_checks should manipulate the monitoring regions to be * prepared for the next access check. * @check_accesses should check the accesses to each region that made after the * last preparation and update the number of observed accesses of each region. * It should also return max number of observed accesses that made as a result * of its update. The value will be used for regions adjustment threshold. * @get_scheme_score should return the priority score of a region for a scheme * 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 and return bytes of the region that the action is successfully * applied. It should also report how many bytes of the region has passed * filters (&struct damos_filter) that handled by itself. * @target_valid should check whether the target is still valid for the * monitoring. * @cleanup_target is called before the target will be deallocated. * @cleanup is called from @kdamond just before its termination.
*/ struct damon_operations { enum damon_ops_id id; void (*init)(struct damon_ctx *context); void (*update)(struct damon_ctx *context); void (*prepare_access_checks)(struct damon_ctx *context); unsignedint (*check_accesses)(struct damon_ctx *context); int (*get_scheme_score)(struct damon_ctx *context, struct damon_target *t, struct damon_region *r, struct damos *scheme); unsignedlong (*apply_scheme)(struct damon_ctx *context, struct damon_target *t, struct damon_region *r, struct damos *scheme, unsignedlong *sz_filter_passed); bool (*target_valid)(struct damon_target *t); void (*cleanup_target)(struct damon_target *t); void (*cleanup)(struct damon_ctx *context);
};
/* * struct damon_call_control - Control damon_call(). * * @fn: Function to be called back. * @data: Data that will be passed to @fn. * @repeat: Repeat invocations. * @return_code: Return code from @fn invocation. * @dealloc_on_cancel: De-allocate when canceled. * * Control damon_call(), which requests specific kdamond to invoke a given * function. Refer to damon_call() for more details.
*/ struct damon_call_control { int (*fn)(void *data); void *data; bool repeat; int return_code; bool dealloc_on_cancel; /* private: internal use only */ /* informs if the kdamond finished handling of the request */ struct completion completion; /* informs if the kdamond canceled @fn infocation */ bool canceled; /* List head for siblings. */ struct list_head list;
};
/** * struct damon_intervals_goal - Monitoring intervals auto-tuning goal. * * @access_bp: Access events observation ratio to achieve in bp. * @aggrs: Number of aggregations to achieve @access_bp within. * @min_sample_us: Minimum resulting sampling interval in microseconds. * @max_sample_us: Maximum resulting sampling interval in microseconds. * * DAMON automatically tunes &damon_attrs->sample_interval and * &damon_attrs->aggr_interval aiming the ratio in bp (1/10,000) of * DAMON-observed access events to theoretical maximum amount within @aggrs * aggregations be same to @access_bp. The logic increases * &damon_attrs->aggr_interval and &damon_attrs->sampling_interval in same * ratio if the current access events observation ratio is lower than the * target for each @aggrs aggregations, and vice versa. * * If @aggrs is zero, the tuning is disabled and hence this struct is ignored.
*/ struct damon_intervals_goal { unsignedlong access_bp; unsignedlong aggrs; unsignedlong min_sample_us; unsignedlong max_sample_us;
};
/** * 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. * @intervals_goal: Intervals auto-tuning goal. * @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 during the last @sample_interval. If such access is found, DAMON * aggregates the information by increasing &damon_region->nr_accesses for * @aggr_interval time. For each @aggr_interval, the count is reset. DAMON * also checks whether the target memory regions need update (e.g., by * ``mmap()`` calls from the application, in case of virtual memory monitoring) * and applies the changes for each @ops_update_interval. All time intervals * are in micro-seconds. Please refer to &struct damon_operations and &struct * damon_call_control for more detail.
*/ struct damon_attrs { unsignedlong sample_interval; unsignedlong aggr_interval; unsignedlong ops_update_interval; struct damon_intervals_goal intervals_goal; unsignedlong min_nr_regions; unsignedlong max_nr_regions; /* private: internal use only */ /* * @aggr_interval to @sample_interval ratio. * Core-external components call damon_set_attrs() with &damon_attrs * that this field is unset. In the case, damon_set_attrs() sets this * field of resulting &damon_attrs. Core-internal components such as * kdamond_tune_intervals() calls damon_set_attrs() with &damon_attrs * that this field is set. In the case, damon_set_attrs() just keep * it.
*/ unsignedlong aggr_samples;
};
/** * 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. * * For each monitoring context, one kernel thread for the monitoring is * created. The pointer to the thread is stored in @kdamond. * * Once started, the monitoring thread runs until explicitly required to be * terminated or every monitoring target is invalid. The validity of the * targets is checked via the &damon_operations.target_valid of @ops. The * termination can also be explicitly requested by calling damon_stop(). * The thread sets @kdamond to NULL when it terminates. Therefore, users can * know whether the monitoring is ongoing or terminated by reading @kdamond. * Reads and writes to @kdamond from outside of the monitoring thread must * be protected by @kdamond_lock. * * Note that the monitoring thread protects only @kdamond via @kdamond_lock. * Accesses to other fields must be protected by themselves. * * @ops: Set of monitoring operations for given use cases. * * @adaptive_targets: Head of monitoring targets (&damon_target) list. * @schemes: Head of schemes (&damos) list.
*/ struct damon_ctx { struct damon_attrs attrs;
/* private: internal use only */ /* number of sample intervals that passed since this context started */ unsignedlong passed_sample_intervals; /* * number of sample intervals that should be passed before next * aggregation
*/ unsignedlong next_aggregation_sis; /* * number of sample intervals that should be passed before next ops * update
*/ unsignedlong next_ops_update_sis; /* * number of sample intervals that should be passed before next * intervals tuning
*/ unsignedlong next_intervals_tune_sis; /* for waiting until the execution of the kdamond_fn is started */ struct completion kdamond_started; /* for scheme quotas prioritization */ unsignedlong *regions_score_histogram;
/* * Add a region between two other regions
*/ staticinlinevoid damon_insert_region(struct damon_region *r, struct damon_region *prev, struct damon_region *next, struct damon_target *t)
{
__list_add(&r->list, &prev->list, &next->list);
t->nr_regions++;
}
staticinlineunsignedint damon_max_nr_accesses(conststruct damon_attrs *attrs)
{ /* {aggr,sample}_interval are unsigned long, hence could overflow */ return min(attrs->aggr_interval / attrs->sample_interval,
(unsignedlong)UINT_MAX);
}
int damon_start(struct damon_ctx **ctxs, int nr_ctxs, bool exclusive); int damon_stop(struct damon_ctx **ctxs, int nr_ctxs); bool damon_is_running(struct damon_ctx *ctx);
int damon_call(struct damon_ctx *ctx, struct damon_call_control *control); int damos_walk(struct damon_ctx *ctx, struct damos_walk_control *control);
int damon_set_region_biggest_system_ram_default(struct damon_target *t, unsignedlong *start, unsignedlong *end);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.