diff --git a/src/metadata/metadata_status.h b/src/metadata/metadata_status.h index 375179b..3693cdb 100644 --- a/src/metadata/metadata_status.h +++ b/src/metadata/metadata_status.h @@ -229,20 +229,23 @@ static inline bool metadata_clear_dirty_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 5e693e5..d9bcc20 100644 --- a/src/utils/utils_cache_line.c +++ b/src/utils/utils_cache_line.c @@ -139,32 +139,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); - - /* - * increment dirty clines statistic for given cline - */ - env_atomic_inc(&req->core->runtime_meta-> - part_counters[part_id].dirty_clines); - - if (likely(evict_policy_ops[evp_type].dirty_cline)) - evict_policy_ops[evp_type].dirty_cline(cache, part_id, line); - + 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); + 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()); + + /* + * Update the number of dirty cached data for that + * core object + */ + env_atomic_inc(&req->core->runtime_meta->dirty_clines); + + /* + * increment dirty clines statistic for given cline + */ + env_atomic_inc(&req->core->runtime_meta-> + part_counters[part_id].dirty_clines); + + 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); }