Flush metadata after changing status of each sector

In case of cleaning metadata used to be flushed only when status of whole cache
line changed to clean.

This patch ensures that metadata flush is triggered after changin status of each
single sector is cache line.

Signed-off-by: Michal Mielewczyk <michal.mielewczyk@intel.com>
This commit is contained in:
Michal Mielewczyk 2020-01-23 03:41:31 -05:00
parent 2f10365086
commit d9c987e068
2 changed files with 39 additions and 39 deletions

View File

@ -200,30 +200,25 @@ static inline bool metadata_test_and_clear_dirty_sec(
/* /*
* Marks given cache line's bits as clean * 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 * @return false for other cases
*/ */
static inline bool metadata_clear_dirty_sec_changed( static inline bool metadata_clear_dirty_sec_changed(
struct ocf_cache *cache, ocf_cache_line_t line, 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(); OCF_METADATA_BITS_LOCK_WR();
was_dirty = cache->metadata.iface.test_dirty(cache, line, sec_changed = cache->metadata.iface.test_dirty(cache, line,
cache->metadata.settings.sector_start, start, stop, false);
cache->metadata.settings.sector_end, *line_is_clean = !cache->metadata.iface.clear_dirty(cache, line,
false); start, stop);
if (was_dirty) {
is_dirty = cache->metadata.iface.clear_dirty(cache, line,
start, stop);
}
OCF_METADATA_BITS_UNLOCK_WR(); OCF_METADATA_BITS_UNLOCK_WR();
return was_dirty && !is_dirty; return sec_changed;
} }
/* /*

View File

@ -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_cache_line_t line = req->map[map_idx].coll_idx;
ocf_part_id_t part_id = ocf_metadata_get_partition_id(cache, line); ocf_part_id_t part_id = ocf_metadata_get_partition_id(cache, line);
uint8_t evp_type = cache->conf_meta->eviction_policy_type; 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)) { if (metadata_clear_dirty_sec_changed(cache, line, start_bit, end_bit,
/* &line_is_clean)) {
* Update the number of dirty cached data for that
* core object
*/
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);
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, ocf_metadata_flush_mark(cache, req, map_idx, CLEAN, start_bit,
end_bit); end_bit);
if (line_is_clean) {
/*
* Update the number of dirty cached data for that
* core object
*/
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);
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);
}
} }
} }
void set_cache_line_dirty(struct ocf_cache *cache, uint8_t start_bit, void set_cache_line_dirty(struct ocf_cache *cache, uint8_t start_bit,