From d2fe82dc8540ec17003b2808da4fc9cc82579e2d Mon Sep 17 00:00:00 2001 From: Jan Musial Date: Thu, 12 Mar 2020 07:12:18 +0100 Subject: [PATCH] Add memory check before engaging promotion policy Signed-off-by: Jan Musial --- src/promotion/nhit/nhit.c | 25 +++++++++++++++++++++++++ src/promotion/nhit/nhit_hash.c | 24 +++++++++++++++++++++--- src/promotion/nhit/nhit_hash.h | 2 ++ src/promotion/promotion.c | 11 +++++++++++ 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/promotion/nhit/nhit.c b/src/promotion/nhit/nhit.c index b2d2fc5..535e821 100644 --- a/src/promotion/nhit/nhit.c +++ b/src/promotion/nhit/nhit.c @@ -27,10 +27,35 @@ void nhit_setup(ocf_cache_t cache) cfg->trigger_threshold = OCF_NHIT_TRIGGER_DEFAULT; } +static uint64_t nhit_sizeof(ocf_cache_t cache) +{ + uint64_t size = 0; + + size += sizeof(struct nhit_policy_context); + size += nhit_hash_sizeof(ocf_metadata_get_cachelines_count(cache) * + NHIT_MAPPING_RATIO); + + return size; +} + ocf_error_t nhit_init(ocf_cache_t cache) { struct nhit_policy_context *ctx; int result = 0; + uint64_t available, size; + + size = nhit_sizeof(cache); + available = env_get_free_memory(); + + if (size >= available) { + ocf_cache_log(cache, log_err, "Not enough memory to " + "initialize 'nhit' promotion policy! " + "Required %lu, available %lu\n", + (long unsigned)size, + (long unsigned)available); + + return -OCF_ERR_NO_FREE_RAM; + } ctx = env_vmalloc(sizeof(*ctx)); if (!ctx) { diff --git a/src/promotion/nhit/nhit_hash.c b/src/promotion/nhit/nhit_hash.c index 59bc622..d68e556 100644 --- a/src/promotion/nhit/nhit_hash.c +++ b/src/promotion/nhit/nhit_hash.c @@ -107,6 +107,26 @@ struct nhit_hash { env_spinlock rb_pointer_lock; }; +static uint64_t calculate_hash_buckets(uint64_t hash_size) +{ + return OCF_DIV_ROUND_UP(hash_size / 4, HASH_PRIME) * HASH_PRIME - 1; +} + +uint64_t nhit_hash_sizeof(uint64_t hash_size) +{ + uint64_t size = 0; + uint64_t n_buckets = calculate_hash_buckets(hash_size); + + size += sizeof(struct nhit_hash); + + size += n_buckets * sizeof(ocf_cache_line_t); + size += n_buckets * sizeof(env_rwsem); + + size += hash_size * sizeof(struct nhit_list_elem); + + return size; +} + ocf_error_t nhit_hash_init(uint64_t hash_size, nhit_hash_t *ctx) { int result = 0; @@ -121,9 +141,7 @@ ocf_error_t nhit_hash_init(uint64_t hash_size, nhit_hash_t *ctx) } new_ctx->rb_entries = hash_size; - new_ctx->hash_entries = OCF_DIV_ROUND_UP( - new_ctx->rb_entries / 4, - HASH_PRIME) * HASH_PRIME - 1; + new_ctx->hash_entries = calculate_hash_buckets(hash_size); new_ctx->hash_map = env_vzalloc( new_ctx->hash_entries * sizeof(*new_ctx->hash_map)); diff --git a/src/promotion/nhit/nhit_hash.h b/src/promotion/nhit/nhit_hash.h index 407b34c..12c0949 100644 --- a/src/promotion/nhit/nhit_hash.h +++ b/src/promotion/nhit/nhit_hash.h @@ -10,6 +10,8 @@ typedef struct nhit_hash *nhit_hash_t; +uint64_t nhit_hash_sizeof(uint64_t hash_size); + ocf_error_t nhit_hash_init(uint64_t hash_size, nhit_hash_t *ctx); void nhit_hash_deinit(nhit_hash_t ctx); diff --git a/src/promotion/promotion.c b/src/promotion/promotion.c index 8bfea02..0ed7e96 100644 --- a/src/promotion/promotion.c +++ b/src/promotion/promotion.c @@ -48,6 +48,13 @@ ocf_error_t ocf_promotion_init(ocf_cache_t cache, ocf_promotion_t type) if (result) { env_vfree(cache->promotion_policy); cache->promotion_policy = NULL; + ocf_cache_log(cache, log_info, + "Policy '%s' failed to initialize\n", + ocf_promotion_policies[type].name); + } else { + ocf_cache_log(cache, log_info, + "Policy '%s' initialized successfully\n", + ocf_promotion_policies[type].name); } return result; @@ -99,6 +106,10 @@ ocf_error_t ocf_promotion_set_policy(ocf_promotion_policy_t policy, "Falling back to 'always' promotion policy\n"); cache->conf_meta->promotion_policy_type = ocf_promotion_always; policy->type = ocf_promotion_always; + } else { + ocf_cache_log(cache, log_info, + "Switched to '%s' promotion policy\n", + ocf_promotion_policies[type].name); } return result;