ocf/src/ocf_cache_priv.h
Adam Rutkowski 53ee7c1d3a Per-cpu refcounters
Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
Signed-off-by: Jan Musial <jan.musial@huawei.com>
Signed-off-by: Michal Mielewczyk <michal.mielewczyk@huawei.com>
Signed-off-by: Rafal Stefanowski <rafal.stefanowski@huawei.com>
2025-02-06 12:04:34 +01:00

194 lines
4.3 KiB
C

/*
* Copyright(c) 2012-2022 Intel Corporation
* Copyright(c) 2024-2025 Huawei Technologies
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __OCF_CACHE_PRIV_H__
#define __OCF_CACHE_PRIV_H__
#include "ocf/ocf.h"
#include "ocf_env.h"
#include "ocf_volume_priv.h"
#include "ocf_core_priv.h"
#include "ocf_part.h"
#include "metadata/metadata_structs.h"
#include "utils/utils_list.h"
#include "utils/utils_pipeline.h"
#include "utils/utils_async_lock.h"
#include "ocf_stats_priv.h"
#include "cleaning/cleaning.h"
#include "ocf_logger_priv.h"
#include "ocf_queue_priv.h"
#include "promotion/promotion.h"
#define DIRTY_FLUSHED 1
#define DIRTY_NOT_FLUSHED 0
/* Cache device */
struct ocf_cache_device {
struct ocf_volume front_volume;
struct ocf_volume volume;
/* Hash Table contains contains pointer to the entry in
* Collision Table so it actually contains collision Table
* indexes.
* Invalid entry is collision_table_entries.
*/
unsigned int hash_table_entries;
unsigned int collision_table_entries;
int metadata_error;
/*!< This field indicates that an error during metadata IO
* occurred
*/
uint64_t metadata_offset;
struct {
struct ocf_alock *cache_line;
} concurrency;
struct ocf_superblock_runtime *runtime_meta;
};
struct ocf_cache {
char name[OCF_CACHE_NAME_SIZE];
ocf_ctx_t owner;
struct list_head list;
/* unset running to not serve any more I/O requests */
unsigned long cache_state;
struct ocf_superblock_config *conf_meta;
struct ocf_cache_device *device;
struct ocf_lst user_part_list;
struct ocf_user_part user_parts[OCF_USER_IO_CLASS_MAX + 1];
struct ocf_part free;
uint32_t fallback_pt_error_threshold;
ocf_queue_t mngt_queue;
struct ocf_metadata metadata;
struct {
/* cache get/put counter */
struct env_refcnt cache;
/* # of requests potentially dirtying cachelines */
struct env_refcnt dirty;
/* # of requests accessing attached metadata, excluding
* management reqs */
struct env_refcnt metadata;
/* # of requests in d2c mode */
struct env_refcnt d2c;
} refcnt;
struct {
env_allocator *allocator;
struct ocf_alock *concurrency;
} standby;
struct ocf_core core[OCF_CORE_MAX];
ocf_pipeline_t stop_pipeline;
env_atomic fallback_pt_error_counter;
env_atomic pending_read_misses_list_blocked;
env_atomic pending_read_misses_list_count;
env_atomic flush_in_progress;
env_mutex flush_mutex;
env_atomic attach_pt;
struct ocf_cleaner cleaner;
struct list_head io_queues;
env_spinlock io_queues_lock;
ocf_promotion_policy_t promotion_policy;
struct {
uint32_t max_queue_size;
uint32_t queue_unblock_size;
} backfill;
void *priv;
/*
* Most of the time this variable is set to 0, unless user requested
* interruption of flushing process.
*/
int flushing_interrupted;
uint16_t ocf_core_inactive_count;
bool pt_unaligned_io;
bool use_submit_io_fast;
struct {
struct ocf_async_lock lock;
} __attribute__((aligned(64)));
// This should be on it's own cacheline ideally
env_atomic last_access_ms;
};
static inline ocf_core_t ocf_cache_get_core(ocf_cache_t cache,
ocf_core_id_t core_id)
{
if (core_id >= OCF_CORE_MAX)
return NULL;
return &cache->core[core_id];
}
#define for_each_core_all(_cache, _core, _id) \
for (_id = 0; _core = &_cache->core[_id], _id < OCF_CORE_MAX; _id++)
#define for_each_core(_cache, _core, _id) \
for_each_core_all(_cache, _core, _id) \
if (_core->added)
#define for_each_core_metadata(_cache, _core, _id) \
for_each_core_all(_cache, _core, _id) \
if (_core->conf_meta->valid)
#define ocf_cache_log_prefix(cache, lvl, prefix, fmt, ...) \
ocf_log_prefix(ocf_cache_get_ctx(cache), lvl, "%s" prefix, \
fmt, ocf_cache_get_name(cache), ##__VA_ARGS__)
#define ocf_cache_log(cache, lvl, fmt, ...) \
ocf_cache_log_prefix(cache, lvl, ": ", fmt, ##__VA_ARGS__)
#define ocf_cache_log_rl(cache) \
ocf_log_rl(ocf_cache_get_ctx(cache))
static inline uint64_t ocf_get_cache_occupancy(ocf_cache_t cache)
{
uint64_t result = 0;
ocf_core_t core;
ocf_core_id_t core_id;
for_each_core(cache, core, core_id)
result += env_atomic_read(&core->runtime_meta->cached_clines);
return result;
}
uint32_t ocf_cache_get_queue_count(ocf_cache_t cache);
int ocf_cache_set_name(ocf_cache_t cache, const char *src, size_t src_size);
int ocf_cache_volume_type_init(ocf_ctx_t ctx);
bool ocf_cache_mode_is_valid(ocf_cache_mode_t mode);
#endif /* __OCF_CACHE_PRIV_H__ */