From 90b62d4d843b62574d3ba6989811f1826f787b6f Mon Sep 17 00:00:00 2001 From: Daniel Madej Date: Mon, 13 Oct 2025 10:14:59 +0200 Subject: [PATCH 1/5] Field description alignment fix Signed-off-by: Daniel Madej --- src/cleaning/alru_structs.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/cleaning/alru_structs.h b/src/cleaning/alru_structs.h index 64c338ea..ea3c2166 100644 --- a/src/cleaning/alru_structs.h +++ b/src/cleaning/alru_structs.h @@ -1,6 +1,7 @@ /* * Copyright(c) 2012-2021 Intel Corporation * Copyright(c) 2022 David Lee + * Copyright(c) 2025 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __CLEANING_ALRU_STRUCTS_H__ @@ -17,11 +18,11 @@ struct alru_cleaning_policy_meta { } __attribute__((packed)); struct alru_cleaning_policy_config { - uint32_t thread_wakeup_time; /* in seconds */ - uint32_t stale_buffer_time; /* in seconds */ - uint32_t flush_max_buffers; /* in lines */ - uint32_t activity_threshold; /* in milliseconds */ - uint32_t max_dirty_ratio; /* percent */ + uint32_t thread_wakeup_time; /* in seconds */ + uint32_t stale_buffer_time; /* in seconds */ + uint32_t flush_max_buffers; /* in lines */ + uint32_t activity_threshold; /* in milliseconds */ + uint32_t max_dirty_ratio; /* percent */ }; struct alru_cleaning_policy { From dbf21d4642816ff3f70367e50e279b16751e9370 Mon Sep 17 00:00:00 2001 From: Daniel Madej Date: Mon, 13 Oct 2025 13:08:10 +0200 Subject: [PATCH 2/5] Changed misleading 'max dirty ratio' name The updated name is 'dirty ratio trigger threshold' Signed-off-by: Daniel Madej --- inc/cleaning/alru.h | 18 ++++++++++-------- src/cleaning/alru.c | 26 +++++++++++++------------- src/cleaning/alru_structs.h | 2 +- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/inc/cleaning/alru.h b/inc/cleaning/alru.h index d7303986..e3f91e51 100644 --- a/inc/cleaning/alru.h +++ b/inc/cleaning/alru.h @@ -1,6 +1,7 @@ /* * Copyright(c) 2012-2021 Intel Corporation * Copyright(c) 2022 David Lee + * Copyright(c) 2025 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __OCF_CLEANING_ALRU_H__ @@ -16,7 +17,7 @@ enum ocf_cleaning_alru_parameters { ocf_alru_stale_buffer_time, ocf_alru_flush_max_buffers, ocf_alru_activity_threshold, - ocf_alru_max_dirty_ratio, + ocf_alru_dirty_ratio_threshold, }; /** @@ -69,15 +70,16 @@ enum ocf_cleaning_alru_parameters { #define OCF_ALRU_DEFAULT_ACTIVITY_THRESHOLD 10000 /** - * ALRU max dirty ratio for a cache device + * ALRU dirty-ratio-based cleaning trigger threshold */ -/** Minimum dirty ratio value */ -#define OCF_ALRU_MIN_MAX_DIRTY_RATIO 0 -/** Maximum dirty ratio value */ -#define OCF_ALRU_MAX_MAX_DIRTY_RATIO 100 -/** Default dirty ratio value */ -#define OCF_ALRU_DEFAULT_MAX_DIRTY_RATIO OCF_ALRU_MAX_MAX_DIRTY_RATIO +/** Minimum dirty ratio trigger threshold value */ +#define OCF_ALRU_MIN_DIRTY_RATIO_THRESHOLD 0 +/** Maximum dirty ratio trigger threshold value */ +#define OCF_ALRU_MAX_DIRTY_RATIO_THRESHOLD 100 +/** Default dirty ratio trigger threshold value */ +#define OCF_ALRU_DEFAULT_DIRTY_RATIO_THRESHOLD \ + OCF_ALRU_MAX_DIRTY_RATIO_THRESHOLD /** * @} */ diff --git a/src/cleaning/alru.c b/src/cleaning/alru.c index acf8eeeb..06519738 100644 --- a/src/cleaning/alru.c +++ b/src/cleaning/alru.c @@ -356,7 +356,7 @@ void cleaning_policy_alru_setup(struct ocf_cache *cache) config->stale_buffer_time = OCF_ALRU_DEFAULT_STALENESS_TIME; config->flush_max_buffers = OCF_ALRU_DEFAULT_FLUSH_MAX_BUFFERS; config->activity_threshold = OCF_ALRU_DEFAULT_ACTIVITY_THRESHOLD; - config->max_dirty_ratio = OCF_ALRU_DEFAULT_MAX_DIRTY_RATIO; + config->dirty_ratio_threshold = OCF_ALRU_DEFAULT_DIRTY_RATIO_THRESHOLD; } int cleaning_policy_alru_initialize(ocf_cache_t cache, int kick_cleaner) @@ -763,15 +763,15 @@ int cleaning_policy_alru_set_cleaning_param(ocf_cache_t cache, "activity time threshold: %d\n", config->activity_threshold); break; - case ocf_alru_max_dirty_ratio: + case ocf_alru_dirty_ratio_threshold: OCF_CLEANING_CHECK_PARAM(cache, param_value, - OCF_ALRU_MIN_MAX_DIRTY_RATIO, - OCF_ALRU_MAX_MAX_DIRTY_RATIO, - "max_dirty_ratio"); - config->max_dirty_ratio = param_value; + OCF_ALRU_MIN_DIRTY_RATIO_THRESHOLD, + OCF_ALRU_MAX_DIRTY_RATIO_THRESHOLD, + "dirty_ratio_threshold"); + config->dirty_ratio_threshold = param_value; ocf_cache_log(cache, log_info, "Write-back flush thread " - "max dirty ratio: %d\n", - config->max_dirty_ratio); + "dirty ratio trigger threshold: %d\n", + config->dirty_ratio_threshold); break; default: return -OCF_ERR_INVAL; @@ -800,8 +800,8 @@ int cleaning_policy_alru_get_cleaning_param(ocf_cache_t cache, case ocf_alru_activity_threshold: *param_value = config->activity_threshold; break; - case ocf_alru_max_dirty_ratio: - *param_value = config->max_dirty_ratio; + case ocf_alru_dirty_ratio_threshold: + *param_value = config->dirty_ratio_threshold; break; default: return -OCF_ERR_INVAL; @@ -854,13 +854,13 @@ static bool check_for_dirty_ratio(ocf_cache_t cache, { struct ocf_cache_info info; - if (config->max_dirty_ratio == OCF_ALRU_MAX_MAX_DIRTY_RATIO) + if (config->dirty_ratio_threshold == OCF_ALRU_MAX_DIRTY_RATIO_THRESHOLD) return false; if (ocf_cache_get_info(cache, &info)) return false; - return info.dirty * 100 / info.size >= config->max_dirty_ratio; + return info.dirty * 100 / info.size >= config->dirty_ratio_threshold; } static bool is_cleanup_possible(ocf_cache_t cache, struct alru_flush_ctx *fctx) @@ -873,7 +873,7 @@ static bool is_cleanup_possible(ocf_cache_t cache, struct alru_flush_ctx *fctx) if (check_for_dirty_ratio(cache, config)) { fctx->dirty_ratio_exceeded = true; OCF_DEBUG_PARAM(cache, "Dirty ratio exceeds: %u%%", - config->max_dirty_ratio); + config->dirty_ratio_threshold); return true; } diff --git a/src/cleaning/alru_structs.h b/src/cleaning/alru_structs.h index ea3c2166..e40f862a 100644 --- a/src/cleaning/alru_structs.h +++ b/src/cleaning/alru_structs.h @@ -22,7 +22,7 @@ struct alru_cleaning_policy_config { uint32_t stale_buffer_time; /* in seconds */ uint32_t flush_max_buffers; /* in lines */ uint32_t activity_threshold; /* in milliseconds */ - uint32_t max_dirty_ratio; /* percent */ + uint32_t dirty_ratio_threshold; /* percent */ }; struct alru_cleaning_policy { From ca23d851dce3e9abb438823dea3a04c887b46b58 Mon Sep 17 00:00:00 2001 From: Daniel Madej Date: Mon, 13 Oct 2025 13:20:23 +0200 Subject: [PATCH 3/5] Hysteresis for dirty ratio dependent cleaning After triggering flushing because of exceeding dirty ratio threshold, there will be inertia before the trigger is disabled. Signed-off-by: Daniel Madej --- inc/cleaning/alru.h | 9 +++++++++ src/cleaning/alru.c | 18 +++++++++++++++++- src/cleaning/alru_structs.h | 1 + 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/inc/cleaning/alru.h b/inc/cleaning/alru.h index e3f91e51..66ff157d 100644 --- a/inc/cleaning/alru.h +++ b/inc/cleaning/alru.h @@ -80,6 +80,15 @@ enum ocf_cleaning_alru_parameters { /** Default dirty ratio trigger threshold value */ #define OCF_ALRU_DEFAULT_DIRTY_RATIO_THRESHOLD \ OCF_ALRU_MAX_DIRTY_RATIO_THRESHOLD + +/** + * ALRU dirty-ratio-based cleaning trigger inertia + * Cleaning triggered by exceeding dirty ratio threshold will stop + * when dirty ratio drops below (threshold - inertia). + */ + +/** Default dirty ratio trigger inertia */ +#define OCF_ALRU_DEFAULT_DIRTY_RATIO_INERTIA (128 * MiB) /** * @} */ diff --git a/src/cleaning/alru.c b/src/cleaning/alru.c index 06519738..b6e37f92 100644 --- a/src/cleaning/alru.c +++ b/src/cleaning/alru.c @@ -59,6 +59,7 @@ struct alru_flush_ctx { struct alru_context { struct alru_flush_ctx flush_ctx; + bool dirty_ratio_triggered; env_spinlock list_lock[OCF_USER_IO_CLASS_MAX]; }; @@ -357,6 +358,7 @@ void cleaning_policy_alru_setup(struct ocf_cache *cache) config->flush_max_buffers = OCF_ALRU_DEFAULT_FLUSH_MAX_BUFFERS; config->activity_threshold = OCF_ALRU_DEFAULT_ACTIVITY_THRESHOLD; config->dirty_ratio_threshold = OCF_ALRU_DEFAULT_DIRTY_RATIO_THRESHOLD; + config->dirty_ratio_inertia = OCF_ALRU_DEFAULT_DIRTY_RATIO_INERTIA; } int cleaning_policy_alru_initialize(ocf_cache_t cache, int kick_cleaner) @@ -853,6 +855,9 @@ static bool check_for_dirty_ratio(ocf_cache_t cache, struct alru_cleaning_policy_config *config) { struct ocf_cache_info info; + struct alru_context *ctx; + /* values in cache lines */ + ocf_cache_line_t threshold_cl, inertia_cl; if (config->dirty_ratio_threshold == OCF_ALRU_MAX_DIRTY_RATIO_THRESHOLD) return false; @@ -860,7 +865,18 @@ static bool check_for_dirty_ratio(ocf_cache_t cache, if (ocf_cache_get_info(cache, &info)) return false; - return info.dirty * 100 / info.size >= config->dirty_ratio_threshold; + ctx = cache->cleaner.cleaning_policy_context; + threshold_cl = info.size / 100 * config->dirty_ratio_threshold; + if (ctx->dirty_ratio_triggered) { + inertia_cl = config->dirty_ratio_inertia / info.cache_line_size; + if (inertia_cl >= threshold_cl) + return true; + + threshold_cl -= inertia_cl; + } + + ctx->dirty_ratio_triggered = info.dirty >= threshold_cl; + return ctx->dirty_ratio_triggered; } static bool is_cleanup_possible(ocf_cache_t cache, struct alru_flush_ctx *fctx) diff --git a/src/cleaning/alru_structs.h b/src/cleaning/alru_structs.h index e40f862a..78f06dfe 100644 --- a/src/cleaning/alru_structs.h +++ b/src/cleaning/alru_structs.h @@ -23,6 +23,7 @@ struct alru_cleaning_policy_config { uint32_t flush_max_buffers; /* in lines */ uint32_t activity_threshold; /* in milliseconds */ uint32_t dirty_ratio_threshold; /* percent */ + uint32_t dirty_ratio_inertia; /* bytes */ }; struct alru_cleaning_policy { From 0352d772bb3be88fd13c08a0e664e74df26fa18a Mon Sep 17 00:00:00 2001 From: Daniel Madej Date: Mon, 13 Oct 2025 13:20:30 +0200 Subject: [PATCH 4/5] Configurable dirty ratio hysteresis Signed-off-by: Daniel Madej --- inc/cleaning/alru.h | 5 +++++ src/cleaning/alru.c | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/inc/cleaning/alru.h b/inc/cleaning/alru.h index 66ff157d..2804481c 100644 --- a/inc/cleaning/alru.h +++ b/inc/cleaning/alru.h @@ -18,6 +18,7 @@ enum ocf_cleaning_alru_parameters { ocf_alru_flush_max_buffers, ocf_alru_activity_threshold, ocf_alru_dirty_ratio_threshold, + ocf_alru_dirty_ratio_inertia, }; /** @@ -87,6 +88,10 @@ enum ocf_cleaning_alru_parameters { * when dirty ratio drops below (threshold - inertia). */ +/** Minimum dirty ratio trigger inertia value */ +#define OCF_ALRU_MIN_DIRTY_RATIO_INERTIA 0 +/** Maximum dirty ratio trigger inertia value */ +#define OCF_ALRU_MAX_DIRTY_RATIO_INERTIA UINT_MAX /** Default dirty ratio trigger inertia */ #define OCF_ALRU_DEFAULT_DIRTY_RATIO_INERTIA (128 * MiB) /** diff --git a/src/cleaning/alru.c b/src/cleaning/alru.c index b6e37f92..833a93cc 100644 --- a/src/cleaning/alru.c +++ b/src/cleaning/alru.c @@ -775,6 +775,16 @@ int cleaning_policy_alru_set_cleaning_param(ocf_cache_t cache, "dirty ratio trigger threshold: %d\n", config->dirty_ratio_threshold); break; + case ocf_alru_dirty_ratio_inertia: + OCF_CLEANING_CHECK_PARAM(cache, param_value, + OCF_ALRU_MIN_DIRTY_RATIO_INERTIA, + OCF_ALRU_MAX_DIRTY_RATIO_INERTIA, + "dirty_ratio_inertia"); + config->dirty_ratio_inertia = param_value; + ocf_cache_log(cache, log_info, "Write-back flush thread " + "dirty ratio trigger inertia: %d\n", + config->dirty_ratio_inertia); + break; default: return -OCF_ERR_INVAL; } @@ -805,6 +815,9 @@ int cleaning_policy_alru_get_cleaning_param(ocf_cache_t cache, case ocf_alru_dirty_ratio_threshold: *param_value = config->dirty_ratio_threshold; break; + case ocf_alru_dirty_ratio_inertia: + *param_value = config->dirty_ratio_inertia; + break; default: return -OCF_ERR_INVAL; } From 2a409380c24cb8d02e718df64f10982cb5052322 Mon Sep 17 00:00:00 2001 From: Daniel Madej Date: Mon, 13 Oct 2025 15:30:56 +0200 Subject: [PATCH 5/5] Pass `alru_context` from calling function Signed-off-by: Daniel Madej --- src/cleaning/alru.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/cleaning/alru.c b/src/cleaning/alru.c index 833a93cc..c4bf543d 100644 --- a/src/cleaning/alru.c +++ b/src/cleaning/alru.c @@ -865,10 +865,10 @@ static bool clean_later(ocf_cache_t cache, uint32_t *delta) } static bool check_for_dirty_ratio(ocf_cache_t cache, - struct alru_cleaning_policy_config *config) + struct alru_cleaning_policy_config *config, + struct alru_context *ctx) { struct ocf_cache_info info; - struct alru_context *ctx; /* values in cache lines */ ocf_cache_line_t threshold_cl, inertia_cl; @@ -878,7 +878,6 @@ static bool check_for_dirty_ratio(ocf_cache_t cache, if (ocf_cache_get_info(cache, &info)) return false; - ctx = cache->cleaner.cleaning_policy_context; threshold_cl = info.size / 100 * config->dirty_ratio_threshold; if (ctx->dirty_ratio_triggered) { inertia_cl = config->dirty_ratio_inertia / info.cache_line_size; @@ -892,14 +891,14 @@ static bool check_for_dirty_ratio(ocf_cache_t cache, return ctx->dirty_ratio_triggered; } -static bool is_cleanup_possible(ocf_cache_t cache, struct alru_flush_ctx *fctx) +static bool is_cleanup_possible(ocf_cache_t cache, struct alru_context *ctx) { + struct alru_flush_ctx *fctx = &ctx->flush_ctx; struct alru_cleaning_policy_config *config; uint32_t delta; - config = (void *)&cache->conf_meta->cleaning[ocf_cleaning_alru].data; - if (check_for_dirty_ratio(cache, config)) { + if (check_for_dirty_ratio(cache, config, ctx)) { fctx->dirty_ratio_exceeded = true; OCF_DEBUG_PARAM(cache, "Dirty ratio exceeds: %u%%", config->dirty_ratio_threshold); @@ -1056,7 +1055,7 @@ static void alru_clean(struct alru_context *ctx) ocf_cache_t cache = fctx->cache; int to_clean; - if (!is_cleanup_possible(cache, fctx)) { + if (!is_cleanup_possible(cache, ctx)) { alru_clean_complete(fctx, 0); return; }