diff --git a/src/engine/engine_common.c b/src/engine/engine_common.c index 88a8d52..a8d5fc1 100644 --- a/src/engine/engine_common.c +++ b/src/engine/engine_common.c @@ -538,15 +538,14 @@ void inc_fallback_pt_error_counter(ocf_cache_t cache) static int _ocf_engine_refresh(struct ocf_request *req) { - struct ocf_cache *cache = req->cache; int result; - OCF_METADATA_LOCK_RD(); /* Check under metadata RD lock */ + ocf_req_hash_lock_rd(req); result = ocf_engine_check(req); - OCF_METADATA_UNLOCK_RD(); + ocf_req_hash_unlock_rd(req); if (result == 0) { diff --git a/src/engine/engine_discard.c b/src/engine/engine_discard.c index e460f4f..8c10c7d 100644 --- a/src/engine/engine_discard.c +++ b/src/engine/engine_discard.c @@ -170,7 +170,7 @@ int _ocf_discard_step_do(struct ocf_request *req) if (ocf_engine_mapped_count(req)) { /* There are mapped cache line, need to remove them */ - OCF_METADATA_LOCK_WR(); /*- Metadata WR access ---------------*/ + ocf_req_hash_lock_wr(req); /* Remove mapped cache lines from metadata */ ocf_purge_map_info(req); @@ -181,16 +181,16 @@ int _ocf_discard_step_do(struct ocf_request *req) _ocf_discard_step_complete); } - OCF_METADATA_UNLOCK_WR(); /*- END Metadata WR access ---------*/ + ocf_req_hash_unlock_wr(req); } - OCF_METADATA_LOCK_RD(); + ocf_req_hash_lock_rd(req); /* Even if no cachelines are mapped they could be tracked in promotion * policy. RD lock suffices. */ ocf_promotion_req_purge(req->cache->promotion_policy, req); - OCF_METADATA_UNLOCK_RD(); + ocf_req_hash_unlock_rd(req); OCF_DEBUG_RQ(req, "Discard"); _ocf_discard_step_complete(req, 0); @@ -224,11 +224,12 @@ static int _ocf_discard_step(struct ocf_request *req) req->core_line_count = req->core_line_last - req->core_line_first + 1; req->io_if = &_io_if_discard_step_resume; - OCF_METADATA_LOCK_RD(); /*- Metadata READ access, No eviction --------*/ - ENV_BUG_ON(env_memset(req->map, sizeof(*req->map) * req->core_line_count, 0)); + ocf_req_hash(req); + ocf_req_hash_lock_rd(req); + /* Travers to check if request is mapped fully */ ocf_engine_traverse(req); @@ -239,7 +240,7 @@ static int _ocf_discard_step(struct ocf_request *req) lock = OCF_LOCK_ACQUIRED; } - OCF_METADATA_UNLOCK_RD(); /*- END Metadata READ access----------------*/ + ocf_req_hash_unlock_rd(req); if (lock >= 0) { if (OCF_LOCK_ACQUIRED == lock) { diff --git a/src/engine/engine_fast.c b/src/engine/engine_fast.c index 78bf350..8cfe96c 100644 --- a/src/engine/engine_fast.c +++ b/src/engine/engine_fast.c @@ -58,8 +58,6 @@ static void _ocf_read_fast_complete(struct ocf_request *req, int error) static int _ocf_read_fast_do(struct ocf_request *req) { - struct ocf_cache *cache = req->cache; - if (ocf_engine_is_miss(req)) { /* It seams that after resume, now request is MISS, do PT */ OCF_DEBUG_RQ(req, "Switching to read PT"); @@ -74,14 +72,14 @@ static int _ocf_read_fast_do(struct ocf_request *req) if (req->info.re_part) { OCF_DEBUG_RQ(req, "Re-Part"); - OCF_METADATA_LOCK_WR(); + ocf_req_hash_lock_wr(req); /* Probably some cache lines are assigned into wrong * partition. Need to move it to new one */ ocf_part_move(req); - OCF_METADATA_UNLOCK_WR(); + ocf_req_hash_unlock_wr(req); } /* Submit IO */ @@ -110,7 +108,6 @@ int ocf_read_fast(struct ocf_request *req) { bool hit; int lock = OCF_LOCK_NOT_ACQUIRED; - struct ocf_cache *cache = req->cache; /* Get OCF request - increase reference counter */ ocf_req_get(req); @@ -120,7 +117,8 @@ int ocf_read_fast(struct ocf_request *req) /*- Metadata RD access -----------------------------------------------*/ - OCF_METADATA_LOCK_RD(); + ocf_req_hash(req); + ocf_req_hash_lock_rd(req); /* Traverse request to cache if there is hit */ ocf_engine_traverse(req); @@ -131,7 +129,7 @@ int ocf_read_fast(struct ocf_request *req) lock = ocf_req_async_lock_rd(req, ocf_engine_on_resume); } - OCF_METADATA_UNLOCK_RD(); + ocf_req_hash_unlock_rd(req); if (hit) { OCF_DEBUG_RQ(req, "Fast path success"); @@ -179,7 +177,6 @@ int ocf_write_fast(struct ocf_request *req) { bool mapped; int lock = OCF_LOCK_NOT_ACQUIRED; - struct ocf_cache *cache = req->cache; /* Get OCF request - increase reference counter */ ocf_req_get(req); @@ -189,7 +186,8 @@ int ocf_write_fast(struct ocf_request *req) /*- Metadata RD access -----------------------------------------------*/ - OCF_METADATA_LOCK_RD(); + ocf_req_hash(req); + ocf_req_hash_lock_rd(req); /* Traverse request to cache if there is hit */ ocf_engine_traverse(req); @@ -200,7 +198,7 @@ int ocf_write_fast(struct ocf_request *req) lock = ocf_req_async_lock_wr(req, ocf_engine_on_resume); } - OCF_METADATA_UNLOCK_RD(); + ocf_req_hash_unlock_rd(req); if (mapped) { if (lock >= 0) { diff --git a/src/engine/engine_inv.c b/src/engine/engine_inv.c index 347d3cf..4824fb0 100644 --- a/src/engine/engine_inv.c +++ b/src/engine/engine_inv.c @@ -43,9 +43,9 @@ static int _ocf_invalidate_do(struct ocf_request *req) ENV_BUG_ON(env_atomic_read(&req->req_remaining)); - OCF_METADATA_LOCK_WR(); + ocf_req_hash_lock_wr(req); ocf_purge_map_info(req); - OCF_METADATA_UNLOCK_WR(); + ocf_req_hash_unlock_wr(req); env_atomic_inc(&req->req_remaining); diff --git a/src/engine/engine_pt.c b/src/engine/engine_pt.c index 0a910a8..799f7b0 100644 --- a/src/engine/engine_pt.c +++ b/src/engine/engine_pt.c @@ -52,16 +52,14 @@ static inline void _ocf_read_pt_submit(struct ocf_request *req) int ocf_read_pt_do(struct ocf_request *req) { - struct ocf_cache *cache = req->cache; - /* Get OCF request - increase reference counter */ ocf_req_get(req); if (req->info.dirty_any) { - OCF_METADATA_LOCK_RD(); + ocf_req_hash_lock_rd(req); /* Need to clean, start it */ ocf_engine_clean(req); - OCF_METADATA_UNLOCK_RD(); + ocf_req_hash_unlock_rd(req); /* Do not processing, because first we need to clean request */ ocf_req_put(req); @@ -72,14 +70,14 @@ int ocf_read_pt_do(struct ocf_request *req) if (req->info.re_part) { OCF_DEBUG_RQ(req, "Re-Part"); - OCF_METADATA_LOCK_WR(); + ocf_req_hash_lock_wr(req); /* Probably some cache lines are assigned into wrong * partition. Need to move it to new one */ ocf_part_move(req); - OCF_METADATA_UNLOCK_WR(); + ocf_req_hash_unlock_wr(req); } /* Submit read IO to the core */ @@ -105,7 +103,6 @@ int ocf_read_pt(struct ocf_request *req) { bool use_cache = false; int lock = OCF_LOCK_NOT_ACQUIRED; - struct ocf_cache *cache = req->cache; OCF_DEBUG_TRACE(req->cache); @@ -117,7 +114,8 @@ int ocf_read_pt(struct ocf_request *req) /* Set resume io_if */ req->io_if = &_io_if_pt_resume; - OCF_METADATA_LOCK_RD(); /*- Metadata RD access -----------------------*/ + ocf_req_hash(req); + ocf_req_hash_lock_rd(req); /* Traverse request to check if there are mapped cache lines */ ocf_engine_traverse(req); @@ -136,7 +134,7 @@ int ocf_read_pt(struct ocf_request *req) } } - OCF_METADATA_UNLOCK_RD(); /*- END Metadata RD access -----------------*/ + ocf_req_hash_unlock_rd(req); if (use_cache) { /* diff --git a/src/engine/engine_rd.c b/src/engine/engine_rd.c index 8e593c7..cf1c550 100644 --- a/src/engine/engine_rd.c +++ b/src/engine/engine_rd.c @@ -137,8 +137,6 @@ err_alloc: static int _ocf_read_generic_do(struct ocf_request *req) { - struct ocf_cache *cache = req->cache; - if (ocf_engine_is_miss(req) && req->map->rd_locked) { /* Miss can be handled only on write locks. * Need to switch to PT @@ -153,12 +151,12 @@ static int _ocf_read_generic_do(struct ocf_request *req) if (ocf_engine_is_miss(req)) { if (req->info.dirty_any) { - OCF_METADATA_LOCK_RD(); + ocf_req_hash_lock_rd(req); /* Request is dirty need to clean request */ ocf_engine_clean(req); - OCF_METADATA_UNLOCK_RD(); + ocf_req_hash_unlock_rd(req); /* We need to clean request before processing, return */ ocf_req_put(req); @@ -166,25 +164,25 @@ static int _ocf_read_generic_do(struct ocf_request *req) return 0; } - OCF_METADATA_LOCK_RD(); + ocf_req_hash_lock_rd(req); /* Set valid status bits map */ ocf_set_valid_map_info(req); - OCF_METADATA_UNLOCK_RD(); + ocf_req_hash_unlock_rd(req); } if (req->info.re_part) { OCF_DEBUG_RQ(req, "Re-Part"); - OCF_METADATA_LOCK_WR(); + ocf_req_hash_lock_wr(req); /* Probably some cache lines are assigned into wrong * partition. Need to move it to new one */ ocf_part_move(req); - OCF_METADATA_UNLOCK_WR(); + ocf_req_hash_unlock_wr(req); } OCF_DEBUG_RQ(req, "Submit"); @@ -216,6 +214,7 @@ int ocf_read_generic(struct ocf_request *req) int lock = OCF_LOCK_NOT_ACQUIRED; struct ocf_cache *cache = req->cache; bool promote = true; + struct ocf_metadata_lock *metadata_lock = &cache->metadata.lock; ocf_io_start(&req->ioi.io); @@ -231,10 +230,11 @@ int ocf_read_generic(struct ocf_request *req) /* Set resume call backs */ req->io_if = &_io_if_read_generic_resume; + /* calculate hashes for hash-bucket locking */ + ocf_req_hash(req); + /*- Metadata RD access -----------------------------------------------*/ - - OCF_METADATA_LOCK_RD(); - + ocf_req_hash_lock_rd(req); /* Traverse request to cache if there is hit */ ocf_engine_traverse(req); @@ -251,27 +251,27 @@ int ocf_read_generic(struct ocf_request *req) */ lock = ocf_req_async_lock_wr(req, ocf_engine_on_resume); } - } - - if (!mapped) { + } else { promote = ocf_promotion_req_should_promote( cache->promotion_policy, req); } - OCF_METADATA_UNLOCK_RD(); + if (mapped || !promote) { + ocf_req_hash_unlock_rd(req); + } else { + /*- Metadata RD access ---------------------------------------*/ + ocf_req_hash_lock_upgrade(req); + ocf_engine_map(req); + ocf_req_hash_unlock_wr(req); - /*- END Metadata RD access -------------------------------------------*/ - - 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'. - */ - if (ocf_engine_evict(req) == LOOKUP_MAPPED) - ocf_engine_map(req); + if (req->info.mapping_error) { + /* Still not mapped - evict cachelines under global + * metadata write lock */ + ocf_metadata_start_exclusive_access(metadata_lock); + if (ocf_engine_evict(req) == LOOKUP_MAPPED) + ocf_engine_map(req); + ocf_metadata_end_exclusive_access(metadata_lock); + } if (!req->info.mapping_error) { if (ocf_engine_is_hit(req)) { @@ -288,9 +288,6 @@ int ocf_read_generic(struct ocf_request *req) ocf_engine_on_resume); } } - OCF_METADATA_UNLOCK_WR(); - - /*- END Metadata WR access -----------------------------------*/ } if (promote && !req->info.mapping_error) { diff --git a/src/engine/engine_wa.c b/src/engine/engine_wa.c index 3c854c2..f5face0 100644 --- a/src/engine/engine_wa.c +++ b/src/engine/engine_wa.c @@ -38,19 +38,19 @@ static void _ocf_read_wa_complete(struct ocf_request *req, int error) int ocf_write_wa(struct ocf_request *req) { - struct ocf_cache *cache = req->cache; - ocf_io_start(&req->ioi.io); /* Get OCF request - increase reference counter */ ocf_req_get(req); - OCF_METADATA_LOCK_RD(); /*- Metadata RD access -----------------------*/ + ocf_req_hash(req); + + ocf_req_hash_lock_rd(req); /*- Metadata RD access -----------------------*/ /* Traverse request to check if there are mapped cache lines */ ocf_engine_traverse(req); - OCF_METADATA_UNLOCK_RD(); /*- END Metadata RD access -----------------*/ + ocf_req_hash_unlock_rd(req); /*- END Metadata RD access -----------------*/ if (ocf_engine_is_hit(req)) { ocf_req_clear(req); diff --git a/src/engine/engine_wb.c b/src/engine/engine_wb.c index 1cf052a..4546b18 100644 --- a/src/engine/engine_wb.c +++ b/src/engine/engine_wb.c @@ -25,23 +25,21 @@ static const struct ocf_io_if _io_if_wb_resume = { static void _ocf_write_wb_update_bits(struct ocf_request *req) { - struct ocf_cache *cache = req->cache; - if (ocf_engine_is_miss(req)) { - OCF_METADATA_LOCK_RD(); + ocf_req_hash_lock_rd(req); /* Update valid status bits */ ocf_set_valid_map_info(req); - OCF_METADATA_UNLOCK_RD(); + ocf_req_hash_unlock_rd(req); } if (!ocf_engine_is_dirty_all(req)) { - OCF_METADATA_LOCK_WR(); + ocf_req_hash_lock_wr(req); /* set dirty bits, and mark if metadata flushing is required */ ocf_set_dirty_map_info(req); - OCF_METADATA_UNLOCK_WR(); + ocf_req_hash_unlock_wr(req); } } @@ -127,14 +125,14 @@ static inline void _ocf_write_wb_submit(struct ocf_request *req) if (req->info.re_part) { OCF_DEBUG_RQ(req, "Re-Part"); - OCF_METADATA_LOCK_WR(); + ocf_req_hash_lock_wr(req); /* Probably some cache lines are assigned into wrong * partition. Need to move it to new one */ ocf_part_move(req); - OCF_METADATA_UNLOCK_WR(); + ocf_req_hash_unlock_wr(req); } OCF_DEBUG_RQ(req, "Submit Data"); @@ -169,8 +167,8 @@ 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; + struct ocf_metadata_lock *metadata_lock = &req->cache->metadata.lock; ocf_io_start(&req->ioi.io); @@ -182,7 +180,8 @@ int ocf_write_wb(struct ocf_request *req) /* TODO: Handle fits into dirty */ - OCF_METADATA_LOCK_RD(); /*- Metadata READ access, No eviction --------*/ + ocf_req_hash(req); + ocf_req_hash_lock_rd(req); /*- Metadata READ access, No eviction --------*/ /* Travers to check if request is mapped fully */ ocf_engine_traverse(req); @@ -191,31 +190,32 @@ int ocf_write_wb(struct ocf_request *req) if (mapped) { /* All cache line are mapped, lock request for WRITE access */ lock = ocf_req_async_lock_wr(req, ocf_engine_on_resume); - } - - if (!mapped) { + } else { promote = ocf_promotion_req_should_promote( - cache->promotion_policy, req); + req->cache->promotion_policy, req); } - OCF_METADATA_UNLOCK_RD(); /*- END Metadata READ access----------------*/ + if (mapped || !promote) { + ocf_req_hash_unlock_rd(req); + } else { + /*- Metadata RD access ---------------------------------------*/ + ocf_req_hash_lock_upgrade(req); + ocf_engine_map(req); + ocf_req_hash_unlock_wr(req); - 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'. - */ - if (ocf_engine_evict(req) == LOOKUP_MAPPED) - ocf_engine_map(req); + if (req->info.mapping_error) { + /* Still not mapped - evict cachelines under global + * metadata write lock */ + ocf_metadata_start_exclusive_access(metadata_lock); + if (ocf_engine_evict(req) == LOOKUP_MAPPED) + ocf_engine_map(req); + ocf_metadata_end_exclusive_access(metadata_lock); + } if (!req->info.mapping_error) { /* Lock request for WRITE access */ lock = ocf_req_async_lock_wr(req, ocf_engine_on_resume); } - - OCF_METADATA_UNLOCK_WR(); /*- END Metadata WR access ---------*/ } if (promote && !req->info.mapping_error) { diff --git a/src/engine/engine_wi.c b/src/engine/engine_wi.c index 482b156..ff947e4 100644 --- a/src/engine/engine_wi.c +++ b/src/engine/engine_wi.c @@ -52,12 +52,12 @@ static int ocf_write_wi_update_and_flush_metadata(struct ocf_request *req) if (ocf_engine_mapped_count(req)) { /* There are mapped cache line, need to remove them */ - OCF_METADATA_LOCK_WR(); /*- Metadata WR access ---------------*/ + ocf_req_hash_lock_wr(req); /*- Metadata WR access ---------------*/ /* Remove mapped cache lines from metadata */ ocf_purge_map_info(req); - OCF_METADATA_UNLOCK_WR(); /*- END Metadata WR access ---------*/ + ocf_req_hash_unlock_wr(req); /*- END Metadata WR access ---------*/ if (req->info.flush_metadata) { /* Request was dirty and need to flush metadata */ @@ -135,7 +135,6 @@ static const struct ocf_io_if _io_if_wi_resume = { int ocf_write_wi(struct ocf_request *req) { int lock = OCF_LOCK_NOT_ACQUIRED; - struct ocf_cache *cache = req->cache; OCF_DEBUG_TRACE(req->cache); @@ -147,7 +146,8 @@ int ocf_write_wi(struct ocf_request *req) /* Set resume io_if */ req->io_if = &_io_if_wi_resume; - OCF_METADATA_LOCK_RD(); /*- Metadata READ access, No eviction --------*/ + ocf_req_hash(req); + ocf_req_hash_lock_rd(req); /*- Metadata READ access, No eviction --------*/ /* Travers to check if request is mapped fully */ ocf_engine_traverse(req); @@ -159,7 +159,7 @@ int ocf_write_wi(struct ocf_request *req) lock = OCF_LOCK_ACQUIRED; } - OCF_METADATA_UNLOCK_RD(); /*- END Metadata READ access----------------*/ + ocf_req_hash_unlock_rd(req); /*- END Metadata READ access----------------*/ if (lock >= 0) { if (lock == OCF_LOCK_ACQUIRED) { diff --git a/src/engine/engine_wo.c b/src/engine/engine_wo.c index 5687280..193198d 100644 --- a/src/engine/engine_wo.c +++ b/src/engine/engine_wo.c @@ -201,7 +201,6 @@ static const struct ocf_io_if _io_if_wo_resume = { int ocf_read_wo(struct ocf_request *req) { - ocf_cache_t cache = req->cache; int lock = OCF_LOCK_ACQUIRED; OCF_DEBUG_TRACE(req->cache); @@ -214,7 +213,8 @@ int ocf_read_wo(struct ocf_request *req) /* Set resume call backs */ req->io_if = &_io_if_wo_resume; - OCF_METADATA_LOCK_RD(); /*- Metadata RD access -----------------------*/ + ocf_req_hash(req); + ocf_req_hash_lock_rd(req); /*- Metadata RD access -----------------------*/ /* Traverse request to check if there are mapped cache lines */ ocf_engine_traverse(req); @@ -226,7 +226,7 @@ int ocf_read_wo(struct ocf_request *req) lock = ocf_req_async_lock_rd(req, ocf_engine_on_resume); } - OCF_METADATA_UNLOCK_RD(); /*- END Metadata RD access -----------------*/ + ocf_req_hash_unlock_rd(req); /*- END Metadata RD access -----------------*/ if (lock >= 0) { if (lock != OCF_LOCK_ACQUIRED) { diff --git a/src/engine/engine_wt.c b/src/engine/engine_wt.c index db2a81c..7273f95 100644 --- a/src/engine/engine_wt.c +++ b/src/engine/engine_wt.c @@ -97,19 +97,17 @@ static inline void _ocf_write_wt_submit(struct ocf_request *req) static void _ocf_write_wt_update_bits(struct ocf_request *req) { - struct ocf_cache *cache = req->cache; - if (ocf_engine_is_miss(req)) { - OCF_METADATA_LOCK_RD(); + ocf_req_hash_lock_rd(req); /* Update valid status bits */ ocf_set_valid_map_info(req); - OCF_METADATA_UNLOCK_RD(); + ocf_req_hash_unlock_rd(req); } if (req->info.dirty_any) { - OCF_METADATA_LOCK_WR(); + ocf_req_hash_lock_wr(req); /* Writes goes to SDD and HDD, need to update status bits from * dirty to clean @@ -117,20 +115,20 @@ static void _ocf_write_wt_update_bits(struct ocf_request *req) ocf_set_clean_map_info(req); - OCF_METADATA_UNLOCK_WR(); + ocf_req_hash_unlock_wr(req); } if (req->info.re_part) { OCF_DEBUG_RQ(req, "Re-Part"); - OCF_METADATA_LOCK_WR(); + ocf_req_hash_lock_wr(req); /* Probably some cache lines are assigned into wrong * partition. Need to move it to new one */ ocf_part_move(req); - OCF_METADATA_UNLOCK_WR(); + ocf_req_hash_unlock_wr(req); } } @@ -164,8 +162,8 @@ 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; + struct ocf_metadata_lock *metadata_lock = &req->cache->metadata.lock; ocf_io_start(&req->ioi.io); @@ -175,7 +173,8 @@ int ocf_write_wt(struct ocf_request *req) /* Set resume io_if */ req->io_if = &_io_if_wt_resume; - OCF_METADATA_LOCK_RD(); /*- Metadata READ access, No eviction --------*/ + ocf_req_hash(req); + ocf_req_hash_lock_rd(req); /*- Metadata READ access, No eviction --------*/ /* Travers to check if request is mapped fully */ ocf_engine_traverse(req); @@ -184,31 +183,32 @@ int ocf_write_wt(struct ocf_request *req) if (mapped) { /* All cache line are mapped, lock request for WRITE access */ lock = ocf_req_async_lock_wr(req, ocf_engine_on_resume); - } - - if (!mapped) { + } else { promote = ocf_promotion_req_should_promote( - cache->promotion_policy, req); + req->cache->promotion_policy, req); } - OCF_METADATA_UNLOCK_RD(); /*- END Metadata READ access----------------*/ + if (mapped || !promote) { + ocf_req_hash_unlock_rd(req); + } else { + /*- Metadata RD access ---------------------------------------*/ + ocf_req_hash_lock_upgrade(req); + ocf_engine_map(req); + ocf_req_hash_unlock_wr(req); - 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'. - */ - if (ocf_engine_evict(req) == LOOKUP_MAPPED) - ocf_engine_map(req); + if (req->info.mapping_error) { + /* Still not mapped - evict cachelines under global + * metadata write lock */ + ocf_metadata_start_exclusive_access(metadata_lock); + if (ocf_engine_evict(req) == LOOKUP_MAPPED) + ocf_engine_map(req); + ocf_metadata_end_exclusive_access(metadata_lock); + } if (!req->info.mapping_error) { /* Lock request for WRITE access */ lock = ocf_req_async_lock_wr(req, ocf_engine_on_resume); } - - OCF_METADATA_UNLOCK_WR(); /*- END Metadata WR access ---------*/ } if (promote && !req->info.mapping_error) { diff --git a/src/engine/engine_zero.c b/src/engine/engine_zero.c index d5cb240..23f665c 100644 --- a/src/engine/engine_zero.c +++ b/src/engine/engine_zero.c @@ -18,19 +18,17 @@ static int ocf_zero_purge(struct ocf_request *req) { - struct ocf_cache *cache = req->cache; - if (req->error) { ocf_engine_error(req, true, "Failed to discard data on cache"); } else { /* There are mapped cache line, need to remove them */ - OCF_METADATA_LOCK_WR(); /*- Metadata WR access ---------------*/ + ocf_req_hash_lock_wr(req); /*- Metadata WR access ---------------*/ /* Remove mapped cache lines from metadata */ ocf_purge_map_info(req); - OCF_METADATA_UNLOCK_WR(); /*- END Metadata WR access ---------*/ + ocf_req_hash_unlock_wr(req); /*- END Metadata WR access ---------*/ } ocf_req_unlock_wr(req); @@ -142,6 +140,10 @@ void ocf_engine_zero_line(struct ocf_request *req) ENV_BUG_ON(req->core_line_count != 1); + /* No hash bucket locking here - ocf_engine_zero_line caller must hold + * metadata global write lock, so we have exclusive access to all hash + * buckets here. */ + /* Traverse to check if request is mapped */ ocf_engine_traverse(req);