Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backfill optimization #834

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/cleaning/acp.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ static ocf_cache_line_t _acp_trylock_dirty(struct ocf_cache *cache,
ocf_engine_lookup_map_entry(cache, &info, core_id,
core_line);

if (info.status == LOOKUP_HIT &&
if ((info.status == LOOKUP_HIT || info.status == LOOKUP_HIT_INVALID) &&
metadata_test_dirty(cache, info.coll_idx)) {
locked = ocf_cache_line_try_lock_rd(
ocf_cache_line_concurrency(cache),
Expand Down
1 change: 1 addition & 0 deletions src/engine/cache_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct ocf_thread_priv;
#define LOOKUP_HIT 5
#define LOOKUP_MISS 6
#define LOOKUP_REMAPPED 8
#define LOOKUP_HIT_INVALID 9

static inline ocf_req_cache_mode_t ocf_cache_mode_to_req_cache_mode(
ocf_cache_mode_t mode)
Expand Down
78 changes: 77 additions & 1 deletion src/engine/engine_bf.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,91 @@ static void _ocf_backfill_complete(struct ocf_request *req, int error)
}
}

#define __entries_not_adjacent(__req, __i, __j) \
__req->map[__i].coll_idx + 1 != __req->map[__j].coll_idx

#define __is_the_last_chunk(__req, __i) (__i == (__req->core_line_count - 1))

#define __skip_on_the_last_entry(__skip, __req, __i) \
__skip * (int)__is_the_last_chunk(__req, __i)
Comment on lines +74 to +77
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's no longer 90's, unlikely() should do.


static int _ocf_backfill_do(struct ocf_request *req)
{
ocf_cache_t cache = req->cache;
uint64_t metadata_offset = cache->device->metadata_offset;
ocf_cache_line_size_t cache_line_size = ocf_line_size(cache);
uint64_t addr, bytes, total_bytes = 0;
uint64_t seek, skip, last_chunk_size;
uint32_t i;

req->data = req->cp_data;
if (unlikely(req->data == NULL)) {
_ocf_backfill_complete(req, -OCF_ERR_NO_MEM);
return 0;
}

ocf_engine_forward_cache_io_req(req, OCF_WRITE, _ocf_backfill_complete);
req->cache_forward_end = _ocf_backfill_complete;

if (ocf_engine_is_sequential(req)) {
addr = metadata_offset;
addr += req->map[0].coll_idx * cache_line_size;
addr += req->addr % cache_line_size;

ocf_core_stats_cache_block_update(req->core, req->part_id,
OCF_WRITE, req->bytes);

ocf_req_forward_cache_io(req, OCF_WRITE, addr, req->bytes,
req->offset);
return 0;
}

seek = req->addr % cache_line_size;
last_chunk_size = (req->addr + req->bytes) % cache_line_size;
skip = (cache_line_size - last_chunk_size) % cache_line_size;
Comment on lines +110 to +111
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This math is very confusing. The last_chunk_size is not really last chunk size, because it can be 0 if last chunk is aligned to cache line size, and then to account for that, the skip is "corrected" with this surprising modulo.


ocf_req_forward_cache_get(req);
for (i = 0; i < req->core_line_count; i++) {
if (req->map[i].status == LOOKUP_HIT) {
/* This is the 1st cache line in the interval, and it's
a hit. Don't write it to the cache */
total_bytes += cache_line_size;
total_bytes -= seek;
/* Seek should be taken into account for the first chunk
only */
seek = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer unlikely() on if (i == 0). Now we are zeroing this seek here and there many times for completely no reason.

continue;
}

addr = metadata_offset;
addr += req->map[i].coll_idx * cache_line_size;

bytes = cache_line_size;
for (; i < (req->core_line_count - 1); i++) {
if (__entries_not_adjacent(req, i, i + 1))
break;

bytes += cache_line_size;
}

/* Seek should be taken into account for the first chunk only */
addr += seek;
bytes -= seek;
Comment on lines +138 to +139
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here we completely unnecessarily add/subtract 0 on every loop iteration.

seek = 0;

bytes -= __skip_on_the_last_entry(skip, req, i);

bytes = OCF_MIN(bytes, req->bytes - total_bytes);

ocf_core_stats_cache_block_update(req->core, req->part_id,
OCF_WRITE, bytes);

ocf_req_forward_cache_io(req, OCF_WRITE, addr, bytes,
req->offset + total_bytes);

total_bytes += bytes;
}

ocf_req_forward_cache_put(req);

return 0;
}
Expand Down
11 changes: 7 additions & 4 deletions src/engine/engine_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ static void ocf_engine_update_req_info(struct ocf_cache *cache,

ENV_BUG_ON(entry->status != LOOKUP_HIT &&
entry->status != LOOKUP_MISS &&
entry->status != LOOKUP_REMAPPED);
entry->status != LOOKUP_REMAPPED &&
entry->status != LOOKUP_HIT_INVALID);

/* Handle return value */
if (entry->status == LOOKUP_HIT) {
Expand All @@ -152,6 +153,7 @@ static void ocf_engine_update_req_info(struct ocf_cache *cache,
req->info.hit_no++;
} else {
req->info.invalid_no++;
entry->status = LOOKUP_HIT_INVALID;
}

/* Check request is dirty */
Expand All @@ -165,7 +167,7 @@ static void ocf_engine_update_req_info(struct ocf_cache *cache,
}
}

if (entry->status == LOOKUP_HIT || entry->status == LOOKUP_REMAPPED) {
if (entry->status == LOOKUP_HIT || entry->status == LOOKUP_HIT_INVALID || entry->status == LOOKUP_REMAPPED) {
if (req->part_id != ocf_metadata_get_partition_id(cache,
entry->coll_idx)) {
/*
Expand Down Expand Up @@ -201,7 +203,7 @@ void ocf_engine_set_hot(struct ocf_request *req)
entry = &(req->map[i]);
status = entry->status;

if (status == LOOKUP_HIT) {
if (status == LOOKUP_HIT || status == LOOKUP_HIT_INVALID) {
/* Update eviction (LRU) */
ocf_lru_hot_cline(cache, entry->coll_idx);
}
Expand Down Expand Up @@ -330,6 +332,7 @@ static void ocf_engine_map_hndl_error(struct ocf_cache *cache,

switch (entry->status) {
case LOOKUP_HIT:
case LOOKUP_HIT_INVALID:
case LOOKUP_MISS:
break;

Expand Down Expand Up @@ -537,7 +540,7 @@ static int _ocf_engine_clean_getter(struct ocf_cache *cache,

entry = &req->map[item];

if (entry->status != LOOKUP_HIT)
if (entry->status != LOOKUP_HIT && entry->status != LOOKUP_HIT_INVALID)
return -1;

if (!metadata_test_dirty(cache, entry->coll_idx))
Expand Down
3 changes: 2 additions & 1 deletion src/utils/utils_user_part.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright(c) 2012-2021 Intel Corporation
* Copyright(c) 2024 Huawei Technologies
* SPDX-License-Identifier: BSD-3-Clause
*/

Expand Down Expand Up @@ -112,7 +113,7 @@ void ocf_user_part_move(struct ocf_request *req)
* cachelines are assigned to target partition during eviction.
* So only hit cachelines are interesting.
*/
if (entry->status != LOOKUP_HIT) {
if (entry->status != LOOKUP_HIT && entry->status != LOOKUP_HIT_INVALID) {
/* No HIT */
continue;
}
Expand Down