Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/metadata/metadata_collision.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,40 @@ struct ocf_hash_entry {
};
};

/**
* @brief Hash bucket of core line
*
* Hash function intentionally returns consecutive (modulo @hash_entries)
* values for consecutive @core_line. 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.
*
* @param hash_entries - Number of entries in hash segment
* @param core_line - Core line number
* @param core_id - Core id
*/
static inline ocf_cache_line_t ocf_metadata_collision_hash(
ocf_cache_line_t hash_entries, uint64_t core_line,
ocf_core_id_t core_id)
{
return (ocf_cache_line_t) ((core_line + (core_id * (hash_entries / 32)))
% hash_entries);
}

/**
* @brief Hash bucket following given one
*
* @param hash_entries - Number of entries in hash segment
* @param hash - Hash bucket
*/
static inline ocf_cache_line_t ocf_metadata_collision_hash_next(
ocf_cache_line_t hash_entries, ocf_cache_line_t hash)
{
hash++;
return likely(hash < hash_entries) ? hash : 0;
}

/**
* @brief Metadata map structure
*/
Expand Down
37 changes: 37 additions & 0 deletions src/metadata/metadata_layout.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,39 @@ bool ocf_metadata_segment_layout_is_flapped(
}
}

uint32_t ocf_metadata_segment_layout_checksum_superblock(const void *data)
{
return env_crc32(0, data,
offsetof(struct ocf_superblock_config, checksum));
}

uint32_t ocf_metadata_segment_layout_checksum_page(
const struct ocf_metadata_segment_layout *segment,
uint32_t crc, const void *page)
{
ENV_BUG_ON(segment->id == metadata_segment_sb_config);

return env_crc32(crc, page, PAGE_SIZE);
}

uint32_t ocf_metadata_segment_layout_checksum_segment(
const struct ocf_metadata_segment_layout *segment,
const void *(*get_page)(void *opaque, unsigned idx),
void *opaque)
{
uint32_t step = 0;
uint32_t crc = 0;
unsigned i;

for (i = 0; i < segment->pages; i++) {
crc = ocf_metadata_segment_layout_checksum_page(segment,
crc, get_page(opaque, i));
OCF_COND_RESCHED(step, 10000);
}

return crc;
}

/*
* Set up segment with given number of entries at given offset
*
Expand Down Expand Up @@ -203,6 +236,9 @@ void ocf_metadata_layout_init_fixed_size(

layout->on_disk = on_disk;

for (i = 0; i < metadata_segment_max; i++)
layout->segment[i].id = i;

for (i = 0; i < metadata_segment_fixed_size_max; i++) {
page += ocf_metadata_layout_setup_segment(layout, i, 0,
ocf_metadata_segment_layout_entries(i, 0),
Expand All @@ -227,6 +263,7 @@ void ocf_metadata_layout_set_cachelines(struct ocf_metadata_layout *layout,
if (i == metadata_segment_cleaning && cleaner_disabled) {
ENV_BUG_ON(env_memset(&layout->segment[i],
sizeof(layout->segment[i]), 0));
layout->segment[i].id = i;
layout->segment[i].disabled = true;
continue;
}
Expand Down
39 changes: 39 additions & 0 deletions src/metadata/metadata_layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
#define OCF_METADATA_SEGMENT_ALIGNMENT (128 * KiB)

struct ocf_metadata_segment_layout {
enum ocf_metadata_segment_id id;
/*!< Segment id */

uint32_t entry_size;
/*!< Size of single entry */

Expand Down Expand Up @@ -122,6 +125,42 @@ static inline uint64_t ocf_metadata_segment_layout_offset(
flapping_idx;
}

/**
* @brief Checksum of superblock config
*
* Checksum covers struct ocf_superblock_config up to the checksum array.
*
* @param data - Superblock config (struct ocf_superblock_config)
*/
uint32_t ocf_metadata_segment_layout_checksum_superblock(const void *data);

/**
* @brief Update segment checksum with single page of segment data
*
* @param segment - Segment layout (other than superblock config)
* @param crc - Checksum of preceding pages (0 for first page)
* @param page - Page of segment data
*/
uint32_t ocf_metadata_segment_layout_checksum_page(
const struct ocf_metadata_segment_layout *segment, uint32_t crc,
const void *page);

/**
* @brief Checksum of segment data
*
* Checksum covers all pages of segment data as kept in memory, i.e. entries
* packed densely one after another (without unused remainder of each page
* on disk), followed by zeros up to the number of pages of the segment.
*
* @param segment - Segment layout (other than superblock config)
* @param get_page - Callback returning page of segment data of given index
* @param opaque - Private data passed to @get_page
*/
uint32_t ocf_metadata_segment_layout_checksum_segment(
const struct ocf_metadata_segment_layout *segment,
const void *(*get_page)(void *opaque, unsigned idx),
void *opaque);

/**
* @brief Initialize layout of fixed size segments
*
Expand Down
19 changes: 7 additions & 12 deletions src/metadata/metadata_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,22 @@
#ifndef __METADATA_MISC_H__
#define __METADATA_MISC_H__

/* 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.
*/
#include "metadata_collision.h"

/* See ocf_metadata_collision_hash() */
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)
{
const unsigned int entries = cache->device->hash_table_entries;

return (ocf_cache_line_t) ((core_line_num + (core_id * (entries / 32)))
% entries);
return ocf_metadata_collision_hash(cache->device->hash_table_entries,
core_line_num, core_id);
}

