Handle D2C early and fast

Avoid unnecessary code execution in D2C mode.
Avoid multiple req->d2c check in normal I/O path.

Signed-off-by: Robert Baldyga <robert.baldyga@huawei.com>
Signed-off-by: Michal Mielewczyk <michal.mielewczyk@huawei.com>
This commit is contained in:
Robert Baldyga 2023-09-25 16:03:52 +02:00 committed by Michal Mielewczyk
parent df280cf5ec
commit 7d53dd1e41
4 changed files with 44 additions and 72 deletions

View File

@ -21,7 +21,6 @@
#include "engine_fast.h"
#include "engine_flush.h"
#include "engine_discard.h"
#include "engine_d2c.h"
#include "../utils/utils_user_part.h"
#include "../utils/utils_refcnt.h"
#include "../ocf_request.h"
@ -42,9 +41,6 @@ enum ocf_io_if_type {
OCF_IO_FAST_IF,
OCF_IO_FLUSH_IF,
OCF_IO_DISCARD_IF,
OCF_IO_D2C_IF,
OCF_IO_D2C_FLUSH_IF,
OCF_IO_D2C_DISCARD_IF,
OCF_IO_PRIV_MAX_IF,
};
@ -112,27 +108,6 @@ static const struct ocf_io_if IO_IFS[OCF_IO_PRIV_MAX_IF] = {
},
.name = "Discard",
},
[OCF_IO_D2C_IF] = {
.cbs = {
[OCF_READ] = ocf_d2c_io,
[OCF_WRITE] = ocf_d2c_io,
},
.name = "Direct to core io",
},
[OCF_IO_D2C_FLUSH_IF] = {
.cbs = {
[OCF_READ] = ocf_d2c_flush,
[OCF_WRITE] = ocf_d2c_flush,
},
.name = "Direct to core flush",
},
[OCF_IO_D2C_DISCARD_IF] = {
.cbs = {
[OCF_READ] = ocf_d2c_discard,
[OCF_WRITE] = ocf_d2c_discard,
},
.name = "Direct to core discard",
},
};
static const struct ocf_io_if *cache_mode_io_if_map[ocf_req_cache_mode_max] = {
@ -143,7 +118,6 @@ static const struct ocf_io_if *cache_mode_io_if_map[ocf_req_cache_mode_max] = {
[ocf_req_cache_mode_wo] = &IO_IFS[OCF_IO_WO_IF],
[ocf_req_cache_mode_pt] = &IO_IFS[OCF_IO_PT_IF],
[ocf_req_cache_mode_fast] = &IO_IFS[OCF_IO_FAST_IF],
[ocf_req_cache_mode_d2c] = &IO_IFS[OCF_IO_D2C_IF],
};
const char *ocf_get_io_iface_name(ocf_req_cache_mode_t cache_mode)
@ -178,11 +152,6 @@ void ocf_resolve_effective_cache_mode(ocf_cache_t cache,
{
ocf_cache_mode_t cache_mode;
if (req->d2c) {
req->cache_mode = ocf_req_cache_mode_d2c;
return;
}
if (ocf_fallback_pt_is_on(cache)){
req->cache_mode = ocf_req_cache_mode_pt;
return;
@ -266,11 +235,6 @@ void ocf_engine_hndl_discard_req(struct ocf_request *req)
{
ocf_req_get(req);
if (req->d2c) {
IO_IFS[OCF_IO_D2C_DISCARD_IF].cbs[req->rw](req);
return;
}
IO_IFS[OCF_IO_DISCARD_IF].cbs[req->rw](req);
}
@ -278,9 +242,7 @@ void ocf_engine_hndl_flush_req(struct ocf_request *req)
{
ocf_req_get(req);
req->engine_handler = (req->d2c) ?
IO_IFS[OCF_IO_D2C_FLUSH_IF].cbs[req->rw] :
IO_IFS[OCF_IO_FLUSH_IF].cbs[req->rw];
req->engine_handler = IO_IFS[OCF_IO_FLUSH_IF].cbs[req->rw];
ocf_queue_push_req(req, OCF_QUEUE_ALLOW_SYNC);
}

View File

@ -29,7 +29,7 @@ static void _ocf_d2c_completion(struct ocf_request *req, int error)
ocf_req_put(req);
}
int ocf_d2c_io(struct ocf_request *req)
int ocf_d2c_io_fast(struct ocf_request *req)
{
OCF_DEBUG_TRACE(req->cache);
@ -46,13 +46,10 @@ int ocf_d2c_io(struct ocf_request *req)
ocf_core_stats_request_pt_update(req->core, req->part_id, req->rw,
req->info.hit_no, req->core_line_count);
/* Put OCF request - decrease reference counter */
ocf_req_put(req);
return 0;
}
int ocf_d2c_flush(struct ocf_request *req)
int ocf_d2c_flush_fast(struct ocf_request *req)
{
OCF_DEBUG_TRACE(req->cache);
@ -69,13 +66,10 @@ int ocf_d2c_flush(struct ocf_request *req)
ocf_core_stats_request_pt_update(req->core, req->part_id, req->rw,
req->info.hit_no, req->core_line_count);
/* Put OCF request - decrease reference counter */
ocf_req_put(req);
return 0;
}
int ocf_d2c_discard(struct ocf_request *req)
int ocf_d2c_discard_fast(struct ocf_request *req)
{
OCF_DEBUG_TRACE(req->cache);
@ -92,8 +86,5 @@ int ocf_d2c_discard(struct ocf_request *req)
ocf_core_stats_request_pt_update(req->core, req->part_id, req->rw,
req->info.hit_no, req->core_line_count);
/* Put OCF request - decrease reference counter */
ocf_req_put(req);
return 0;
}

View File

@ -7,10 +7,10 @@
#ifndef ENGINE_2DC_H_
#define ENGINE_2DC_H_
int ocf_d2c_io(struct ocf_request *req);
int ocf_d2c_io_fast(struct ocf_request *req);
int ocf_d2c_flush(struct ocf_request *req);
int ocf_d2c_flush_fast(struct ocf_request *req);
int ocf_d2c_discard(struct ocf_request *req);
int ocf_d2c_discard_fast(struct ocf_request *req);
#endif /* ENGINE_2DC_H_ */

View File

@ -10,6 +10,7 @@
#include "ocf_io_priv.h"
#include "metadata/metadata.h"
#include "engine/cache_engine.h"
#include "engine/engine_d2c.h"
#include "utils/utils_user_part.h"
#include "ocf_request.h"
@ -241,10 +242,6 @@ static int ocf_core_submit_io_fast(struct ocf_io *io, struct ocf_request *req,
ocf_req_cache_mode_t original_mode, resolved_mode;
int ret;
if (req->d2c) {
return OCF_FAST_PATH_NO;
}
if (req->cache_mode == ocf_req_cache_mode_pt)
return OCF_FAST_PATH_NO;
@ -286,21 +283,27 @@ static void ocf_core_volume_submit_io(struct ocf_io *io)
return;
}
ret = ocf_req_alloc_map(req);
if (ret) {
ocf_io_end(io, ret);
req->core = core;
req->complete = ocf_req_complete;
ocf_io_get(io);
if (unlikely(req->d2c)) {
ocf_core_update_stats(core, io);
ocf_d2c_io_fast(req);
return;
}
ret = ocf_req_alloc_map(req);
if (ret)
goto err;
req->part_id = ocf_user_part_class2id(cache, io->io_class);
req->core = core;
req->complete = ocf_req_complete;
ocf_resolve_effective_cache_mode(cache, core, req);
ocf_core_update_stats(core, io);
ocf_io_get(io);
/* Prevent race condition */
ocf_req_get(req);
@ -317,9 +320,14 @@ static void ocf_core_volume_submit_io(struct ocf_io *io)
ret = ocf_engine_hndl_req(req);
if (ret) {
dec_counter_if_req_was_dirty(req);
ocf_io_end(io, ret);
ocf_io_put(io);
goto err;
}
return;
err:
ocf_io_end(io, ret);
ocf_io_put(io);
}
static void ocf_core_volume_submit_flush(struct ocf_io *io)
@ -351,6 +359,11 @@ static void ocf_core_volume_submit_flush(struct ocf_io *io)
ocf_io_get(io);
if (unlikely(req->d2c)) {
ocf_d2c_flush_fast(req);
return;
}
ocf_engine_hndl_flush_req(req);
}
@ -383,17 +396,23 @@ static void ocf_core_volume_submit_discard(struct ocf_io *io)
return;
}
ret = ocf_req_alloc_map_discard(req);
if (ret) {
ocf_io_end(io, -OCF_ERR_NO_MEM);
return;
}
req->core = core;
req->complete = ocf_req_complete;
ocf_io_get(io);
if (unlikely(req->d2c)) {
ocf_d2c_discard_fast(req);
return;
}
ret = ocf_req_alloc_map_discard(req);
if (ret) {
ocf_io_end(io, -OCF_ERR_NO_MEM);
ocf_io_put(io);
return;
}
ocf_engine_hndl_discard_req(req);
}