diff --git a/src/metadata/metadata_status.h b/src/metadata/metadata_status.h index 375179ba..10faec8f 100644 --- a/src/metadata/metadata_status.h +++ b/src/metadata/metadata_status.h @@ -200,49 +200,47 @@ static inline bool metadata_test_and_clear_dirty_sec( /* * Marks given cache line's bits as clean * - * @return true if the cache line was dirty and became clean + * @return true if any cache line's sector was dirty and became clean * @return false for other cases */ static inline bool metadata_clear_dirty_sec_changed( struct ocf_cache *cache, ocf_cache_line_t line, - uint8_t start, uint8_t stop) + uint8_t start, uint8_t stop, bool *line_is_clean) { - bool was_dirty, is_dirty = false; + bool sec_changed; OCF_METADATA_BITS_LOCK_WR(); - was_dirty = cache->metadata.iface.test_dirty(cache, line, - cache->metadata.settings.sector_start, - cache->metadata.settings.sector_end, - false); - - if (was_dirty) { - is_dirty = cache->metadata.iface.clear_dirty(cache, line, - start, stop); - } + sec_changed = cache->metadata.iface.test_dirty(cache, line, + start, stop, false); + *line_is_clean = !cache->metadata.iface.clear_dirty(cache, line, + start, stop); OCF_METADATA_BITS_UNLOCK_WR(); - return was_dirty && !is_dirty; + return sec_changed; } /* * Marks given cache line's bits as dirty * - * @return true if the cache line was clean and became dirty - * @return false if the cache line was dirty before marking bits + * @return true if any cache line's sector became dirty + * @return false for other cases */ static inline bool metadata_set_dirty_sec_changed( struct ocf_cache *cache, ocf_cache_line_t line, - uint8_t start, uint8_t stop) + uint8_t start, uint8_t stop, bool *line_was_dirty) { - bool was_dirty; + bool sec_changed; OCF_METADATA_BITS_LOCK_WR(); - was_dirty = cache->metadata.iface.set_dirty(cache, line, start, stop); + sec_changed = !cache->metadata.iface.test_dirty(cache, line, + start, stop, true); + *line_was_dirty = cache->metadata.iface.set_dirty(cache, line, start, + stop); OCF_METADATA_BITS_UNLOCK_WR(); - return !was_dirty; + return sec_changed; } /******************************************************************************* diff --git a/src/utils/utils_cache_line.c b/src/utils/utils_cache_line.c index 5e693e58..8b734710 100644 --- a/src/utils/utils_cache_line.c +++ b/src/utils/utils_cache_line.c @@ -102,35 +102,40 @@ void set_cache_line_clean(struct ocf_cache *cache, uint8_t start_bit, ocf_cache_line_t line = req->map[map_idx].coll_idx; ocf_part_id_t part_id = ocf_metadata_get_partition_id(cache, line); uint8_t evp_type = cache->conf_meta->eviction_policy_type; + bool line_is_clean; - if (metadata_clear_dirty_sec_changed(cache, line, start_bit, end_bit)) { - /* - * Update the number of dirty cached data for that - * core object - */ - if (env_atomic_dec_and_test(&req->core->runtime_meta-> - dirty_clines)) { + if (metadata_clear_dirty_sec_changed(cache, line, start_bit, end_bit, + &line_is_clean)) { + ocf_metadata_flush_mark(cache, req, map_idx, CLEAN, start_bit, + end_bit); + if (line_is_clean) { /* - * If this is last dirty cline reset dirty - * timestamp + * Update the number of dirty cached data for that + * core object */ - env_atomic64_set(&req->core->runtime_meta-> - dirty_since, 0); - } + if (env_atomic_dec_and_test(&req->core->runtime_meta-> + dirty_clines)) { + /* + * If this is last dirty cline reset dirty + * timestamp + */ + env_atomic64_set(&req->core->runtime_meta-> + dirty_since, 0); + } - /* - * decrement dirty clines statistic for given cline - */ - env_atomic_dec(&req->core->runtime_meta-> - part_counters[part_id].dirty_clines); + /* + * decrement dirty clines statistic for given cline + */ + env_atomic_dec(&req->core->runtime_meta-> + part_counters[part_id].dirty_clines); - if (likely(evict_policy_ops[evp_type].clean_cline)) - evict_policy_ops[evp_type].clean_cline(cache, part_id, line); + if (likely(evict_policy_ops[evp_type].clean_cline)) + evict_policy_ops[evp_type].clean_cline(cache, part_id, line); - ocf_purge_cleaning_policy(cache, line); - ocf_metadata_flush_mark(cache, req, map_idx, CLEAN, start_bit, - end_bit); + ocf_purge_cleaning_policy(cache, line); + } } + } void set_cache_line_dirty(struct ocf_cache *cache, uint8_t start_bit, @@ -139,32 +144,36 @@ void set_cache_line_dirty(struct ocf_cache *cache, uint8_t start_bit, ocf_cache_line_t line = req->map[map_idx].coll_idx; ocf_part_id_t part_id = ocf_metadata_get_partition_id(cache, line); uint8_t evp_type = cache->conf_meta->eviction_policy_type; + bool line_was_dirty; - if (metadata_set_dirty_sec_changed(cache, line, start_bit, end_bit)) { - /* - * If this is first dirty cline set dirty timestamp - */ - env_atomic64_cmpxchg(&req->core->runtime_meta->dirty_since, - 0, env_get_tick_count()); - - /* - * Update the number of dirty cached data for that - * core object - */ - env_atomic_inc(&req->core->runtime_meta->dirty_clines); + if (metadata_set_dirty_sec_changed(cache, line, start_bit, end_bit, + &line_was_dirty)) { + ocf_metadata_flush_mark(cache, req, map_idx, DIRTY, start_bit, + end_bit); + if (!line_was_dirty) { + /* + * If this is first dirty cline set dirty timestamp + */ + env_atomic64_cmpxchg(&req->core->runtime_meta->dirty_since, + 0, env_get_tick_count()); - /* - * increment dirty clines statistic for given cline - */ - env_atomic_inc(&req->core->runtime_meta-> - part_counters[part_id].dirty_clines); + /* + * Update the number of dirty cached data for that + * core object + */ + env_atomic_inc(&req->core->runtime_meta->dirty_clines); - if (likely(evict_policy_ops[evp_type].dirty_cline)) - evict_policy_ops[evp_type].dirty_cline(cache, part_id, line); + /* + * increment dirty clines statistic for given cline + */ + env_atomic_inc(&req->core->runtime_meta-> + part_counters[part_id].dirty_clines); - ocf_metadata_flush_mark(cache, req, map_idx, DIRTY, start_bit, - end_bit); + if (likely(evict_policy_ops[evp_type].dirty_cline)) + evict_policy_ops[evp_type].dirty_cline(cache, part_id, line); + } } + ocf_cleaning_set_hot_cache_line(cache, line); }