Add option to disable cleaner

This allows to avoid allocating cleaner metadata section and effectively
save up to 20% of metadata memory footprint.

Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
Robert Baldyga 2022-04-14 21:30:31 +02:00
parent 761ff2f053
commit d4df912f46
9 changed files with 65 additions and 4 deletions

View File

@ -155,7 +155,10 @@ typedef enum {
/** Operation only allowed in standby mode **/ /** Operation only allowed in standby mode **/
OCF_ERR_CACHE_NOT_STANDBY, OCF_ERR_CACHE_NOT_STANDBY,
OCF_ERR_MAX = OCF_ERR_CACHE_NOT_STANDBY, /** Operation not allowed when cleaner is disabled **/
OCF_ERR_CLEANER_DISABLED,
OCF_ERR_MAX = OCF_ERR_CLEANER_DISABLED,
} ocf_error_t; } ocf_error_t;

View File

@ -424,6 +424,21 @@ struct ocf_mngt_cache_attach_config {
* @brief If set, cache device will be discarded on cache start * @brief If set, cache device will be discarded on cache start
*/ */
bool discard_on_start; bool discard_on_start;
/**
* @brief If set, asynchronous cleaning will be disabled
*
* Has similar effect to setting cleaning policy to NOP, but
* additionally prevents allocating "cleaning" metadata section,
* which can reduce memory footprint by up to 20%.
*
* When this option is selected, any attempt to change the cleaning
* policy will fail.
*
* @note This option is meaningful only with ocf_mngt_cache_attach().
* When used with ocf_mngt_cache_load() it's ignored.
*/
bool disable_cleaner;
}; };
/** /**
@ -441,6 +456,7 @@ static inline void ocf_mngt_cache_attach_config_set_default(
cfg->open_cores = true; cfg->open_cores = true;
cfg->force = false; cfg->force = false;
cfg->discard_on_start = true; cfg->discard_on_start = true;
cfg->disable_cleaner = false;
cfg->device.perform_test = true; cfg->device.perform_test = true;
cfg->device.volume_params = NULL; cfg->device.volume_params = NULL;
} }

View File

@ -638,7 +638,8 @@ static void ocf_metadata_flush_unlock_collision_page(
* Initialize hash metadata interface * Initialize hash metadata interface
*/ */
int ocf_metadata_init_variable_size(struct ocf_cache *cache, int ocf_metadata_init_variable_size(struct ocf_cache *cache,
uint64_t device_size, ocf_cache_line_size_t line_size) uint64_t device_size, ocf_cache_line_size_t line_size,
bool cleaner_disabled)
{ {
int result = 0; int result = 0;
uint32_t i = 0; uint32_t i = 0;
@ -688,6 +689,12 @@ int ocf_metadata_init_variable_size(struct ocf_cache *cache,
raw->raw_type = metadata_raw_type_atomic; raw->raw_type = metadata_raw_type_atomic;
} }
if (i == metadata_segment_cleaning && cleaner_disabled) {
raw->entry_size = 0;
raw->entries_in_page = 1;
continue;
}
/* Entry size configuration */ /* Entry size configuration */
raw->entry_size raw->entry_size
= ocf_metadata_get_element_size(i, line_size); = ocf_metadata_get_element_size(i, line_size);
@ -715,6 +722,9 @@ int ocf_metadata_init_variable_size(struct ocf_cache *cache,
*/ */
for (i = metadata_segment_variable_size_start; for (i = metadata_segment_variable_size_start;
i < metadata_segment_max; i++) { i < metadata_segment_max; i++) {
if (i == metadata_segment_cleaning && cleaner_disabled)
continue;
if (i == metadata_segment_collision) { if (i == metadata_segment_collision) {
lock_page = lock_page =
ocf_metadata_flush_lock_collision_page; ocf_metadata_flush_lock_collision_page;
@ -779,6 +789,7 @@ finalize:
cache->conf_meta->cachelines = ctrl->cachelines; cache->conf_meta->cachelines = ctrl->cachelines;
cache->conf_meta->line_size = line_size; cache->conf_meta->line_size = line_size;
cache->conf_meta->cleaner_disabled = cleaner_disabled;
ocf_metadata_raw_info(cache, ctrl); ocf_metadata_raw_info(cache, ctrl);
@ -1620,6 +1631,7 @@ static void ocf_metadata_load_properties_cmpl(
properties.shutdown_status = superblock->clean_shutdown; properties.shutdown_status = superblock->clean_shutdown;
properties.dirty_flushed = superblock->dirty_flushed; properties.dirty_flushed = superblock->dirty_flushed;
properties.cache_name = superblock->name; properties.cache_name = superblock->name;
properties.cleaner_disabled = superblock->cleaner_disabled;
OCF_CMPL_RET(priv, 0, &properties); OCF_CMPL_RET(priv, 0, &properties);
} }

View File

@ -41,10 +41,12 @@ int ocf_metadata_init(struct ocf_cache *cache,
* @param cache - Cache instance * @param cache - Cache instance
* @param device_size - Device size in bytes * @param device_size - Device size in bytes
* @param cache_line_size Cache line size * @param cache_line_size Cache line size
* @param cleaner_disabled Cleaner is disabled
* @return 0 - Operation success otherwise failure * @return 0 - Operation success otherwise failure
*/ */
int ocf_metadata_init_variable_size(struct ocf_cache *cache, int ocf_metadata_init_variable_size(struct ocf_cache *cache,
uint64_t device_size, ocf_cache_line_size_t cache_line_size); uint64_t device_size, ocf_cache_line_size_t line_size,
bool cleaner_disabled);
/** /**
* @brief Initialize collision table * @brief Initialize collision table
@ -201,6 +203,7 @@ struct ocf_metadata_load_properties {
ocf_cache_mode_t cache_mode; ocf_cache_mode_t cache_mode;
ocf_cache_line_size_t line_size; ocf_cache_line_size_t line_size;
char *cache_name; char *cache_name;
bool cleaner_disabled;
}; };
typedef void (*ocf_metadata_load_properties_end_t)(void *priv, int error, typedef void (*ocf_metadata_load_properties_end_t)(void *priv, int error,

View File

@ -18,6 +18,8 @@ ocf_metadata_get_cleaning_policy(struct ocf_cache *cache,
struct ocf_metadata_ctrl *ctrl struct ocf_metadata_ctrl *ctrl
= (struct ocf_metadata_ctrl *) cache->metadata.priv; = (struct ocf_metadata_ctrl *) cache->metadata.priv;
ENV_BUG_ON(cache->conf_meta->cleaner_disabled);
return ocf_metadata_raw_wr_access(cache, return ocf_metadata_raw_wr_access(cache,
&(ctrl->raw_desc[metadata_segment_cleaning]), line); &(ctrl->raw_desc[metadata_segment_cleaning]), line);
} }

View File

@ -110,8 +110,11 @@ static void ocf_metadata_store_segment(ocf_pipeline_t pipeline,
int ocf_metadata_validate_superblock(ocf_ctx_t ctx, int ocf_metadata_validate_superblock(ocf_ctx_t ctx,
struct ocf_superblock_config *superblock) struct ocf_superblock_config *superblock)
{ {
const char *segment_name;
uint32_t crc; uint32_t crc;
segment_name = ocf_metadata_segment_names[metadata_segment_sb_config];
if (superblock->magic_number != CACHE_MAGIC_NUMBER) { if (superblock->magic_number != CACHE_MAGIC_NUMBER) {
ocf_log(ctx, log_info, "Cannot detect pre-existing metadata\n"); ocf_log(ctx, log_info, "Cannot detect pre-existing metadata\n");
return -OCF_ERR_NO_METADATA; return -OCF_ERR_NO_METADATA;
@ -178,6 +181,14 @@ int ocf_metadata_validate_superblock(ocf_ctx_t ctx,
return -OCF_ERR_INVAL; return -OCF_ERR_INVAL;
} }
if (superblock->cleaner_disabled &&
superblock->cleaning_policy_type != ocf_cleaning_nop) {
ocf_log(ctx, log_err, "Loading %s: cleaner is disabled, but "
"cleaning policy is not set to nop!\n",
segment_name);
return -OCF_ERR_INVAL;
}
if (superblock->promotion_policy_type < 0 || if (superblock->promotion_policy_type < 0 ||
superblock->promotion_policy_type >= superblock->promotion_policy_type >=
ocf_promotion_max) { ocf_promotion_max) {

View File

@ -45,6 +45,7 @@ struct ocf_superblock_config {
unsigned long valid_core_bitmap[(OCF_CORE_MAX / unsigned long valid_core_bitmap[(OCF_CORE_MAX /
(sizeof(unsigned long) * 8)) + 1]; (sizeof(unsigned long) * 8)) + 1];
bool cleaner_disabled;
ocf_cleaning_t cleaning_policy_type; ocf_cleaning_t cleaning_policy_type;
struct cleaning_policy_config cleaning[CLEANING_POLICY_TYPE_MAX]; struct cleaning_policy_config cleaning[CLEANING_POLICY_TYPE_MAX];

View File

@ -162,6 +162,9 @@ struct ocf_cache_attach_context {
uint8_t dirty_flushed; uint8_t dirty_flushed;
/*!< is dirty data fully flushed */ /*!< is dirty data fully flushed */
bool cleaner_disabled;
/*!< is cleaner disabled */
} metadata; } metadata;
struct { struct {
@ -1117,6 +1120,7 @@ static void _ocf_mngt_load_read_properties_end(void *priv, int error,
context->metadata.shutdown_status = properties->shutdown_status; context->metadata.shutdown_status = properties->shutdown_status;
context->metadata.dirty_flushed = properties->dirty_flushed; context->metadata.dirty_flushed = properties->dirty_flushed;
context->metadata.line_size = properties->line_size; context->metadata.line_size = properties->line_size;
context->metadata.cleaner_disabled = properties->cleaner_disabled;
cache->conf_meta->cache_mode = properties->cache_mode; cache->conf_meta->cache_mode = properties->cache_mode;
ocf_pipeline_next(context->pipeline); ocf_pipeline_next(context->pipeline);
@ -1134,6 +1138,7 @@ static void _ocf_mngt_init_properties(ocf_pipeline_t pipeline,
context->metadata.dirty_flushed = DIRTY_FLUSHED; context->metadata.dirty_flushed = DIRTY_FLUSHED;
context->metadata.line_size = context->cfg.cache_line_size ?: context->metadata.line_size = context->cfg.cache_line_size ?:
cache->metadata.line_size; cache->metadata.line_size;
context->metadata.cleaner_disabled = context->cfg.disable_cleaner;
ocf_pipeline_next(pipeline); ocf_pipeline_next(pipeline);
} }
@ -1172,7 +1177,8 @@ static void _ocf_mngt_attach_prepare_metadata(ocf_pipeline_t pipeline,
* Initialize variable size metadata segments * Initialize variable size metadata segments
*/ */
ret = ocf_metadata_init_variable_size(cache, context->volume_size, ret = ocf_metadata_init_variable_size(cache, context->volume_size,
context->metadata.line_size); context->metadata.line_size,
context->metadata.cleaner_disabled);
if (ret) if (ret)
OCF_PL_FINISH_RET(pipeline, ret); OCF_PL_FINISH_RET(pipeline, ret);
@ -1227,6 +1233,9 @@ static void _ocf_mngt_attach_init_services(ocf_pipeline_t pipeline,
ocf_cache_t cache = context->cache; ocf_cache_t cache = context->cache;
ocf_error_t result; ocf_error_t result;
if (context->metadata.cleaner_disabled)
__set_cleaning_policy(cache, ocf_cleaning_nop);
result = __init_cleaning_policy(cache); result = __init_cleaning_policy(cache);
if (result) { if (result) {
ocf_cache_log(cache, log_err, ocf_cache_log(cache, log_err,
@ -2186,6 +2195,7 @@ static void _ocf_mngt_standby_init_properties(ocf_pipeline_t pipeline,
context->metadata.dirty_flushed = DIRTY_FLUSHED; context->metadata.dirty_flushed = DIRTY_FLUSHED;
context->metadata.line_size = context->cfg.cache_line_size ?: context->metadata.line_size = context->cfg.cache_line_size ?:
cache->metadata.line_size; cache->metadata.line_size;
context->metadata.cleaner_disabled = context->cfg.disable_cleaner;
ocf_pipeline_next(pipeline); ocf_pipeline_next(pipeline);
} }

View File

@ -1043,6 +1043,9 @@ void ocf_mngt_cache_cleaning_set_policy(ocf_cache_t cache,
OCF_CMPL_RET(priv, 0); OCF_CMPL_RET(priv, 0);
} }
if (cache->conf_meta->cleaner_disabled)
OCF_CMPL_RET(priv, -OCF_ERR_CLEANER_DISABLED);
ret = ocf_pipeline_create(&pipeline, cache, ret = ocf_pipeline_create(&pipeline, cache,
&_ocf_mngt_cache_set_cleaning_policy); &_ocf_mngt_cache_set_cleaning_policy);
if (ret) if (ret)