ocf/src/layer_space_management.c
Robert Baldyga a8e1ce8cc5 Initial commit
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
2018-11-29 15:14:21 +01:00

115 lines
2.8 KiB
C

/*
* Copyright(c) 2012-2018 Intel Corporation
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#include "ocf/ocf.h"
#include "layer_space_management.h"
#include "utils/utils_allocator.h"
#include "utils/utils_part.h"
#include "concurrency/ocf_concurrency.h"
#include "engine/engine_common.h"
#include "eviction/ops.h"
static uint32_t ocf_evict_calculate(struct ocf_user_part *part,
uint32_t to_evict)
{
if (part->runtime->curr_size <= part->config->min_size) {
/*
* Cannot evict from this partition because current size
* is less than minimum size
*/
return 0;
}
if (to_evict < OCF_TO_EVICTION_MIN)
to_evict = OCF_TO_EVICTION_MIN;
if (to_evict > (part->runtime->curr_size - part->config->min_size))
to_evict = part->runtime->curr_size - part->config->min_size;
return to_evict;
}
static inline uint32_t ocf_evict_do(struct ocf_cache *cache,
uint32_t io_queue, const uint32_t evict_cline_no,
ocf_core_id_t core_id, ocf_part_id_t target_part_id)
{
uint32_t to_evict = 0, evicted = 0;
struct ocf_user_part *part;
struct ocf_user_part *target_part = &cache->user_parts[target_part_id];
ocf_part_id_t part_id;
/* For each partition from the lowest priority to highest one */
for_each_part(cache, part, part_id) {
if (!ocf_eviction_can_evict(cache))
goto out;
/*
* Check stop and continue conditions
*/
if (target_part->config->priority > part->config->priority) {
/*
* iterate partition have higher priority, do not evict
*/
break;
}
if (!part->config->flags.eviction) {
/* It seams that no more partition for eviction */
break;
}
if (part_id == target_part_id) {
/* Omit targeted, evict from different first */
continue;
}
if (evicted >= evict_cline_no) {
/* Evicted requested number of cache line, stop */
goto out;
}
to_evict = ocf_evict_calculate(part, evict_cline_no);
if (to_evict == 0) {
/* No cache lines to evict for this partition */
continue;
}
evicted += ocf_eviction_need_space(cache, io_queue,
part_id, to_evict, core_id);
}
if (!ocf_eviction_can_evict(cache))
goto out;
if (evicted < evict_cline_no) {
/* Now we can evict form targeted partition */
to_evict = ocf_evict_calculate(target_part, evict_cline_no);
if (to_evict) {
evicted += ocf_eviction_need_space(cache, io_queue,
target_part_id, to_evict, core_id);
}
}
out:
return evicted;
}
int space_managment_evict_do(struct ocf_cache *cache,
struct ocf_request *req, uint32_t evict_cline_no)
{
uint32_t evicted;
if (evict_cline_no <= cache->device->freelist_part->curr_size)
return LOOKUP_MAPPED;
evict_cline_no = evict_cline_no - cache->device->freelist_part->curr_size;
evicted = ocf_evict_do(cache, req->io_queue, evict_cline_no,
req->core_id, req->part_id);
if (evict_cline_no <= evicted)
return LOOKUP_MAPPED;
req->info.eviction_error |= true;
return LOOKUP_MISS;
}