From 4d2d31ff76075db31593eee0b3f8e5a5581138de Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Thu, 30 May 2019 14:39:16 +0200 Subject: [PATCH 1/6] Introduce ocf_io_internal Signed-off-by: Robert Baldyga --- example/simple/src/volume.c | 2 +- inc/ocf_io.h | 28 ++++++----------- src/metadata/metadata_io.c | 2 +- src/ocf_core.c | 23 +++++--------- src/ocf_io.c | 62 +++++++++++++++++++++++-------------- src/ocf_io_priv.h | 7 +++++ src/ocf_volume.c | 26 ++++++++++------ src/ocf_volume_priv.h | 12 ++++--- 8 files changed, 87 insertions(+), 75 deletions(-) diff --git a/example/simple/src/volume.c b/example/simple/src/volume.c index a47ff35..1aae692 100644 --- a/example/simple/src/volume.c +++ b/example/simple/src/volume.c @@ -48,7 +48,7 @@ static void volume_submit_io(struct ocf_io *io) struct myvolume *myvolume; data = ocf_io_get_data(io); - myvolume = ocf_volume_get_priv(io->volume); + myvolume = ocf_volume_get_priv(ocf_io_get_volume(io)); if (io->dir == OCF_WRITE) { memcpy(myvolume->mem + io->addr, diff --git a/inc/ocf_io.h b/inc/ocf_io.h index 6892c46..281c6e1 100644 --- a/inc/ocf_io.h +++ b/inc/ocf_io.h @@ -48,16 +48,6 @@ typedef void (*ocf_end_io_t)(struct ocf_io *io, int error); * @brief OCF IO main structure */ struct ocf_io { - /** - * @brief OCF IO destination volume - */ - ocf_volume_t volume; - - /** - * @brief Operations set for this OCF IO - */ - const struct ocf_io_ops *ops; - /** * @brief OCF IO destination address */ @@ -237,11 +227,7 @@ static inline void ocf_io_set_handle(struct ocf_io *io, ocf_handle_io_t fn) * @retval 0 Data set up successfully * @retval Non-zero Data set up failure */ -static inline int ocf_io_set_data(struct ocf_io *io, ctx_data_t *data, - uint32_t offset) -{ - return io->ops->set_data(io, data, offset); -} +int ocf_io_set_data(struct ocf_io *io, ctx_data_t *data, uint32_t offset); /** * @brief Get data vector from OCF IO @@ -252,10 +238,7 @@ static inline int ocf_io_set_data(struct ocf_io *io, ctx_data_t *data, * * @return Data vector from IO */ -static inline ctx_data_t *ocf_io_get_data(struct ocf_io *io) -{ - return io->ops->get_data(io); -} +ctx_data_t *ocf_io_get_data(struct ocf_io *io); /** * @brief Set queue to which IO should be submitted @@ -276,4 +259,11 @@ static inline void ocf_io_set_queue(struct ocf_io *io, ocf_queue_t queue) */ void ocf_io_handle(struct ocf_io *io, void *opaque); +/** + * @brief Get volume associated with io + * + * @param[in] io OCF IO to be handled + */ +ocf_volume_t ocf_io_get_volume(struct ocf_io *io); + #endif /* __OCF_IO_H__ */ diff --git a/src/metadata/metadata_io.c b/src/metadata/metadata_io.c index 4c360ec..29eabfe 100644 --- a/src/metadata/metadata_io.c +++ b/src/metadata/metadata_io.c @@ -63,7 +63,7 @@ static void metadata_io_read_i_atomic_step_end(struct ocf_io *io, int error) { struct metadata_io_read_i_atomic_context *context = io->priv1; - OCF_DEBUG_TRACE(ocf_volume_get_cache(io->volume)); + OCF_DEBUG_TRACE(ocf_volume_get_cache(ocf_io_get_volume(io))); ocf_io_put(io); diff --git a/src/ocf_core.c b/src/ocf_core.c index 33a6628..e163bb7 100644 --- a/src/ocf_core.c +++ b/src/ocf_core.c @@ -165,18 +165,10 @@ static inline void dec_counter_if_req_was_dirty(struct ocf_core_io *core_io, static inline int ocf_core_validate_io(struct ocf_io *io) { - ocf_core_t core; + ocf_volume_t volume = ocf_io_get_volume(io); + ocf_core_t core = ocf_volume_to_core(volume); - if (!io->volume) - return -OCF_ERR_INVAL; - - if (!io->ops) - return -OCF_ERR_INVAL; - - if (io->addr >= ocf_volume_get_length(io->volume)) - return -OCF_ERR_INVAL; - - if (io->addr + io->bytes > ocf_volume_get_length(io->volume)) + if (io->addr + io->bytes > ocf_volume_get_length(volume)) return -OCF_ERR_INVAL; if (io->io_class >= OCF_IO_CLASS_MAX) @@ -194,7 +186,6 @@ static inline int ocf_core_validate_io(struct ocf_io *io) /* Core volume I/O must not be queued on management queue - this would * break I/O accounting code, resulting in use-after-free type of errors * after cache detach, core remove etc. */ - core = ocf_volume_to_core(io->volume); if (io->io_queue == ocf_core_get_cache(core)->mngt_queue) return -OCF_ERR_INVAL; @@ -234,7 +225,7 @@ void ocf_core_submit_io_mode(struct ocf_io *io, ocf_cache_mode_t cache_mode) core_io = ocf_io_to_core_io(io); - core = ocf_volume_to_core(io->volume); + core = ocf_volume_to_core(ocf_io_get_volume(io)); cache = ocf_core_get_cache(core); ocf_trace_init_io(core_io, cache); @@ -311,7 +302,7 @@ int ocf_core_submit_io_fast(struct ocf_io *io) core_io = ocf_io_to_core_io(io); - core = ocf_volume_to_core(io->volume); + core = ocf_volume_to_core(ocf_io_get_volume(io)); cache = ocf_core_get_cache(core); if (unlikely(!env_bit_test(ocf_cache_state_running, @@ -413,7 +404,7 @@ static void ocf_core_volume_submit_flush(struct ocf_io *io) core_io = ocf_io_to_core_io(io); - core = ocf_volume_to_core(io->volume); + core = ocf_volume_to_core(ocf_io_get_volume(io)); cache = ocf_core_get_cache(core); if (unlikely(!env_bit_test(ocf_cache_state_running, @@ -455,7 +446,7 @@ static void ocf_core_volume_submit_discard(struct ocf_io *io) core_io = ocf_io_to_core_io(io); - core = ocf_volume_to_core(io->volume); + core = ocf_volume_to_core(ocf_io_get_volume(io)); cache = ocf_core_get_cache(core); if (unlikely(!env_bit_test(ocf_cache_state_running, diff --git a/src/ocf_io.c b/src/ocf_io.c index 081eede..8aaad76 100644 --- a/src/ocf_io.c +++ b/src/ocf_io.c @@ -26,8 +26,8 @@ * +-------------------------+ <---------------- */ -#define OCF_IO_TOTAL_SIZE(priv_size) (sizeof(struct ocf_io_meta) + \ - sizeof(struct ocf_io) + priv_size) +#define OCF_IO_TOTAL_SIZE(priv_size) \ + (sizeof(struct ocf_io_internal) + priv_size) env_allocator *ocf_io_allocator_create(uint32_t size, const char *name) { @@ -43,35 +43,29 @@ void ocf_io_allocator_destroy(env_allocator *allocator) * IO internal API */ -void *ocf_io_get_meta(struct ocf_io* io) +static struct ocf_io_internal *ocf_io_get_internal(struct ocf_io* io) { - return (void *)io - sizeof(struct ocf_io_meta); + return container_of(io, struct ocf_io_internal, io); } struct ocf_io *ocf_io_new(ocf_volume_t volume) { - struct ocf_io *io; - struct ocf_io_meta *io_meta; - void *data; + struct ocf_io_internal *ioi; if (!ocf_refcnt_inc(&volume->refcnt)) return NULL; - data = env_allocator_new(volume->type->allocator); - if (!data) { + ioi = env_allocator_new(volume->type->allocator); + if (!ioi) { ocf_refcnt_dec(&volume->refcnt); return NULL; } - io = data + sizeof(struct ocf_io_meta); + ioi->meta.volume = volume; + ioi->meta.ops = &volume->type->properties->io_ops; + env_atomic_set(&ioi->meta.ref_count, 1); - io_meta = ocf_io_get_meta(io); - - io->volume = volume; - io->ops = &volume->type->properties->io_ops; - env_atomic_set(&io_meta->ref_count, 1); - - return io; + return &ioi->io; } /* @@ -83,22 +77,42 @@ void *ocf_io_get_priv(struct ocf_io* io) return (void *)io + sizeof(struct ocf_io); } +int ocf_io_set_data(struct ocf_io *io, ctx_data_t *data, uint32_t offset) +{ + struct ocf_io_internal *ioi = ocf_io_get_internal(io); + + return ioi->meta.ops->set_data(io, data, offset); +} + +ctx_data_t *ocf_io_get_data(struct ocf_io *io) +{ + struct ocf_io_internal *ioi = ocf_io_get_internal(io); + + return ioi->meta.ops->get_data(io); +} + void ocf_io_get(struct ocf_io *io) { - struct ocf_io_meta *io_meta = ocf_io_get_meta(io); + struct ocf_io_internal *ioi = ocf_io_get_internal(io); - env_atomic_inc_return(&io_meta->ref_count); + env_atomic_inc_return(&ioi->meta.ref_count); } void ocf_io_put(struct ocf_io *io) { - struct ocf_io_meta *io_meta = ocf_io_get_meta(io); + struct ocf_io_internal *ioi = ocf_io_get_internal(io); - if (env_atomic_dec_return(&io_meta->ref_count)) + if (env_atomic_dec_return(&ioi->meta.ref_count)) return; - ocf_refcnt_dec(&io->volume->refcnt); + ocf_refcnt_dec(&ioi->meta.volume->refcnt); - env_allocator_del(io->volume->type->allocator, - (void *)io - sizeof(struct ocf_io_meta)); + env_allocator_del(ioi->meta.volume->type->allocator, (void *)ioi); +} + +ocf_volume_t ocf_io_get_volume(struct ocf_io *io) +{ + struct ocf_io_internal *ioi = ocf_io_get_internal(io); + + return ioi->meta.volume; } diff --git a/src/ocf_io_priv.h b/src/ocf_io_priv.h index c7279ed..948e0b3 100644 --- a/src/ocf_io_priv.h +++ b/src/ocf_io_priv.h @@ -10,10 +10,17 @@ #include "ocf_request.h" struct ocf_io_meta { + ocf_volume_t volume; + const struct ocf_io_ops *ops; env_atomic ref_count; struct ocf_request *req; }; +struct ocf_io_internal { + struct ocf_io_meta meta; + struct ocf_io io; +}; + env_allocator *ocf_io_allocator_create(uint32_t size, const char *name); void ocf_io_allocator_destroy(env_allocator *allocator); diff --git a/src/ocf_volume.c b/src/ocf_volume.c index 329a08a..96aa042 100644 --- a/src/ocf_volume.c +++ b/src/ocf_volume.c @@ -234,40 +234,46 @@ struct ocf_io *ocf_volume_new_io(ocf_volume_t volume) void ocf_volume_submit_io(struct ocf_io *io) { - ENV_BUG_ON(!io->volume->type->properties->ops.submit_io); + ocf_volume_t volume = ocf_io_get_volume(io); - if (!io->volume->opened) + ENV_BUG_ON(!volume->type->properties->ops.submit_io); + + if (!volume->opened) io->end(io, -OCF_ERR_IO); - io->volume->type->properties->ops.submit_io(io); + volume->type->properties->ops.submit_io(io); } void ocf_volume_submit_flush(struct ocf_io *io) { - ENV_BUG_ON(!io->volume->type->properties->ops.submit_flush); + ocf_volume_t volume = ocf_io_get_volume(io); - if (!io->volume->opened) + ENV_BUG_ON(!volume->type->properties->ops.submit_flush); + + if (!volume->opened) io->end(io, -OCF_ERR_IO); - if (!io->volume->type->properties->ops.submit_flush) { + if (!volume->type->properties->ops.submit_flush) { ocf_io_end(io, 0); return; } - io->volume->type->properties->ops.submit_flush(io); + volume->type->properties->ops.submit_flush(io); } void ocf_volume_submit_discard(struct ocf_io *io) { - if (!io->volume->opened) + ocf_volume_t volume = ocf_io_get_volume(io); + + if (!volume->opened) io->end(io, -OCF_ERR_IO); - if (!io->volume->type->properties->ops.submit_discard) { + if (!volume->type->properties->ops.submit_discard) { ocf_io_end(io, 0); return; } - io->volume->type->properties->ops.submit_discard(io); + volume->type->properties->ops.submit_discard(io); } int ocf_volume_open(ocf_volume_t volume, void *volume_params) diff --git a/src/ocf_volume_priv.h b/src/ocf_volume_priv.h index de36153..e2b9249 100644 --- a/src/ocf_volume_priv.h +++ b/src/ocf_volume_priv.h @@ -42,16 +42,20 @@ void ocf_volume_set_uuid(ocf_volume_t volume, static inline void ocf_volume_submit_metadata(struct ocf_io *io) { - ENV_BUG_ON(!io->volume->type->properties->ops.submit_metadata); + ocf_volume_t volume = ocf_io_get_volume(io); - io->volume->type->properties->ops.submit_metadata(io); + ENV_BUG_ON(!volume->type->properties->ops.submit_metadata); + + volume->type->properties->ops.submit_metadata(io); } static inline void ocf_volume_submit_write_zeroes(struct ocf_io *io) { - ENV_BUG_ON(!io->volume->type->properties->ops.submit_write_zeroes); + ocf_volume_t volume = ocf_io_get_volume(io); - io->volume->type->properties->ops.submit_write_zeroes(io); + ENV_BUG_ON(!volume->type->properties->ops.submit_write_zeroes); + + volume->type->properties->ops.submit_write_zeroes(io); } #endif /*__OCF_VOLUME_PRIV_H__ */ From 1454b75c0fadb77376a603602a720d26999e791f Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Tue, 16 Jul 2019 18:28:40 +0200 Subject: [PATCH 2/6] ocf_io_internal - update tests Signed-off-by: Robert Baldyga --- tests/functional/pyocf/types/io.py | 8 +++----- tests/functional/pyocf/types/volume.py | 20 ++++++++++++++----- .../pyocf/wrappers/ocf_io_wrappers.c | 11 ---------- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/tests/functional/pyocf/types/io.py b/tests/functional/pyocf/types/io.py index 16c8a2a..8670d55 100644 --- a/tests/functional/pyocf/types/io.py +++ b/tests/functional/pyocf/types/io.py @@ -37,8 +37,6 @@ class Io(Structure): _instances_ = {} _fields_ = [ - ("_volume", c_void_p), - ("_ops", POINTER(IoOps)), ("_addr", c_uint64), ("_flags", c_uint64), ("_bytes", c_uint32), @@ -110,7 +108,7 @@ class Io(Structure): def set_data(self, data: Data, offset: int = 0): self.data = data - OcfLib.getInstance().ocf_io_set_data_wrapper(byref(self), data, offset) + OcfLib.getInstance().ocf_io_set_data(byref(self), data, offset) def set_queue(self, queue: Queue): OcfLib.getInstance().ocf_io_set_queue_wrapper(byref(self), queue.handle) @@ -137,7 +135,7 @@ lib.ocf_io_set_queue_wrapper.argtypes = [POINTER(Io), c_uint32] lib.ocf_core_new_io_wrapper.argtypes = [c_void_p] lib.ocf_core_new_io_wrapper.restype = c_void_p -lib.ocf_io_set_data_wrapper.argtypes = [POINTER(Io), c_void_p, c_uint32] -lib.ocf_io_set_data_wrapper.restype = c_int +lib.ocf_io_set_data.argtypes = [POINTER(Io), c_void_p, c_uint32] +lib.ocf_io_set_data.restype = c_int lib.ocf_io_set_queue_wrapper.argtypes = [POINTER(Io), c_void_p] diff --git a/tests/functional/pyocf/types/volume.py b/tests/functional/pyocf/types/volume.py index 168e4af..6a6e18e 100644 --- a/tests/functional/pyocf/types/volume.py +++ b/tests/functional/pyocf/types/volume.py @@ -145,7 +145,9 @@ class Volume(Structure): @VolumeOps.SUBMIT_IO def _submit_io(io): io_structure = cast(io, POINTER(Io)) - volume = Volume.get_instance(io_structure.contents._volume) + volume = Volume.get_instance( + OcfLib.getInstance().ocf_io_get_volume(io_structure) + ) volume.submit_io(io_structure) @@ -153,7 +155,9 @@ class Volume(Structure): @VolumeOps.SUBMIT_FLUSH def _submit_flush(flush): io_structure = cast(flush, POINTER(Io)) - volume = Volume.get_instance(io_structure.contents._volume) + volume = Volume.get_instance( + OcfLib.getInstance().ocf_io_get_volume(io_structure) + ) volume.submit_flush(io_structure) @@ -166,7 +170,9 @@ class Volume(Structure): @VolumeOps.SUBMIT_DISCARD def _submit_discard(discard): io_structure = cast(discard, POINTER(Io)) - volume = Volume.get_instance(io_structure.contents._volume) + volume = Volume.get_instance( + OcfLib.getInstance().ocf_io_get_volume(io_structure) + ) volume.submit_discard(io_structure) @@ -273,11 +279,11 @@ class Volume(Structure): offset = io_priv.contents._offset if io.contents._dir == IoDir.WRITE: - src_ptr = cast(io.contents._ops.contents._get_data(io), c_void_p) + src_ptr = cast(OcfLib.getInstance().ocf_io_get_data(io), c_void_p) src = Data.get_instance(src_ptr.value).handle.value + offset dst = self._storage + io.contents._addr elif io.contents._dir == IoDir.READ: - dst_ptr = cast(io.contents._ops.contents._get_data(io), c_void_p) + dst_ptr = cast(OcfLib.getInstance().ocf_io_get_data(io), c_void_p) dst = Data.get_instance(dst_ptr.value).handle.value + offset src = self._storage + io.contents._addr @@ -342,3 +348,7 @@ class TraceDevice(Volume): lib = OcfLib.getInstance() lib.ocf_io_get_priv.restype = POINTER(VolumeIoPriv) +lib.ocf_io_get_volume.argtypes = [c_void_p] +lib.ocf_io_get_volume.restype = c_void_p +lib.ocf_io_get_data.argtypes = [c_void_p] +lib.ocf_io_get_data.restype = c_void_p diff --git a/tests/functional/pyocf/wrappers/ocf_io_wrappers.c b/tests/functional/pyocf/wrappers/ocf_io_wrappers.c index 2d029bf..7f6eaf5 100644 --- a/tests/functional/pyocf/wrappers/ocf_io_wrappers.c +++ b/tests/functional/pyocf/wrappers/ocf_io_wrappers.c @@ -33,17 +33,6 @@ void ocf_io_set_handle_wrapper(struct ocf_io *io, ocf_handle_io_t fn) ocf_io_set_handle(io, fn); } -int ocf_io_set_data_wrapper(struct ocf_io *io, ctx_data_t *data, - uint32_t offset) -{ - return ocf_io_set_data(io, data, offset); -} - -ctx_data_t *ocf_io_get_data_wrapper(struct ocf_io *io) -{ - return ocf_io_get_data(io); -} - void ocf_io_set_queue_wrapper(struct ocf_io *io, ocf_queue_t queue) { ocf_io_set_queue(io, queue); From e254c9b587ca2610b76e71d8bbb0d57ce6cdaff6 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Fri, 31 May 2019 14:51:06 +0200 Subject: [PATCH 3/6] Merge new_io and configure into one function Signed-off-by: Robert Baldyga --- doc/HOME.md | 10 ++--- example/simple/src/main.c | 6 +-- inc/ocf_core.h | 13 +++++- inc/ocf_io.h | 31 -------------- inc/ocf_volume.h | 11 ++++- src/engine/engine_discard.c | 15 +++---- src/metadata/metadata.c | 5 +-- src/metadata/metadata_hash.c | 10 ++--- src/metadata/metadata_io.c | 33 ++++++--------- src/metadata/metadata_raw_atomic.c | 4 +- src/metadata/metadata_raw_dynamic.c | 10 ++--- src/ocf_cache.c | 2 +- src/ocf_io.c | 11 ++++- src/ocf_io_priv.h | 4 +- src/ocf_request.h | 1 + src/ocf_volume.c | 6 ++- src/utils/utils_cleaner.c | 33 +++++++-------- src/utils/utils_io.c | 63 +++++++++++++---------------- src/utils/utils_io.h | 18 +++++---- 19 files changed, 130 insertions(+), 156 deletions(-) diff --git a/doc/HOME.md b/doc/HOME.md index 3129928..caad482 100644 --- a/doc/HOME.md +++ b/doc/HOME.md @@ -263,19 +263,17 @@ void read_end(struct ocf_io *io, int error) ocf_io_put(io); } -int read(ocf_core_t core, void *data, addr, uint32_t length) +int read(ocf_core_t core, ocf_queue_t queue, void *data, addr, uint32_t length) { /* Allocate IO */ - struct ocf_io *io = ocf_new_io(core); + struct ocf_io *io; + io = ocf_core_new_io(core, queue, addr, length, OCF_READ, 0, 0); if (!io) { /* Cannot allocate IO */ return -ENOMEM; } - /* Configure IO, set address, flags, IO class, and etc... */ - ocf_io_configure(io, addr, length, OCF_READ, 0, 0); - /* Set completion context and function */ ocf_io_set_cmpl(io, NULL, NULL, read_end); @@ -286,7 +284,7 @@ int read(ocf_core_t core, void *data, addr, uint32_t length) } /* Send IO requests to the cache */ - ocf_submit_io(io); + ocf_core_submit_io(io); /* Just it */ return 0; diff --git a/example/simple/src/main.c b/example/simple/src/main.c index 308c4ad..9cd3506 100644 --- a/example/simple/src/main.c +++ b/example/simple/src/main.c @@ -260,16 +260,12 @@ int submit_io(ocf_core_t core, struct volume_data *data, struct ocf_io *io; /* Allocate new io */ - io = ocf_core_new_io(core); + io = ocf_core_new_io(core, cache_priv->io_queue, addr, len, dir, 0, 0); if (!io) return -ENOMEM; - /* Setup io address, lenght, direction, flags and ioclass */ - ocf_io_configure(io, addr, len, dir, 0, 0); /* Assign data to io */ ocf_io_set_data(io, data, 0); - /* Setup io queue to */ - ocf_io_set_queue(io, cache_priv->io_queue); /* Setup completion function */ ocf_io_set_cmpl(io, NULL, NULL, cmpl); /* Submit io */ diff --git a/inc/ocf_core.h b/inc/ocf_core.h index 4275596..d7825f5 100644 --- a/inc/ocf_core.h +++ b/inc/ocf_core.h @@ -128,14 +128,23 @@ int ocf_core_get(ocf_cache_t cache, ocf_core_id_t id, ocf_core_t *core); * @brief Allocate new ocf_io * * @param[in] core Core object + * @param[in] queue IO queue handle + * @param[in] addr OCF IO destination address + * @param[in] bytes OCF IO size in bytes + * @param[in] dir OCF IO direction + * @param[in] io_class OCF IO destination class + * @param[in] flags OCF IO flags * * @retval ocf_io object */ -static inline struct ocf_io *ocf_core_new_io(ocf_core_t core) +static inline struct ocf_io *ocf_core_new_io(ocf_core_t core, ocf_queue_t queue, + uint64_t addr, uint32_t bytes, uint32_t dir, + uint32_t io_class, uint64_t flags) { ocf_volume_t volume = ocf_core_get_front_volume(core); - return ocf_volume_new_io(volume); + return ocf_volume_new_io(volume, queue, addr, bytes, dir, + io_class, flags); } /** diff --git a/inc/ocf_io.h b/inc/ocf_io.h index 281c6e1..f268320 100644 --- a/inc/ocf_io.h +++ b/inc/ocf_io.h @@ -140,26 +140,6 @@ struct ocf_io_ops { */ void *ocf_io_get_priv(struct ocf_io *io); -/** - * @brief Configure OCF IO - * - * @param[in] io OCF IO - * @param[in] addr OCF IO destination address - * @param[in] bytes OCF IO size in bytes - * @param[in] dir OCF IO direction - * @param[in] io_class OCF IO destination class - * @param[in] flags OCF IO flags - */ -static inline void ocf_io_configure(struct ocf_io *io, uint64_t addr, - uint32_t bytes, uint32_t dir, uint32_t io_class, uint64_t flags) -{ - io->addr = addr; - io->bytes = bytes; - io->io_class = io_class; - io->flags = flags; - io->dir = dir; -} - /** * @brief Increase reference counter in OCF IO * @@ -240,17 +220,6 @@ int ocf_io_set_data(struct ocf_io *io, ctx_data_t *data, uint32_t offset); */ ctx_data_t *ocf_io_get_data(struct ocf_io *io); -/** - * @brief Set queue to which IO should be submitted - * - * @param[in] io OCF IO to set up - * @param[in] queue IO queue handle - */ -static inline void ocf_io_set_queue(struct ocf_io *io, ocf_queue_t queue) -{ - io->io_queue = queue; -} - /** * @brief Handle IO in cache engine * diff --git a/inc/ocf_volume.h b/inc/ocf_volume.h index e074b5e..bd7fa3b 100644 --- a/inc/ocf_volume.h +++ b/inc/ocf_volume.h @@ -256,10 +256,19 @@ int ocf_volume_is_atomic(ocf_volume_t volume); * @brief Allocate new io * * @param[in] volume Volume + * @param[in] queue IO queue handle + * @param[in] addr OCF IO destination address + * @param[in] bytes OCF IO size in bytes + * @param[in] dir OCF IO direction + * @param[in] io_class OCF IO destination class + * @param[in] flags OCF IO flags * * @return ocf_io on success atomic, otherwise NULL */ -struct ocf_io *ocf_volume_new_io(ocf_volume_t volume); +struct ocf_io *ocf_volume_new_io(ocf_volume_t volume, ocf_queue_t queue, + uint64_t addr, uint32_t bytes, uint32_t dir, + uint32_t io_class, uint64_t flags); + /** * @brief Submit io to volume diff --git a/src/engine/engine_discard.c b/src/engine/engine_discard.c index 4b80573..f23938f 100644 --- a/src/engine/engine_discard.c +++ b/src/engine/engine_discard.c @@ -69,19 +69,17 @@ static int _ocf_discard_core(struct ocf_request *req) { struct ocf_io *io; - io = ocf_volume_new_io(&req->core->volume); + io = ocf_volume_new_io(&req->core->volume, req->io_queue, + SECTORS_TO_BYTES(req->discard.sector), + SECTORS_TO_BYTES(req->discard.nr_sects), + OCF_WRITE, 0, 0); if (!io) { _ocf_discard_complete_req(req, -OCF_ERR_NO_MEM); return -OCF_ERR_NO_MEM; } - ocf_io_configure(io, SECTORS_TO_BYTES(req->discard.sector), - SECTORS_TO_BYTES(req->discard.nr_sects), - OCF_WRITE, 0, 0); - ocf_io_set_cmpl(io, req, NULL, _ocf_discard_core_complete); ocf_io_set_data(io, req->data, 0); - ocf_io_set_queue(io, req->io_queue); ocf_volume_submit_discard(io); @@ -109,16 +107,15 @@ static int _ocf_discard_flush_cache(struct ocf_request *req) { struct ocf_io *io; - io = ocf_volume_new_io(&req->cache->device->volume); + io = ocf_volume_new_io(&req->cache->device->volume, req->io_queue, + 0, 0, OCF_WRITE, 0, 0); if (!io) { ocf_metadata_error(req->cache); _ocf_discard_complete_req(req, -OCF_ERR_NO_MEM); return -OCF_ERR_NO_MEM; } - ocf_io_configure(io, 0, 0, OCF_WRITE, 0, 0); ocf_io_set_cmpl(io, req, NULL, _ocf_discard_cache_flush_complete); - ocf_io_set_queue(io, req->io_queue); ocf_volume_submit_flush(io); diff --git a/src/metadata/metadata.c b/src/metadata/metadata.c index f7984e5..6fdfb5d 100644 --- a/src/metadata/metadata.c +++ b/src/metadata/metadata.c @@ -199,7 +199,8 @@ static int ocf_metadata_read_sb(ocf_ctx_t ctx, ocf_volume_t volume, context->priv2 = priv2; /* Allocate resources for IO */ - io = ocf_volume_new_io(volume); + io = ocf_volume_new_io(volume, NULL, 0, sb_pages * PAGE_SIZE, + OCF_READ, 0, 0); if (!io) { ocf_log(ctx, log_err, "Memory allocation error"); result = -OCF_ERR_NO_MEM; @@ -224,8 +225,6 @@ static int ocf_metadata_read_sb(ocf_ctx_t ctx, ocf_volume_t volume, goto err_set_data; } - ocf_io_configure(io, 0, sb_pages * PAGE_SIZE, OCF_READ, 0, 0); - ocf_io_set_cmpl(io, context, NULL, ocf_metadata_read_sb_complete); ocf_volume_submit_io(io); diff --git a/src/metadata/metadata_hash.c b/src/metadata/metadata_hash.c index 0788ee1..44f4a01 100644 --- a/src/metadata/metadata_hash.c +++ b/src/metadata/metadata_hash.c @@ -711,18 +711,16 @@ static int ocf_metadata_query_cores_io(ocf_volume_t volume, env_atomic_inc(&context->count); /* Allocate new IO */ - io = ocf_volume_new_io(volume); + io = ocf_volume_new_io(volume, NULL, + PAGES_TO_BYTES(page), + PAGES_TO_BYTES(num_pages), + OCF_READ, 0, 0); if (!io) { err = -OCF_ERR_NO_MEM; goto exit_error; } /* Setup IO */ - ocf_io_configure(io, - PAGES_TO_BYTES(page), - PAGES_TO_BYTES(num_pages), - OCF_READ, 0, 0); - ocf_io_set_cmpl(io, context, NULL, ocf_metadata_query_cores_end_io); err = ocf_io_set_data(io, data, PAGES_TO_BYTES(offset)); diff --git a/src/metadata/metadata_io.c b/src/metadata/metadata_io.c index 29eabfe..35183a3 100644 --- a/src/metadata/metadata_io.c +++ b/src/metadata/metadata_io.c @@ -99,18 +99,17 @@ int metadata_io_read_i_atomic_step(struct ocf_request *req) ctx_data_seek(cache->owner, context->data, ctx_data_seek_begin, 0); /* Allocate new IO */ - io = ocf_new_cache_io(cache); + io = ocf_new_cache_io(cache, req->io_queue, + cache->device->metadata_offset + + SECTORS_TO_BYTES(context->curr_offset), + SECTORS_TO_BYTES(context->curr_count), OCF_READ, 0, 0); + if (!io) { metadata_io_read_i_atomic_complete(context, -OCF_ERR_NO_MEM); return 0; } /* Setup IO */ - ocf_io_configure(io, cache->device->metadata_offset + - SECTORS_TO_BYTES(context->curr_offset), - SECTORS_TO_BYTES(context->curr_count), OCF_READ, 0, 0); - - ocf_io_set_queue(io, req->io_queue); ocf_io_set_cmpl(io, context, NULL, metadata_io_read_i_atomic_step_end); result = ocf_io_set_data(io, context->data, 0); if (result) { @@ -231,19 +230,16 @@ static int ocf_restart_meta_io(struct ocf_request *req) metadata_io_req_fill(meta_io_req); OCF_METADATA_UNLOCK_RD(); - io = ocf_new_cache_io(cache); + io = ocf_new_cache_io(cache, req->io_queue, + PAGES_TO_BYTES(meta_io_req->page), + PAGES_TO_BYTES(meta_io_req->count), + OCF_WRITE, 0, 0); if (!io) { metadata_io_i_asynch_end(meta_io_req, -OCF_ERR_NO_MEM); return 0; } /* Setup IO */ - ocf_io_configure(io, - PAGES_TO_BYTES(meta_io_req->page), - PAGES_TO_BYTES(meta_io_req->count), - OCF_WRITE, 0, 0); - - ocf_io_set_queue(io, req->io_queue); ocf_io_set_cmpl(io, meta_io_req, NULL, metadata_io_i_asynch_cmpl); ret = ocf_io_set_data(io, meta_io_req->data, 0); if (ret) { @@ -415,7 +411,10 @@ static int metadata_io_i_asynch(ocf_cache_t cache, ocf_queue_t queue, int dir, ret = metadata_updater_check_overlaps(cache, &a_req->reqs[i]); if (ret == 0) { /* Allocate new IO */ - io = ocf_new_cache_io(cache); + io = ocf_new_cache_io(cache, queue, + PAGES_TO_BYTES(a_req->reqs[i].page), + PAGES_TO_BYTES(a_req->reqs[i].count), + dir, 0, 0); if (!io) { error = -OCF_ERR_NO_MEM; metadata_io_req_error(cache, a_req, i, error); @@ -426,12 +425,6 @@ static int metadata_io_i_asynch(ocf_cache_t cache, ocf_queue_t queue, int dir, metadata_io_req_fill(&a_req->reqs[i]); /* Setup IO */ - ocf_io_configure(io, - PAGES_TO_BYTES(a_req->reqs[i].page), - PAGES_TO_BYTES(a_req->reqs[i].count), - dir, 0, 0); - - ocf_io_set_queue(io, queue); ocf_io_set_cmpl(io, &a_req->reqs[i], NULL, metadata_io_i_asynch_cmpl); error = ocf_io_set_data(io, a_req->reqs[i].data, 0); diff --git a/src/metadata/metadata_raw_atomic.c b/src/metadata/metadata_raw_atomic.c index 370ed4c..46e2907 100644 --- a/src/metadata/metadata_raw_atomic.c +++ b/src/metadata/metadata_raw_atomic.c @@ -70,8 +70,9 @@ static int _raw_atomic_io_discard_do(struct ocf_cache *cache, void *context, uint64_t start_addr, uint32_t len, struct _raw_atomic_flush_ctx *ctx) { struct ocf_request *req = context; - struct ocf_io *io = ocf_new_cache_io(cache); + struct ocf_io *io; + io = ocf_new_cache_io(cache, NULL, start_addr, len, OCF_WRITE, 0, 0); if (!io) { req->error = -OCF_ERR_NO_MEM; return req->error; @@ -82,7 +83,6 @@ static int _raw_atomic_io_discard_do(struct ocf_cache *cache, void *context, env_atomic_inc(&ctx->flush_req_cnt); - ocf_io_configure(io, start_addr, len, OCF_WRITE, 0, 0); ocf_io_set_cmpl(io, ctx, NULL, _raw_atomic_io_discard_end); if (cache->device->volume.features.discard_zeroes) diff --git a/src/metadata/metadata_raw_dynamic.c b/src/metadata/metadata_raw_dynamic.c index 25905a2..9da8d0b 100644 --- a/src/metadata/metadata_raw_dynamic.c +++ b/src/metadata/metadata_raw_dynamic.c @@ -336,7 +336,10 @@ static int raw_dynamic_load_all_read(struct ocf_request *req) count = OCF_MIN(RAW_DYNAMIC_LOAD_PAGES, raw->ssd_pages - context->i); /* Allocate IO */ - context->io = ocf_new_cache_io(context->cache); + context->io = ocf_new_cache_io(context->cache, req->io_queue, + PAGES_TO_BYTES(raw->ssd_pages_offset + context->i), + PAGES_TO_BYTES(count), OCF_READ, 0, 0); + if (!context->io) { raw_dynamic_load_all_complete(context, -OCF_ERR_NO_MEM); return 0; @@ -349,11 +352,6 @@ static int raw_dynamic_load_all_read(struct ocf_request *req) raw_dynamic_load_all_complete(context, result); return 0; } - ocf_io_configure(context->io, - PAGES_TO_BYTES(raw->ssd_pages_offset + context->i), - PAGES_TO_BYTES(count), OCF_READ, 0, 0); - - ocf_io_set_queue(context->io, req->io_queue); ocf_io_set_cmpl(context->io, context, NULL, raw_dynamic_load_all_read_end); diff --git a/src/ocf_cache.c b/src/ocf_cache.c index 02470ef..1e4b110 100644 --- a/src/ocf_cache.c +++ b/src/ocf_cache.c @@ -14,7 +14,7 @@ ocf_volume_t ocf_cache_get_volume(ocf_cache_t cache) { - return ocf_cache_is_device_attached(cache) ? &cache->device->volume : NULL; + return cache->device ? &cache->device->volume : NULL; } ocf_cache_id_t ocf_cache_get_id(ocf_cache_t cache) diff --git a/src/ocf_io.c b/src/ocf_io.c index 8aaad76..fd12b35 100644 --- a/src/ocf_io.c +++ b/src/ocf_io.c @@ -48,7 +48,9 @@ static struct ocf_io_internal *ocf_io_get_internal(struct ocf_io* io) return container_of(io, struct ocf_io_internal, io); } -struct ocf_io *ocf_io_new(ocf_volume_t volume) +struct ocf_io *ocf_io_new(ocf_volume_t volume, ocf_queue_t queue, + uint64_t addr, uint32_t bytes, uint32_t dir, + uint32_t io_class, uint64_t flags) { struct ocf_io_internal *ioi; @@ -65,6 +67,13 @@ struct ocf_io *ocf_io_new(ocf_volume_t volume) ioi->meta.ops = &volume->type->properties->io_ops; env_atomic_set(&ioi->meta.ref_count, 1); + ioi->io.io_queue = queue; + ioi->io.addr = addr; + ioi->io.bytes = bytes; + ioi->io.dir = dir; + ioi->io.io_class = io_class; + ioi->io.flags = flags; + return &ioi->io; } diff --git a/src/ocf_io_priv.h b/src/ocf_io_priv.h index 948e0b3..42ce735 100644 --- a/src/ocf_io_priv.h +++ b/src/ocf_io_priv.h @@ -25,7 +25,9 @@ env_allocator *ocf_io_allocator_create(uint32_t size, const char *name); void ocf_io_allocator_destroy(env_allocator *allocator); -struct ocf_io *ocf_io_new(ocf_volume_t volume); +struct ocf_io *ocf_io_new(ocf_volume_t volume, ocf_queue_t queue, + uint64_t addr, uint32_t bytes, uint32_t dir, + uint32_t io_class, uint64_t flags); static inline void ocf_io_start(struct ocf_io *io) { diff --git a/src/ocf_request.h b/src/ocf_request.h index 44590b2..605216e 100644 --- a/src/ocf_request.h +++ b/src/ocf_request.h @@ -7,6 +7,7 @@ #define __OCF_REQUEST_H__ #include "ocf_env.h" +#include "ocf_io_priv.h" struct ocf_req_allocator; diff --git a/src/ocf_volume.c b/src/ocf_volume.c index 96aa042..a141059 100644 --- a/src/ocf_volume.c +++ b/src/ocf_volume.c @@ -227,9 +227,11 @@ int ocf_volume_is_atomic(ocf_volume_t volume) return volume->type->properties->caps.atomic_writes; } -struct ocf_io *ocf_volume_new_io(ocf_volume_t volume) +struct ocf_io *ocf_volume_new_io(ocf_volume_t volume, ocf_queue_t queue, + uint64_t addr, uint32_t bytes, uint32_t dir, + uint32_t io_class, uint64_t flags) { - return ocf_io_new(volume); + return ocf_io_new(volume, queue, addr, bytes, dir, io_class, flags); } void ocf_volume_submit_io(struct ocf_io *io) diff --git a/src/utils/utils_cleaner.c b/src/utils/utils_cleaner.c index 8c20d02..c20265e 100644 --- a/src/utils/utils_cleaner.c +++ b/src/utils/utils_cleaner.c @@ -270,16 +270,14 @@ static int _ocf_cleaner_fire_flush_cache(struct ocf_request *req) OCF_DEBUG_TRACE(req->cache); - io = ocf_volume_new_io(&req->cache->device->volume); + io = ocf_new_cache_io(req->cache, req->io_queue, 0, 0, OCF_WRITE, 0, 0); if (!io) { ocf_metadata_error(req->cache); req->error = -OCF_ERR_NO_MEM; return -OCF_ERR_NO_MEM; } - ocf_io_configure(io, 0, 0, OCF_WRITE, 0, 0); ocf_io_set_cmpl(io, req, NULL, _ocf_cleaner_flush_cache_io_end); - ocf_io_set_queue(io, req->io_queue); ocf_volume_submit_flush(io); @@ -395,6 +393,7 @@ static int _ocf_cleaner_fire_flush_cores(struct ocf_request *req) ocf_core_id_t core_id = OCF_CORE_MAX; struct ocf_cache *cache = req->cache; struct ocf_map_info *iter = req->map; + ocf_core_t core; struct ocf_io *io; OCF_DEBUG_TRACE(req->cache); @@ -419,15 +418,15 @@ static int _ocf_cleaner_fire_flush_cores(struct ocf_request *req) env_atomic_inc(&req->req_remaining); - io = ocf_new_core_io(cache, core_id); + core = ocf_cache_get_core(cache, core_id); + io = ocf_new_core_io(core, req->io_queue, 0, 0, + OCF_WRITE, 0, 0); if (!io) { _ocf_cleaner_flush_cores_io_end(iter, req, -OCF_ERR_NO_MEM); continue; } - ocf_io_configure(io, 0, 0, OCF_WRITE, 0, 0); ocf_io_set_cmpl(io, iter, req, _ocf_cleaner_flush_cores_io_cmpl); - ocf_io_set_queue(io, req->io_queue); ocf_volume_submit_flush(io); } @@ -480,25 +479,24 @@ static void _ocf_cleaner_core_io_for_dirty_range(struct ocf_request *req, { uint64_t addr, offset; int err; - struct ocf_cache *cache = req->cache; + ocf_cache_t cache = req->cache; + ocf_core_t core = ocf_cache_get_core(cache, iter->core_id); struct ocf_io *io; struct ocf_counters_block *core_stats = &cache->core[iter->core_id].counters->core_blocks; ocf_part_id_t part_id = ocf_metadata_get_partition_id(cache, iter->coll_idx); - io = ocf_new_core_io(cache, iter->core_id); - if (!io) - goto error; - addr = (ocf_line_size(cache) * iter->core_line) + SECTORS_TO_BYTES(begin); offset = (ocf_line_size(cache) * iter->hash_key) + SECTORS_TO_BYTES(begin); - ocf_io_configure(io, addr, SECTORS_TO_BYTES(end - begin), OCF_WRITE, - part_id, 0); - ocf_io_set_queue(io, req->io_queue); + io = ocf_new_core_io(core, req->io_queue, addr, + SECTORS_TO_BYTES(end - begin), OCF_WRITE, part_id, 0); + if (!io) + goto error; + err = ocf_io_set_data(io, req->data, offset); if (err) { ocf_io_put(io); @@ -660,7 +658,9 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req) cache_stats = &cache->core[iter->core_id]. counters->cache_blocks; - io = ocf_new_cache_io(cache); + io = ocf_new_cache_io(cache, req->io_queue, + addr, ocf_line_size(cache), + OCF_READ, part_id, 0); if (!io) { /* Allocation error */ iter->invalid = true; @@ -681,9 +681,6 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req) part_id = ocf_metadata_get_partition_id(cache, iter->coll_idx); ocf_io_set_cmpl(io, iter, req, _ocf_cleaner_cache_io_cmpl); - ocf_io_configure(io, addr, ocf_line_size(cache), OCF_READ, - part_id, 0); - ocf_io_set_queue(io, req->io_queue); err = ocf_io_set_data(io, req->data, offset); if (err) { ocf_io_put(io); diff --git a/src/utils/utils_io.c b/src/utils/utils_io.c index ff405c8..c658a47 100644 --- a/src/utils/utils_io.c +++ b/src/utils/utils_io.c @@ -31,11 +31,10 @@ void ocf_submit_volume_flush(ocf_volume_t volume, { struct ocf_io *io; - io = ocf_volume_new_io(volume); + io = ocf_volume_new_io(volume, NULL, 0, 0, OCF_WRITE, 0, 0); if (!io) OCF_CMPL_RET(priv, -OCF_ERR_NO_MEM); - ocf_io_configure(io, 0, 0, OCF_WRITE, 0, 0); ocf_io_set_cmpl(io, cmpl, priv, _ocf_volume_flush_end); ocf_volume_submit_flush(io); @@ -74,7 +73,10 @@ void ocf_submit_volume_discard(ocf_volume_t volume, uint64_t addr, context->priv = priv; while (length) { - io = ocf_volume_new_io(volume); + bytes = OCF_MIN(length, max_length); + + io = ocf_volume_new_io(volume, NULL, addr, bytes, + OCF_WRITE, 0, 0); if (!io) { context->error = -OCF_ERR_NO_MEM; break; @@ -82,9 +84,6 @@ void ocf_submit_volume_discard(ocf_volume_t volume, uint64_t addr, env_atomic_inc(&context->req_remaining); - bytes = OCF_MIN(length, max_length); - - ocf_io_configure(io, addr, bytes, OCF_WRITE, 0, 0); ocf_io_set_cmpl(io, context, NULL, ocf_submit_volume_end); ocf_volume_submit_discard(io); @@ -116,7 +115,10 @@ void ocf_submit_write_zeros(ocf_volume_t volume, uint64_t addr, context->priv = priv; while (length) { - io = ocf_volume_new_io(volume); + bytes = OCF_MIN(length, max_length); + + io = ocf_volume_new_io(volume, NULL, addr, bytes, + OCF_WRITE, 0, 0); if (!io) { context->error = -OCF_ERR_NO_MEM; break; @@ -124,9 +126,6 @@ void ocf_submit_write_zeros(ocf_volume_t volume, uint64_t addr, env_atomic_inc(&context->req_remaining); - bytes = OCF_MIN(length, max_length); - - ocf_io_configure(io, addr, bytes, OCF_WRITE, 0, 0); ocf_io_set_cmpl(io, context, NULL, ocf_submit_volume_end); ocf_volume_submit_write_zeroes(io); @@ -181,7 +180,7 @@ void ocf_submit_cache_page(ocf_cache_t cache, uint64_t addr, int dir, context->cmpl = cmpl; context->priv = priv; - io = ocf_volume_new_io(&cache->device->volume); + io = ocf_new_cache_io(cache, NULL, addr, PAGE_SIZE, dir, 0, 0); if (!io) { result = -OCF_ERR_NO_MEM; goto err_io; @@ -200,7 +199,6 @@ void ocf_submit_cache_page(ocf_cache_t cache, uint64_t addr, int dir, if (result) goto err_set_data; - ocf_io_configure(io, addr, PAGE_SIZE, dir, 0, 0); ocf_io_set_cmpl(io, context, NULL, ocf_submit_cache_page_end); ocf_volume_submit_io(io); @@ -245,12 +243,6 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache, cache_stats = &req->core->counters->cache_blocks; if (reqs == 1) { - io = ocf_new_cache_io(cache); - if (!io) { - callback(req, -OCF_ERR_NO_MEM); - goto update_stats; - } - addr = ocf_metadata_map_lg2phy(cache, req->map[first_cl].coll_idx); addr *= ocf_line_size(cache); @@ -258,8 +250,13 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache, addr += ((req->byte_position + offset) % ocf_line_size(cache)); bytes = size; - ocf_io_configure(io, addr, bytes, dir, class, flags); - ocf_io_set_queue(io, req->io_queue); + io = ocf_new_cache_io(cache, req->io_queue, + addr, bytes, dir, class, flags); + if (!io) { + callback(req, -OCF_ERR_NO_MEM); + goto update_stats; + } + ocf_io_set_cmpl(io, req, callback, ocf_submit_volume_req_cmpl); err = ocf_io_set_data(io, req->data, offset); @@ -277,15 +274,6 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache, /* Issue requests to cache. */ for (i = 0; i < reqs; i++) { - io = ocf_new_cache_io(cache); - - if (!io) { - /* Finish all IOs which left with ERROR */ - for (; i < reqs; i++) - callback(req, -OCF_ERR_NO_MEM); - goto update_stats; - } - addr = ocf_metadata_map_lg2phy(cache, req->map[first_cl + i].coll_idx); addr *= ocf_line_size(cache); @@ -309,8 +297,15 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache, bytes = OCF_MIN(bytes, size - total_bytes); ENV_BUG_ON(bytes == 0); - ocf_io_configure(io, addr, bytes, dir, class, flags); - ocf_io_set_queue(io, req->io_queue); + io = ocf_new_cache_io(cache, req->io_queue, + addr, bytes, dir, class, flags); + if (!io) { + /* Finish all IOs which left with ERROR */ + for (; i < reqs; i++) + callback(req, -OCF_ERR_NO_MEM); + goto update_stats; + } + ocf_io_set_cmpl(io, req, callback, ocf_submit_volume_req_cmpl); err = ocf_io_set_data(io, req->data, offset + total_bytes); @@ -350,15 +345,13 @@ void ocf_submit_volume_req(ocf_volume_t volume, struct ocf_request *req, else if (dir == OCF_READ) env_atomic64_add(req->byte_length, &core_stats->read_bytes); - io = ocf_volume_new_io(volume); + io = ocf_volume_new_io(volume, req->io_queue, req->byte_position, + req->byte_length, dir, class, flags); if (!io) { callback(req, -OCF_ERR_NO_MEM); return; } - ocf_io_configure(io, req->byte_position, req->byte_length, dir, - class, flags); - ocf_io_set_queue(io, req->io_queue); ocf_io_set_cmpl(io, req, callback, ocf_submit_volume_req_cmpl); err = ocf_io_set_data(io, req->data, 0); if (err) { diff --git a/src/utils/utils_io.h b/src/utils/utils_io.h index b1a5d47..418491c 100644 --- a/src/utils/utils_io.h +++ b/src/utils/utils_io.h @@ -64,17 +64,21 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache, struct ocf_request *req, int dir, uint64_t offset, uint64_t size, unsigned int reqs, ocf_req_end_t callback); -static inline struct ocf_io *ocf_new_cache_io(struct ocf_cache *cache) +static inline struct ocf_io *ocf_new_cache_io(ocf_cache_t cache, + ocf_queue_t queue, uint64_t addr, uint32_t bytes, + uint32_t dir, uint32_t io_class, uint64_t flags) + { - return ocf_volume_new_io(&cache->device->volume); + return ocf_volume_new_io(ocf_cache_get_volume(cache), queue, + addr, bytes, dir, io_class, flags); } -static inline struct ocf_io *ocf_new_core_io(struct ocf_cache *cache, - ocf_core_id_t core_id) +static inline struct ocf_io *ocf_new_core_io(ocf_core_t core, + ocf_queue_t queue, uint64_t addr, uint32_t bytes, + uint32_t dir, uint32_t io_class, uint64_t flags) { - ENV_BUG_ON(core_id >= OCF_CORE_MAX); - - return ocf_volume_new_io(&cache->core[core_id].volume); + return ocf_volume_new_io(ocf_core_get_volume(core), queue, + addr, bytes, dir, io_class, flags); } #endif /* UTILS_IO_H_ */ From 2efd563df1db63bd34cae399aa38d606b33a657c Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Sat, 13 Jul 2019 10:49:23 +0200 Subject: [PATCH 4/6] Merge new_io and configure - update tests Signed-off-by: Robert Baldyga --- tests/functional/pyocf/types/core.py | 47 +++++++++++++++---- tests/functional/pyocf/types/io.py | 23 --------- .../pyocf/wrappers/ocf_io_wrappers.c | 17 ++----- tests/functional/tests/basic/test_pyocf.py | 5 +- tests/functional/tests/engine/test_wo.py | 9 ++-- .../tests/management/test_add_remove.py | 6 +-- .../tests/management/test_start_stop.py | 11 ++--- .../tests/security/test_negative_io.py | 5 +- .../tests/security/test_secure_erase.py | 30 ++++++------ 9 files changed, 71 insertions(+), 82 deletions(-) diff --git a/tests/functional/pyocf/types/core.py b/tests/functional/pyocf/types/core.py index 6ed0e5f..223f9e6 100644 --- a/tests/functional/pyocf/types/core.py +++ b/tests/functional/pyocf/types/core.py @@ -11,9 +11,10 @@ from ctypes import ( c_int, c_uint8, c_uint16, + c_uint32, + c_uint64, c_char_p, c_bool, - c_uint32, cast, byref, create_string_buffer, @@ -22,6 +23,7 @@ from datetime import timedelta from .data import Data from .io import Io, IoDir +from .queue import Queue from .shared import Uuid, OcfCompletion, OcfError, SeqCutOffPolicy from .stats.core import CoreStats from .stats.shared import UsageStats, RequestsStats, BlocksStats, ErrorsStats @@ -92,17 +94,25 @@ class Core: def get_handle(self): return self.handle - def new_io(self): + def new_io( + self, queue: Queue, addr: int, length: int, direction: IoDir, + io_class: int, flags: int + ): if not self.cache: raise Exception("Core isn't attached to any cache") - io = OcfLib.getInstance().ocf_core_new_io_wrapper(self.handle) + io = OcfLib.getInstance().ocf_core_new_io_wrapper( + self.handle, queue.handle, addr, length, direction, io_class, flags) return Io.from_pointer(io) - def new_core_io(self): + def new_core_io( + self, queue: Queue, addr: int, length: int, direction: IoDir, + io_class: int, flags: int + ): lib = OcfLib.getInstance() - core = lib.ocf_core_get_volume(self.handle) - io = lib.ocf_volume_new_io(core) + volume = lib.ocf_core_get_volume(self.handle) + io = lib.ocf_volume_new_io( + volume, queue.handle, addr, length, direction, io_class, flags) return Io.from_pointer(io) def get_stats(self): @@ -166,10 +176,9 @@ class Core: position = 0 while position < read_buffer_all.size: - io = self.new_io() - io.configure(position, cache_line_size, IoDir.READ, 0, 0) + io = self.new_io(self.cache.get_default_queue(), position, + cache_line_size, IoDir.READ, 0, 0) io.set_data(read_buffer) - io.set_queue(self.cache.get_default_queue()) cmpl = OcfCompletion([("err", c_int)]) io.callback = cmpl.callback @@ -187,7 +196,15 @@ class Core: lib = OcfLib.getInstance() lib.ocf_core_get_volume.restype = c_void_p -lib.ocf_volume_new_io.argtypes = [c_void_p] +lib.ocf_volume_new_io.argtypes = [ + c_void_p, + c_void_p, + c_uint64, + c_uint32, + c_uint32, + c_uint32, + c_uint64, +] lib.ocf_volume_new_io.restype = c_void_p lib.ocf_core_get_volume.argtypes = [c_void_p] lib.ocf_core_get_volume.restype = c_void_p @@ -197,3 +214,13 @@ lib.ocf_stats_collect_core.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p, c lib.ocf_stats_collect_core.restype = c_int lib.ocf_core_get_stats.argtypes = [c_void_p, c_void_p] lib.ocf_core_get_stats.restype = c_int +lib.ocf_core_new_io_wrapper.argtypes = [ + c_void_p, + c_void_p, + c_uint64, + c_uint32, + c_uint32, + c_uint32, + c_uint64, +] +lib.ocf_core_new_io_wrapper.restype = c_void_p diff --git a/tests/functional/pyocf/types/io.py b/tests/functional/pyocf/types/io.py index 8670d55..7e3671c 100644 --- a/tests/functional/pyocf/types/io.py +++ b/tests/functional/pyocf/types/io.py @@ -18,7 +18,6 @@ from enum import IntEnum from ..ocf import OcfLib from .data import Data -from .queue import Queue class IoDir(IntEnum): @@ -99,20 +98,10 @@ class Io(Structure): def submit(self): return OcfLib.getInstance().ocf_core_submit_io_wrapper(byref(self)) - def configure( - self, addr: int, length: int, direction: IoDir, io_class: int, flags: int - ): - OcfLib.getInstance().ocf_io_configure_wrapper( - byref(self), addr, length, direction, io_class, flags - ) - def set_data(self, data: Data, offset: int = 0): self.data = data OcfLib.getInstance().ocf_io_set_data(byref(self), data, offset) - def set_queue(self, queue: Queue): - OcfLib.getInstance().ocf_io_set_queue_wrapper(byref(self), queue.handle) - IoOps.SET_DATA = CFUNCTYPE(c_int, POINTER(Io), c_void_p, c_uint32) IoOps.GET_DATA = CFUNCTYPE(c_void_p, POINTER(Io)) @@ -120,22 +109,10 @@ IoOps.GET_DATA = CFUNCTYPE(c_void_p, POINTER(Io)) IoOps._fields_ = [("_set_data", IoOps.SET_DATA), ("_get_data", IoOps.GET_DATA)] lib = OcfLib.getInstance() -lib.ocf_core_new_io_wrapper.restype = POINTER(Io) lib.ocf_io_set_cmpl_wrapper.argtypes = [POINTER(Io), c_void_p, c_void_p, Io.END] -lib.ocf_io_configure_wrapper.argtypes = [ - POINTER(Io), - c_uint64, - c_uint32, - c_uint32, - c_uint32, - c_uint64, -] -lib.ocf_io_set_queue_wrapper.argtypes = [POINTER(Io), c_uint32] lib.ocf_core_new_io_wrapper.argtypes = [c_void_p] lib.ocf_core_new_io_wrapper.restype = c_void_p lib.ocf_io_set_data.argtypes = [POINTER(Io), c_void_p, c_uint32] lib.ocf_io_set_data.restype = c_int - -lib.ocf_io_set_queue_wrapper.argtypes = [POINTER(Io), c_void_p] diff --git a/tests/functional/pyocf/wrappers/ocf_io_wrappers.c b/tests/functional/pyocf/wrappers/ocf_io_wrappers.c index 7f6eaf5..79b9331 100644 --- a/tests/functional/pyocf/wrappers/ocf_io_wrappers.c +++ b/tests/functional/pyocf/wrappers/ocf_io_wrappers.c @@ -6,15 +6,11 @@ #include "ocf/ocf_io.h" #include "ocf/ocf_core.h" -struct ocf_io *ocf_core_new_io_wrapper(ocf_core_t core) +struct ocf_io *ocf_core_new_io_wrapper(ocf_core_t core, ocf_queue_t queue, + uint64_t addr, uint32_t bytes, uint32_t dir, + uint32_t io_class, uint64_t flags) { - return ocf_core_new_io(core); -} - -void ocf_io_configure_wrapper(struct ocf_io *io, uint64_t addr, - uint32_t bytes, uint32_t dir, uint32_t class, uint64_t flags) -{ - ocf_io_configure(io, addr, bytes, dir, class, flags); + return ocf_core_new_io(core, queue, addr, bytes, dir, io_class, flags); } void ocf_io_set_cmpl_wrapper(struct ocf_io *io, void *context, @@ -33,11 +29,6 @@ void ocf_io_set_handle_wrapper(struct ocf_io *io, ocf_handle_io_t fn) ocf_io_set_handle(io, fn); } -void ocf_io_set_queue_wrapper(struct ocf_io *io, ocf_queue_t queue) -{ - ocf_io_set_queue(io, queue); -} - void ocf_core_submit_io_wrapper(struct ocf_io *io) { ocf_core_submit_io(io); diff --git a/tests/functional/tests/basic/test_pyocf.py b/tests/functional/tests/basic/test_pyocf.py index 872d187..24c6cce 100644 --- a/tests/functional/tests/basic/test_pyocf.py +++ b/tests/functional/tests/basic/test_pyocf.py @@ -32,10 +32,9 @@ def test_simple_wt_write(pyocf_ctx): core_device.reset_stats() write_data = Data.from_string("This is test data") - io = core.new_io() + io = core.new_io(cache.get_default_queue(), 20, write_data.size, + IoDir.WRITE, 0, 0) io.set_data(write_data) - io.configure(20, write_data.size, IoDir.WRITE, 0, 0) - io.set_queue(cache.get_default_queue()) cmpl = OcfCompletion([("err", c_int)]) io.callback = cmpl.callback diff --git a/tests/functional/tests/engine/test_wo.py b/tests/functional/tests/engine/test_wo.py index db2862f..b5e042b 100644 --- a/tests/functional/tests/engine/test_wo.py +++ b/tests/functional/tests/engine/test_wo.py @@ -19,8 +19,6 @@ from pyocf.types.shared import OcfCompletion def __io(io, queue, address, size, data, direction): io.set_data(data, 0) - io.configure(address, size, direction, 0, 0) - io.set_queue(queue) completion = OcfCompletion([("err", c_int)]) io.callback = completion.callback io.submit() @@ -28,7 +26,8 @@ def __io(io, queue, address, size, data, direction): return int(completion.results['err']) -def _io(io, queue, address, size, data, offset, direction): +def _io(new_io, queue, address, size, data, offset, direction): + io = new_io(queue, address, size, direction, 0, 0) if direction == IoDir.READ: _data = Data.from_bytes(bytes(size)) else: @@ -40,12 +39,12 @@ def _io(io, queue, address, size, data, offset, direction): def io_to_core(core, address, size, data, offset, direction): - return _io(core.new_core_io(), core.cache.get_default_queue(), address, size, + return _io(core.new_core_io, core.cache.get_default_queue(), address, size, data, offset, direction) def io_to_exp_obj(core, address, size, data, offset, direction): - return _io(core.new_io(), core.cache.get_default_queue(), address, size, data, + return _io(core.new_io, core.cache.get_default_queue(), address, size, data, offset, direction) diff --git a/tests/functional/tests/management/test_add_remove.py b/tests/functional/tests/management/test_add_remove.py index 1d2cdfc..e855c17 100644 --- a/tests/functional/tests/management/test_add_remove.py +++ b/tests/functional/tests/management/test_add_remove.py @@ -101,10 +101,10 @@ def test_10add_remove_with_io(pyocf_ctx): assert stats["conf"]["core_count"] == 1 write_data = Data.from_string("Test data") - io = core.new_io() + io = core.new_io( + cache.get_default_queue(), 20, write_data.size, IoDir.WRITE, 0, 0 + ) io.set_data(write_data) - io.configure(20, write_data.size, IoDir.WRITE, 0, 0) - io.set_queue(cache.get_default_queue()) cmpl = OcfCompletion([("err", c_int)]) io.callback = cmpl.callback diff --git a/tests/functional/tests/management/test_start_stop.py b/tests/functional/tests/management/test_start_stop.py index 3e86b3d..46258e4 100644 --- a/tests/functional/tests/management/test_start_stop.py +++ b/tests/functional/tests/management/test_start_stop.py @@ -372,10 +372,10 @@ def run_io_and_cache_data_if_possible(exported_obj, mode, cls, cls_no): def io_to_core(exported_obj: Core, data: Data, offset: int, to_core_device=False): - io = exported_obj.new_core_io() if to_core_device else exported_obj.new_io() + new_io = exported_obj.new_core_io if to_core_device else exported_obj.new_io + io = new_io(exported_obj.cache.get_default_queue(), offset, data.size, + IoDir.WRITE, 0, 0) io.set_data(data) - io.configure(offset, data.size, IoDir.WRITE, 0, 0) - io.set_queue(exported_obj.cache.get_default_queue()) completion = OcfCompletion([("err", c_int)]) io.callback = completion.callback @@ -387,10 +387,9 @@ def io_to_core(exported_obj: Core, data: Data, offset: int, to_core_device=False def io_from_exported_object(exported_obj: Core, buffer_size: int, offset: int): read_buffer = Data(buffer_size) - io = exported_obj.new_io() - io.configure(offset, read_buffer.size, IoDir.READ, 0, 0) + io = exported_obj.new_io(exported_obj.cache.get_default_queue(), offset, + read_buffer.size, IoDir.READ, 0, 0) io.set_data(read_buffer) - io.set_queue(exported_obj.cache.get_default_queue()) completion = OcfCompletion([("err", c_int)]) io.callback = completion.callback diff --git a/tests/functional/tests/security/test_negative_io.py b/tests/functional/tests/security/test_negative_io.py index ffd4001..69a82ea 100644 --- a/tests/functional/tests/security/test_negative_io.py +++ b/tests/functional/tests/security/test_negative_io.py @@ -164,10 +164,9 @@ def prepare_cache_and_core(core_size: Size, cache_size: Size = Size.from_MiB(20) def io_operation(core: Core, data: Data, io_direction: int, offset: int = 0, io_class: int = 0): - io = core.new_io() + io = core.new_io(core.cache.get_default_queue(), offset, data.size, + io_direction, io_class, 0) io.set_data(data) - io.configure(offset, data.size, io_direction, io_class, 0) - io.set_queue(core.cache.get_default_queue()) completion = OcfCompletion([("err", c_int)]) io.callback = completion.callback diff --git a/tests/functional/tests/security/test_secure_erase.py b/tests/functional/tests/security/test_secure_erase.py index a6a5155..8eda3d4 100644 --- a/tests/functional/tests/security/test_secure_erase.py +++ b/tests/functional/tests/security/test_secure_erase.py @@ -87,10 +87,10 @@ def test_secure_erase_simple_io_read_misses(cache_mode): cache.add_core(core) write_data = Data.from_string("This is test data") - io = core.new_io() + io = core.new_io( + cache.get_default_queue(), 20, write_data.size, IoDir.WRITE, 0, 0 + ) io.set_data(write_data) - io.configure(20, write_data.size, IoDir.WRITE, 0, 0) - io.set_queue(cache.get_default_queue()) cmpl = OcfCompletion([("err", c_int)]) io.callback = cmpl.callback @@ -100,12 +100,11 @@ def test_secure_erase_simple_io_read_misses(cache_mode): cmpls = [] for i in range(100): read_data = Data(500) - io = core.new_io() - io.set_data(read_data) - io.configure( - (i * 1259) % int(core_device.size), read_data.size, IoDir.READ, 0, 0 + io = core.new_io( + cache.get_default_queue(), (i * 1259) % int(core_device.size), + read_data.size, IoDir.READ, 0, 0 ) - io.set_queue(cache.get_default_queue()) + io.set_data(read_data) cmpl = OcfCompletion([("err", c_int)]) io.callback = cmpl.callback @@ -116,10 +115,10 @@ def test_secure_erase_simple_io_read_misses(cache_mode): c.wait() write_data = Data.from_string("TEST DATA" * 100) - io = core.new_io() + io = core.new_io( + cache.get_default_queue(), 500, write_data.size, IoDir.WRITE, 0, 0 + ) io.set_data(write_data) - io.configure(500, write_data.size, IoDir.WRITE, 0, 0) - io.set_queue(cache.get_default_queue()) cmpl = OcfCompletion([("err", c_int)]) io.callback = cmpl.callback @@ -169,12 +168,11 @@ def test_secure_erase_simple_io_cleaning(): cmpls = [] for i in range(10000): read_data = Data(S.from_KiB(120)) - io = core.new_io() - io.set_data(read_data) - io.configure( - (i * 1259) % int(core_device.size), read_data.size, IoDir.WRITE, 0, 0 + io = core.new_io( + cache.get_default_queue(), (i * 1259) % int(core_device.size), + read_data.size, IoDir.WRITE, 0, 0 ) - io.set_queue(cache.get_default_queue()) + io.set_data(read_data) cmpl = OcfCompletion([("err", c_int)]) io.callback = cmpl.callback From 61414f889e6ce7417bf24daa8343facd9b1e803c Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 29 May 2019 14:31:48 +0200 Subject: [PATCH 5/6] Introduce OCF IO allocator Signed-off-by: Robert Baldyga --- inc/ocf_types.h | 2 +- src/ocf_ctx.c | 14 ++++++-- src/ocf_io.c | 48 ++++++++++++++++++++++---- src/ocf_io_priv.h | 5 +-- src/ocf_volume.c | 17 ++++++---- src/ocf_volume_priv.h | 10 ++++-- src/utils/utils_cleaner.c | 20 +++++------ src/utils/utils_io_allocator.h | 62 ++++++++++++++++++++++++++++++++++ 8 files changed, 147 insertions(+), 31 deletions(-) create mode 100644 src/utils/utils_io_allocator.h diff --git a/inc/ocf_types.h b/inc/ocf_types.h index 95a55e8..fb02373 100644 --- a/inc/ocf_types.h +++ b/inc/ocf_types.h @@ -65,7 +65,7 @@ struct ocf_volume_type; /** * @brief handle to volume type */ -typedef const struct ocf_volume_type *ocf_volume_type_t; +typedef struct ocf_volume_type *ocf_volume_type_t; /** * @brief handle to volume uuid diff --git a/src/ocf_ctx.c b/src/ocf_ctx.c index c1a7310..113d631 100644 --- a/src/ocf_ctx.c +++ b/src/ocf_ctx.c @@ -15,8 +15,9 @@ /* * */ -int ocf_ctx_register_volume_type(ocf_ctx_t ctx, uint8_t type_id, - const struct ocf_volume_properties *properties) +int ocf_ctx_register_volume_type_extended(ocf_ctx_t ctx, uint8_t type_id, + const struct ocf_volume_properties *properties, + const struct ocf_volume_extended *extended) { int result = 0; @@ -31,7 +32,7 @@ int ocf_ctx_register_volume_type(ocf_ctx_t ctx, uint8_t type_id, goto err; } - ocf_volume_type_init(&ctx->volume_type[type_id], properties); + ocf_volume_type_init(&ctx->volume_type[type_id], properties, extended); if (!ctx->volume_type[type_id]) result = -EINVAL; @@ -50,6 +51,13 @@ err: return result; } +int ocf_ctx_register_volume_type(ocf_ctx_t ctx, uint8_t type_id, + const struct ocf_volume_properties *properties) +{ + return ocf_ctx_register_volume_type_extended(ctx, type_id, + properties, NULL); +} + /* * */ diff --git a/src/ocf_io.c b/src/ocf_io.c index fd12b35..5e89bf8 100644 --- a/src/ocf_io.c +++ b/src/ocf_io.c @@ -6,6 +6,7 @@ #include "ocf/ocf.h" #include "ocf_io_priv.h" #include "ocf_volume_priv.h" +#include "utils/utils_io_allocator.h" /* * This is io allocator dedicated for bottom devices. @@ -26,17 +27,49 @@ * +-------------------------+ <---------------- */ -#define OCF_IO_TOTAL_SIZE(priv_size) \ +#define OCF_IO_TOTAL(priv_size) \ (sizeof(struct ocf_io_internal) + priv_size) -env_allocator *ocf_io_allocator_create(uint32_t size, const char *name) +static int ocf_io_allocator_default_init(ocf_io_allocator_t allocator, + uint32_t priv_size, const char *name) { - return env_allocator_create(OCF_IO_TOTAL_SIZE(size), name); + allocator->priv = env_allocator_create(OCF_IO_TOTAL(priv_size), name); + if (!allocator->priv) + return -OCF_ERR_NO_MEM; + + return 0; } -void ocf_io_allocator_destroy(env_allocator *allocator) +static void ocf_io_allocator_default_deinit(ocf_io_allocator_t allocator) { - env_allocator_destroy(allocator); + env_allocator_destroy(allocator->priv); + allocator->priv = NULL; +} + +static void *ocf_io_allocator_default_new(ocf_io_allocator_t allocator, + ocf_volume_t volume, ocf_queue_t queue, + uint64_t addr, uint32_t bytes, uint32_t dir) +{ + return env_allocator_new(allocator->priv); +} + +static void ocf_io_allocator_default_del(ocf_io_allocator_t allocator, void *obj) +{ + env_allocator_del(allocator->priv, obj); +} + +const struct ocf_io_allocator_type type_default = { + .ops = { + .allocator_init = ocf_io_allocator_default_init, + .allocator_deinit = ocf_io_allocator_default_deinit, + .allocator_new = ocf_io_allocator_default_new, + .allocator_del = ocf_io_allocator_default_del, + }, +}; + +ocf_io_allocator_type_t ocf_io_allocator_get_type_default(void) +{ + return &type_default; } /* @@ -57,7 +90,8 @@ struct ocf_io *ocf_io_new(ocf_volume_t volume, ocf_queue_t queue, if (!ocf_refcnt_inc(&volume->refcnt)) return NULL; - ioi = env_allocator_new(volume->type->allocator); + ioi = ocf_io_allocator_new(&volume->type->allocator, volume, queue, + addr, bytes, dir); if (!ioi) { ocf_refcnt_dec(&volume->refcnt); return NULL; @@ -116,7 +150,7 @@ void ocf_io_put(struct ocf_io *io) ocf_refcnt_dec(&ioi->meta.volume->refcnt); - env_allocator_del(ioi->meta.volume->type->allocator, (void *)ioi); + ocf_io_allocator_del(&ioi->meta.volume->type->allocator, (void *)ioi); } ocf_volume_t ocf_io_get_volume(struct ocf_io *io) diff --git a/src/ocf_io_priv.h b/src/ocf_io_priv.h index 42ce735..4735b5c 100644 --- a/src/ocf_io_priv.h +++ b/src/ocf_io_priv.h @@ -8,6 +8,7 @@ #include "ocf/ocf.h" #include "ocf_request.h" +#include "utils/utils_io_allocator.h" struct ocf_io_meta { ocf_volume_t volume; @@ -21,9 +22,9 @@ struct ocf_io_internal { struct ocf_io io; }; -env_allocator *ocf_io_allocator_create(uint32_t size, const char *name); +int ocf_io_allocator_init(ocf_io_allocator_t allocator, ocf_io_allocator_type_t type, + uint32_t priv_size, const char *name); -void ocf_io_allocator_destroy(env_allocator *allocator); struct ocf_io *ocf_io_new(ocf_volume_t volume, ocf_queue_t queue, uint64_t addr, uint32_t bytes, uint32_t dir, diff --git a/src/ocf_volume.c b/src/ocf_volume.c index a141059..404b8c1 100644 --- a/src/ocf_volume.c +++ b/src/ocf_volume.c @@ -16,9 +16,11 @@ */ int ocf_volume_type_init(struct ocf_volume_type **type, - const struct ocf_volume_properties *properties) + const struct ocf_volume_properties *properties, + const struct ocf_volume_extended *extended) { const struct ocf_volume_ops *ops = &properties->ops; + ocf_io_allocator_type_t allocator_type; struct ocf_volume_type *new_type; int ret; @@ -34,12 +36,15 @@ int ocf_volume_type_init(struct ocf_volume_type **type, if (!new_type) return -OCF_ERR_NO_MEM; - new_type->allocator = ocf_io_allocator_create( + if (extended && extended->allocator_type) + allocator_type = extended->allocator_type; + else + allocator_type = ocf_io_allocator_get_type_default(); + + ret = ocf_io_allocator_init(&new_type->allocator, allocator_type, properties->io_priv_size, properties->name); - if (!new_type->allocator) { - ret = -OCF_ERR_NO_MEM; + if (ret) goto err; - } new_type->properties = properties; @@ -54,7 +59,7 @@ err: void ocf_volume_type_deinit(struct ocf_volume_type *type) { - ocf_io_allocator_destroy(type->allocator); + ocf_io_allocator_deinit(&type->allocator); env_free(type); } diff --git a/src/ocf_volume_priv.h b/src/ocf_volume_priv.h index e2b9249..1e51a37 100644 --- a/src/ocf_volume_priv.h +++ b/src/ocf_volume_priv.h @@ -9,10 +9,15 @@ #include "ocf_env.h" #include "ocf_io_priv.h" #include "utils/utils_refcnt.h" +#include "utils/utils_io_allocator.h" + +struct ocf_volume_extended { + ocf_io_allocator_type_t allocator_type; +}; struct ocf_volume_type { const struct ocf_volume_properties *properties; - env_allocator *allocator; + struct ocf_io_allocator allocator; }; struct ocf_volume { @@ -31,7 +36,8 @@ struct ocf_volume { }; int ocf_volume_type_init(struct ocf_volume_type **type, - const struct ocf_volume_properties *properties); + const struct ocf_volume_properties *properties, + const struct ocf_volume_extended *extended); void ocf_volume_type_deinit(struct ocf_volume_type *type); diff --git a/src/utils/utils_cleaner.c b/src/utils/utils_cleaner.c index c20265e..e9a2f08 100644 --- a/src/utils/utils_cleaner.c +++ b/src/utils/utils_cleaner.c @@ -658,16 +658,6 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req) cache_stats = &cache->core[iter->core_id]. counters->cache_blocks; - io = ocf_new_cache_io(cache, req->io_queue, - addr, ocf_line_size(cache), - OCF_READ, part_id, 0); - if (!io) { - /* Allocation error */ - iter->invalid = true; - _ocf_cleaner_set_error(req); - continue; - } - OCF_DEBUG_PARAM(req->cache, "Cache read, line = %u", iter->coll_idx); @@ -680,6 +670,16 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req) part_id = ocf_metadata_get_partition_id(cache, iter->coll_idx); + io = ocf_new_cache_io(cache, req->io_queue, + addr, ocf_line_size(cache), + OCF_READ, part_id, 0); + if (!io) { + /* Allocation error */ + iter->invalid = true; + _ocf_cleaner_set_error(req); + continue; + } + ocf_io_set_cmpl(io, iter, req, _ocf_cleaner_cache_io_cmpl); err = ocf_io_set_data(io, req->data, offset); if (err) { diff --git a/src/utils/utils_io_allocator.h b/src/utils/utils_io_allocator.h new file mode 100644 index 0000000..2a7bae2 --- /dev/null +++ b/src/utils/utils_io_allocator.h @@ -0,0 +1,62 @@ +/* + * Copyright(c) 2019 Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause-Clear + */ + +#ifndef __UTILS_IO_ALLOCATOR_H__ +#define __UTILS_IO_ALLOCATOR_H__ + +#include "ocf/ocf_types.h" + +typedef struct ocf_io_allocator *ocf_io_allocator_t; + +struct ocf_io_allocator_ops { + int (*allocator_init)(ocf_io_allocator_t allocator, + uint32_t priv_size, const char *name); + void (*allocator_deinit)(ocf_io_allocator_t allocator); + void *(*allocator_new)(ocf_io_allocator_t allocator, + ocf_volume_t volume, ocf_queue_t queue, + uint64_t addr, uint32_t bytes, uint32_t dir); + void (*allocator_del)(ocf_io_allocator_t allocator, void *obj); +}; + +struct ocf_io_allocator_type { + struct ocf_io_allocator_ops ops; +}; + +typedef const struct ocf_io_allocator_type *ocf_io_allocator_type_t; + +struct ocf_io_allocator { + const struct ocf_io_allocator_type *type; + void *priv; +}; + +static inline void *ocf_io_allocator_new(ocf_io_allocator_t allocator, + ocf_volume_t volume, ocf_queue_t queue, + uint64_t addr, uint32_t bytes, uint32_t dir) +{ + return allocator->type->ops.allocator_new(allocator, volume, queue, + addr, bytes, dir); +} + +static inline void ocf_io_allocator_del(ocf_io_allocator_t allocator, void *obj) +{ + allocator->type->ops.allocator_del(allocator, obj); +} + +static inline int ocf_io_allocator_init(ocf_io_allocator_t allocator, + ocf_io_allocator_type_t type, uint32_t size, const char *name) + +{ + allocator->type = type; + return allocator->type->ops.allocator_init(allocator, size, name); +} + +static inline void ocf_io_allocator_deinit(ocf_io_allocator_t allocator) +{ + allocator->type->ops.allocator_deinit(allocator); +} + +ocf_io_allocator_type_t ocf_io_allocator_get_type_default(void); + +#endif /* __UTILS_IO_ALLOCATOR__ */ From e64bb50a4badb068dfdb5f6334cdd7a35ceac996 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Mon, 3 Jun 2019 11:28:03 +0200 Subject: [PATCH 6/6] Allocate io and request in single allocation Signed-off-by: Robert Baldyga --- src/engine/cache_engine.c | 13 ++- src/engine/engine_d2c.c | 2 +- src/engine/engine_discard.c | 2 +- src/engine/engine_fast.c | 4 +- src/engine/engine_pt.c | 2 +- src/engine/engine_rd.c | 2 +- src/engine/engine_wa.c | 2 +- src/engine/engine_wb.c | 2 +- src/engine/engine_wi.c | 2 +- src/engine/engine_wo.c | 2 +- src/engine/engine_wt.c | 2 +- src/ocf_core.c | 219 +++++++++++++++++++----------------- src/ocf_core_priv.h | 14 --- src/ocf_ctx_priv.h | 5 + src/ocf_io_priv.h | 2 +- src/ocf_queue.c | 6 +- src/ocf_request.c | 26 ++++- src/ocf_request.h | 22 +++- src/ocf_trace_priv.h | 35 +++--- src/utils/utils_io.c | 8 +- 20 files changed, 209 insertions(+), 163 deletions(-) diff --git a/src/engine/cache_engine.c b/src/engine/cache_engine.c index 1e0bdda..41eff2e 100644 --- a/src/engine/cache_engine.c +++ b/src/engine/cache_engine.c @@ -254,6 +254,8 @@ int ocf_engine_hndl_req(struct ocf_request *req, if (!req->io_if) return -OCF_ERR_INVAL; + ocf_req_get(req); + /* Till OCF engine is not synchronous fully need to push OCF request * to into OCF workers */ @@ -273,6 +275,8 @@ int ocf_engine_hndl_fast_req(struct ocf_request *req, if (!io_if) return -OCF_ERR_INVAL; + ocf_req_get(req); + switch (req->rw) { case OCF_READ: ret = io_if->read(req); @@ -281,9 +285,12 @@ int ocf_engine_hndl_fast_req(struct ocf_request *req, ret = io_if->write(req); break; default: - return OCF_FAST_PATH_NO; + ret = OCF_FAST_PATH_NO; } + if (ret == OCF_FAST_PATH_NO) + ocf_req_put(req); + return ret; } @@ -299,6 +306,8 @@ static void ocf_engine_hndl_2dc_req(struct ocf_request *req) void ocf_engine_hndl_discard_req(struct ocf_request *req) { + ocf_req_get(req); + if (req->d2c) { ocf_engine_hndl_2dc_req(req); return; @@ -314,6 +323,8 @@ void ocf_engine_hndl_discard_req(struct ocf_request *req) void ocf_engine_hndl_ops_req(struct ocf_request *req) { + ocf_req_get(req); + if (req->d2c) req->io_if = &IO_IFS[OCF_IO_D2C_IF]; else diff --git a/src/engine/engine_d2c.c b/src/engine/engine_d2c.c index 8728daf..337769d 100644 --- a/src/engine/engine_d2c.c +++ b/src/engine/engine_d2c.c @@ -42,7 +42,7 @@ int ocf_io_d2c(struct ocf_request *req) OCF_DEBUG_TRACE(req->cache); - ocf_io_start(req->io); + ocf_io_start(&req->ioi.io); /* Get OCF request - increase reference counter */ ocf_req_get(req); diff --git a/src/engine/engine_discard.c b/src/engine/engine_discard.c index f23938f..2b0f66b 100644 --- a/src/engine/engine_discard.c +++ b/src/engine/engine_discard.c @@ -255,7 +255,7 @@ int ocf_discard(struct ocf_request *req) { OCF_DEBUG_TRACE(req->cache); - ocf_io_start(req->io); + ocf_io_start(&req->ioi.io); if (req->rw == OCF_READ) { req->complete(req, -OCF_ERR_INVAL); diff --git a/src/engine/engine_fast.c b/src/engine/engine_fast.c index 971e410..3921104 100644 --- a/src/engine/engine_fast.c +++ b/src/engine/engine_fast.c @@ -128,7 +128,7 @@ int ocf_read_fast(struct ocf_request *req) hit = ocf_engine_is_hit(req); if (hit) { - ocf_io_start(req->io); + ocf_io_start(&req->ioi.io); lock = ocf_req_trylock_rd(req); } @@ -198,7 +198,7 @@ int ocf_write_fast(struct ocf_request *req) mapped = ocf_engine_is_mapped(req); if (mapped) { - ocf_io_start(req->io); + ocf_io_start(&req->ioi.io); lock = ocf_req_trylock_wr(req); } diff --git a/src/engine/engine_pt.c b/src/engine/engine_pt.c index 9444421..852b953 100644 --- a/src/engine/engine_pt.c +++ b/src/engine/engine_pt.c @@ -110,7 +110,7 @@ int ocf_read_pt(struct ocf_request *req) OCF_DEBUG_TRACE(req->cache); - ocf_io_start(req->io); + ocf_io_start(&req->ioi.io); /* Get OCF request - increase reference counter */ ocf_req_get(req); diff --git a/src/engine/engine_rd.c b/src/engine/engine_rd.c index 0a58a9e..d04e289 100644 --- a/src/engine/engine_rd.c +++ b/src/engine/engine_rd.c @@ -217,7 +217,7 @@ int ocf_read_generic(struct ocf_request *req) int lock = OCF_LOCK_NOT_ACQUIRED; struct ocf_cache *cache = req->cache; - ocf_io_start(req->io); + ocf_io_start(&req->ioi.io); if (env_atomic_read(&cache->pending_read_misses_list_blocked)) { /* There are conditions to bypass IO */ diff --git a/src/engine/engine_wa.c b/src/engine/engine_wa.c index 2d8a5e8..5613445 100644 --- a/src/engine/engine_wa.c +++ b/src/engine/engine_wa.c @@ -40,7 +40,7 @@ int ocf_write_wa(struct ocf_request *req) { struct ocf_cache *cache = req->cache; - ocf_io_start(req->io); + ocf_io_start(&req->ioi.io); /* Get OCF request - increase reference counter */ ocf_req_get(req); diff --git a/src/engine/engine_wb.c b/src/engine/engine_wb.c index d7a8c08..a3e0063 100644 --- a/src/engine/engine_wb.c +++ b/src/engine/engine_wb.c @@ -172,7 +172,7 @@ int ocf_write_wb(struct ocf_request *req) int lock = OCF_LOCK_NOT_ACQUIRED; struct ocf_cache *cache = req->cache; - ocf_io_start(req->io); + ocf_io_start(&req->ioi.io); /* Not sure if we need this. */ ocf_req_get(req); diff --git a/src/engine/engine_wi.c b/src/engine/engine_wi.c index 832d9b8..1fdae6b 100644 --- a/src/engine/engine_wi.c +++ b/src/engine/engine_wi.c @@ -140,7 +140,7 @@ int ocf_write_wi(struct ocf_request *req) OCF_DEBUG_TRACE(req->cache); - ocf_io_start(req->io); + ocf_io_start(&req->ioi.io); /* Get OCF request - increase reference counter */ ocf_req_get(req); diff --git a/src/engine/engine_wo.c b/src/engine/engine_wo.c index 13f09fa..f4fba5f 100644 --- a/src/engine/engine_wo.c +++ b/src/engine/engine_wo.c @@ -207,7 +207,7 @@ int ocf_read_wo(struct ocf_request *req) OCF_DEBUG_TRACE(req->cache); - ocf_io_start(req->io); + ocf_io_start(&req->ioi.io); /* Get OCF request - increase reference counter */ ocf_req_get(req); diff --git a/src/engine/engine_wt.c b/src/engine/engine_wt.c index a5be349..0e3adf3 100644 --- a/src/engine/engine_wt.c +++ b/src/engine/engine_wt.c @@ -167,7 +167,7 @@ int ocf_write_wt(struct ocf_request *req) int lock = OCF_LOCK_NOT_ACQUIRED; struct ocf_cache *cache = req->cache; - ocf_io_start(req->io); + ocf_io_start(&req->ioi.io); /* Get OCF request - increase reference counter */ ocf_req_get(req); diff --git a/src/ocf_core.c b/src/ocf_core.c index e163bb7..6446c6c 100644 --- a/src/ocf_core.c +++ b/src/ocf_core.c @@ -134,9 +134,12 @@ int ocf_core_visit(ocf_cache_t cache, ocf_core_visitor_t visitor, void *cntx, /* *** HELPER FUNCTIONS *** */ -static inline struct ocf_core_io *ocf_io_to_core_io(struct ocf_io *io) +static inline struct ocf_request *ocf_io_to_req(struct ocf_io *io) { - return ocf_io_get_priv(io); + struct ocf_io_internal *ioi; + + ioi = container_of(io, struct ocf_io_internal, io); + return container_of(ioi, struct ocf_request, ioi); } static inline ocf_core_t ocf_volume_to_core(ocf_volume_t volume) @@ -146,21 +149,19 @@ static inline ocf_core_t ocf_volume_to_core(ocf_volume_t volume) return core_volume->core; } -static inline int ocf_io_set_dirty(ocf_cache_t cache, - struct ocf_core_io *core_io) +static inline int ocf_io_set_dirty(struct ocf_request *req) { - core_io->dirty = !!ocf_refcnt_inc(&cache->refcnt.dirty); - return core_io->dirty ? 0 : -EBUSY; + 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_core_io *core_io, - ocf_cache_t cache) +static inline void dec_counter_if_req_was_dirty(struct ocf_request *req) { - if (!core_io->dirty) + if (!req->dirty) return; - core_io->dirty = 0; - ocf_refcnt_dec(&cache->refcnt.dirty); + req->dirty = 0; + ocf_refcnt_dec(&req->cache->refcnt.dirty); } static inline int ocf_core_validate_io(struct ocf_io *io) @@ -195,21 +196,20 @@ static inline int ocf_core_validate_io(struct ocf_io *io) static void ocf_req_complete(struct ocf_request *req, int error) { /* Log trace */ - ocf_trace_io_cmpl(ocf_io_to_core_io(req->io), req->cache); + ocf_trace_io_cmpl(req); /* Complete IO */ - ocf_io_end(req->io, error); + ocf_io_end(&req->ioi.io, error); - dec_counter_if_req_was_dirty(ocf_io_to_core_io(req->io), req->cache); + dec_counter_if_req_was_dirty(req); /* Invalidate OCF IO, it is not valid after completion */ - ocf_io_put(req->io); - req->io = NULL; + ocf_io_put(&req->ioi.io); } void ocf_core_submit_io_mode(struct ocf_io *io, ocf_cache_mode_t cache_mode) { - struct ocf_core_io *core_io; + struct ocf_request *req; ocf_req_cache_mode_t req_cache_mode; ocf_core_t core; ocf_cache_t cache; @@ -219,16 +219,15 @@ void ocf_core_submit_io_mode(struct ocf_io *io, ocf_cache_mode_t cache_mode) ret = ocf_core_validate_io(io); if (ret < 0) { - io->end(io, ret); + ocf_io_end(io, ret); return; } - core_io = ocf_io_to_core_io(io); - + req = ocf_io_to_req(io); core = ocf_volume_to_core(ocf_io_get_volume(io)); cache = ocf_core_get_cache(core); - ocf_trace_init_io(core_io, cache); + ocf_trace_init_io(req); if (unlikely(!env_bit_test(ocf_cache_state_running, &cache->cache_state))) { @@ -245,50 +244,40 @@ void ocf_core_submit_io_mode(struct ocf_io *io, ocf_cache_mode_t cache_mode) if (io->dir == OCF_WRITE && ocf_req_cache_mode_has_lazy_write(req_cache_mode) && - ocf_io_set_dirty(cache, core_io)) { + ocf_io_set_dirty(req)) { req_cache_mode = ocf_req_cache_mode_wt; } - core_io->req = ocf_req_new(io->io_queue, core, io->addr, io->bytes, - io->dir); - if (!core_io->req) { - dec_counter_if_req_was_dirty(core_io, cache); - io->end(io, -OCF_ERR_NO_MEM); - return; - } - - if (core_io->req->d2c) + if (req->d2c) req_cache_mode = ocf_req_cache_mode_d2c; - core_io->req->part_id = ocf_part_class2id(cache, io->io_class); - core_io->req->data = core_io->data; - core_io->req->complete = ocf_req_complete; - core_io->req->io = io; + req->core = core; + req->complete = ocf_req_complete; + req->part_id = ocf_part_class2id(cache, io->io_class); - ocf_seq_cutoff_update(core, core_io->req); + ocf_seq_cutoff_update(core, req); ocf_core_update_stats(core, io); if (io->dir == OCF_WRITE) - ocf_trace_io(core_io, ocf_event_operation_wr, cache); + ocf_trace_io(req, ocf_event_operation_wr); else if (io->dir == OCF_READ) - ocf_trace_io(core_io, ocf_event_operation_rd, cache); + ocf_trace_io(req, ocf_event_operation_rd); ocf_io_get(io); - ret = ocf_engine_hndl_req(core_io->req, req_cache_mode); + + ret = ocf_engine_hndl_req(req, req_cache_mode); if (ret) { - dec_counter_if_req_was_dirty(core_io, cache); - ocf_req_put(core_io->req); - io->end(io, ret); + dec_counter_if_req_was_dirty(req); + ocf_io_end(io, ret); } } int ocf_core_submit_io_fast(struct ocf_io *io) { - struct ocf_core_io *core_io; + struct ocf_request *req; ocf_req_cache_mode_t req_cache_mode; struct ocf_event_io trace_event; - struct ocf_request *req; ocf_core_t core; ocf_cache_t cache; int fast; @@ -300,8 +289,7 @@ int ocf_core_submit_io_fast(struct ocf_io *io) if (ret < 0) return ret; - core_io = ocf_io_to_core_io(io); - + req = ocf_io_to_req(io); core = ocf_volume_to_core(ocf_io_get_volume(io)); cache = ocf_core_get_cache(core); @@ -311,11 +299,17 @@ int ocf_core_submit_io_fast(struct ocf_io *io) return 0; } + 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); if (io->dir == OCF_WRITE && ocf_req_cache_mode_has_lazy_write(req_cache_mode) && - ocf_io_set_dirty(cache, core_io)) { + ocf_io_set_dirty(req)) { req_cache_mode = ocf_req_cache_mode_wt; } @@ -335,35 +329,22 @@ int ocf_core_submit_io_fast(struct ocf_io *io) req_cache_mode = ocf_req_cache_mode_fast; } - core_io->req = ocf_req_new_extended(io->io_queue, core, - io->addr, io->bytes, io->dir); - // We need additional pointer to req in case completion arrives before - // we leave this function and core_io is freed - req = core_io->req; - - if (!req) { - dec_counter_if_req_was_dirty(core_io, cache); - io->end(io, -OCF_ERR_NO_MEM); - return 0; - } if (req->d2c) { - dec_counter_if_req_was_dirty(core_io, cache); - ocf_req_put(req); + dec_counter_if_req_was_dirty(req); return -OCF_ERR_IO; } - req->part_id = ocf_part_class2id(cache, io->io_class); - req->data = core_io->data; + req->core = core; req->complete = ocf_req_complete; - req->io = io; + req->part_id = ocf_part_class2id(cache, io->io_class); ocf_core_update_stats(core, io); if (cache->trace.trace_callback) { if (io->dir == OCF_WRITE) - ocf_trace_prep_io_event(&trace_event, core_io, ocf_event_operation_wr); + ocf_trace_prep_io_event(&trace_event, req, ocf_event_operation_wr); else if (io->dir == OCF_READ) - ocf_trace_prep_io_event(&trace_event, core_io, ocf_event_operation_rd); + ocf_trace_prep_io_event(&trace_event, req, ocf_event_operation_rd); } ocf_io_get(io); @@ -375,10 +356,9 @@ int ocf_core_submit_io_fast(struct ocf_io *io) return 0; } - dec_counter_if_req_was_dirty(core_io, cache); + dec_counter_if_req_was_dirty(req); ocf_io_put(io); - ocf_req_put(req); return -OCF_ERR_IO; } @@ -389,7 +369,7 @@ static void ocf_core_volume_submit_io(struct ocf_io *io) static void ocf_core_volume_submit_flush(struct ocf_io *io) { - struct ocf_core_io *core_io; + struct ocf_request *req; ocf_core_t core; ocf_cache_t cache; int ret; @@ -402,8 +382,7 @@ static void ocf_core_volume_submit_flush(struct ocf_io *io) return; } - core_io = ocf_io_to_core_io(io); - + req = ocf_io_to_req(io); core = ocf_volume_to_core(ocf_io_get_volume(io)); cache = ocf_core_get_cache(core); @@ -413,25 +392,18 @@ static void ocf_core_volume_submit_flush(struct ocf_io *io) return; } - core_io->req = ocf_req_new(io->io_queue, core, io->addr, io->bytes, - io->dir); - if (!core_io->req) { - ocf_io_end(io, -OCF_ERR_NO_MEM); - return; - } + req->core = core; + req->complete = ocf_req_complete; - core_io->req->complete = ocf_req_complete; - core_io->req->io = io; - core_io->req->data = core_io->data; - - ocf_trace_io(core_io, ocf_event_operation_flush, cache); + ocf_trace_io(req, ocf_event_operation_flush); ocf_io_get(io); - ocf_engine_hndl_ops_req(core_io->req); + + ocf_engine_hndl_ops_req(req); } static void ocf_core_volume_submit_discard(struct ocf_io *io) { - struct ocf_core_io *core_io; + struct ocf_request *req; ocf_core_t core; ocf_cache_t cache; int ret; @@ -444,8 +416,7 @@ static void ocf_core_volume_submit_discard(struct ocf_io *io) return; } - core_io = ocf_io_to_core_io(io); - + req = ocf_io_to_req(io); core = ocf_volume_to_core(ocf_io_get_volume(io)); cache = ocf_core_get_cache(core); @@ -455,20 +426,19 @@ static void ocf_core_volume_submit_discard(struct ocf_io *io) return; } - core_io->req = ocf_req_new_discard(io->io_queue, core, - io->addr, io->bytes, OCF_WRITE); - if (!core_io->req) { + ret = ocf_req_alloc_map_discard(req); + if (ret) { ocf_io_end(io, -OCF_ERR_NO_MEM); return; } - core_io->req->complete = ocf_req_complete; - core_io->req->io = io; - core_io->req->data = core_io->data; + req->core = core; + req->complete = ocf_req_complete; - ocf_trace_io(core_io, ocf_event_operation_discard, cache); + ocf_trace_io(req, ocf_event_operation_discard); ocf_io_get(io); - ocf_engine_hndl_discard_req(core_io->req); + + ocf_engine_hndl_discard_req(req); } /* *** VOLUME OPS *** */ @@ -508,32 +478,32 @@ static uint64_t ocf_core_volume_get_byte_length(ocf_volume_t volume) static int ocf_core_io_set_data(struct ocf_io *io, ctx_data_t *data, uint32_t offset) { - struct ocf_core_io *core_io; + struct ocf_request *req; OCF_CHECK_NULL(io); if (!data || offset) return -OCF_ERR_INVAL; - core_io = ocf_io_to_core_io(io); - core_io->data = data; + req = ocf_io_to_req(io); + req->data = data; return 0; } static ctx_data_t *ocf_core_io_get_data(struct ocf_io *io) { - struct ocf_core_io *core_io; + struct ocf_request *req; OCF_CHECK_NULL(io); - core_io = ocf_io_to_core_io(io); - return core_io->data; + req = ocf_io_to_req(io); + return req->data; } const struct ocf_volume_properties ocf_core_volume_properties = { .name = "OCF Core", - .io_priv_size = sizeof(struct ocf_core_io), + .io_priv_size = 0, /* Not used - custom allocator */ .volume_priv_size = sizeof(struct ocf_core_volume), .caps = { .atomic_writes = 0, @@ -555,10 +525,55 @@ const struct ocf_volume_properties ocf_core_volume_properties = { }, }; +static int ocf_core_io_allocator_init(ocf_io_allocator_t allocator, + uint32_t priv_size, const char *name) +{ + return 0; +} + +static void ocf_core_io_allocator_deinit(ocf_io_allocator_t allocator) +{ +} + +static void *ocf_core_io_allocator_new(ocf_io_allocator_t allocator, + ocf_volume_t volume, ocf_queue_t queue, + uint64_t addr, uint32_t bytes, uint32_t dir) +{ + struct ocf_request *req; + + req = ocf_req_new(queue, NULL, addr, bytes, dir); + if (!req) + return NULL; + + return &req->ioi; +} + +static void ocf_core_io_allocator_del(ocf_io_allocator_t allocator, void *obj) +{ + struct ocf_request *req; + + req = container_of(obj, struct ocf_request, ioi); + ocf_req_put(req); +} + +const struct ocf_io_allocator_type ocf_core_io_allocator_type = { + .ops = { + .allocator_init = ocf_core_io_allocator_init, + .allocator_deinit = ocf_core_io_allocator_deinit, + .allocator_new = ocf_core_io_allocator_new, + .allocator_del = ocf_core_io_allocator_del, + }, +}; + +const struct ocf_volume_extended ocf_core_volume_extended = { + .allocator_type = &ocf_core_io_allocator_type, +}; + int ocf_core_volume_type_init(ocf_ctx_t ctx) { - return ocf_ctx_register_volume_type(ctx, 0, - &ocf_core_volume_properties); + return ocf_ctx_register_volume_type_extended(ctx, 0, + &ocf_core_volume_properties, + &ocf_core_volume_extended); } void ocf_core_volume_type_deinit(ocf_ctx_t ctx) diff --git a/src/ocf_core_priv.h b/src/ocf_core_priv.h index af12013..0030e11 100644 --- a/src/ocf_core_priv.h +++ b/src/ocf_core_priv.h @@ -18,20 +18,6 @@ #define ocf_core_log(core, lvl, fmt, ...) \ ocf_core_log_prefix(core, lvl, ": ", fmt, ##__VA_ARGS__) -struct ocf_core_io { - bool dirty; - /*!< Indicates if io leaves dirty data */ - - struct ocf_request *req; - ctx_data_t *data; - - log_sid_t sid; - /*!< Sequence ID */ - - uint64_t timestamp; - /*!< Timestamp */ -}; - struct ocf_metadata_uuid { uint32_t size; uint8_t data[OCF_VOLUME_UUID_MAX_SIZE]; diff --git a/src/ocf_ctx_priv.h b/src/ocf_ctx_priv.h index 3de4a51..e3a2153 100644 --- a/src/ocf_ctx_priv.h +++ b/src/ocf_ctx_priv.h @@ -9,6 +9,7 @@ #include "ocf_env.h" #include "ocf/ocf_ctx.h" #include "ocf_logger_priv.h" +#include "ocf_volume_priv.h" #define OCF_VOLUME_TYPE_MAX 8 @@ -45,6 +46,10 @@ struct ocf_ctx { #define ocf_log_stack_trace(ctx) \ ocf_log_stack_trace_raw(&ctx->logger) +int ocf_ctx_register_volume_type_extended(ocf_ctx_t ctx, uint8_t type_id, + const struct ocf_volume_properties *properties, + const struct ocf_volume_extended *extended); + /** * @name Environment data buffer operations wrappers * @{ diff --git a/src/ocf_io_priv.h b/src/ocf_io_priv.h index 4735b5c..175bd3b 100644 --- a/src/ocf_io_priv.h +++ b/src/ocf_io_priv.h @@ -7,7 +7,6 @@ #define __OCF_IO_PRIV_H__ #include "ocf/ocf.h" -#include "ocf_request.h" #include "utils/utils_io_allocator.h" struct ocf_io_meta { @@ -17,6 +16,7 @@ struct ocf_io_meta { struct ocf_request *req; }; + struct ocf_io_internal { struct ocf_io_meta meta; struct ocf_io io; diff --git a/src/ocf_queue.c b/src/ocf_queue.c index 04cebae..ffd034f 100644 --- a/src/ocf_queue.c +++ b/src/ocf_queue.c @@ -90,10 +90,10 @@ void ocf_queue_run_single(ocf_queue_t q) if (!io_req) return; - if (io_req->io && io_req->io->handle) - io_req->io->handle(io_req->io, io_req); + if (io_req->ioi.io.handle) + io_req->ioi.io.handle(&io_req->ioi.io, io_req); else - ocf_io_handle(io_req->io, io_req); + ocf_io_handle(&io_req->ioi.io, io_req); } void ocf_queue_run(ocf_queue_t q) diff --git a/src/ocf_request.c b/src/ocf_request.c index 6de4b40..57cc838 100644 --- a/src/ocf_request.c +++ b/src/ocf_request.c @@ -201,6 +201,10 @@ struct ocf_request *ocf_req_new(ocf_queue_t queue, ocf_core_t core, req->rw = rw; req->part_id = PARTITION_DEFAULT; + req->discard.sector = BYTES_TO_SECTORS(addr); + req->discard.nr_sects = BYTES_TO_SECTORS(bytes); + req->discard.handled = 0; + return req; } @@ -218,6 +222,24 @@ int ocf_req_alloc_map(struct ocf_request *req) return 0; } +int ocf_req_alloc_map_discard(struct ocf_request *req) +{ + if (req->byte_length <= MAX_TRIM_RQ_SIZE) + return ocf_req_alloc_map(req); + + /* + * NOTE: For cache line size bigger than 8k a single-allocation mapping + * can handle more than MAX_TRIM_RQ_SIZE, so for these cache line sizes + * discard request uses only part of the mapping array. + */ + req->byte_length = MAX_TRIM_RQ_SIZE; + req->core_line_last = ocf_bytes_2_lines(req->cache, + req->byte_position + req->byte_length - 1); + req->core_line_count = req->core_line_last - req->core_line_first + 1; + + return ocf_req_alloc_map(req); +} + struct ocf_request *ocf_req_new_extended(ocf_queue_t queue, ocf_core_t core, uint64_t addr, uint32_t bytes, int rw) { @@ -243,10 +265,6 @@ struct ocf_request *ocf_req_new_discard(ocf_queue_t queue, ocf_core_t core, if (!req) return NULL; - req->discard.sector = BYTES_TO_SECTORS(addr); - req->discard.nr_sects = BYTES_TO_SECTORS(bytes); - req->discard.handled = 0; - return req; } diff --git a/src/ocf_request.h b/src/ocf_request.h index 605216e..858577d 100644 --- a/src/ocf_request.h +++ b/src/ocf_request.h @@ -104,6 +104,9 @@ struct ocf_req_discard_info { * @brief OCF IO request */ struct ocf_request { + struct ocf_io_internal ioi; + /*!< OCF IO associated with request */ + env_atomic ref_count; /*!< Reference usage count, once OCF request reaches zero it * will be de-initialed. Get/Put method are intended to modify @@ -180,6 +183,12 @@ struct ocf_request { uint8_t master_io_req_type : 2; /*!< Core device request context type */ + log_sid_t sid; + /*!< Tracing sequence ID */ + + uint64_t timestamp; + /*!< Tracing timestamp */ + ocf_queue_t io_queue; /*!< I/O queue handle for which request should be submitted */ @@ -192,9 +201,6 @@ struct ocf_request { void (*complete)(struct ocf_request *ocf_req, int error); /*!< Request completion function */ - struct ocf_io *io; - /*!< OCF IO associated with request */ - struct ocf_req_discard_info discard; struct ocf_map_info *map; @@ -243,6 +249,16 @@ struct ocf_request *ocf_req_new(ocf_queue_t queue, ocf_core_t core, */ int ocf_req_alloc_map(struct ocf_request *req); +/** + * @brief Allocate OCF request map for discard request + * + * @param req OCF request + * + * @retval 0 Allocation succeed + * @retval non-zero Allocation failed + */ +int ocf_req_alloc_map_discard(struct ocf_request *req); + /** * @brief Allocate new OCF request with NOIO map allocation for huge request * diff --git a/src/ocf_trace_priv.h b/src/ocf_trace_priv.h index ae4cab0..e45e69d 100644 --- a/src/ocf_trace_priv.h +++ b/src/ocf_trace_priv.h @@ -40,19 +40,17 @@ static inline uint64_t ocf_trace_seq_id(ocf_cache_t cache) return env_atomic64_inc_return(&cache->trace.trace_seq_ref); } -static inline void ocf_trace_init_io(struct ocf_core_io *io, ocf_cache_t cache) +static inline void ocf_trace_init_io(struct ocf_request *req) { - io->timestamp = env_ticks_to_nsecs(env_get_tick_count()); - io->sid = ocf_trace_seq_id(cache); + req->timestamp = env_ticks_to_nsecs(env_get_tick_count()); + req->sid = ocf_trace_seq_id(req->cache); } static inline void ocf_trace_prep_io_event(struct ocf_event_io *ev, - struct ocf_core_io *io, ocf_event_operation_t op) + struct ocf_request *req, ocf_event_operation_t op) { - struct ocf_request *req = io->req; - - ocf_event_init_hdr(&ev->hdr, ocf_event_type_io, io->sid, - io->timestamp, sizeof(*ev)); + ocf_event_init_hdr(&ev->hdr, ocf_event_type_io, req->sid, + req->timestamp, sizeof(*ev)); ev->addr = req->byte_position; if (op == ocf_event_operation_discard) @@ -63,7 +61,7 @@ static inline void ocf_trace_prep_io_event(struct ocf_event_io *ev, ev->operation = op; ev->core_id = ocf_core_get_id(req->core); - ev->io_class = req->io->io_class; + ev->io_class = req->ioi.io.io_class; } static inline void ocf_trace_push(ocf_queue_t queue, void *trace, uint32_t size) @@ -103,34 +101,31 @@ static inline void ocf_trace_push(ocf_queue_t queue, void *trace, uint32_t size) env_atomic64_dec(&queue->trace_ref_cntr); } -static inline void ocf_trace_io(struct ocf_core_io *io, ocf_event_operation_t dir, ocf_cache_t cache) +static inline void ocf_trace_io(struct ocf_request *req, + ocf_event_operation_t dir) { struct ocf_event_io ev; - struct ocf_request *req; - if (!cache->trace.trace_callback) + if (!req->cache->trace.trace_callback) return; - req = io->req; - ocf_trace_prep_io_event(&ev, io, dir); + ocf_trace_prep_io_event(&ev, req, dir); ocf_trace_push(req->io_queue, &ev, sizeof(ev)); } -static inline void ocf_trace_io_cmpl(struct ocf_core_io *io, ocf_cache_t cache) +static inline void ocf_trace_io_cmpl(struct ocf_request *req) { struct ocf_event_io_cmpl ev; - struct ocf_request *req; - if (!cache->trace.trace_callback) + if (!req->cache->trace.trace_callback) return; - req = io->req; ocf_event_init_hdr(&ev.hdr, ocf_event_type_io_cmpl, - ocf_trace_seq_id(cache), + ocf_trace_seq_id(req->cache), env_ticks_to_nsecs(env_get_tick_count()), sizeof(ev)); - ev.rsid = io->sid; + ev.rsid = req->sid; ev.is_hit = ocf_engine_is_hit(req); ocf_trace_push(req->io_queue, &ev, sizeof(ev)); diff --git a/src/utils/utils_io.c b/src/utils/utils_io.c index c658a47..c57e731 100644 --- a/src/utils/utils_io.c +++ b/src/utils/utils_io.c @@ -228,8 +228,8 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache, uint64_t size, unsigned int reqs, ocf_req_end_t callback) { struct ocf_counters_block *cache_stats; - uint64_t flags = req->io ? req->io->flags : 0; - uint32_t class = req->io ? req->io->io_class : 0; + uint64_t flags = req->ioi.io.flags; + uint32_t class = req->ioi.io.io_class; uint64_t addr, bytes, total_bytes = 0; struct ocf_io *io; int err; @@ -333,8 +333,8 @@ void ocf_submit_volume_req(ocf_volume_t volume, struct ocf_request *req, ocf_req_end_t callback) { struct ocf_counters_block *core_stats; - uint64_t flags = req->io ? req->io->flags : 0; - uint32_t class = req->io ? req->io->io_class : 0; + uint64_t flags = req->ioi.io.flags; + uint32_t class = req->ioi.io.io_class; int dir = req->rw; struct ocf_io *io; int err;