cleaner: Check mapping after taking cache line lock
Signed-off-by: Robert Baldyga <robert.baldyga@huawei.com>
This commit is contained in:
parent
0a13bea889
commit
dfb2e1a8d5
@ -651,7 +651,6 @@ static void _acp_flush(struct acp_context *acp)
|
|||||||
.cmpl_context = acp,
|
.cmpl_context = acp,
|
||||||
.cmpl_fn = _acp_flush_end,
|
.cmpl_fn = _acp_flush_end,
|
||||||
.lock_cacheline = false,
|
.lock_cacheline = false,
|
||||||
.lock_metadata = true,
|
|
||||||
.cmpl_queue = true,
|
.cmpl_queue = true,
|
||||||
.io_queue = cache->cleaner.io_queue,
|
.io_queue = cache->cleaner.io_queue,
|
||||||
};
|
};
|
||||||
|
@ -940,7 +940,6 @@ void cleaning_alru_perform_cleaning(ocf_cache_t cache, ocf_cleaner_end_t cmpl)
|
|||||||
fctx->attribs.cmpl_context = fctx;
|
fctx->attribs.cmpl_context = fctx;
|
||||||
fctx->attribs.cmpl_fn = alru_clean_complete;
|
fctx->attribs.cmpl_fn = alru_clean_complete;
|
||||||
fctx->attribs.lock_cacheline = true;
|
fctx->attribs.lock_cacheline = true;
|
||||||
fctx->attribs.lock_metadata = false;
|
|
||||||
fctx->attribs.io_queue = cache->cleaner.io_queue;
|
fctx->attribs.io_queue = cache->cleaner.io_queue;
|
||||||
fctx->attribs.cmpl_queue = true;
|
fctx->attribs.cmpl_queue = true;
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright(c) 2012-2022 Intel Corporation
|
* Copyright(c) 2012-2022 Intel Corporation
|
||||||
|
* Copyright(c) 2024 Huawei Technologies Co., Ltd.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -555,7 +556,6 @@ void ocf_engine_clean(struct ocf_request *req)
|
|||||||
/* Initialize attributes for cleaner */
|
/* Initialize attributes for cleaner */
|
||||||
struct ocf_cleaner_attribs attribs = {
|
struct ocf_cleaner_attribs attribs = {
|
||||||
.lock_cacheline = false,
|
.lock_cacheline = false,
|
||||||
.lock_metadata = false,
|
|
||||||
|
|
||||||
.cmpl_context = req,
|
.cmpl_context = req,
|
||||||
.cmpl_fn = _ocf_engine_clean_end,
|
.cmpl_fn = _ocf_engine_clean_end,
|
||||||
|
@ -444,7 +444,6 @@ static void _ocf_mngt_flush_container(
|
|||||||
|
|
||||||
fc->req = req;
|
fc->req = req;
|
||||||
fc->attribs.lock_cacheline = true;
|
fc->attribs.lock_cacheline = true;
|
||||||
fc->attribs.lock_metadata = false;
|
|
||||||
fc->attribs.cmpl_context = fc;
|
fc->attribs.cmpl_context = fc;
|
||||||
fc->attribs.cmpl_fn = _ocf_mngt_flush_portion_end;
|
fc->attribs.cmpl_fn = _ocf_mngt_flush_portion_end;
|
||||||
fc->attribs.io_queue = cache->mngt_queue;
|
fc->attribs.io_queue = cache->mngt_queue;
|
||||||
|
@ -591,7 +591,6 @@ void ocf_lru_clean(ocf_cache_t cache, struct ocf_user_part *user_part,
|
|||||||
struct ocf_part_cleaning_ctx *ctx = &user_part->cleaning;
|
struct ocf_part_cleaning_ctx *ctx = &user_part->cleaning;
|
||||||
struct ocf_cleaner_attribs attribs = {
|
struct ocf_cleaner_attribs attribs = {
|
||||||
.lock_cacheline = false,
|
.lock_cacheline = false,
|
||||||
.lock_metadata = true,
|
|
||||||
|
|
||||||
.cmpl_context = ctx,
|
.cmpl_context = ctx,
|
||||||
.cmpl_fn = ocf_lru_clean_end,
|
.cmpl_fn = ocf_lru_clean_end,
|
||||||
|
@ -339,7 +339,7 @@ static int _ocf_cleaner_update_metadata(struct ocf_request *req)
|
|||||||
|
|
||||||
/* Update metadata */
|
/* Update metadata */
|
||||||
for (i = 0; i < req->core_line_count; i++, iter++) {
|
for (i = 0; i < req->core_line_count; i++, iter++) {
|
||||||
if (iter->status == LOOKUP_MISS)
|
if (!iter->flush)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (iter->invalid) {
|
if (iter->invalid) {
|
||||||
@ -384,7 +384,7 @@ static void _ocf_cleaner_flush_cores_io_end(struct ocf_map_info *map,
|
|||||||
if (error) {
|
if (error) {
|
||||||
/* Flush error, set error for all cache line of this core */
|
/* Flush error, set error for all cache line of this core */
|
||||||
for (i = 0; i < req->core_line_count; i++, iter++) {
|
for (i = 0; i < req->core_line_count; i++, iter++) {
|
||||||
if (iter->status == LOOKUP_MISS)
|
if (!iter->flush)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (iter->core_id == map->core_id)
|
if (iter->core_id == map->core_id)
|
||||||
@ -434,7 +434,7 @@ static int _ocf_cleaner_fire_flush_cores(struct ocf_request *req)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iter->status == LOOKUP_MISS)
|
if (!iter->flush)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (core_id == iter->core_id)
|
if (core_id == iter->core_id)
|
||||||
@ -603,7 +603,7 @@ static int _ocf_cleaner_fire_core(struct ocf_request *req)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iter->status == LOOKUP_MISS)
|
if (!iter->flush)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ocf_hb_cline_prot_lock_rd(&cache->metadata.lock,
|
ocf_hb_cline_prot_lock_rd(&cache->metadata.lock,
|
||||||
@ -677,7 +677,7 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req)
|
|||||||
core = ocf_cache_get_core(cache, iter->core_id);
|
core = ocf_cache_get_core(cache, iter->core_id);
|
||||||
if (!core)
|
if (!core)
|
||||||
continue;
|
continue;
|
||||||
if (iter->status == LOOKUP_MISS)
|
if (!iter->flush)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
OCF_DEBUG_PARAM(req->cache, "Cache read, line = %u",
|
OCF_DEBUG_PARAM(req->cache, "Cache read, line = %u",
|
||||||
@ -722,6 +722,33 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _ocf_cleaner_check_map(struct ocf_request *req)
|
||||||
|
{
|
||||||
|
ocf_core_id_t core_id;
|
||||||
|
uint64_t core_line;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < req->core_line_count; ++i) {
|
||||||
|
ocf_metadata_get_core_info(req->cache, req->map[i].coll_idx,
|
||||||
|
&core_id, &core_line);
|
||||||
|
|
||||||
|
if (core_id != req->map[i].core_id)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (core_line != req->map[i].core_line)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!metadata_test_dirty(req->cache, req->map[i].coll_idx))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
req->map[i].flush = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ocf_cleaner_fire_cache(req);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int _ocf_cleaner_do_fire(struct ocf_request *req, uint32_t count)
|
static int _ocf_cleaner_do_fire(struct ocf_request *req, uint32_t count)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
@ -729,7 +756,7 @@ static int _ocf_cleaner_do_fire(struct ocf_request *req, uint32_t count)
|
|||||||
/* Set counts of cache IOs */
|
/* Set counts of cache IOs */
|
||||||
env_atomic_set(&req->req_remaining, count);
|
env_atomic_set(&req->req_remaining, count);
|
||||||
|
|
||||||
req->engine_handler = _ocf_cleaner_fire_cache;
|
req->engine_handler = _ocf_cleaner_check_map;
|
||||||
req->core_line_count = count;
|
req->core_line_count = count;
|
||||||
|
|
||||||
/* Handle cache lines locks */
|
/* Handle cache lines locks */
|
||||||
@ -738,7 +765,7 @@ static int _ocf_cleaner_do_fire(struct ocf_request *req, uint32_t count)
|
|||||||
if (result >= 0) {
|
if (result >= 0) {
|
||||||
if (result == OCF_LOCK_ACQUIRED) {
|
if (result == OCF_LOCK_ACQUIRED) {
|
||||||
OCF_DEBUG_MSG(req->cache, "Lock acquired");
|
OCF_DEBUG_MSG(req->cache, "Lock acquired");
|
||||||
_ocf_cleaner_fire_cache(req);
|
_ocf_cleaner_check_map(req);
|
||||||
} else {
|
} else {
|
||||||
OCF_DEBUG_MSG(req->cache, "NO Lock");
|
OCF_DEBUG_MSG(req->cache, "NO Lock");
|
||||||
}
|
}
|
||||||
@ -793,7 +820,6 @@ void ocf_cleaner_fire(struct ocf_cache *cache,
|
|||||||
int err;
|
int err;
|
||||||
ocf_core_id_t core_id;
|
ocf_core_id_t core_id;
|
||||||
uint64_t core_sector;
|
uint64_t core_sector;
|
||||||
bool skip;
|
|
||||||
|
|
||||||
/* Allocate master request */
|
/* Allocate master request */
|
||||||
master = _ocf_cleaner_alloc_master_req(cache, max, attribs);
|
master = _ocf_cleaner_alloc_master_req(cache, max, attribs);
|
||||||
@ -850,40 +876,6 @@ void ocf_cleaner_fire(struct ocf_cache *cache,
|
|||||||
ocf_metadata_get_core_info(cache, cache_line, &core_id,
|
ocf_metadata_get_core_info(cache, cache_line, &core_id,
|
||||||
&core_sector);
|
&core_sector);
|
||||||
|
|
||||||
if (attribs->lock_metadata) {
|
|
||||||
ocf_hb_cline_prot_lock_rd(&cache->metadata.lock,
|
|
||||||
req->lock_idx, core_id, core_sector);
|
|
||||||
}
|
|
||||||
|
|
||||||
skip = false;
|
|
||||||
|
|
||||||
/* when line already cleaned - rare condition under heavy
|
|
||||||
* I/O workload.
|
|
||||||
*/
|
|
||||||
if (!metadata_test_dirty(cache, cache_line)) {
|
|
||||||
OCF_DEBUG_MSG(cache, "Not dirty");
|
|
||||||
skip = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!skip && !metadata_test_valid_any(cache, cache_line)) {
|
|
||||||
OCF_DEBUG_MSG(cache, "No any valid");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Extremely disturbing cache line state
|
|
||||||
* Cache line (sector) cannot be dirty and not valid
|
|
||||||
*/
|
|
||||||
ENV_BUG();
|
|
||||||
skip = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attribs->lock_metadata) {
|
|
||||||
ocf_hb_cline_prot_unlock_rd(&cache->metadata.lock,
|
|
||||||
req->lock_idx, core_id, core_sector);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skip)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (unlikely(!cache->core[core_id].opened)) {
|
if (unlikely(!cache->core[core_id].opened)) {
|
||||||
OCF_DEBUG_MSG(cache, "Core object inactive");
|
OCF_DEBUG_MSG(cache, "Core object inactive");
|
||||||
continue;
|
continue;
|
||||||
|
@ -28,7 +28,6 @@ typedef int (*ocf_cleaner_get_item)(struct ocf_cache *cache,
|
|||||||
*/
|
*/
|
||||||
struct ocf_cleaner_attribs {
|
struct ocf_cleaner_attribs {
|
||||||
uint8_t lock_cacheline : 1; /*!< Cleaner to lock cachelines on its own */
|
uint8_t lock_cacheline : 1; /*!< Cleaner to lock cachelines on its own */
|
||||||
uint8_t lock_metadata : 1; /*!< Cleaner to lock metadata on its own */
|
|
||||||
|
|
||||||
uint8_t cmpl_queue : 1;
|
uint8_t cmpl_queue : 1;
|
||||||
/*!< Completion needs to be called from the queue context */
|
/*!< Completion needs to be called from the queue context */
|
||||||
|
Loading…
Reference in New Issue
Block a user