Occupancy per ioclass utilities
Functions to check space availability and to manage cachelines reservation Signed-off-by: Michal Mielewczyk <michal.mielewczyk@intel.com>
This commit is contained in:
parent
600bd1d859
commit
05f3c22dad
@ -190,3 +190,82 @@ void ocf_part_set_valid(struct ocf_cache *cache, ocf_part_id_t id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t ocf_part_evict_size(struct ocf_request *req)
|
||||||
|
{
|
||||||
|
uint32_t needed_cache_lines, part_available, cache_lines_to_evict;
|
||||||
|
uint32_t part_occupancy, part_occupancy_debt;
|
||||||
|
struct ocf_user_part *target_part = &req->cache->user_parts[req->part_id];
|
||||||
|
uint32_t part_occupancy_limit =
|
||||||
|
ocf_part_get_max_size(req->cache, target_part);
|
||||||
|
|
||||||
|
needed_cache_lines = ocf_engine_repart_count(req) +
|
||||||
|
ocf_engine_unmapped_count(req);
|
||||||
|
|
||||||
|
part_occupancy = ocf_part_get_occupancy(target_part);
|
||||||
|
|
||||||
|
if (part_occupancy_limit >= part_occupancy) {
|
||||||
|
part_available = part_occupancy_limit - part_occupancy;
|
||||||
|
part_occupancy_debt = 0;
|
||||||
|
} else {
|
||||||
|
/* Occupancy is greater than occupancy limit. Evict missing number of
|
||||||
|
* cachelines, but no more than single eviction limit */
|
||||||
|
part_occupancy_debt = min((uint32_t)OCF_PENDING_EVICTION_LIMIT,
|
||||||
|
part_occupancy - part_occupancy_limit);
|
||||||
|
part_available = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ocf_freelist_num_free(req->cache->freelist) <
|
||||||
|
ocf_engine_unmapped_count(req)) {
|
||||||
|
/* Number of cachelines to insert greater than number of free
|
||||||
|
* cachelines */
|
||||||
|
if (part_available >= needed_cache_lines) {
|
||||||
|
/* Cache is full, but target's part occupancy limit is not reached
|
||||||
|
*/
|
||||||
|
ocf_req_clear_part_evict(req);
|
||||||
|
cache_lines_to_evict = needed_cache_lines;
|
||||||
|
} else {
|
||||||
|
/* Cache is full and target part reached it's occupancy limit */
|
||||||
|
ocf_req_set_part_evict(req);
|
||||||
|
cache_lines_to_evict = needed_cache_lines - part_available;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (part_available < needed_cache_lines) {
|
||||||
|
/* Enough of free cache lines, but partition reached it's occupancy
|
||||||
|
* limit */
|
||||||
|
cache_lines_to_evict = needed_cache_lines - part_available;
|
||||||
|
ocf_req_set_part_evict(req);
|
||||||
|
|
||||||
|
} else if (part_available >= needed_cache_lines) {
|
||||||
|
/* Enough free cachelines available and they can be assigned to target
|
||||||
|
* partition */
|
||||||
|
cache_lines_to_evict = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache_lines_to_evict + part_occupancy_debt;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ocf_part_check_space(struct ocf_request *req, uint32_t *to_evict)
|
||||||
|
{
|
||||||
|
uint32_t ret = OCF_PART_IS_FULL;
|
||||||
|
uint32_t _to_evict;
|
||||||
|
struct ocf_user_part *target_part = &req->cache->user_parts[req->part_id];
|
||||||
|
|
||||||
|
if (!ocf_part_is_enabled(target_part) &&
|
||||||
|
ocf_part_get_occupancy(target_part) == 0) {
|
||||||
|
/* If partition is disabled, but has assigned cachelines, eviction has
|
||||||
|
* to be triggered */
|
||||||
|
return OCF_PART_IS_DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
_to_evict = ocf_part_evict_size(req);
|
||||||
|
|
||||||
|
if (_to_evict == 0)
|
||||||
|
ret = OCF_PART_HAS_SPACE;
|
||||||
|
|
||||||
|
if (to_evict)
|
||||||
|
*to_evict = _to_evict;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "../ocf_request.h"
|
#include "../ocf_request.h"
|
||||||
#include "../engine/cache_engine.h"
|
#include "../engine/cache_engine.h"
|
||||||
|
#include "../engine/engine_common.h"
|
||||||
#include "../metadata/metadata_partition.h"
|
#include "../metadata/metadata_partition.h"
|
||||||
|
|
||||||
void ocf_part_init(struct ocf_cache *cache);
|
void ocf_part_init(struct ocf_cache *cache);
|
||||||
@ -72,7 +73,27 @@ static inline void ocf_part_sort(struct ocf_cache *cache)
|
|||||||
ocf_lst_sort(&cache->lst_part);
|
ocf_lst_sort(&cache->lst_part);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline ocf_cache_mode_t ocf_part_get_cache_mode(struct ocf_cache *cache,
|
static inline bool ocf_part_is_enabled(struct ocf_user_part *part)
|
||||||
|
{
|
||||||
|
return part->config->max_size != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OCF_PART_HAS_SPACE 0
|
||||||
|
#define OCF_PART_IS_FULL 1
|
||||||
|
#define OCF_PART_IS_DISABLED 2
|
||||||
|
/**
|
||||||
|
* Check whether there is enough free cachelines to serve request. If partition
|
||||||
|
* occupancy limit is reached, `req->part_evict` is set to true. Otherwise
|
||||||
|
* flag is set to false and eviction from any partition should be triggered.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* OCF_PART_HAS_SPACE when cachelines alloted successfully
|
||||||
|
* OCF_PART_IS_FULL when need to evict some cachelines to serve request
|
||||||
|
* OCF_PART_IS_DISABLED when caching for particular partition is disabled
|
||||||
|
*/
|
||||||
|
uint32_t ocf_part_check_space(struct ocf_request *req, uint32_t *to_evict);
|
||||||
|
|
||||||
|
static inline ocf_cache_mode_t ocf_part_get_cache_mode(ocf_cache_t cache,
|
||||||
ocf_part_id_t part_id)
|
ocf_part_id_t part_id)
|
||||||
{
|
{
|
||||||
if (part_id < OCF_IO_CLASS_MAX)
|
if (part_id < OCF_IO_CLASS_MAX)
|
||||||
|
Loading…
Reference in New Issue
Block a user