diff --git a/src/engine/engine_common.c b/src/engine/engine_common.c
index 0af7597..2632140 100644
--- a/src/engine/engine_common.c
+++ b/src/engine/engine_common.c
@@ -430,55 +430,50 @@ static inline int ocf_prepare_clines_miss(struct ocf_request *req,
{
int lock_status = -OCF_ERR_NO_LOCK;
struct ocf_metadata_lock *metadata_lock = &req->cache->metadata.lock;
- uint32_t clines_to_evict = 0;
- int res;
+
+ /* requests to disabled partitions go in pass-through */
+ if (!ocf_part_is_enabled(&req->cache->user_parts[req->part_id])) {
+ ocf_req_set_mapping_error(req);
+ ocf_req_hash_unlock_rd(req);
+ return lock_status;
+ }
+
+ if (!ocf_part_has_space(req)) {
+ ocf_req_hash_unlock_rd(req);
+ goto eviction;
+ }
/* Mapping must be performed holding (at least) hash-bucket write lock */
ocf_req_hash_lock_upgrade(req);
- /* Verify whether partition occupancy threshold is not reached yet or cache
- * is not out of free cachelines */
- res = ocf_part_check_space(req, &clines_to_evict);
- if (res == OCF_PART_IS_DISABLED) {
- ocf_req_set_mapping_error(req);
- ocf_req_hash_unlock_wr(req);
- return lock_status;
- }
-
- if (res == OCF_PART_HAS_SPACE) {
- ocf_engine_map(req);
- if (ocf_req_test_mapping_error(req)) {
- goto eviction;
- }
+ ocf_engine_map(req);
+ if (!ocf_req_test_mapping_error(req)) {
lock_status = lock_clines(req, engine_cbs);
if (lock_status < 0) {
/* Mapping succeeded, but we failed to acquire cacheline lock.
* Don't try to evict, just return error to caller */
ocf_req_set_mapping_error(req);
}
-
ocf_req_hash_unlock_wr(req);
return lock_status;
}
-eviction:
ocf_req_hash_unlock_wr(req);
+
+eviction:
ocf_metadata_start_exclusive_access(metadata_lock);
- ocf_part_check_space(req, &clines_to_evict);
+ /* repeat traversation to pick up latest metadata status */
+ ocf_engine_traverse(req);
- if (space_managment_evict_do(req->cache, req, clines_to_evict) ==
- LOOKUP_MISS) {
- ocf_req_set_mapping_error(req);
- goto unlock;
- }
+ if (!ocf_part_has_space(req))
+ ocf_req_set_part_evict(req);
+ else
+ ocf_req_clear_part_evict(req);
- if (!ocf_part_is_enabled(&req->cache->user_parts[req->part_id])) {
- /* Partition is disabled but it had cachelines assigned. Now, that they
- * are evicted, don't try to map cachelines - we don't want to insert
- * new cachelines - the request should be submited in pass through mode
- * instead */
+ if (space_managment_evict_do(req->cache, req,
+ ocf_engine_unmapped_count(req)) == LOOKUP_MISS) {
ocf_req_set_mapping_error(req);
goto unlock;
}
diff --git a/src/engine/engine_fast.c b/src/engine/engine_fast.c
index 23a828b..5a89e8c 100644
--- a/src/engine/engine_fast.c
+++ b/src/engine/engine_fast.c
@@ -108,7 +108,7 @@ int ocf_read_fast(struct ocf_request *req)
{
bool hit;
int lock = OCF_LOCK_NOT_ACQUIRED;
- bool part_has_space = false;
+ bool part_has_space;
/* Get OCF request - increase reference counter */
ocf_req_get(req);
@@ -126,8 +126,7 @@ int ocf_read_fast(struct ocf_request *req)
hit = ocf_engine_is_hit(req);
- if (ocf_part_check_space(req, NULL) == OCF_PART_HAS_SPACE)
- part_has_space = true;
+ part_has_space = ocf_part_has_space(req);
if (hit && part_has_space) {
ocf_io_start(&req->ioi.io);
@@ -197,8 +196,7 @@ int ocf_write_fast(struct ocf_request *req)
mapped = ocf_engine_is_mapped(req);
- if (ocf_part_check_space(req, NULL) == OCF_PART_HAS_SPACE)
- part_has_space = true;
+ part_has_space = ocf_part_has_space(req);
if (mapped && part_has_space) {
ocf_io_start(&req->ioi.io);
diff --git a/src/utils/utils_part.c b/src/utils/utils_part.c
index 7ee28d8..3da853b 100644
--- a/src/utils/utils_part.c
+++ b/src/utils/utils_part.c
@@ -190,82 +190,3 @@ 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;
-}
diff --git a/src/utils/utils_part.h b/src/utils/utils_part.h
index c37a43d..bf40602 100644
--- a/src/utils/utils_part.h
+++ b/src/utils/utils_part.h
@@ -100,20 +100,29 @@ 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 uint32_t ocf_part_overflow_size(struct ocf_cache *cache,
+ struct ocf_user_part *part)
+{
+ uint32_t part_occupancy = ocf_part_get_occupancy(part);
+ uint32_t part_occupancy_limit = ocf_part_get_max_size(cache, part);
+
+ if (part_occupancy > part_occupancy_limit)
+ return part_occupancy - part_occupancy_limit;
+
+ return 0;
+}
+
+static inline bool ocf_part_has_space(struct ocf_request *req)
+{
+ struct ocf_user_part *target_part = &req->cache->user_parts[req->part_id];
+ uint64_t part_occupancy_limit =
+ ocf_part_get_max_size(req->cache, target_part);
+ uint64_t needed_cache_lines = ocf_engine_repart_count(req) +
+ ocf_engine_unmapped_count(req);
+ uint64_t part_occupancy = ocf_part_get_occupancy(target_part);
+
+ return (part_occupancy + needed_cache_lines <= part_occupancy_limit);
+}
static inline ocf_cache_mode_t ocf_part_get_cache_mode(ocf_cache_t cache,
ocf_part_id_t part_id)
diff --git a/tests/unit/tests/engine/engine_common.c/prepare_clines_miss.c b/tests/unit/tests/engine/engine_common.c/prepare_clines_miss.c
index 81fec82..5534f23 100644
--- a/tests/unit/tests/engine/engine_common.c/prepare_clines_miss.c
+++ b/tests/unit/tests/engine/engine_common.c/prepare_clines_miss.c
@@ -44,8 +44,7 @@ void __wrap_ocf_req_hash_unlock_wr(struct ocf_request *req)
{
}
-uint32_t __wrap_ocf_part_check_space(struct ocf_request *req,
- uint32_t *to_evict)
+uint32_t __wrap_ocf_part_has_space(struct ocf_request *req)
{
return mock();
}
@@ -98,7 +97,7 @@ static void ocf_prepare_clines_miss_test01(void **state)
{
struct ocf_request req = {};
print_test_description("Target part is disabled and empty\n");
- will_return(__wrap_ocf_part_check_space, OCF_PART_IS_DISABLED);
+ will_return(__wrap_ocf_part_is_enabled, false);
expect_function_call(__wrap_ocf_req_set_mapping_error);
assert_int_equal(ocf_prepare_clines_miss(&req, NULL), -OCF_ERR_NO_LOCK);
}
@@ -107,13 +106,8 @@ static void ocf_prepare_clines_miss_test02(void **state)
{
struct ocf_request req = {};
print_test_description("Target part is disabled but has cachelines assigned.\n");
- print_test_description("\tTrigger eviction and mark mapping error\n");
+ print_test_description("\tMark mapping error\n");
- will_return(__wrap_ocf_part_check_space, OCF_PART_IS_FULL);
- will_return(__wrap_ocf_part_check_space, OCF_PART_IS_FULL);
-
- expect_function_call(__wrap_space_managment_evict_do);
- will_return(__wrap_space_managment_evict_do, LOOKUP_MAPPED);
will_return(__wrap_ocf_part_is_enabled, false);
expect_function_call(__wrap_ocf_req_set_mapping_error);
@@ -126,12 +120,12 @@ static void ocf_prepare_clines_miss_test03(void **state)
print_test_description("Target part is enabled but doesn't have enough space.\n");
print_test_description("\tEviction is ok and cachelines lock is acquired.\n");
- will_return(__wrap_ocf_part_check_space, OCF_PART_IS_FULL);
- will_return(__wrap_ocf_part_check_space, OCF_PART_IS_FULL);
+ will_return(__wrap_ocf_part_is_enabled, true);
+ will_return(__wrap_ocf_part_has_space, false);
+ will_return(__wrap_ocf_part_has_space, false);
expect_function_call(__wrap_space_managment_evict_do);
will_return(__wrap_space_managment_evict_do, LOOKUP_MAPPED);
- will_return(__wrap_ocf_part_is_enabled, true);
expect_function_call(__wrap_ocf_engine_map);
@@ -149,9 +143,10 @@ static void ocf_prepare_clines_miss_test04(void **state)
print_test_description("Target part is enabled but doesn't have enough space.\n");
print_test_description("\tEviction failed\n");
- will_return(__wrap_ocf_part_check_space, OCF_PART_IS_FULL);
- will_return(__wrap_ocf_part_check_space, OCF_PART_IS_FULL);
+ will_return(__wrap_ocf_part_is_enabled, true);
+ will_return(__wrap_ocf_part_has_space, false);
+ will_return(__wrap_ocf_part_has_space, false);
expect_function_call(__wrap_space_managment_evict_do);
will_return(__wrap_space_managment_evict_do, LOOKUP_MISS);
expect_function_call(__wrap_ocf_req_set_mapping_error);
@@ -165,8 +160,8 @@ static void ocf_prepare_clines_miss_test05(void **state)
print_test_description("Target part is enabled but doesn't have enough space.\n");
print_test_description("Eviction is ok, but mapping failed.\n");
- will_return(__wrap_ocf_part_check_space, OCF_PART_IS_FULL);
- will_return(__wrap_ocf_part_check_space, OCF_PART_IS_FULL);
+ will_return(__wrap_ocf_part_has_space, false);
+ will_return(__wrap_ocf_part_has_space, false);
expect_function_call(__wrap_space_managment_evict_do);
will_return(__wrap_space_managment_evict_do, LOOKUP_HIT);
@@ -185,8 +180,8 @@ static void ocf_prepare_clines_miss_test06(void **state)
print_test_description("Target part is enabled but doesn't have enough space.\n");
print_test_description("Eviction and mapping were ok, but failed to lock cachelines.\n");
- will_return(__wrap_ocf_part_check_space, OCF_PART_IS_FULL);
- will_return(__wrap_ocf_part_check_space, OCF_PART_IS_FULL);
+ will_return(__wrap_ocf_part_has_space, false);
+ will_return(__wrap_ocf_part_has_space, false);
expect_function_call(__wrap_space_managment_evict_do);
will_return(__wrap_space_managment_evict_do, LOOKUP_HIT);
@@ -210,8 +205,8 @@ static void ocf_prepare_clines_miss_test07(void **state)
print_test_description("Target part is enabled but doesn't have enough space.\n");
print_test_description("Eviction and mapping were ok, lock not acquired.\n");
- will_return(__wrap_ocf_part_check_space, OCF_PART_IS_FULL);
- will_return(__wrap_ocf_part_check_space, OCF_PART_IS_FULL);
+ will_return(__wrap_ocf_part_has_space, false);
+ will_return(__wrap_ocf_part_has_space, false);
expect_function_call(__wrap_space_managment_evict_do);
will_return(__wrap_space_managment_evict_do, LOOKUP_HIT);
@@ -233,7 +228,8 @@ static void ocf_prepare_clines_miss_test08(void **state)
print_test_description("Target part is enabled has enough space.\n");
print_test_description("\tMapping and cacheline lock are both ok\n");
- will_return(__wrap_ocf_part_check_space, OCF_PART_HAS_SPACE);
+ will_return(__wrap_ocf_part_is_enabled, true);
+ will_return(__wrap_ocf_part_has_space, true);
expect_function_call(__wrap_ocf_engine_map);
will_return(__wrap_ocf_req_test_mapping_error, false);
diff --git a/tests/unit/tests/utils/utils_part.c/ocf_part_evict_size.c b/tests/unit/tests/utils/utils_part.c/ocf_part_evict_size.c
deleted file mode 100644
index 2980372..0000000
--- a/tests/unit/tests/utils/utils_part.c/ocf_part_evict_size.c
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * src/utils/utils_part.c
- * ocf_part_evict_size
- *
- * INSERT HERE LIST OF FUNCTIONS YOU WANT TO LEAVE
- * ONE FUNCTION PER LINE
- *
- */
-
-#undef static
-
-#undef inline
-
-
-#include
-#include
-#include
-#include
-#include "print_desc.h"
-
-#include "ocf/ocf.h"
-#include "../ocf_cache_priv.h"
-#include "../ocf_request.h"
-#include "../metadata/metadata.h"
-#include "../engine/cache_engine.h"
-#include "../eviction/ops.h"
-#include "utils_part.h"
-
-#include "utils/utils_part.c/ocf_part_evict_size_generated_wraps.c"
-
-uint32_t __wrap_ocf_part_get_max_size(ocf_cache_t cache,
- struct ocf_user_part *target_part)
-{
- return mock();
-}
-
-uint32_t __wrap_ocf_engine_repart_count(struct ocf_request *req)
-{
- return mock();
-}
-
-uint32_t __wrap_ocf_engine_unmapped_count(struct ocf_request *req)
-{
- return mock();
-}
-
-uint32_t __wrap_ocf_part_get_occupancy(struct ocf_user_part *target_part)
-{
- return mock();
-}
-
-ocf_cache_line_t __wrap_ocf_freelist_num_free(ocf_freelist_t freelist)
-{
- return mock();
-}
-
-void __wrap_ocf_req_set_part_evict(struct ocf_request *req)
-{
- function_called();
-}
-
-void __wrap_ocf_req_clear_part_evict(struct ocf_request *req)
-{
- function_called();
-}
-
-static void ocf_part_evict_size_test01(void **state)
-{
- uint32_t max_part_size = 1024;
- uint32_t cachelines_to_repart = 0;
- uint32_t cachelines_to_map = 320;
- uint32_t part_occupied_cachelines = 512;
- uint32_t freelist_size = 500;
-
- struct ocf_request req;
- req.cache = test_malloc(sizeof(struct ocf_cache));
-
- print_test_description("Enough free space available");
-
- will_return(__wrap_ocf_part_get_max_size, max_part_size);
-
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
- will_return(__wrap_ocf_engine_repart_count, cachelines_to_repart);
-
- will_return(__wrap_ocf_part_get_occupancy, part_occupied_cachelines);
-
- // Enough free cachelines to map a whole request
- will_return(__wrap_ocf_freelist_num_free, freelist_size);
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
-
- assert_int_equal(ocf_part_evict_size(&req), 0);
-
- test_free(req.cache);
-}
-
-static void ocf_part_evict_size_test02(void **state)
-{
- uint32_t max_part_size = 1024;
- uint32_t cachelines_to_repart = 0;
- uint32_t cachelines_to_map = 320;
- uint32_t part_occupied_cachelines = 960;
- uint32_t freelist_size = 500;
-
- struct ocf_request req;
- req.cache = test_malloc(sizeof(struct ocf_cache));
-
- uint32_t available_cachelines = max_part_size - part_occupied_cachelines;
- uint32_t cachelines_to_evict = cachelines_to_map - available_cachelines;
-
- print_test_description("Cache has enough free cachelines,"
- " but target partition must be evicted");
-
- will_return(__wrap_ocf_part_get_max_size, max_part_size);
-
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
- will_return(__wrap_ocf_engine_repart_count, cachelines_to_repart);
-
- will_return(__wrap_ocf_part_get_occupancy, part_occupied_cachelines);
-
- will_return(__wrap_ocf_freelist_num_free, freelist_size);
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
-
- expect_function_call(__wrap_ocf_req_set_part_evict);
-
- assert_int_equal(ocf_part_evict_size(&req), cachelines_to_evict);
-
- test_free(req.cache);
-}
-
-static void ocf_part_evict_size_test03(void **state)
-{
- uint32_t max_part_size = 1024;
- uint32_t cachelines_to_repart = 320;
- uint32_t cachelines_to_map = 0;
- uint32_t part_occupied_cachelines = 512;
- uint32_t freelist_size = 0;
-
- struct ocf_request req;
- req.cache = test_malloc(sizeof(struct ocf_cache));
-
- uint32_t cachelines_to_evict = 0;
-
- print_test_description("Only repart (no mapping). Freelist is empty but "
- "space in a target part is availabe,");
- print_test_description("\tso no cachelines should be "
- " evcited from cache");
-
- will_return(__wrap_ocf_part_get_max_size, max_part_size);
-
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
- will_return(__wrap_ocf_engine_repart_count, cachelines_to_repart);
-
- will_return(__wrap_ocf_part_get_occupancy, part_occupied_cachelines);
-
- will_return(__wrap_ocf_freelist_num_free, freelist_size);
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
-
- assert_int_equal(ocf_part_evict_size(&req), cachelines_to_evict);
-
- test_free(req.cache);
-}
-
-static void ocf_part_evict_size_test04(void **state)
-{
- uint32_t max_part_size = 1024;
- uint32_t cachelines_to_repart = 320;
- uint32_t cachelines_to_map = 0;
- uint32_t part_occupied_cachelines = 1100;
- uint32_t freelist_size = 0;
-
- struct ocf_request req;
- req.cache = test_malloc(sizeof(struct ocf_cache));
-
- uint32_t cachelines_debt = part_occupied_cachelines - max_part_size;
- uint32_t cachelines_to_evict = cachelines_to_repart + cachelines_debt;
-
- print_test_description("Only repart (no mapping). Freelist is empty and no"
- " space in target part is availabe.");
- print_test_description("\tEvict only from target partition");
-
- will_return(__wrap_ocf_part_get_max_size, max_part_size);
-
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
- will_return(__wrap_ocf_engine_repart_count, cachelines_to_repart);
-
- will_return(__wrap_ocf_part_get_occupancy, part_occupied_cachelines);
-
- will_return(__wrap_ocf_freelist_num_free, freelist_size);
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
-
- expect_function_call(__wrap_ocf_req_set_part_evict);
-
- assert_int_equal(ocf_part_evict_size(&req), cachelines_to_evict);
-
- test_free(req.cache);
-}
-
-static void ocf_part_evict_size_test05(void **state)
-{
- uint32_t max_part_size = 1024;
- uint32_t cachelines_to_repart = 0;
- uint32_t cachelines_to_map = 320;
- uint32_t part_occupied_cachelines = 960;
- uint32_t freelist_size = 0;
-
- struct ocf_request req;
- req.cache = test_malloc(sizeof(struct ocf_cache));
-
- uint32_t available_cachelines = max_part_size - part_occupied_cachelines;
- uint32_t cachelines_to_evict = cachelines_to_map - available_cachelines;
-
- print_test_description("Freelist is empty and no space in the target part "
- "is available");
-
- will_return(__wrap_ocf_part_get_max_size, max_part_size);
-
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
- will_return(__wrap_ocf_engine_repart_count, cachelines_to_repart);
-
- will_return(__wrap_ocf_part_get_occupancy, part_occupied_cachelines);
-
- will_return(__wrap_ocf_freelist_num_free, freelist_size);
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
-
- expect_function_call(__wrap_ocf_req_set_part_evict);
-
- assert_int_equal(ocf_part_evict_size(&req), cachelines_to_evict);
-
- test_free(req.cache);
-}
-
-static void ocf_part_evict_size_test06(void **state)
-{
- uint32_t max_part_size = 1024;
- uint32_t cachelines_to_repart = 0;
- uint32_t cachelines_to_map = 320;
- uint32_t part_occupied_cachelines = 320;
- uint32_t freelist_size = 0;
-
- struct ocf_request req;
- req.cache = test_malloc(sizeof(struct ocf_cache));
-
- uint32_t available_cachelines = max_part_size - part_occupied_cachelines;
- uint32_t cachelines_to_evict = cachelines_to_map;
-
- print_test_description("Freelist is empty but target part has enough space");
-
- will_return(__wrap_ocf_part_get_max_size, max_part_size);
-
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
- will_return(__wrap_ocf_engine_repart_count, cachelines_to_repart);
-
- will_return(__wrap_ocf_part_get_occupancy, part_occupied_cachelines);
-
- will_return(__wrap_ocf_freelist_num_free, freelist_size);
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
-
- expect_function_call(__wrap_ocf_req_clear_part_evict);
-
- assert_int_equal(ocf_part_evict_size(&req), cachelines_to_evict);
-
- test_free(req.cache);
-}
-
-static void ocf_part_evict_size_test07(void **state)
-{
- uint32_t max_part_size = 1024;
- uint32_t cachelines_to_repart = 0;
- uint32_t cachelines_to_map = 320;
- uint32_t part_occupied_cachelines = 1280;
- uint32_t freelist_size = 0;
-
- struct ocf_request req;
- req.cache = test_malloc(sizeof(struct ocf_cache));
-
- uint32_t debt_cachelines = part_occupied_cachelines - max_part_size;
- uint32_t cachelines_to_evict = cachelines_to_map + debt_cachelines;
-
- print_test_description("Freelist is empty and part occupancy exceeded");
-
- will_return(__wrap_ocf_part_get_max_size, max_part_size);
-
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
- will_return(__wrap_ocf_engine_repart_count, cachelines_to_repart);
-
- will_return(__wrap_ocf_part_get_occupancy, part_occupied_cachelines);
-
- will_return(__wrap_ocf_freelist_num_free, freelist_size);
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
-
- expect_function_call(__wrap_ocf_req_set_part_evict);
-
- assert_int_equal(ocf_part_evict_size(&req),
- (part_occupied_cachelines - max_part_size) + cachelines_to_map);
-
- test_free(req.cache);
-}
-
-static void ocf_part_evict_size_test08(void **state)
-{
- uint32_t max_part_size = 1024;
- uint32_t cachelines_to_repart = 320;
- uint32_t cachelines_to_map = 0;
- uint32_t part_occupied_cachelines = 1280;
- uint32_t freelist_size = 0;
-
- struct ocf_request req;
- req.cache = test_malloc(sizeof(struct ocf_cache));
-
- uint32_t debt_cachelines = part_occupied_cachelines - max_part_size;
- uint32_t cachelines_to_evict = debt_cachelines + cachelines_to_repart;
-
- print_test_description("Target part occupancy limit is exceeded during "
- "repart");
-
- will_return(__wrap_ocf_part_get_max_size, max_part_size);
-
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
- will_return(__wrap_ocf_engine_repart_count, cachelines_to_repart);
-
- will_return(__wrap_ocf_part_get_occupancy, part_occupied_cachelines);
-
- will_return(__wrap_ocf_freelist_num_free, freelist_size);
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
-
- expect_function_call(__wrap_ocf_req_set_part_evict);
-
- assert_int_equal(ocf_part_evict_size(&req),
- (part_occupied_cachelines - max_part_size) + cachelines_to_repart);
-
- test_free(req.cache);
-}
-
-static void ocf_part_evict_size_test09(void **state)
-{
- uint32_t max_part_size = 1024;
- uint32_t cachelines_to_repart = 320;
- uint32_t cachelines_to_map = 0;
- uint32_t part_occupied_cachelines = 320;
- uint32_t freelist_size = 0;
-
- struct ocf_request req;
- req.cache = test_malloc(sizeof(struct ocf_cache));
-
- uint32_t cachelines_to_evict = 0;
-
- print_test_description("Repart while target part has enough of available "
- "space");
-
- will_return(__wrap_ocf_part_get_max_size, max_part_size);
-
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
- will_return(__wrap_ocf_engine_repart_count, cachelines_to_repart);
-
- will_return(__wrap_ocf_part_get_occupancy, part_occupied_cachelines);
-
- will_return(__wrap_ocf_freelist_num_free, freelist_size);
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
-
- assert_int_equal(ocf_part_evict_size(&req), cachelines_to_evict);
-
- test_free(req.cache);
-}
-
-static void ocf_part_evict_size_test10(void **state)
-{
- uint32_t max_part_size = 1024;
- uint32_t cachelines_to_repart = 0;
- uint32_t cachelines_to_map = 320;
- uint32_t part_occupied_cachelines = 320;
- uint32_t freelist_size = 320;
-
- struct ocf_request req;
- req.cache = test_malloc(sizeof(struct ocf_cache));
-
- uint32_t cachelines_to_evict = 0;
-
- print_test_description("Enough of available cachelines in target part, "
- "freelist has exactly required number of free cachelines");
-
- will_return(__wrap_ocf_part_get_max_size, max_part_size);
-
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
- will_return(__wrap_ocf_engine_repart_count, cachelines_to_repart);
-
- will_return(__wrap_ocf_part_get_occupancy, part_occupied_cachelines);
-
- will_return(__wrap_ocf_freelist_num_free, freelist_size);
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
-
- assert_int_equal(ocf_part_evict_size(&req), cachelines_to_evict);
-
- test_free(req.cache);
-}
-
-static void ocf_part_evict_size_test11(void **state)
-{
- uint32_t max_part_size = 1024;
- uint32_t cachelines_to_repart = 320;
- uint32_t cachelines_to_map = 0;
- uint32_t part_occupied_cachelines = 384;
- uint32_t freelist_size = 0;
-
- struct ocf_request req;
- req.cache = test_malloc(sizeof(struct ocf_cache));
-
- uint32_t cachelines_to_evict = 0;
-
- print_test_description("Number of cachelines to repart is equal to number "
- "of cachelines available in the target partition");
-
- will_return(__wrap_ocf_part_get_max_size, max_part_size);
-
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
- will_return(__wrap_ocf_engine_repart_count, cachelines_to_repart);
-
- will_return(__wrap_ocf_part_get_occupancy, part_occupied_cachelines);
-
- will_return(__wrap_ocf_freelist_num_free, freelist_size);
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
-
- assert_int_equal(ocf_part_evict_size(&req), cachelines_to_evict);
-
- test_free(req.cache);
-}
-
-static void ocf_part_evict_size_test12(void **state)
-{
- uint32_t max_part_size = 0;
- uint32_t cachelines_to_repart = 0;
- uint32_t cachelines_to_map = 320;
- uint32_t part_occupied_cachelines = 384;
- uint32_t freelist_size = 0;
-
- struct ocf_request req;
- req.cache = test_malloc(sizeof(struct ocf_cache));
-
- uint32_t cachelines_to_evict =
- part_occupied_cachelines + cachelines_to_map;
-
- print_test_description("Freelist IS empty. Max occupancy set to 0, but "
- "some cachelines are still assigned to traget part - evict them");
-
- will_return(__wrap_ocf_part_get_max_size, max_part_size);
-
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
- will_return(__wrap_ocf_engine_repart_count, cachelines_to_repart);
-
- will_return(__wrap_ocf_part_get_occupancy, part_occupied_cachelines);
-
- will_return(__wrap_ocf_freelist_num_free, freelist_size);
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
-
- expect_function_call(__wrap_ocf_req_set_part_evict);
-
- assert_true(ocf_part_evict_size(&req) >= part_occupied_cachelines);
-
- test_free(req.cache);
-}
-
-static void ocf_part_evict_size_test13(void **state)
-{
- uint32_t max_part_size = 0;
- uint32_t cachelines_to_repart = 0;
- uint32_t cachelines_to_map = 320;
- uint32_t part_occupied_cachelines = 384;
- uint32_t freelist_size = 1024;
-
- struct ocf_request req;
- req.cache = test_malloc(sizeof(struct ocf_cache));
-
- uint32_t cachelines_to_evict =
- part_occupied_cachelines + cachelines_to_map;
-
- print_test_description("Freelist IS NOT empty. Max occupancy set to 0, but"
- " some cachelines are still assigned to traget part - evict them");
-
- will_return(__wrap_ocf_part_get_max_size, max_part_size);
-
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
- will_return(__wrap_ocf_engine_repart_count, cachelines_to_repart);
-
- will_return(__wrap_ocf_part_get_occupancy, part_occupied_cachelines);
-
- will_return(__wrap_ocf_freelist_num_free, freelist_size);
- will_return(__wrap_ocf_engine_unmapped_count, cachelines_to_map);
-
- expect_function_call(__wrap_ocf_req_set_part_evict);
-
- assert_true(ocf_part_evict_size(&req) >= part_occupied_cachelines);
-
- test_free(req.cache);
-}
-
-int main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(ocf_part_evict_size_test01),
- cmocka_unit_test(ocf_part_evict_size_test02),
- cmocka_unit_test(ocf_part_evict_size_test03),
- cmocka_unit_test(ocf_part_evict_size_test04),
- cmocka_unit_test(ocf_part_evict_size_test05),
- cmocka_unit_test(ocf_part_evict_size_test06),
- cmocka_unit_test(ocf_part_evict_size_test07),
- cmocka_unit_test(ocf_part_evict_size_test08),
- cmocka_unit_test(ocf_part_evict_size_test09),
- cmocka_unit_test(ocf_part_evict_size_test10),
- cmocka_unit_test(ocf_part_evict_size_test11),
- cmocka_unit_test(ocf_part_evict_size_test12),
- cmocka_unit_test(ocf_part_evict_size_test13)
- };
-
- print_message("Unit test for ocf_part_evict_size\n");
-
- return cmocka_run_group_tests(tests, NULL, NULL);
-}