
Eviction changes allowing to evict (remap) cachelines while holding hash bucket write lock instead of global metadata write lock. As eviction (replacement) is now tightly coupled with request, each request uses eviction size equal to number of its unmapped cachelines. Evicting without global metadata write lock is possible thanks to the fact that remaping is always performed while exclusively holding cacheline (read or write) lock. So for a cacheline on LRU list we acquire cacheline lock, safely resolve hash and consequently write-lock hash bucket. Since cacheline lock is acquired under hash bucket (everywhere except for new eviction implementation), we are certain that noone acquires cacheline lock behind our back. Concurrent eviction threads are eliminated by holding eviction list lock for the duration of critial locking operations. Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
115 lines
2.8 KiB
C
115 lines
2.8 KiB
C
/*
|
|
* Copyright(c) 2012-2021 Intel Corporation
|
|
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
|
*/
|
|
|
|
#ifndef LAYER_EVICTION_POLICY_OPS_H_
|
|
#define LAYER_EVICTION_POLICY_OPS_H_
|
|
|
|
#include "eviction.h"
|
|
#include "../metadata/metadata.h"
|
|
#include "../concurrency/ocf_metadata_concurrency.h"
|
|
|
|
/**
|
|
* @brief Initialize cache line before adding it into eviction
|
|
*
|
|
* @note This operation is called under WR metadata lock
|
|
*/
|
|
static inline void ocf_eviction_init_cache_line(struct ocf_cache *cache,
|
|
ocf_cache_line_t line)
|
|
{
|
|
uint8_t type;
|
|
|
|
type = cache->conf_meta->eviction_policy_type;
|
|
|
|
ENV_BUG_ON(type >= ocf_eviction_max);
|
|
|
|
if (likely(evict_policy_ops[type].init_cline))
|
|
evict_policy_ops[type].init_cline(cache, line);
|
|
}
|
|
|
|
static inline void ocf_eviction_purge_cache_line(
|
|
struct ocf_cache *cache, ocf_cache_line_t line)
|
|
{
|
|
uint8_t type = cache->conf_meta->eviction_policy_type;
|
|
|
|
ENV_BUG_ON(type >= ocf_eviction_max);
|
|
|
|
if (likely(evict_policy_ops[type].rm_cline)) {
|
|
OCF_METADATA_EVICTION_WR_LOCK(line);
|
|
evict_policy_ops[type].rm_cline(cache, line);
|
|
OCF_METADATA_EVICTION_WR_UNLOCK(line);
|
|
}
|
|
}
|
|
|
|
static inline bool ocf_eviction_can_evict(struct ocf_cache *cache)
|
|
{
|
|
uint8_t type = cache->conf_meta->eviction_policy_type;
|
|
|
|
if (likely(evict_policy_ops[type].can_evict))
|
|
return evict_policy_ops[type].can_evict(cache);
|
|
|
|
return true;
|
|
}
|
|
|
|
static inline uint32_t ocf_eviction_need_space(ocf_cache_t cache,
|
|
struct ocf_request *req, struct ocf_user_part *part,
|
|
uint32_t clines)
|
|
{
|
|
uint8_t type;
|
|
uint32_t result = 0;
|
|
|
|
type = cache->conf_meta->eviction_policy_type;
|
|
|
|
ENV_BUG_ON(type >= ocf_eviction_max);
|
|
|
|
if (likely(evict_policy_ops[type].req_clines)) {
|
|
result = evict_policy_ops[type].req_clines(req,
|
|
part, clines);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static inline void ocf_eviction_set_hot_cache_line(
|
|
struct ocf_cache *cache, ocf_cache_line_t line)
|
|
{
|
|
uint8_t type = cache->conf_meta->eviction_policy_type;
|
|
|
|
ENV_BUG_ON(type >= ocf_eviction_max);
|
|
|
|
if (likely(evict_policy_ops[type].hot_cline)) {
|
|
evict_policy_ops[type].hot_cline(cache, line);
|
|
}
|
|
}
|
|
|
|
static inline void ocf_eviction_initialize(struct ocf_cache *cache,
|
|
struct ocf_user_part *part)
|
|
{
|
|
uint8_t type = cache->conf_meta->eviction_policy_type;
|
|
|
|
ENV_BUG_ON(type >= ocf_eviction_max);
|
|
|
|
if (likely(evict_policy_ops[type].init_evp)) {
|
|
OCF_METADATA_EVICTION_WR_LOCK_ALL();
|
|
evict_policy_ops[type].init_evp(cache, part);
|
|
OCF_METADATA_EVICTION_WR_UNLOCK_ALL();
|
|
}
|
|
}
|
|
|
|
static inline void ocf_eviction_flush_dirty(ocf_cache_t cache,
|
|
struct ocf_user_part *part, ocf_queue_t io_queue,
|
|
uint32_t count)
|
|
{
|
|
uint8_t type = cache->conf_meta->eviction_policy_type;
|
|
|
|
ENV_BUG_ON(type >= ocf_eviction_max);
|
|
|
|
if (likely(evict_policy_ops[type].flush_dirty)) {
|
|
evict_policy_ops[type].flush_dirty(cache, part, io_queue,
|
|
count);
|
|
}
|
|
}
|
|
|
|
#endif /* LAYER_EVICTION_POLICY_OPS_H_ */
|