Merge pull request #351 from micrakow/seq_cutoff_pt_fix
Fix seq_cutoff respecting in pt read
This commit is contained in:
commit
ed91895f70
@ -153,14 +153,6 @@ static inline struct ocf_io *ocf_core_new_io(ocf_core_t core, ocf_queue_t queue,
|
||||
io_class, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Submit ocf_io
|
||||
*
|
||||
* @param[in] io IO to be submitted
|
||||
* @param[in] mode Cache mode to be enforced
|
||||
*/
|
||||
void ocf_core_submit_io_mode(struct ocf_io *io, ocf_cache_mode_t cache_mode);
|
||||
|
||||
/**
|
||||
* @brief Submit ocf_io
|
||||
*
|
||||
@ -178,7 +170,7 @@ static inline void ocf_core_submit_io(struct ocf_io *io)
|
||||
* @param[in] io IO to be submitted
|
||||
*
|
||||
* @retval 0 IO has been submitted successfully
|
||||
* @retval Non-zero Fast submit failed. Try to submit IO with ocf_submit_io()
|
||||
* @retval Non-zero Fast submit failed. Try to submit IO with ocf_core_submit_io()
|
||||
*/
|
||||
int ocf_core_submit_io_fast(struct ocf_io *io);
|
||||
|
||||
|
@ -85,7 +85,7 @@ static const struct ocf_io_if IO_IFS[OCF_IO_PRIV_MAX_IF] = {
|
||||
.write = ocf_discard,
|
||||
.name = "Discard",
|
||||
},
|
||||
[OCF_IO_D2C_IF] = {
|
||||
[OCF_IO_D2C_IF] = {
|
||||
.read = ocf_io_d2c,
|
||||
.write = ocf_io_d2c,
|
||||
.name = "Direct to core",
|
||||
@ -223,36 +223,51 @@ void ocf_seq_cutoff_update(ocf_core_t core, struct ocf_request *req)
|
||||
core->seq_cutoff.bytes += req->byte_length;
|
||||
}
|
||||
|
||||
ocf_cache_mode_t ocf_get_effective_cache_mode(ocf_cache_t cache,
|
||||
ocf_core_t core, struct ocf_io *io)
|
||||
void ocf_resolve_effective_cache_mode(ocf_cache_t cache,
|
||||
ocf_core_t core, struct ocf_request *req)
|
||||
{
|
||||
ocf_cache_mode_t mode;
|
||||
if (req->d2c) {
|
||||
req->cache_mode = ocf_req_cache_mode_d2c;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cache->pt_unaligned_io && !ocf_req_is_4k(io->addr, io->bytes))
|
||||
return ocf_cache_mode_pt;
|
||||
if (ocf_fallback_pt_is_on(cache)){
|
||||
req->cache_mode = ocf_req_cache_mode_pt;
|
||||
return;
|
||||
}
|
||||
|
||||
mode = ocf_part_get_cache_mode(cache,
|
||||
ocf_part_class2id(cache, io->io_class));
|
||||
if (!ocf_cache_mode_is_valid(mode))
|
||||
mode = cache->conf_meta->cache_mode;
|
||||
if (cache->pt_unaligned_io && !ocf_req_is_4k(req->byte_position,
|
||||
req->byte_length)) {
|
||||
req->cache_mode = ocf_req_cache_mode_pt;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ocf_seq_cutoff_check(core, io->dir, io->addr, io->bytes))
|
||||
mode = ocf_cache_mode_pt;
|
||||
if (ocf_seq_cutoff_check(core, req->rw, req->byte_position,
|
||||
req->byte_length)) {
|
||||
req->cache_mode = ocf_req_cache_mode_pt;
|
||||
req->seq_cutoff = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ocf_fallback_pt_is_on(cache))
|
||||
mode = ocf_cache_mode_pt;
|
||||
req->cache_mode = ocf_part_get_cache_mode(cache,
|
||||
ocf_part_class2id(cache, req->part_id));
|
||||
if (!ocf_cache_mode_is_valid(req->cache_mode))
|
||||
req->cache_mode = cache->conf_meta->cache_mode;
|
||||
|
||||
return mode;
|
||||
if (req->rw == OCF_WRITE &&
|
||||
ocf_req_cache_mode_has_lazy_write(req->cache_mode) &&
|
||||
ocf_req_set_dirty(req)) {
|
||||
req->cache_mode = ocf_req_cache_mode_wt;
|
||||
}
|
||||
}
|
||||
|
||||
int ocf_engine_hndl_req(struct ocf_request *req,
|
||||
ocf_req_cache_mode_t req_cache_mode)
|
||||
int ocf_engine_hndl_req(struct ocf_request *req)
|
||||
{
|
||||
ocf_cache_t cache = req->cache;
|
||||
|
||||
OCF_CHECK_NULL(cache);
|
||||
|
||||
req->io_if = ocf_get_io_if(req_cache_mode);
|
||||
req->io_if = ocf_get_io_if(req->cache_mode);
|
||||
if (!req->io_if)
|
||||
return -OCF_ERR_INVAL;
|
||||
|
||||
@ -267,13 +282,12 @@ int ocf_engine_hndl_req(struct ocf_request *req,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ocf_engine_hndl_fast_req(struct ocf_request *req,
|
||||
ocf_req_cache_mode_t req_cache_mode)
|
||||
int ocf_engine_hndl_fast_req(struct ocf_request *req)
|
||||
{
|
||||
const struct ocf_io_if *io_if;
|
||||
int ret;
|
||||
|
||||
io_if = ocf_get_io_if(req_cache_mode);
|
||||
io_if = ocf_get_io_if(req->cache_mode);
|
||||
if (!io_if)
|
||||
return -OCF_ERR_INVAL;
|
||||
|
||||
|
@ -40,8 +40,8 @@ struct ocf_io_if {
|
||||
const char *name;
|
||||
};
|
||||
|
||||
ocf_cache_mode_t ocf_get_effective_cache_mode(ocf_cache_t cache,
|
||||
ocf_core_t core, struct ocf_io *io);
|
||||
void ocf_resolve_effective_cache_mode(ocf_cache_t cache,
|
||||
ocf_core_t core, struct ocf_request *req);
|
||||
|
||||
const struct ocf_io_if *ocf_get_io_if(ocf_req_cache_mode_t cache_mode);
|
||||
|
||||
@ -74,14 +74,12 @@ bool ocf_seq_cutoff_check(ocf_core_t core, uint32_t dir, uint64_t addr,
|
||||
struct ocf_request *ocf_engine_pop_req(struct ocf_cache *cache,
|
||||
struct ocf_queue *q);
|
||||
|
||||
int ocf_engine_hndl_req(struct ocf_request *req,
|
||||
ocf_req_cache_mode_t req_cache_mode);
|
||||
int ocf_engine_hndl_req(struct ocf_request *req);
|
||||
|
||||
#define OCF_FAST_PATH_YES 7
|
||||
#define OCF_FAST_PATH_NO 13
|
||||
|
||||
int ocf_engine_hndl_fast_req(struct ocf_request *req,
|
||||
ocf_req_cache_mode_t req_cache_mode);
|
||||
int ocf_engine_hndl_fast_req(struct ocf_request *req);
|
||||
|
||||
void ocf_engine_hndl_discard_req(struct ocf_request *req);
|
||||
|
||||
|
@ -405,7 +405,7 @@ static void _ocf_engine_clean_end(void *private_data, int error)
|
||||
}
|
||||
}
|
||||
|
||||
static int ocf_engine_evict(struct ocf_request *req)
|
||||
static int ocf_engine_evict(struct ocf_request *req)
|
||||
{
|
||||
if (!ocf_engine_unmapped_count(req))
|
||||
return 0;
|
||||
|
@ -120,7 +120,7 @@ int ocf_read_pt(struct ocf_request *req)
|
||||
/* Traverse request to check if there are mapped cache lines */
|
||||
ocf_engine_traverse(req);
|
||||
|
||||
if (req->info.seq_cutoff && ocf_engine_is_dirty_all(req)) {
|
||||
if (req->seq_cutoff && ocf_engine_is_dirty_all(req)) {
|
||||
use_cache = true;
|
||||
} else {
|
||||
if (ocf_engine_mapped_count(req)) {
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "ocf_io_priv.h"
|
||||
#include "metadata/metadata.h"
|
||||
#include "engine/cache_engine.h"
|
||||
#include "ocf_request.h"
|
||||
#include "utils/utils_part.h"
|
||||
#include "ocf_request.h"
|
||||
#include "ocf_trace_priv.h"
|
||||
@ -165,12 +164,6 @@ static inline ocf_core_t ocf_volume_to_core(ocf_volume_t volume)
|
||||
return core_volume->core;
|
||||
}
|
||||
|
||||
static inline int ocf_io_set_dirty(struct ocf_request *req)
|
||||
{
|
||||
req->dirty = !!ocf_refcnt_inc(&req->cache->refcnt.dirty);
|
||||
return req->dirty ? 0 : -EBUSY;
|
||||
}
|
||||
|
||||
static inline void dec_counter_if_req_was_dirty(struct ocf_request *req)
|
||||
{
|
||||
if (!req->dirty)
|
||||
@ -223,10 +216,9 @@ static void ocf_req_complete(struct ocf_request *req, int error)
|
||||
ocf_io_put(&req->ioi.io);
|
||||
}
|
||||
|
||||
void ocf_core_submit_io_mode(struct ocf_io *io, ocf_cache_mode_t cache_mode)
|
||||
void ocf_core_volume_submit_io(struct ocf_io *io)
|
||||
{
|
||||
struct ocf_request *req;
|
||||
ocf_req_cache_mode_t req_cache_mode;
|
||||
ocf_core_t core;
|
||||
ocf_cache_t cache;
|
||||
int ret;
|
||||
@ -251,25 +243,11 @@ void ocf_core_submit_io_mode(struct ocf_io *io, ocf_cache_mode_t cache_mode)
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: instead of casting ocf_cache_mode_t to ocf_req_cache_mode_t
|
||||
we can resolve IO interface here and get rid of the latter. */
|
||||
req_cache_mode = cache_mode;
|
||||
|
||||
if (cache_mode == ocf_cache_mode_none)
|
||||
req_cache_mode = ocf_get_effective_cache_mode(cache, core, io);
|
||||
|
||||
if (io->dir == OCF_WRITE &&
|
||||
ocf_req_cache_mode_has_lazy_write(req_cache_mode) &&
|
||||
ocf_io_set_dirty(req)) {
|
||||
req_cache_mode = ocf_req_cache_mode_wt;
|
||||
}
|
||||
|
||||
if (req->d2c)
|
||||
req_cache_mode = ocf_req_cache_mode_d2c;
|
||||
|
||||
req->part_id = ocf_part_class2id(cache, io->io_class);
|
||||
req->core = core;
|
||||
req->complete = ocf_req_complete;
|
||||
req->part_id = ocf_part_class2id(cache, io->io_class);
|
||||
|
||||
ocf_resolve_effective_cache_mode(cache, core, req);
|
||||
|
||||
ocf_seq_cutoff_update(core, req);
|
||||
|
||||
@ -282,7 +260,7 @@ void ocf_core_submit_io_mode(struct ocf_io *io, ocf_cache_mode_t cache_mode)
|
||||
|
||||
ocf_io_get(io);
|
||||
|
||||
ret = ocf_engine_hndl_req(req, req_cache_mode);
|
||||
ret = ocf_engine_hndl_req(req);
|
||||
if (ret) {
|
||||
dec_counter_if_req_was_dirty(req);
|
||||
ocf_io_end(io, ret);
|
||||
@ -292,7 +270,6 @@ void ocf_core_submit_io_mode(struct ocf_io *io, ocf_cache_mode_t cache_mode)
|
||||
int ocf_core_submit_io_fast(struct ocf_io *io)
|
||||
{
|
||||
struct ocf_request *req;
|
||||
ocf_req_cache_mode_t req_cache_mode;
|
||||
struct ocf_event_io trace_event;
|
||||
ocf_core_t core;
|
||||
ocf_cache_t cache;
|
||||
@ -315,26 +292,29 @@ int ocf_core_submit_io_fast(struct ocf_io *io)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (req->d2c) {
|
||||
dec_counter_if_req_was_dirty(req);
|
||||
return -OCF_ERR_IO;
|
||||
}
|
||||
|
||||
ret = ocf_req_alloc_map(req);
|
||||
if (ret) {
|
||||
ocf_io_end(io, -OCF_ERR_NO_MEM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
req_cache_mode = ocf_get_effective_cache_mode(cache, core, io);
|
||||
req->core = core;
|
||||
req->complete = ocf_req_complete;
|
||||
req->part_id = ocf_part_class2id(cache, io->io_class);
|
||||
|
||||
if (io->dir == OCF_WRITE &&
|
||||
ocf_req_cache_mode_has_lazy_write(req_cache_mode) &&
|
||||
ocf_io_set_dirty(req)) {
|
||||
req_cache_mode = ocf_req_cache_mode_wt;
|
||||
}
|
||||
ocf_resolve_effective_cache_mode(cache, core, req);
|
||||
|
||||
switch (req_cache_mode) {
|
||||
switch (req->cache_mode) {
|
||||
case ocf_req_cache_mode_pt:
|
||||
return -OCF_ERR_IO;
|
||||
case ocf_req_cache_mode_wb:
|
||||
case ocf_req_cache_mode_wo:
|
||||
req_cache_mode = ocf_req_cache_mode_fast;
|
||||
req->cache_mode = ocf_req_cache_mode_fast;
|
||||
break;
|
||||
default:
|
||||
if (cache->use_submit_io_fast)
|
||||
@ -342,18 +322,9 @@ int ocf_core_submit_io_fast(struct ocf_io *io)
|
||||
if (io->dir == OCF_WRITE)
|
||||
return -OCF_ERR_IO;
|
||||
|
||||
req_cache_mode = ocf_req_cache_mode_fast;
|
||||
req->cache_mode = ocf_req_cache_mode_fast;
|
||||
}
|
||||
|
||||
if (req->d2c) {
|
||||
dec_counter_if_req_was_dirty(req);
|
||||
return -OCF_ERR_IO;
|
||||
}
|
||||
|
||||
req->core = core;
|
||||
req->complete = ocf_req_complete;
|
||||
req->part_id = ocf_part_class2id(cache, io->io_class);
|
||||
|
||||
ocf_core_update_stats(core, io);
|
||||
|
||||
if (cache->trace.trace_callback) {
|
||||
@ -365,7 +336,7 @@ int ocf_core_submit_io_fast(struct ocf_io *io)
|
||||
|
||||
ocf_io_get(io);
|
||||
|
||||
fast = ocf_engine_hndl_fast_req(req, req_cache_mode);
|
||||
fast = ocf_engine_hndl_fast_req(req);
|
||||
if (fast != OCF_FAST_PATH_NO) {
|
||||
ocf_trace_push(io->io_queue, &trace_event, sizeof(trace_event));
|
||||
ocf_seq_cutoff_update(core, req);
|
||||
@ -378,11 +349,6 @@ int ocf_core_submit_io_fast(struct ocf_io *io)
|
||||
return -OCF_ERR_IO;
|
||||
}
|
||||
|
||||
static void ocf_core_volume_submit_io(struct ocf_io *io)
|
||||
{
|
||||
ocf_core_submit_io_mode(io, ocf_cache_mode_none);
|
||||
}
|
||||
|
||||
static void ocf_core_volume_submit_flush(struct ocf_io *io)
|
||||
{
|
||||
struct ocf_request *req;
|
||||
|
@ -303,6 +303,12 @@ void ocf_req_put(struct ocf_request *req)
|
||||
ocf_queue_put(queue);
|
||||
}
|
||||
|
||||
int ocf_req_set_dirty(struct ocf_request *req)
|
||||
{
|
||||
req->dirty = !!ocf_refcnt_inc(&req->cache->refcnt.dirty);
|
||||
return req->dirty ? 0 : -OCF_ERR_AGAIN;
|
||||
}
|
||||
|
||||
void ocf_req_clear_info(struct ocf_request *req)
|
||||
{
|
||||
ENV_BUG_ON(env_memset(&req->info, sizeof(req->info), 0));
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "ocf_env.h"
|
||||
#include "ocf_io_priv.h"
|
||||
#include "engine/cache_engine.h"
|
||||
|
||||
struct ocf_req_allocator;
|
||||
|
||||
@ -25,9 +26,6 @@ struct ocf_req_info {
|
||||
uint32_t seq_req : 1;
|
||||
/*!< Sequential cache request flag. */
|
||||
|
||||
uint32_t seq_cutoff : 1;
|
||||
/*!< Sequential cut off set for this request */
|
||||
|
||||
uint32_t flush_metadata : 1;
|
||||
/*!< This bit tells if metadata flushing is required */
|
||||
|
||||
@ -149,6 +147,8 @@ struct ocf_request {
|
||||
ctx_data_t *cp_data;
|
||||
/*!< Copy of request data */
|
||||
|
||||
ocf_req_cache_mode_t cache_mode;
|
||||
|
||||
uint64_t byte_position;
|
||||
/*!< LBA byte position of request in core domain */
|
||||
|
||||
@ -185,6 +185,9 @@ struct ocf_request {
|
||||
uint8_t master_io_req_type : 2;
|
||||
/*!< Core device request context type */
|
||||
|
||||
uint8_t seq_cutoff : 1;
|
||||
/*!< Sequential cut off set for this request */
|
||||
|
||||
log_sid_t sid;
|
||||
/*!< Tracing sequence ID */
|
||||
|
||||
@ -326,6 +329,8 @@ void ocf_req_clear_map(struct ocf_request *req);
|
||||
*/
|
||||
void ocf_req_hash(struct ocf_request *req);
|
||||
|
||||
int ocf_req_set_dirty(struct ocf_request *req);
|
||||
|
||||
/**
|
||||
* @brief Clear OCF request
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user