/* Return the hash based on the hash of the prev core line */
static inline ocf_cache_line_t ocf_metadata_hash_next(ocf_cache_t cache,
ocf_cache_line_t hash)
{
hash++;
return likely(hash < cache->device->hash_table_entries) ? hash : 0;
return ocf_metadata_collision_hash_next(
cache->device->hash_table_entries, hash);
}

void ocf_metadata_remove_cache_line(struct ocf_cache *cache,
Expand Down
37 changes: 23 additions & 14 deletions src/metadata/metadata_raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,19 +157,18 @@ static uint32_t _raw_ram_size_on_ssd(struct ocf_metadata_raw *raw)
/*
* RAM Implementation - Checksum
*/
static uint32_t _raw_ram_checksum(ocf_cache_t cache,
struct ocf_metadata_raw *raw)
static const void *_raw_ram_checksum_get_page(void *opaque, unsigned idx)
{
uint64_t i;
uint32_t step = 0;
uint32_t crc = 0;
struct ocf_metadata_raw *raw = opaque;

for (i = 0; i < raw->layout->pages; i++) {
crc = env_crc32(crc, raw->mem_pool + PAGE_SIZE * i, PAGE_SIZE);
OCF_COND_RESCHED(step, 10000);
}
return (uint8_t *)raw->mem_pool + (uint64_t)idx * PAGE_SIZE;
}

return crc;
static uint32_t _raw_ram_checksum(ocf_cache_t cache,
struct ocf_metadata_raw *raw)
{
return ocf_metadata_segment_layout_checksum_segment(raw->layout,
_raw_ram_checksum_get_page, raw);
}

/*
Expand All @@ -193,6 +192,12 @@ static void *_raw_ram_access(ocf_cache_t cache,
return _RAW_RAM_ADDR(raw, entry);
}

static const void *_raw_ram_rd_access(ocf_cache_t cache,
struct ocf_metadata_raw *raw, uint32_t entry)
{
return _raw_ram_access(cache, raw, entry);
}

static int _raw_ram_drain_page(ocf_cache_t cache,
struct ocf_metadata_raw *raw, ctx_data_t *data, uint32_t page)
{
Expand Down Expand Up @@ -640,7 +645,8 @@ static const struct raw_iface IRAW[metadata_raw_type_max] = {
.size_on_ssd = _raw_ram_size_on_ssd,
.checksum = _raw_ram_checksum,
.page = _raw_ram_page,
.access = _raw_ram_access,
.wr_access = _raw_ram_access,
.rd_access = _raw_ram_rd_access,
.update = _raw_ram_update,
.zero = raw_ram_zero,
.load_all = _raw_ram_load_all,
Expand All @@ -655,7 +661,8 @@ static const struct raw_iface IRAW[metadata_raw_type_max] = {
.size_on_ssd = raw_dynamic_size_on_ssd,
.checksum = raw_dynamic_checksum,
.page = raw_dynamic_page,
.access = raw_dynamic_access,
.wr_access = raw_dynamic_wr_access,
.rd_access = raw_dynamic_rd_access,
.update = raw_dynamic_update,
.zero = raw_ram_zero,
.load_all = raw_dynamic_load_all,
Expand All @@ -670,7 +677,8 @@ static const struct raw_iface IRAW[metadata_raw_type_max] = {
.size_on_ssd = raw_volatile_size_on_ssd,
.checksum = raw_volatile_checksum,
.page = _raw_ram_page,
.access = _raw_ram_access,
.wr_access = _raw_ram_access,
.rd_access = _raw_ram_rd_access,
.update = raw_volatile_update,
.zero = raw_volatile_zero,
.load_all = raw_volatile_load_all,
Expand All @@ -685,7 +693,8 @@ static const struct raw_iface IRAW[metadata_raw_type_max] = {
.size_on_ssd = _raw_ram_size_on_ssd,
.checksum = _raw_ram_checksum,
.page = _raw_ram_page,
.access = _raw_ram_access,
.wr_access = _raw_ram_access,
.rd_access = _raw_ram_rd_access,
.update = _raw_ram_update,
.zero = raw_ram_zero,
.load_all = _raw_ram_load_all,
Expand Down
9 changes: 6 additions & 3 deletions src/metadata/metadata_raw.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,12 @@ struct raw_iface {

uint32_t (*page)(struct ocf_metadata_raw *raw, uint32_t entry);

void* (*access)(ocf_cache_t cache, struct ocf_metadata_raw *raw,
void* (*wr_access)(ocf_cache_t cache, struct ocf_metadata_raw *raw,
uint32_t entry);

const void* (*rd_access)(ocf_cache_t cache,
struct ocf_metadata_raw *raw, uint32_t entry);

int (*update)(ocf_cache_t cache, struct ocf_metadata_raw *raw,
ctx_data_t *data, uint64_t page, uint64_t count);

Expand Down Expand Up @@ -228,7 +231,7 @@ static inline uint32_t ocf_metadata_raw_page(struct ocf_metadata_raw* raw,
static inline void *ocf_metadata_raw_wr_access(ocf_cache_t cache,
struct ocf_metadata_raw *raw, uint32_t entry)
{
return raw->iface->access(cache, raw, entry);
return raw->iface->wr_access(cache, raw, entry);
}

/**
Expand All @@ -242,7 +245,7 @@ static inline void *ocf_metadata_raw_wr_access(ocf_cache_t cache,
static inline const void *ocf_metadata_raw_rd_access( ocf_cache_t cache,
struct ocf_metadata_raw *raw, uint32_t entry)
{
return raw->iface->access(cache, raw, entry);
return raw->iface->rd_access(cache, raw, entry);
}

/**
Expand Down
Loading
Loading