diff --git a/src/engine/engine_wt.c b/src/engine/engine_wt.c index 3b0b33f..dd2e0c4 100644 --- a/src/engine/engine_wt.c +++ b/src/engine/engine_wt.c @@ -18,6 +18,84 @@ #define OCF_ENGINE_DEBUG_IO_NAME "wt" #include "engine_debug.h" +static void _ocf_write_wt_update_bits(struct ocf_request *req) +{ + bool miss = ocf_engine_is_miss(req); + bool dirty_any = req->info.dirty_any; + bool repart = ocf_engine_needs_repart(req); + + if (!miss && !dirty_any && !repart) + return; + + ocf_hb_req_prot_lock_wr(req); + + if (miss) { + /* Update valid status bits */ + ocf_set_valid_map_info(req); + } + + if (dirty_any) { + /* Writes goes to both cache and core, need to update + * status bits from dirty to clean + */ + ocf_set_clean_map_info(req); + } + + if (repart) { + OCF_DEBUG_RQ(req, "Re-Part"); + /* Probably some cache lines are assigned into wrong + * partition. Need to move it to new one + */ + ocf_user_part_move(req); + } + + ocf_hb_req_prot_unlock_wr(req); +} + +static void _ocf_write_wt_do_flush_metadata_compl(struct ocf_request *req, + int error) +{ + if (error) + req->error = error; + + if (env_atomic_dec_return(&req->req_remaining)) + return; + + if (req->error) + ocf_engine_error(req, true, "Failed to write data to cache"); + + ocf_req_unlock_wr(ocf_cache_line_concurrency(req->cache), req); + + req->complete(req, req->info.core_error ? req->error : 0); + + ocf_req_put(req); +} + +static int ocf_write_wt_do_flush_metadata(struct ocf_request *req) +{ + struct ocf_cache *cache = req->cache; + + env_atomic_set(&req->req_remaining, 1); + + _ocf_write_wt_update_bits(req); + + if (req->info.flush_metadata) { + /* Metadata flush IO */ + + ocf_metadata_flush_do_asynch(cache, req, + _ocf_write_wt_do_flush_metadata_compl); + } + + _ocf_write_wt_do_flush_metadata_compl(req, 0); + + return 0; +} + +static const struct ocf_io_if _io_if_wt_flush_metadata = { + .read = ocf_write_wt_do_flush_metadata, + .write = ocf_write_wt_do_flush_metadata, +}; + static void _ocf_write_wt_req_complete(struct ocf_request *req) { if (env_atomic_dec_return(&req->req_remaining)) @@ -33,14 +111,7 @@ static void _ocf_write_wt_req_complete(struct ocf_request *req) ocf_engine_invalidate(req); } else { - /* Unlock reqest from WRITE access */ - ocf_req_unlock_wr(ocf_cache_line_concurrency(req->cache), req); - - /* Complete request */ - req->complete(req, req->info.core_error ? req->error : 0); - - /* Release OCF request */ - ocf_req_put(req); + ocf_engine_push_req_front_if(req, &_io_if_wt_flush_metadata, true); } } @@ -79,13 +150,6 @@ static inline void _ocf_write_wt_submit(struct ocf_request *req) env_atomic_set(&req->req_remaining, ocf_engine_io_count(req)); /* Cache IO */ env_atomic_inc(&req->req_remaining); /* Core device IO */ - if (req->info.flush_metadata) { - /* Metadata flush IO */ - - ocf_metadata_flush_do_asynch(cache, req, - _ocf_write_wt_cache_complete); - } - /* To cache */ ocf_submit_cache_reqs(cache, req, OCF_WRITE, 0, req->byte_length, ocf_engine_io_count(req), _ocf_write_wt_cache_complete); @@ -95,48 +159,11 @@ static inline void _ocf_write_wt_submit(struct ocf_request *req) _ocf_write_wt_core_complete); } -static void _ocf_write_wt_update_bits(struct ocf_request *req) -{ - bool miss = ocf_engine_is_miss(req); - bool dirty_any = req->info.dirty_any; - bool repart = ocf_engine_needs_repart(req); - - if (!miss && !dirty_any && !repart) - return; - - ocf_hb_req_prot_lock_wr(req); - - if (miss) { - /* Update valid status bits */ - ocf_set_valid_map_info(req); - } - - if (dirty_any) { - /* Writes goes to both cache and core, need to update - * status bits from dirty to clean - */ - ocf_set_clean_map_info(req); - } - - if (repart) { - OCF_DEBUG_RQ(req, "Re-Part"); - /* Probably some cache lines are assigned into wrong - * partition. Need to move it to new one - */ - ocf_user_part_move(req); - } - - ocf_hb_req_prot_unlock_wr(req); -} - static int _ocf_write_wt_do(struct ocf_request *req) { /* Get OCF request - increase reference counter */ ocf_req_get(req); - /* Update status bits */ - _ocf_write_wt_update_bits(req); - /* Submit IO */ _ocf_write_wt_submit(req);