Merge pull request #220 from arutk/metadata_offset_hash
New hash function formula
This commit is contained in:
@@ -38,19 +38,19 @@ void ocf_engine_lookup_map_entry(struct ocf_cache *cache,
|
||||
uint64_t core_line)
|
||||
{
|
||||
ocf_cache_line_t line;
|
||||
ocf_cache_line_t hash_key;
|
||||
ocf_cache_line_t hash;
|
||||
|
||||
hash_key = ocf_metadata_hash_func(cache, core_line, core_id);
|
||||
hash = ocf_metadata_hash_func(cache, core_line, core_id);
|
||||
|
||||
/* Initially assume that we have cache miss.
|
||||
* Hash points to proper bucket.
|
||||
*/
|
||||
entry->hash_key = hash_key;
|
||||
entry->hash = hash;
|
||||
entry->status = LOOKUP_MISS;
|
||||
entry->coll_idx = cache->device->collision_table_entries;
|
||||
entry->core_line = core_line;
|
||||
|
||||
line = ocf_metadata_get_hash(cache, hash_key);
|
||||
line = ocf_metadata_get_hash(cache, hash);
|
||||
|
||||
while (line != cache->device->collision_table_entries) {
|
||||
ocf_core_id_t curr_core_id;
|
||||
@@ -347,7 +347,7 @@ void ocf_engine_map(struct ocf_request *req)
|
||||
|
||||
if (entry->status != LOOKUP_HIT) {
|
||||
ocf_engine_map_cache_line(req, entry->core_line,
|
||||
entry->hash_key, &entry->coll_idx);
|
||||
entry->hash, &entry->coll_idx);
|
||||
|
||||
if (req->info.mapping_error) {
|
||||
/*
|
||||
|
||||
@@ -83,8 +83,7 @@ static ocf_cache_line_t ocf_metadata_hash_get_entries(
|
||||
return cache_lines;
|
||||
|
||||
case metadata_segment_hash:
|
||||
return OCF_DIV_ROUND_UP(cache_lines / 4, OCF_HASH_PRIME) *
|
||||
OCF_HASH_PRIME - 1;
|
||||
return OCF_DIV_ROUND_UP(cache_lines, 4);
|
||||
|
||||
case metadata_segment_sb_config:
|
||||
return OCF_DIV_ROUND_UP(sizeof(struct ocf_superblock_config),
|
||||
|
||||
@@ -6,21 +6,19 @@
|
||||
#ifndef __METADATA_MISC_H__
|
||||
#define __METADATA_MISC_H__
|
||||
|
||||
/*
|
||||
* Hash function needs number that has no common factors with both number
|
||||
* of cores and number of entries in metadata hash container (hash lists).
|
||||
* This can be easily achived by picking prime which is bigger than maximum
|
||||
* number of cores and ensuring that count of hash table entries is not
|
||||
* divisible by this number. Let's choose 4099, which is smallest prime
|
||||
* greater than OCF_CORE_MAX (which is 4096).
|
||||
/* Hash function intentionally returns consecutive (modulo @hash_table_entries)
|
||||
* values for consecutive @core_line_num. This way it is trivial to sort all
|
||||
* core lines within a single request in ascending hash value order. This kind
|
||||
* of sorting is required to assure that (future) hash bucket metadata locks are
|
||||
* always acquired in fixed order, eliminating the risk of dead locks.
|
||||
*/
|
||||
#define OCF_HASH_PRIME 4099
|
||||
|
||||
static inline ocf_cache_line_t ocf_metadata_hash_func(ocf_cache_t cache,
|
||||
uint64_t core_line_num, ocf_core_id_t core_id)
|
||||
{
|
||||
return (ocf_cache_line_t) ((core_line_num * OCF_HASH_PRIME + core_id) %
|
||||
cache->device->hash_table_entries);
|
||||
const unsigned int entries = cache->device->hash_table_entries;
|
||||
|
||||
return (ocf_cache_line_t) ((core_line_num + (core_id * (entries / 32)))
|
||||
% entries);
|
||||
}
|
||||
|
||||
void ocf_metadata_sparse_cache_line(struct ocf_cache *cache,
|
||||
|
||||
@@ -50,9 +50,11 @@ struct ocf_req_info {
|
||||
};
|
||||
|
||||
struct ocf_map_info {
|
||||
/* If HIT -> pointer to hash_key and coll_idx */
|
||||
unsigned int hash_key;
|
||||
unsigned int coll_idx;
|
||||
ocf_cache_line_t hash;
|
||||
/*!< target LBA & core id hash */
|
||||
|
||||
ocf_cache_line_t coll_idx;
|
||||
/*!< Index in collision table (in case of hit) */
|
||||
|
||||
uint64_t core_line;
|
||||
|
||||
|
||||
@@ -489,7 +489,7 @@ static void _ocf_cleaner_core_io_for_dirty_range(struct ocf_request *req,
|
||||
|
||||
addr = (ocf_line_size(cache) * iter->core_line)
|
||||
+ SECTORS_TO_BYTES(begin);
|
||||
offset = (ocf_line_size(cache) * iter->hash_key)
|
||||
offset = (ocf_line_size(cache) * iter->hash)
|
||||
+ SECTORS_TO_BYTES(begin);
|
||||
|
||||
io = ocf_new_core_io(core, req->io_queue, addr,
|
||||
@@ -666,7 +666,7 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req)
|
||||
addr *= ocf_line_size(cache);
|
||||
addr += cache->device->metadata_offset;
|
||||
|
||||
offset = ocf_line_size(cache) * iter->hash_key;
|
||||
offset = ocf_line_size(cache) * iter->hash;
|
||||
|
||||
part_id = ocf_metadata_get_partition_id(cache, iter->coll_idx);
|
||||
|
||||
@@ -773,7 +773,7 @@ static int _ocf_cleaner_do_fire(struct ocf_request *req, uint32_t i_out,
|
||||
req->map[i_out].core_id = OCF_CORE_MAX;
|
||||
req->map[i_out].core_line = ULLONG_MAX;
|
||||
req->map[i_out].status = LOOKUP_MISS;
|
||||
req->map[i_out].hash_key = i_out;
|
||||
req->map[i_out].hash = i_out;
|
||||
}
|
||||
|
||||
if (do_sort) {
|
||||
@@ -781,7 +781,7 @@ static int _ocf_cleaner_do_fire(struct ocf_request *req, uint32_t i_out,
|
||||
env_sort(req->map, req->core_line_count, sizeof(req->map[0]),
|
||||
_ocf_cleaner_cmp_private, NULL);
|
||||
for (i = 0; i < req->core_line_count; i++)
|
||||
req->map[i].hash_key = i;
|
||||
req->map[i].hash = i;
|
||||
}
|
||||
|
||||
/* issue actual request */
|
||||
@@ -916,7 +916,7 @@ void ocf_cleaner_fire(struct ocf_cache *cache,
|
||||
req->map[i_out].core_line = core_sector;
|
||||
req->map[i_out].coll_idx = cache_line;
|
||||
req->map[i_out].status = LOOKUP_HIT;
|
||||
req->map[i_out].hash_key = i_out;
|
||||
req->map[i_out].hash = i_out;
|
||||
i_out++;
|
||||
|
||||
if (max == i_out) {
|
||||
|
||||
Reference in New Issue
Block a user