From: corwin <[email protected]> Pull the calculations from split_config() into compute_volume_sub_index_parameters(). For sparse indexes, this eliminates the duplication of both the configs and geometries in favor of merely having 2 sub_index_parameters structures.
Also expand the sub_index_parameters structure to include the small number of fields its users rely on from both the config and the geometry. Signed-off-by: corwin <[email protected]> Signed-off-by: Matthew Sakai <[email protected]> --- drivers/md/dm-vdo/indexer/volume-index.c | 188 +++++++++++------------ 1 file changed, 93 insertions(+), 95 deletions(-) diff --git a/drivers/md/dm-vdo/indexer/volume-index.c b/drivers/md/dm-vdo/indexer/volume-index.c index e78d2725ce8b..03c6b39ccdcc 100644 --- a/drivers/md/dm-vdo/indexer/volume-index.c +++ b/drivers/md/dm-vdo/indexer/volume-index.c @@ -60,6 +60,12 @@ * the index. */ +enum sub_index_parameters_slot { + DENSE = 0, + HOOK = 0, + NON_HOOK = 1, +}; + struct sub_index_parameters { /* The number of bits in address mask */ u8 address_bits; @@ -77,16 +83,10 @@ struct sub_index_parameters { size_t memory_size; /* The number of bytes the index should keep free at all times */ size_t target_free_bytes; -}; - -struct split_config { - /* The hook subindex configuration */ - struct uds_configuration hook_config; - struct index_geometry hook_geometry; - - /* The non-hook subindex configuration */ - struct uds_configuration non_hook_config; - struct index_geometry non_hook_geometry; + /* The mean delta for the volume index */ + u32 volume_index_mean_delta; + /* The number of threads used to process index requests */ + unsigned int zone_count; }; struct chapter_range { @@ -196,8 +196,11 @@ unsigned int uds_get_volume_index_zone(const struct volume_index *volume_index, #define DELTA_LIST_SIZE 256 -static int compute_volume_sub_index_parameters(const struct uds_configuration *config, - struct sub_index_parameters *params) +static int compute_sub_index_parameters(const struct uds_configuration *config, + u64 records_per_chapter, + u32 chapters_per_volume, + bool reduced, + struct sub_index_parameters *params) { u64 entries_in_volume_index, address_span; u32 chapters_in_volume_index, invalid_chapters; @@ -207,17 +210,15 @@ static int compute_volume_sub_index_parameters(const struct uds_configuration *c u64 index_size_in_bits; size_t expected_index_size; u64 min_delta_lists = MAX_ZONES * MAX_ZONES; - struct index_geometry *geometry = config->geometry; - u64 records_per_chapter = geometry->records_per_chapter; - params->chapter_count = geometry->chapters_per_volume; + params->chapter_count = chapters_per_volume; /* * Make sure that the number of delta list records in the volume index does not change when * the volume is reduced by one chapter. This preserves the mapping from name to volume * index delta list. */ rounded_chapters = params->chapter_count; - if (uds_is_reduced_index_geometry(geometry)) + if (reduced) rounded_chapters += 1; delta_list_records = records_per_chapter * rounded_chapters; address_count = config->volume_index_mean_delta * DELTA_LIST_SIZE; @@ -274,9 +275,46 @@ static int compute_volume_sub_index_parameters(const struct uds_configuration *c params->memory_size = expected_index_size * 106 / 100; params->target_free_bytes = expected_index_size / 20; + params->volume_index_mean_delta = config->volume_index_mean_delta; + params->zone_count = config->zone_count; return UDS_SUCCESS; } +static int compute_volume_sub_index_parameters(const struct uds_configuration *config, + struct sub_index_parameters *params) +{ + struct index_geometry *geometry = config->geometry; + u64 sample_records; + u64 dense_chapters; + int result; + bool reduced = uds_is_reduced_index_geometry(geometry); + + if (!uds_is_sparse_index_geometry(config->geometry)) { + return compute_sub_index_parameters(config, + geometry->records_per_chapter, + geometry->chapters_per_volume, + reduced, + ¶ms[DENSE]); + } + + dense_chapters = geometry->chapters_per_volume - geometry->sparse_chapters_per_volume; + sample_records = geometry->records_per_chapter / config->sparse_sample_rate; + + result = compute_sub_index_parameters(config, + sample_records, + geometry->chapters_per_volume, + reduced, + ¶ms[HOOK]); + if (result != UDS_SUCCESS) + return result; + + return compute_sub_index_parameters(config, + geometry->records_per_chapter - sample_records, + dense_chapters, + reduced, + ¶ms[NON_HOOK]); +} + static void uninitialize_volume_sub_index(struct volume_sub_index *sub_index) { vdo_free(vdo_forget(sub_index->flush_chapters)); @@ -298,73 +336,32 @@ void uds_free_volume_index(struct volume_index *volume_index) } -static int compute_volume_sub_index_save_bytes(const struct uds_configuration *config, - size_t *bytes) -{ - struct sub_index_parameters params = { .address_bits = 0 }; - int result; - - result = compute_volume_sub_index_parameters(config, ¶ms); - if (result != UDS_SUCCESS) - return result; - - *bytes = (sizeof(struct sub_index_data) + params.list_count * sizeof(u64) + - uds_compute_delta_index_save_bytes(params.list_count, - params.memory_size)); - return UDS_SUCCESS; -} - -/* This function is only useful if the configuration includes sparse chapters. */ -static void split_configuration(const struct uds_configuration *config, - struct split_config *split) +static size_t compute_volume_sub_index_save_bytes(struct sub_index_parameters *params) { - u64 sample_rate, sample_records; - u64 dense_chapters, sparse_chapters; - - /* Start with copies of the base configuration. */ - split->hook_config = *config; - split->hook_geometry = *config->geometry; - split->hook_config.geometry = &split->hook_geometry; - split->non_hook_config = *config; - split->non_hook_geometry = *config->geometry; - split->non_hook_config.geometry = &split->non_hook_geometry; - - sample_rate = config->sparse_sample_rate; - sparse_chapters = config->geometry->sparse_chapters_per_volume; - dense_chapters = config->geometry->chapters_per_volume - sparse_chapters; - sample_records = config->geometry->records_per_chapter / sample_rate; - - /* Adjust the number of records indexed for each chapter. */ - split->hook_geometry.records_per_chapter = sample_records; - split->non_hook_geometry.records_per_chapter -= sample_records; - - /* Adjust the number of chapters indexed. */ - split->hook_geometry.sparse_chapters_per_volume = 0; - split->non_hook_geometry.sparse_chapters_per_volume = 0; - split->non_hook_geometry.chapters_per_volume = dense_chapters; + return (sizeof(struct sub_index_data) + params->list_count * sizeof(u64) + + uds_compute_delta_index_save_bytes(params->list_count, + params->memory_size)); } static int compute_volume_index_save_bytes(const struct uds_configuration *config, size_t *bytes) { - size_t hook_bytes, non_hook_bytes; - struct split_config split; int result; + struct sub_index_parameters parameters[2] = { + { .address_bits = 0 }, + { .address_bits = 0 }, + }; - if (!uds_is_sparse_index_geometry(config->geometry)) - return compute_volume_sub_index_save_bytes(config, bytes); - - split_configuration(config, &split); - result = compute_volume_sub_index_save_bytes(&split.hook_config, &hook_bytes); + result = compute_volume_sub_index_parameters(config, parameters); if (result != UDS_SUCCESS) return result; - result = compute_volume_sub_index_save_bytes(&split.non_hook_config, - &non_hook_bytes); - if (result != UDS_SUCCESS) - return result; + *bytes = compute_volume_sub_index_save_bytes(¶meters[HOOK]); + if (uds_is_sparse_index_geometry(config->geometry)) { + *bytes += compute_volume_sub_index_save_bytes(¶meters[NON_HOOK]); + *bytes += sizeof(struct volume_index_data); + } - *bytes = sizeof(struct volume_index_data) + hook_bytes + non_hook_bytes; return UDS_SUCCESS; } @@ -1170,48 +1167,43 @@ void uds_get_volume_index_stats(const struct volume_index *volume_index, stats->early_flushes += sparse_stats.early_flushes; } -static int initialize_volume_sub_index(const struct uds_configuration *config, +static int initialize_volume_sub_index(struct sub_index_parameters *params, u64 volume_nonce, u8 tag, struct volume_sub_index *sub_index) { - struct sub_index_parameters params = { .address_bits = 0 }; - unsigned int zone_count = config->zone_count; + unsigned int zone_count = params->zone_count; u64 available_bytes = 0; unsigned int z; int result; - result = compute_volume_sub_index_parameters(config, ¶ms); - if (result != UDS_SUCCESS) - return result; - - sub_index->address_bits = params.address_bits; - sub_index->address_mask = (1u << params.address_bits) - 1; - sub_index->chapter_bits = params.chapter_bits; - sub_index->chapter_mask = (1u << params.chapter_bits) - 1; - sub_index->chapter_count = params.chapter_count; - sub_index->list_count = params.list_count; + sub_index->address_bits = params->address_bits; + sub_index->address_mask = (1u << params->address_bits) - 1; + sub_index->chapter_bits = params->chapter_bits; + sub_index->chapter_mask = (1u << params->chapter_bits) - 1; + sub_index->chapter_count = params->chapter_count; + sub_index->list_count = params->list_count; sub_index->zone_count = zone_count; - sub_index->chapter_zone_bits = params.chapter_size_in_bits / zone_count; + sub_index->chapter_zone_bits = params->chapter_size_in_bits / zone_count; sub_index->volume_nonce = volume_nonce; result = uds_initialize_delta_index(&sub_index->delta_index, zone_count, - params.list_count, params.mean_delta, - params.chapter_bits, params.memory_size, + params->list_count, params->mean_delta, + params->chapter_bits, params->memory_size, tag); if (result != UDS_SUCCESS) return result; for (z = 0; z < sub_index->delta_index.zone_count; z++) available_bytes += sub_index->delta_index.delta_zones[z].size; - available_bytes -= params.target_free_bytes; + available_bytes -= params->target_free_bytes; sub_index->max_zone_bits = (available_bytes * BITS_PER_BYTE) / zone_count; sub_index->memory_size = (sub_index->delta_index.memory_size + sizeof(struct volume_sub_index) + - (params.list_count * sizeof(u64)) + + (params->list_count * sizeof(u64)) + (zone_count * sizeof(struct volume_sub_index_zone))); /* The following arrays are initialized to all zeros. */ - result = vdo_allocate(params.list_count, "first chapter to flush", + result = vdo_allocate(params->list_count, "first chapter to flush", &sub_index->flush_chapters); if (result != VDO_SUCCESS) return result; @@ -1222,10 +1214,13 @@ static int initialize_volume_sub_index(const struct uds_configuration *config, int uds_make_volume_index(const struct uds_configuration *config, u64 volume_nonce, struct volume_index **volume_index_ptr) { - struct split_config split; unsigned int zone; struct volume_index *volume_index; int result; + struct sub_index_parameters parameters[2] = { + { .address_bits = 0 }, + { .address_bits = 0 }, + }; result = vdo_allocate(1, "volume index", &volume_index); if (result != VDO_SUCCESS) @@ -1233,8 +1228,12 @@ int uds_make_volume_index(const struct uds_configuration *config, u64 volume_non volume_index->zone_count = config->zone_count; + result = compute_volume_sub_index_parameters(config, parameters); + if (result != UDS_SUCCESS) + return result; + if (!uds_is_sparse_index_geometry(config->geometry)) { - result = initialize_volume_sub_index(config, volume_nonce, 'm', + result = initialize_volume_sub_index(¶meters[DENSE], volume_nonce, 'm', &volume_index->vi_non_hook); if (result != UDS_SUCCESS) { uds_free_volume_index(volume_index); @@ -1257,8 +1256,7 @@ int uds_make_volume_index(const struct uds_configuration *config, u64 volume_non for (zone = 0; zone < config->zone_count; zone++) mutex_init(&volume_index->zones[zone].hook_mutex); - split_configuration(config, &split); - result = initialize_volume_sub_index(&split.non_hook_config, volume_nonce, 'd', + result = initialize_volume_sub_index(¶meters[NON_HOOK], volume_nonce, 'd', &volume_index->vi_non_hook); if (result != UDS_SUCCESS) { uds_free_volume_index(volume_index); @@ -1266,7 +1264,7 @@ int uds_make_volume_index(const struct uds_configuration *config, u64 volume_non "Error creating non hook volume index"); } - result = initialize_volume_sub_index(&split.hook_config, volume_nonce, 's', + result = initialize_volume_sub_index(¶meters[HOOK], volume_nonce, 's', &volume_index->vi_hook); if (result != UDS_SUCCESS) { uds_free_volume_index(volume_index); -- 2.53.0
