diff --git a/src/engine/engine_common.c b/src/engine/engine_common.c index c57aefe..88a8d52 100644 --- a/src/engine/engine_common.c +++ b/src/engine/engine_common.c @@ -16,7 +16,6 @@ #include "../utils/utils_cleaner.h" #include "../metadata/metadata.h" #include "../eviction/eviction.h" -#include "../promotion/promotion.h" void ocf_engine_error(struct ocf_request *req, bool stop_cache, const char *msg) @@ -315,18 +314,15 @@ void ocf_engine_map(struct ocf_request *req) int status = LOOKUP_MAPPED; ocf_core_id_t core_id = ocf_core_get_id(req->core); - if (!ocf_promotion_req_should_promote(cache->promotion_policy, req)) { + if (!ocf_engine_unmapped_count(req)) + return; + + if (ocf_engine_unmapped_count(req) > + ocf_freelist_num_free(cache->freelist)) { req->info.mapping_error = 1; return; } - if (ocf_engine_unmapped_count(req)) - status = space_managment_evict_do(cache, req, - ocf_engine_unmapped_count(req)); - - if (req->info.mapping_error) - return; - ocf_req_clear_info(req); req->info.seq_req = true; @@ -397,6 +393,15 @@ static void _ocf_engine_clean_end(void *private_data, int error) } } +int ocf_engine_evict(struct ocf_request *req) +{ + if (!ocf_engine_unmapped_count(req)) + return 0; + + return space_managment_evict_do(req->cache, req, + ocf_engine_unmapped_count(req)); +} + static int _ocf_engine_clean_getter(struct ocf_cache *cache, void *getter_context, uint32_t item, ocf_cache_line_t *line) { diff --git a/src/engine/engine_common.h b/src/engine/engine_common.h index b581da5..1a4d689 100644 --- a/src/engine/engine_common.h +++ b/src/engine/engine_common.h @@ -162,19 +162,28 @@ void ocf_engine_lookup_map_entry(struct ocf_cache *cache, uint64_t core_line); /** - * @brief Traverse request in order to lookup cache lines If there are misses - * need to call eviction. This process is called 'mapping'. - * - * @note This function CALL EVICTION + * @brief Traverse request in order to lookup cache lines. If there are misses, + * attempt to map free cache lines. * * @param req OCF request */ void ocf_engine_map(struct ocf_request *req); +/** + * @brief Evict cachelines to populate freelist. + * + * @param req OCF request + * + * @returns eviction status + * @retval LOOKUP_MAPPED successfully evicted required number of cachelines + * @retval LOOKUP_MISS eviction failure + */ +int ocf_engine_evict(struct ocf_request *req); + /** * @brief Traverse OCF request (lookup cache) * - * @note This function DO NOT CALL EVICTION. Only lookup in metadata is + * @note This function does not evict cachelines. Only lookup in metadata is * performed. Main purpose of this function is to check if there is a HIT. * * @param req OCF request diff --git a/src/engine/engine_rd.c b/src/engine/engine_rd.c index a26ef10..8e593c7 100644 --- a/src/engine/engine_rd.c +++ b/src/engine/engine_rd.c @@ -215,6 +215,7 @@ int ocf_read_generic(struct ocf_request *req) bool mapped; int lock = OCF_LOCK_NOT_ACQUIRED; struct ocf_cache *cache = req->cache; + bool promote = true; ocf_io_start(&req->ioi.io); @@ -252,21 +253,25 @@ int ocf_read_generic(struct ocf_request *req) } } + if (!mapped) { + promote = ocf_promotion_req_should_promote( + cache->promotion_policy, req); + } + OCF_METADATA_UNLOCK_RD(); /*- END Metadata RD access -------------------------------------------*/ - if (!mapped) { - + if (!mapped && promote) { /*- Metadata WR access ---------------------------------------*/ - OCF_METADATA_LOCK_WR(); /* Now there is exclusive access for metadata. May traverse once * again. If there are misses need to call eviction. This * process is called 'mapping'. */ - ocf_engine_map(req); + if (ocf_engine_evict(req) == LOOKUP_MAPPED) + ocf_engine_map(req); if (!req->info.mapping_error) { if (ocf_engine_is_hit(req)) { @@ -288,7 +293,7 @@ int ocf_read_generic(struct ocf_request *req) /*- END Metadata WR access -----------------------------------*/ } - if (!req->info.mapping_error) { + if (promote && !req->info.mapping_error) { if (lock >= 0) { if (lock != OCF_LOCK_ACQUIRED) { /* Lock was not acquired, need to wait for resume */ diff --git a/src/engine/engine_wb.c b/src/engine/engine_wb.c index 1a9938b..1cf052a 100644 --- a/src/engine/engine_wb.c +++ b/src/engine/engine_wb.c @@ -170,6 +170,7 @@ int ocf_write_wb(struct ocf_request *req) bool mapped; int lock = OCF_LOCK_NOT_ACQUIRED; struct ocf_cache *cache = req->cache; + bool promote = true; ocf_io_start(&req->ioi.io); @@ -192,16 +193,22 @@ int ocf_write_wb(struct ocf_request *req) lock = ocf_req_async_lock_wr(req, ocf_engine_on_resume); } + if (!mapped) { + promote = ocf_promotion_req_should_promote( + cache->promotion_policy, req); + } + OCF_METADATA_UNLOCK_RD(); /*- END Metadata READ access----------------*/ - if (!mapped) { + if (!mapped && promote) { OCF_METADATA_LOCK_WR(); /*- Metadata WR access, eviction -----*/ /* Now there is exclusive access for metadata. May traverse once * again. If there are misses need to call eviction. This * process is called 'mapping'. */ - ocf_engine_map(req); + if (ocf_engine_evict(req) == LOOKUP_MAPPED) + ocf_engine_map(req); if (!req->info.mapping_error) { /* Lock request for WRITE access */ @@ -211,7 +218,7 @@ int ocf_write_wb(struct ocf_request *req) OCF_METADATA_UNLOCK_WR(); /*- END Metadata WR access ---------*/ } - if (!req->info.mapping_error) { + if (promote && !req->info.mapping_error) { if (lock >= 0) { if (lock != OCF_LOCK_ACQUIRED) { /* WR lock was not acquired, need to wait for resume */ diff --git a/src/engine/engine_wt.c b/src/engine/engine_wt.c index 9db3ec3..db2a81c 100644 --- a/src/engine/engine_wt.c +++ b/src/engine/engine_wt.c @@ -165,6 +165,7 @@ int ocf_write_wt(struct ocf_request *req) bool mapped; int lock = OCF_LOCK_NOT_ACQUIRED; struct ocf_cache *cache = req->cache; + bool promote = true; ocf_io_start(&req->ioi.io); @@ -185,16 +186,22 @@ int ocf_write_wt(struct ocf_request *req) lock = ocf_req_async_lock_wr(req, ocf_engine_on_resume); } + if (!mapped) { + promote = ocf_promotion_req_should_promote( + cache->promotion_policy, req); + } + OCF_METADATA_UNLOCK_RD(); /*- END Metadata READ access----------------*/ - if (!mapped) { + if (!mapped && promote) { OCF_METADATA_LOCK_WR(); /*- Metadata WR access, eviction -----*/ /* Now there is exclusive access for metadata. May traverse once * again. If there are misses need to call eviction. This * process is called 'mapping'. */ - ocf_engine_map(req); + if (ocf_engine_evict(req) == LOOKUP_MAPPED) + ocf_engine_map(req); if (!req->info.mapping_error) { /* Lock request for WRITE access */ @@ -204,7 +211,7 @@ int ocf_write_wt(struct ocf_request *req) OCF_METADATA_UNLOCK_WR(); /*- END Metadata WR access ---------*/ } - if (!req->info.mapping_error) { + if (promote && !req->info.mapping_error) { if (lock >= 0) { if (lock != OCF_LOCK_ACQUIRED) { /* WR lock was not acquired, need to wait for resume */