Merge pull request #216 from robertbaldyga/io-and-req-in-single-allocation
Allocate io and req in single allocation
This commit is contained in:
commit
232f0cd8d7
10
doc/HOME.md
10
doc/HOME.md
@ -263,19 +263,17 @@ void read_end(struct ocf_io *io, int error)
|
|||||||
ocf_io_put(io);
|
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 */
|
/* 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) {
|
if (!io) {
|
||||||
/* Cannot allocate IO */
|
/* Cannot allocate IO */
|
||||||
return -ENOMEM;
|
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 */
|
/* Set completion context and function */
|
||||||
ocf_io_set_cmpl(io, NULL, NULL, read_end);
|
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 */
|
/* Send IO requests to the cache */
|
||||||
ocf_submit_io(io);
|
ocf_core_submit_io(io);
|
||||||
|
|
||||||
/* Just it */
|
/* Just it */
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -260,16 +260,12 @@ int submit_io(ocf_core_t core, struct volume_data *data,
|
|||||||
struct ocf_io *io;
|
struct ocf_io *io;
|
||||||
|
|
||||||
/* Allocate new 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)
|
if (!io)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* Setup io address, lenght, direction, flags and ioclass */
|
|
||||||
ocf_io_configure(io, addr, len, dir, 0, 0);
|
|
||||||
/* Assign data to io */
|
/* Assign data to io */
|
||||||
ocf_io_set_data(io, data, 0);
|
ocf_io_set_data(io, data, 0);
|
||||||
/* Setup io queue to */
|
|
||||||
ocf_io_set_queue(io, cache_priv->io_queue);
|
|
||||||
/* Setup completion function */
|
/* Setup completion function */
|
||||||
ocf_io_set_cmpl(io, NULL, NULL, cmpl);
|
ocf_io_set_cmpl(io, NULL, NULL, cmpl);
|
||||||
/* Submit io */
|
/* Submit io */
|
||||||
|
@ -48,7 +48,7 @@ static void volume_submit_io(struct ocf_io *io)
|
|||||||
struct myvolume *myvolume;
|
struct myvolume *myvolume;
|
||||||
|
|
||||||
data = ocf_io_get_data(io);
|
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) {
|
if (io->dir == OCF_WRITE) {
|
||||||
memcpy(myvolume->mem + io->addr,
|
memcpy(myvolume->mem + io->addr,
|
||||||
|
@ -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
|
* @brief Allocate new ocf_io
|
||||||
*
|
*
|
||||||
* @param[in] core Core object
|
* @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
|
* @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);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
59
inc/ocf_io.h
59
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
|
* @brief OCF IO main structure
|
||||||
*/
|
*/
|
||||||
struct ocf_io {
|
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
|
* @brief OCF IO destination address
|
||||||
*/
|
*/
|
||||||
@ -150,26 +140,6 @@ struct ocf_io_ops {
|
|||||||
*/
|
*/
|
||||||
void *ocf_io_get_priv(struct ocf_io *io);
|
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
|
* @brief Increase reference counter in OCF IO
|
||||||
*
|
*
|
||||||
@ -237,11 +207,7 @@ static inline void ocf_io_set_handle(struct ocf_io *io, ocf_handle_io_t fn)
|
|||||||
* @retval 0 Data set up successfully
|
* @retval 0 Data set up successfully
|
||||||
* @retval Non-zero Data set up failure
|
* @retval Non-zero Data set up failure
|
||||||
*/
|
*/
|
||||||
static inline int ocf_io_set_data(struct ocf_io *io, ctx_data_t *data,
|
int ocf_io_set_data(struct ocf_io *io, ctx_data_t *data, uint32_t offset);
|
||||||
uint32_t offset)
|
|
||||||
{
|
|
||||||
return io->ops->set_data(io, data, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get data vector from OCF IO
|
* @brief Get data vector from OCF IO
|
||||||
@ -252,21 +218,7 @@ static inline int ocf_io_set_data(struct ocf_io *io, ctx_data_t *data,
|
|||||||
*
|
*
|
||||||
* @return Data vector from IO
|
* @return Data vector from IO
|
||||||
*/
|
*/
|
||||||
static inline ctx_data_t *ocf_io_get_data(struct ocf_io *io)
|
ctx_data_t *ocf_io_get_data(struct ocf_io *io);
|
||||||
{
|
|
||||||
return io->ops->get_data(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
|
* @brief Handle IO in cache engine
|
||||||
@ -276,4 +228,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);
|
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__ */
|
#endif /* __OCF_IO_H__ */
|
||||||
|
@ -65,7 +65,7 @@ struct ocf_volume_type;
|
|||||||
/**
|
/**
|
||||||
* @brief handle to 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
|
* @brief handle to volume uuid
|
||||||
|
@ -256,10 +256,19 @@ int ocf_volume_is_atomic(ocf_volume_t volume);
|
|||||||
* @brief Allocate new io
|
* @brief Allocate new io
|
||||||
*
|
*
|
||||||
* @param[in] volume Volume
|
* @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
|
* @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
|
* @brief Submit io to volume
|
||||||
|
@ -254,6 +254,8 @@ int ocf_engine_hndl_req(struct ocf_request *req,
|
|||||||
if (!req->io_if)
|
if (!req->io_if)
|
||||||
return -OCF_ERR_INVAL;
|
return -OCF_ERR_INVAL;
|
||||||
|
|
||||||
|
ocf_req_get(req);
|
||||||
|
|
||||||
/* Till OCF engine is not synchronous fully need to push OCF request
|
/* Till OCF engine is not synchronous fully need to push OCF request
|
||||||
* to into OCF workers
|
* to into OCF workers
|
||||||
*/
|
*/
|
||||||
@ -273,6 +275,8 @@ int ocf_engine_hndl_fast_req(struct ocf_request *req,
|
|||||||
if (!io_if)
|
if (!io_if)
|
||||||
return -OCF_ERR_INVAL;
|
return -OCF_ERR_INVAL;
|
||||||
|
|
||||||
|
ocf_req_get(req);
|
||||||
|
|
||||||
switch (req->rw) {
|
switch (req->rw) {
|
||||||
case OCF_READ:
|
case OCF_READ:
|
||||||
ret = io_if->read(req);
|
ret = io_if->read(req);
|
||||||
@ -281,9 +285,12 @@ int ocf_engine_hndl_fast_req(struct ocf_request *req,
|
|||||||
ret = io_if->write(req);
|
ret = io_if->write(req);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return OCF_FAST_PATH_NO;
|
ret = OCF_FAST_PATH_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret == OCF_FAST_PATH_NO)
|
||||||
|
ocf_req_put(req);
|
||||||
|
|
||||||
return ret;
|
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)
|
void ocf_engine_hndl_discard_req(struct ocf_request *req)
|
||||||
{
|
{
|
||||||
|
ocf_req_get(req);
|
||||||
|
|
||||||
if (req->d2c) {
|
if (req->d2c) {
|
||||||
ocf_engine_hndl_2dc_req(req);
|
ocf_engine_hndl_2dc_req(req);
|
||||||
return;
|
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)
|
void ocf_engine_hndl_ops_req(struct ocf_request *req)
|
||||||
{
|
{
|
||||||
|
ocf_req_get(req);
|
||||||
|
|
||||||
if (req->d2c)
|
if (req->d2c)
|
||||||
req->io_if = &IO_IFS[OCF_IO_D2C_IF];
|
req->io_if = &IO_IFS[OCF_IO_D2C_IF];
|
||||||
else
|
else
|
||||||
|
@ -42,7 +42,7 @@ int ocf_io_d2c(struct ocf_request *req)
|
|||||||
|
|
||||||
OCF_DEBUG_TRACE(req->cache);
|
OCF_DEBUG_TRACE(req->cache);
|
||||||
|
|
||||||
ocf_io_start(req->io);
|
ocf_io_start(&req->ioi.io);
|
||||||
|
|
||||||
/* Get OCF request - increase reference counter */
|
/* Get OCF request - increase reference counter */
|
||||||
ocf_req_get(req);
|
ocf_req_get(req);
|
||||||
|
@ -71,19 +71,17 @@ static int _ocf_discard_core(struct ocf_request *req)
|
|||||||
{
|
{
|
||||||
struct ocf_io *io;
|
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) {
|
if (!io) {
|
||||||
_ocf_discard_complete_req(req, -OCF_ERR_NO_MEM);
|
_ocf_discard_complete_req(req, -OCF_ERR_NO_MEM);
|
||||||
return -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_cmpl(io, req, NULL, _ocf_discard_core_complete);
|
||||||
ocf_io_set_data(io, req->data, 0);
|
ocf_io_set_data(io, req->data, 0);
|
||||||
ocf_io_set_queue(io, req->io_queue);
|
|
||||||
|
|
||||||
ocf_volume_submit_discard(io);
|
ocf_volume_submit_discard(io);
|
||||||
|
|
||||||
@ -111,16 +109,15 @@ static int _ocf_discard_flush_cache(struct ocf_request *req)
|
|||||||
{
|
{
|
||||||
struct ocf_io *io;
|
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) {
|
if (!io) {
|
||||||
ocf_metadata_error(req->cache);
|
ocf_metadata_error(req->cache);
|
||||||
_ocf_discard_complete_req(req, -OCF_ERR_NO_MEM);
|
_ocf_discard_complete_req(req, -OCF_ERR_NO_MEM);
|
||||||
return -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_cmpl(io, req, NULL, _ocf_discard_cache_flush_complete);
|
||||||
ocf_io_set_queue(io, req->io_queue);
|
|
||||||
|
|
||||||
ocf_volume_submit_flush(io);
|
ocf_volume_submit_flush(io);
|
||||||
|
|
||||||
@ -260,7 +257,7 @@ int ocf_discard(struct ocf_request *req)
|
|||||||
{
|
{
|
||||||
OCF_DEBUG_TRACE(req->cache);
|
OCF_DEBUG_TRACE(req->cache);
|
||||||
|
|
||||||
ocf_io_start(req->io);
|
ocf_io_start(&req->ioi.io);
|
||||||
|
|
||||||
if (req->rw == OCF_READ) {
|
if (req->rw == OCF_READ) {
|
||||||
req->complete(req, -OCF_ERR_INVAL);
|
req->complete(req, -OCF_ERR_INVAL);
|
||||||
|
@ -128,7 +128,7 @@ int ocf_read_fast(struct ocf_request *req)
|
|||||||
|
|
||||||
hit = ocf_engine_is_hit(req);
|
hit = ocf_engine_is_hit(req);
|
||||||
if (hit) {
|
if (hit) {
|
||||||
ocf_io_start(req->io);
|
ocf_io_start(&req->ioi.io);
|
||||||
lock = ocf_req_trylock_rd(req);
|
lock = ocf_req_trylock_rd(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ int ocf_write_fast(struct ocf_request *req)
|
|||||||
|
|
||||||
mapped = ocf_engine_is_mapped(req);
|
mapped = ocf_engine_is_mapped(req);
|
||||||
if (mapped) {
|
if (mapped) {
|
||||||
ocf_io_start(req->io);
|
ocf_io_start(&req->ioi.io);
|
||||||
lock = ocf_req_trylock_wr(req);
|
lock = ocf_req_trylock_wr(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ int ocf_read_pt(struct ocf_request *req)
|
|||||||
|
|
||||||
OCF_DEBUG_TRACE(req->cache);
|
OCF_DEBUG_TRACE(req->cache);
|
||||||
|
|
||||||
ocf_io_start(req->io);
|
ocf_io_start(&req->ioi.io);
|
||||||
|
|
||||||
/* Get OCF request - increase reference counter */
|
/* Get OCF request - increase reference counter */
|
||||||
ocf_req_get(req);
|
ocf_req_get(req);
|
||||||
|
@ -217,7 +217,7 @@ int ocf_read_generic(struct ocf_request *req)
|
|||||||
int lock = OCF_LOCK_NOT_ACQUIRED;
|
int lock = OCF_LOCK_NOT_ACQUIRED;
|
||||||
struct ocf_cache *cache = req->cache;
|
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)) {
|
if (env_atomic_read(&cache->pending_read_misses_list_blocked)) {
|
||||||
/* There are conditions to bypass IO */
|
/* There are conditions to bypass IO */
|
||||||
|
@ -40,7 +40,7 @@ int ocf_write_wa(struct ocf_request *req)
|
|||||||
{
|
{
|
||||||
struct ocf_cache *cache = req->cache;
|
struct ocf_cache *cache = req->cache;
|
||||||
|
|
||||||
ocf_io_start(req->io);
|
ocf_io_start(&req->ioi.io);
|
||||||
|
|
||||||
/* Get OCF request - increase reference counter */
|
/* Get OCF request - increase reference counter */
|
||||||
ocf_req_get(req);
|
ocf_req_get(req);
|
||||||
|
@ -172,7 +172,7 @@ int ocf_write_wb(struct ocf_request *req)
|
|||||||
int lock = OCF_LOCK_NOT_ACQUIRED;
|
int lock = OCF_LOCK_NOT_ACQUIRED;
|
||||||
struct ocf_cache *cache = req->cache;
|
struct ocf_cache *cache = req->cache;
|
||||||
|
|
||||||
ocf_io_start(req->io);
|
ocf_io_start(&req->ioi.io);
|
||||||
|
|
||||||
/* Not sure if we need this. */
|
/* Not sure if we need this. */
|
||||||
ocf_req_get(req);
|
ocf_req_get(req);
|
||||||
|
@ -140,7 +140,7 @@ int ocf_write_wi(struct ocf_request *req)
|
|||||||
|
|
||||||
OCF_DEBUG_TRACE(req->cache);
|
OCF_DEBUG_TRACE(req->cache);
|
||||||
|
|
||||||
ocf_io_start(req->io);
|
ocf_io_start(&req->ioi.io);
|
||||||
|
|
||||||
/* Get OCF request - increase reference counter */
|
/* Get OCF request - increase reference counter */
|
||||||
ocf_req_get(req);
|
ocf_req_get(req);
|
||||||
|
@ -207,7 +207,7 @@ int ocf_read_wo(struct ocf_request *req)
|
|||||||
|
|
||||||
OCF_DEBUG_TRACE(req->cache);
|
OCF_DEBUG_TRACE(req->cache);
|
||||||
|
|
||||||
ocf_io_start(req->io);
|
ocf_io_start(&req->ioi.io);
|
||||||
|
|
||||||
/* Get OCF request - increase reference counter */
|
/* Get OCF request - increase reference counter */
|
||||||
ocf_req_get(req);
|
ocf_req_get(req);
|
||||||
|
@ -167,7 +167,7 @@ int ocf_write_wt(struct ocf_request *req)
|
|||||||
int lock = OCF_LOCK_NOT_ACQUIRED;
|
int lock = OCF_LOCK_NOT_ACQUIRED;
|
||||||
struct ocf_cache *cache = req->cache;
|
struct ocf_cache *cache = req->cache;
|
||||||
|
|
||||||
ocf_io_start(req->io);
|
ocf_io_start(&req->ioi.io);
|
||||||
|
|
||||||
/* Get OCF request - increase reference counter */
|
/* Get OCF request - increase reference counter */
|
||||||
ocf_req_get(req);
|
ocf_req_get(req);
|
||||||
|
@ -199,7 +199,8 @@ static int ocf_metadata_read_sb(ocf_ctx_t ctx, ocf_volume_t volume,
|
|||||||
context->priv2 = priv2;
|
context->priv2 = priv2;
|
||||||
|
|
||||||
/* Allocate resources for IO */
|
/* 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) {
|
if (!io) {
|
||||||
ocf_log(ctx, log_err, "Memory allocation error");
|
ocf_log(ctx, log_err, "Memory allocation error");
|
||||||
result = -OCF_ERR_NO_MEM;
|
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;
|
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_io_set_cmpl(io, context, NULL, ocf_metadata_read_sb_complete);
|
||||||
ocf_volume_submit_io(io);
|
ocf_volume_submit_io(io);
|
||||||
|
|
||||||
|
@ -711,18 +711,16 @@ static int ocf_metadata_query_cores_io(ocf_volume_t volume,
|
|||||||
env_atomic_inc(&context->count);
|
env_atomic_inc(&context->count);
|
||||||
|
|
||||||
/* Allocate new IO */
|
/* 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) {
|
if (!io) {
|
||||||
err = -OCF_ERR_NO_MEM;
|
err = -OCF_ERR_NO_MEM;
|
||||||
goto exit_error;
|
goto exit_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup IO */
|
/* 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_io_set_cmpl(io, context, NULL,
|
||||||
ocf_metadata_query_cores_end_io);
|
ocf_metadata_query_cores_end_io);
|
||||||
err = ocf_io_set_data(io, data, PAGES_TO_BYTES(offset));
|
err = ocf_io_set_data(io, data, PAGES_TO_BYTES(offset));
|
||||||
|
@ -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;
|
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);
|
ocf_io_put(io);
|
||||||
|
|
||||||
@ -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);
|
ctx_data_seek(cache->owner, context->data, ctx_data_seek_begin, 0);
|
||||||
|
|
||||||
/* Allocate new IO */
|
/* 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) {
|
if (!io) {
|
||||||
metadata_io_read_i_atomic_complete(context, -OCF_ERR_NO_MEM);
|
metadata_io_read_i_atomic_complete(context, -OCF_ERR_NO_MEM);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup IO */
|
/* 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);
|
ocf_io_set_cmpl(io, context, NULL, metadata_io_read_i_atomic_step_end);
|
||||||
result = ocf_io_set_data(io, context->data, 0);
|
result = ocf_io_set_data(io, context->data, 0);
|
||||||
if (result) {
|
if (result) {
|
||||||
@ -231,19 +230,16 @@ static int ocf_restart_meta_io(struct ocf_request *req)
|
|||||||
metadata_io_req_fill(meta_io_req);
|
metadata_io_req_fill(meta_io_req);
|
||||||
OCF_METADATA_UNLOCK_RD();
|
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) {
|
if (!io) {
|
||||||
metadata_io_i_asynch_end(meta_io_req, -OCF_ERR_NO_MEM);
|
metadata_io_i_asynch_end(meta_io_req, -OCF_ERR_NO_MEM);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup IO */
|
/* 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);
|
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);
|
ret = ocf_io_set_data(io, meta_io_req->data, 0);
|
||||||
if (ret) {
|
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]);
|
ret = metadata_updater_check_overlaps(cache, &a_req->reqs[i]);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* Allocate new IO */
|
/* 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) {
|
if (!io) {
|
||||||
error = -OCF_ERR_NO_MEM;
|
error = -OCF_ERR_NO_MEM;
|
||||||
metadata_io_req_error(cache, a_req, i, error);
|
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]);
|
metadata_io_req_fill(&a_req->reqs[i]);
|
||||||
|
|
||||||
/* Setup IO */
|
/* 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,
|
ocf_io_set_cmpl(io, &a_req->reqs[i], NULL,
|
||||||
metadata_io_i_asynch_cmpl);
|
metadata_io_i_asynch_cmpl);
|
||||||
error = ocf_io_set_data(io, a_req->reqs[i].data, 0);
|
error = ocf_io_set_data(io, a_req->reqs[i].data, 0);
|
||||||
|
@ -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)
|
uint64_t start_addr, uint32_t len, struct _raw_atomic_flush_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct ocf_request *req = context;
|
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) {
|
if (!io) {
|
||||||
req->error = -OCF_ERR_NO_MEM;
|
req->error = -OCF_ERR_NO_MEM;
|
||||||
return req->error;
|
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);
|
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);
|
ocf_io_set_cmpl(io, ctx, NULL, _raw_atomic_io_discard_end);
|
||||||
|
|
||||||
if (cache->device->volume.features.discard_zeroes)
|
if (cache->device->volume.features.discard_zeroes)
|
||||||
|
@ -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);
|
count = OCF_MIN(RAW_DYNAMIC_LOAD_PAGES, raw->ssd_pages - context->i);
|
||||||
|
|
||||||
/* Allocate IO */
|
/* 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) {
|
if (!context->io) {
|
||||||
raw_dynamic_load_all_complete(context, -OCF_ERR_NO_MEM);
|
raw_dynamic_load_all_complete(context, -OCF_ERR_NO_MEM);
|
||||||
return 0;
|
return 0;
|
||||||
@ -349,11 +352,6 @@ static int raw_dynamic_load_all_read(struct ocf_request *req)
|
|||||||
raw_dynamic_load_all_complete(context, result);
|
raw_dynamic_load_all_complete(context, result);
|
||||||
return 0;
|
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,
|
ocf_io_set_cmpl(context->io, context, NULL,
|
||||||
raw_dynamic_load_all_read_end);
|
raw_dynamic_load_all_read_end);
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
ocf_volume_t ocf_cache_get_volume(ocf_cache_t cache)
|
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)
|
ocf_cache_id_t ocf_cache_get_id(ocf_cache_t cache)
|
||||||
|
242
src/ocf_core.c
242
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 *** */
|
/* *** 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)
|
static inline ocf_core_t ocf_volume_to_core(ocf_volume_t volume)
|
||||||
@ -146,37 +149,27 @@ static inline ocf_core_t ocf_volume_to_core(ocf_volume_t volume)
|
|||||||
return core_volume->core;
|
return core_volume->core;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int ocf_io_set_dirty(ocf_cache_t cache,
|
static inline int ocf_io_set_dirty(struct ocf_request *req)
|
||||||
struct ocf_core_io *core_io)
|
|
||||||
{
|
{
|
||||||
core_io->dirty = !!ocf_refcnt_inc(&cache->refcnt.dirty);
|
req->dirty = !!ocf_refcnt_inc(&req->cache->refcnt.dirty);
|
||||||
return core_io->dirty ? 0 : -EBUSY;
|
return req->dirty ? 0 : -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void dec_counter_if_req_was_dirty(struct ocf_core_io *core_io,
|
static inline void dec_counter_if_req_was_dirty(struct ocf_request *req)
|
||||||
ocf_cache_t cache)
|
|
||||||
{
|
{
|
||||||
if (!core_io->dirty)
|
if (!req->dirty)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
core_io->dirty = 0;
|
req->dirty = 0;
|
||||||
ocf_refcnt_dec(&cache->refcnt.dirty);
|
ocf_refcnt_dec(&req->cache->refcnt.dirty);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int ocf_core_validate_io(struct ocf_io *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)
|
if (io->addr + io->bytes > ocf_volume_get_length(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))
|
|
||||||
return -OCF_ERR_INVAL;
|
return -OCF_ERR_INVAL;
|
||||||
|
|
||||||
if (io->io_class >= OCF_IO_CLASS_MAX)
|
if (io->io_class >= OCF_IO_CLASS_MAX)
|
||||||
@ -194,7 +187,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
|
/* 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
|
* break I/O accounting code, resulting in use-after-free type of errors
|
||||||
* after cache detach, core remove etc. */
|
* after cache detach, core remove etc. */
|
||||||
core = ocf_volume_to_core(io->volume);
|
|
||||||
if (io->io_queue == ocf_core_get_cache(core)->mngt_queue)
|
if (io->io_queue == ocf_core_get_cache(core)->mngt_queue)
|
||||||
return -OCF_ERR_INVAL;
|
return -OCF_ERR_INVAL;
|
||||||
|
|
||||||
@ -204,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)
|
static void ocf_req_complete(struct ocf_request *req, int error)
|
||||||
{
|
{
|
||||||
/* Log trace */
|
/* Log trace */
|
||||||
ocf_trace_io_cmpl(ocf_io_to_core_io(req->io), req->cache);
|
ocf_trace_io_cmpl(req);
|
||||||
|
|
||||||
/* Complete IO */
|
/* 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 */
|
/* Invalidate OCF IO, it is not valid after completion */
|
||||||
ocf_io_put(req->io);
|
ocf_io_put(&req->ioi.io);
|
||||||
req->io = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ocf_core_submit_io_mode(struct ocf_io *io, ocf_cache_mode_t cache_mode)
|
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_req_cache_mode_t req_cache_mode;
|
||||||
ocf_core_t core;
|
ocf_core_t core;
|
||||||
ocf_cache_t cache;
|
ocf_cache_t cache;
|
||||||
@ -228,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);
|
ret = ocf_core_validate_io(io);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
io->end(io, ret);
|
ocf_io_end(io, ret);
|
||||||
return;
|
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));
|
||||||
core = ocf_volume_to_core(io->volume);
|
|
||||||
cache = ocf_core_get_cache(core);
|
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,
|
if (unlikely(!env_bit_test(ocf_cache_state_running,
|
||||||
&cache->cache_state))) {
|
&cache->cache_state))) {
|
||||||
@ -254,50 +244,40 @@ void ocf_core_submit_io_mode(struct ocf_io *io, ocf_cache_mode_t cache_mode)
|
|||||||
|
|
||||||
if (io->dir == OCF_WRITE &&
|
if (io->dir == OCF_WRITE &&
|
||||||
ocf_req_cache_mode_has_lazy_write(req_cache_mode) &&
|
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;
|
req_cache_mode = ocf_req_cache_mode_wt;
|
||||||
}
|
}
|
||||||
|
|
||||||
core_io->req = ocf_req_new(io->io_queue, core, io->addr, io->bytes,
|
if (req->d2c)
|
||||||
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)
|
|
||||||
req_cache_mode = ocf_req_cache_mode_d2c;
|
req_cache_mode = ocf_req_cache_mode_d2c;
|
||||||
|
|
||||||
core_io->req->part_id = ocf_part_class2id(cache, io->io_class);
|
req->core = core;
|
||||||
core_io->req->data = core_io->data;
|
req->complete = ocf_req_complete;
|
||||||
core_io->req->complete = ocf_req_complete;
|
req->part_id = ocf_part_class2id(cache, io->io_class);
|
||||||
core_io->req->io = io;
|
|
||||||
|
|
||||||
ocf_seq_cutoff_update(core, core_io->req);
|
ocf_seq_cutoff_update(core, req);
|
||||||
|
|
||||||
ocf_core_update_stats(core, io);
|
ocf_core_update_stats(core, io);
|
||||||
|
|
||||||
if (io->dir == OCF_WRITE)
|
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)
|
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);
|
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) {
|
if (ret) {
|
||||||
dec_counter_if_req_was_dirty(core_io, cache);
|
dec_counter_if_req_was_dirty(req);
|
||||||
ocf_req_put(core_io->req);
|
ocf_io_end(io, ret);
|
||||||
io->end(io, ret);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ocf_core_submit_io_fast(struct ocf_io *io)
|
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;
|
ocf_req_cache_mode_t req_cache_mode;
|
||||||
struct ocf_event_io trace_event;
|
struct ocf_event_io trace_event;
|
||||||
struct ocf_request *req;
|
|
||||||
ocf_core_t core;
|
ocf_core_t core;
|
||||||
ocf_cache_t cache;
|
ocf_cache_t cache;
|
||||||
int fast;
|
int fast;
|
||||||
@ -309,9 +289,8 @@ int ocf_core_submit_io_fast(struct ocf_io *io)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
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));
|
||||||
core = ocf_volume_to_core(io->volume);
|
|
||||||
cache = ocf_core_get_cache(core);
|
cache = ocf_core_get_cache(core);
|
||||||
|
|
||||||
if (unlikely(!env_bit_test(ocf_cache_state_running,
|
if (unlikely(!env_bit_test(ocf_cache_state_running,
|
||||||
@ -320,11 +299,17 @@ int ocf_core_submit_io_fast(struct ocf_io *io)
|
|||||||
return 0;
|
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);
|
req_cache_mode = ocf_get_effective_cache_mode(cache, core, io);
|
||||||
|
|
||||||
if (io->dir == OCF_WRITE &&
|
if (io->dir == OCF_WRITE &&
|
||||||
ocf_req_cache_mode_has_lazy_write(req_cache_mode) &&
|
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;
|
req_cache_mode = ocf_req_cache_mode_wt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,35 +329,22 @@ int ocf_core_submit_io_fast(struct ocf_io *io)
|
|||||||
req_cache_mode = ocf_req_cache_mode_fast;
|
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) {
|
if (req->d2c) {
|
||||||
dec_counter_if_req_was_dirty(core_io, cache);
|
dec_counter_if_req_was_dirty(req);
|
||||||
ocf_req_put(req);
|
|
||||||
return -OCF_ERR_IO;
|
return -OCF_ERR_IO;
|
||||||
}
|
}
|
||||||
|
|
||||||
req->part_id = ocf_part_class2id(cache, io->io_class);
|
req->core = core;
|
||||||
req->data = core_io->data;
|
|
||||||
req->complete = ocf_req_complete;
|
req->complete = ocf_req_complete;
|
||||||
req->io = io;
|
req->part_id = ocf_part_class2id(cache, io->io_class);
|
||||||
|
|
||||||
ocf_core_update_stats(core, io);
|
ocf_core_update_stats(core, io);
|
||||||
|
|
||||||
if (cache->trace.trace_callback) {
|
if (cache->trace.trace_callback) {
|
||||||
if (io->dir == OCF_WRITE)
|
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)
|
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);
|
ocf_io_get(io);
|
||||||
@ -384,10 +356,9 @@ int ocf_core_submit_io_fast(struct ocf_io *io)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dec_counter_if_req_was_dirty(core_io, cache);
|
dec_counter_if_req_was_dirty(req);
|
||||||
|
|
||||||
ocf_io_put(io);
|
ocf_io_put(io);
|
||||||
ocf_req_put(req);
|
|
||||||
return -OCF_ERR_IO;
|
return -OCF_ERR_IO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,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)
|
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_core_t core;
|
||||||
ocf_cache_t cache;
|
ocf_cache_t cache;
|
||||||
int ret;
|
int ret;
|
||||||
@ -411,9 +382,8 @@ static void ocf_core_volume_submit_flush(struct ocf_io *io)
|
|||||||
return;
|
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));
|
||||||
core = ocf_volume_to_core(io->volume);
|
|
||||||
cache = ocf_core_get_cache(core);
|
cache = ocf_core_get_cache(core);
|
||||||
|
|
||||||
if (unlikely(!env_bit_test(ocf_cache_state_running,
|
if (unlikely(!env_bit_test(ocf_cache_state_running,
|
||||||
@ -422,25 +392,18 @@ static void ocf_core_volume_submit_flush(struct ocf_io *io)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
core_io->req = ocf_req_new(io->io_queue, core, io->addr, io->bytes,
|
req->core = core;
|
||||||
io->dir);
|
req->complete = ocf_req_complete;
|
||||||
if (!core_io->req) {
|
|
||||||
ocf_io_end(io, -OCF_ERR_NO_MEM);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
core_io->req->complete = ocf_req_complete;
|
ocf_trace_io(req, ocf_event_operation_flush);
|
||||||
core_io->req->io = io;
|
|
||||||
core_io->req->data = core_io->data;
|
|
||||||
|
|
||||||
ocf_trace_io(core_io, ocf_event_operation_flush, cache);
|
|
||||||
ocf_io_get(io);
|
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)
|
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_core_t core;
|
||||||
ocf_cache_t cache;
|
ocf_cache_t cache;
|
||||||
int ret;
|
int ret;
|
||||||
@ -453,9 +416,8 @@ static void ocf_core_volume_submit_discard(struct ocf_io *io)
|
|||||||
return;
|
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));
|
||||||
core = ocf_volume_to_core(io->volume);
|
|
||||||
cache = ocf_core_get_cache(core);
|
cache = ocf_core_get_cache(core);
|
||||||
|
|
||||||
if (unlikely(!env_bit_test(ocf_cache_state_running,
|
if (unlikely(!env_bit_test(ocf_cache_state_running,
|
||||||
@ -464,20 +426,19 @@ static void ocf_core_volume_submit_discard(struct ocf_io *io)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
core_io->req = ocf_req_new_discard(io->io_queue, core,
|
ret = ocf_req_alloc_map_discard(req);
|
||||||
io->addr, io->bytes, OCF_WRITE);
|
if (ret) {
|
||||||
if (!core_io->req) {
|
|
||||||
ocf_io_end(io, -OCF_ERR_NO_MEM);
|
ocf_io_end(io, -OCF_ERR_NO_MEM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
core_io->req->complete = ocf_req_complete;
|
req->core = core;
|
||||||
core_io->req->io = io;
|
req->complete = ocf_req_complete;
|
||||||
core_io->req->data = core_io->data;
|
|
||||||
|
|
||||||
ocf_trace_io(core_io, ocf_event_operation_discard, cache);
|
ocf_trace_io(req, ocf_event_operation_discard);
|
||||||
ocf_io_get(io);
|
ocf_io_get(io);
|
||||||
ocf_engine_hndl_discard_req(core_io->req);
|
|
||||||
|
ocf_engine_hndl_discard_req(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* *** VOLUME OPS *** */
|
/* *** VOLUME OPS *** */
|
||||||
@ -517,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,
|
static int ocf_core_io_set_data(struct ocf_io *io,
|
||||||
ctx_data_t *data, uint32_t offset)
|
ctx_data_t *data, uint32_t offset)
|
||||||
{
|
{
|
||||||
struct ocf_core_io *core_io;
|
struct ocf_request *req;
|
||||||
|
|
||||||
OCF_CHECK_NULL(io);
|
OCF_CHECK_NULL(io);
|
||||||
|
|
||||||
if (!data || offset)
|
if (!data || offset)
|
||||||
return -OCF_ERR_INVAL;
|
return -OCF_ERR_INVAL;
|
||||||
|
|
||||||
core_io = ocf_io_to_core_io(io);
|
req = ocf_io_to_req(io);
|
||||||
core_io->data = data;
|
req->data = data;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ctx_data_t *ocf_core_io_get_data(struct ocf_io *io)
|
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);
|
OCF_CHECK_NULL(io);
|
||||||
|
|
||||||
core_io = ocf_io_to_core_io(io);
|
req = ocf_io_to_req(io);
|
||||||
return core_io->data;
|
return req->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct ocf_volume_properties ocf_core_volume_properties = {
|
const struct ocf_volume_properties ocf_core_volume_properties = {
|
||||||
.name = "OCF Core",
|
.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),
|
.volume_priv_size = sizeof(struct ocf_core_volume),
|
||||||
.caps = {
|
.caps = {
|
||||||
.atomic_writes = 0,
|
.atomic_writes = 0,
|
||||||
@ -564,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)
|
int ocf_core_volume_type_init(ocf_ctx_t ctx)
|
||||||
{
|
{
|
||||||
return ocf_ctx_register_volume_type(ctx, 0,
|
return ocf_ctx_register_volume_type_extended(ctx, 0,
|
||||||
&ocf_core_volume_properties);
|
&ocf_core_volume_properties,
|
||||||
|
&ocf_core_volume_extended);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ocf_core_volume_type_deinit(ocf_ctx_t ctx)
|
void ocf_core_volume_type_deinit(ocf_ctx_t ctx)
|
||||||
|
@ -18,20 +18,6 @@
|
|||||||
#define ocf_core_log(core, lvl, fmt, ...) \
|
#define ocf_core_log(core, lvl, fmt, ...) \
|
||||||
ocf_core_log_prefix(core, lvl, ": ", fmt, ##__VA_ARGS__)
|
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 {
|
struct ocf_metadata_uuid {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint8_t data[OCF_VOLUME_UUID_MAX_SIZE];
|
uint8_t data[OCF_VOLUME_UUID_MAX_SIZE];
|
||||||
|
@ -15,8 +15,9 @@
|
|||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int ocf_ctx_register_volume_type(ocf_ctx_t ctx, uint8_t type_id,
|
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_properties *properties,
|
||||||
|
const struct ocf_volume_extended *extended)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
@ -31,7 +32,7 @@ int ocf_ctx_register_volume_type(ocf_ctx_t ctx, uint8_t type_id,
|
|||||||
goto err;
|
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])
|
if (!ctx->volume_type[type_id])
|
||||||
result = -EINVAL;
|
result = -EINVAL;
|
||||||
|
|
||||||
@ -50,6 +51,13 @@ err:
|
|||||||
return result;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "ocf_env.h"
|
#include "ocf_env.h"
|
||||||
#include "ocf/ocf_ctx.h"
|
#include "ocf/ocf_ctx.h"
|
||||||
#include "ocf_logger_priv.h"
|
#include "ocf_logger_priv.h"
|
||||||
|
#include "ocf_volume_priv.h"
|
||||||
|
|
||||||
#define OCF_VOLUME_TYPE_MAX 8
|
#define OCF_VOLUME_TYPE_MAX 8
|
||||||
|
|
||||||
@ -45,6 +46,10 @@ struct ocf_ctx {
|
|||||||
#define ocf_log_stack_trace(ctx) \
|
#define ocf_log_stack_trace(ctx) \
|
||||||
ocf_log_stack_trace_raw(&ctx->logger)
|
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
|
* @name Environment data buffer operations wrappers
|
||||||
* @{
|
* @{
|
||||||
|
113
src/ocf_io.c
113
src/ocf_io.c
@ -6,6 +6,7 @@
|
|||||||
#include "ocf/ocf.h"
|
#include "ocf/ocf.h"
|
||||||
#include "ocf_io_priv.h"
|
#include "ocf_io_priv.h"
|
||||||
#include "ocf_volume_priv.h"
|
#include "ocf_volume_priv.h"
|
||||||
|
#include "utils/utils_io_allocator.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is io allocator dedicated for bottom devices.
|
* This is io allocator dedicated for bottom devices.
|
||||||
@ -26,52 +27,88 @@
|
|||||||
* +-------------------------+ <----------------
|
* +-------------------------+ <----------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define OCF_IO_TOTAL_SIZE(priv_size) (sizeof(struct ocf_io_meta) + \
|
#define OCF_IO_TOTAL(priv_size) \
|
||||||
sizeof(struct ocf_io) + 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IO internal API
|
* 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 *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 *io;
|
struct ocf_io_internal *ioi;
|
||||||
struct ocf_io_meta *io_meta;
|
|
||||||
void *data;
|
|
||||||
|
|
||||||
if (!ocf_refcnt_inc(&volume->refcnt))
|
if (!ocf_refcnt_inc(&volume->refcnt))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
data = env_allocator_new(volume->type->allocator);
|
ioi = ocf_io_allocator_new(&volume->type->allocator, volume, queue,
|
||||||
if (!data) {
|
addr, bytes, dir);
|
||||||
|
if (!ioi) {
|
||||||
ocf_refcnt_dec(&volume->refcnt);
|
ocf_refcnt_dec(&volume->refcnt);
|
||||||
return NULL;
|
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);
|
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;
|
||||||
|
|
||||||
io->volume = volume;
|
return &ioi->io;
|
||||||
io->ops = &volume->type->properties->io_ops;
|
|
||||||
env_atomic_set(&io_meta->ref_count, 1);
|
|
||||||
|
|
||||||
return io;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -83,22 +120,42 @@ void *ocf_io_get_priv(struct ocf_io* io)
|
|||||||
return (void *)io + sizeof(struct ocf_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)
|
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)
|
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;
|
return;
|
||||||
|
|
||||||
ocf_refcnt_dec(&io->volume->refcnt);
|
ocf_refcnt_dec(&ioi->meta.volume->refcnt);
|
||||||
|
|
||||||
env_allocator_del(io->volume->type->allocator,
|
ocf_io_allocator_del(&ioi->meta.volume->type->allocator, (void *)ioi);
|
||||||
(void *)io - sizeof(struct ocf_io_meta));
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
@ -7,18 +7,28 @@
|
|||||||
#define __OCF_IO_PRIV_H__
|
#define __OCF_IO_PRIV_H__
|
||||||
|
|
||||||
#include "ocf/ocf.h"
|
#include "ocf/ocf.h"
|
||||||
#include "ocf_request.h"
|
#include "utils/utils_io_allocator.h"
|
||||||
|
|
||||||
struct ocf_io_meta {
|
struct ocf_io_meta {
|
||||||
|
ocf_volume_t volume;
|
||||||
|
const struct ocf_io_ops *ops;
|
||||||
env_atomic ref_count;
|
env_atomic ref_count;
|
||||||
struct ocf_request *req;
|
struct ocf_request *req;
|
||||||
};
|
};
|
||||||
|
|
||||||
env_allocator *ocf_io_allocator_create(uint32_t size, const char *name);
|
|
||||||
|
|
||||||
void ocf_io_allocator_destroy(env_allocator *allocator);
|
struct ocf_io_internal {
|
||||||
|
struct ocf_io_meta meta;
|
||||||
|
struct ocf_io io;
|
||||||
|
};
|
||||||
|
|
||||||
struct ocf_io *ocf_io_new(ocf_volume_t volume);
|
int ocf_io_allocator_init(ocf_io_allocator_t allocator, ocf_io_allocator_type_t type,
|
||||||
|
uint32_t priv_size, const char *name);
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
static inline void ocf_io_start(struct ocf_io *io)
|
||||||
{
|
{
|
||||||
|
@ -90,10 +90,10 @@ void ocf_queue_run_single(ocf_queue_t q)
|
|||||||
if (!io_req)
|
if (!io_req)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (io_req->io && io_req->io->handle)
|
if (io_req->ioi.io.handle)
|
||||||
io_req->io->handle(io_req->io, io_req);
|
io_req->ioi.io.handle(&io_req->ioi.io, io_req);
|
||||||
else
|
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)
|
void ocf_queue_run(ocf_queue_t q)
|
||||||
|
@ -201,6 +201,10 @@ struct ocf_request *ocf_req_new(ocf_queue_t queue, ocf_core_t core,
|
|||||||
req->rw = rw;
|
req->rw = rw;
|
||||||
req->part_id = PARTITION_DEFAULT;
|
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;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,6 +222,24 @@ int ocf_req_alloc_map(struct ocf_request *req)
|
|||||||
return 0;
|
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,
|
struct ocf_request *ocf_req_new_extended(ocf_queue_t queue, ocf_core_t core,
|
||||||
uint64_t addr, uint32_t bytes, int rw)
|
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)
|
if (!req)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
req->discard.sector = BYTES_TO_SECTORS(addr);
|
|
||||||
req->discard.nr_sects = BYTES_TO_SECTORS(bytes);
|
|
||||||
req->discard.handled = 0;
|
|
||||||
|
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#define __OCF_REQUEST_H__
|
#define __OCF_REQUEST_H__
|
||||||
|
|
||||||
#include "ocf_env.h"
|
#include "ocf_env.h"
|
||||||
|
#include "ocf_io_priv.h"
|
||||||
|
|
||||||
struct ocf_req_allocator;
|
struct ocf_req_allocator;
|
||||||
|
|
||||||
@ -103,6 +104,9 @@ struct ocf_req_discard_info {
|
|||||||
* @brief OCF IO request
|
* @brief OCF IO request
|
||||||
*/
|
*/
|
||||||
struct ocf_request {
|
struct ocf_request {
|
||||||
|
struct ocf_io_internal ioi;
|
||||||
|
/*!< OCF IO associated with request */
|
||||||
|
|
||||||
env_atomic ref_count;
|
env_atomic ref_count;
|
||||||
/*!< Reference usage count, once OCF request reaches zero it
|
/*!< Reference usage count, once OCF request reaches zero it
|
||||||
* will be de-initialed. Get/Put method are intended to modify
|
* will be de-initialed. Get/Put method are intended to modify
|
||||||
@ -179,6 +183,12 @@ struct ocf_request {
|
|||||||
uint8_t master_io_req_type : 2;
|
uint8_t master_io_req_type : 2;
|
||||||
/*!< Core device request context type */
|
/*!< Core device request context type */
|
||||||
|
|
||||||
|
log_sid_t sid;
|
||||||
|
/*!< Tracing sequence ID */
|
||||||
|
|
||||||
|
uint64_t timestamp;
|
||||||
|
/*!< Tracing timestamp */
|
||||||
|
|
||||||
ocf_queue_t io_queue;
|
ocf_queue_t io_queue;
|
||||||
/*!< I/O queue handle for which request should be submitted */
|
/*!< I/O queue handle for which request should be submitted */
|
||||||
|
|
||||||
@ -191,9 +201,6 @@ struct ocf_request {
|
|||||||
void (*complete)(struct ocf_request *ocf_req, int error);
|
void (*complete)(struct ocf_request *ocf_req, int error);
|
||||||
/*!< Request completion function */
|
/*!< Request completion function */
|
||||||
|
|
||||||
struct ocf_io *io;
|
|
||||||
/*!< OCF IO associated with request */
|
|
||||||
|
|
||||||
struct ocf_req_discard_info discard;
|
struct ocf_req_discard_info discard;
|
||||||
|
|
||||||
struct ocf_map_info *map;
|
struct ocf_map_info *map;
|
||||||
@ -242,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);
|
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
|
* @brief Allocate new OCF request with NOIO map allocation for huge request
|
||||||
*
|
*
|
||||||
|
@ -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);
|
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());
|
req->timestamp = env_ticks_to_nsecs(env_get_tick_count());
|
||||||
io->sid = ocf_trace_seq_id(cache);
|
req->sid = ocf_trace_seq_id(req->cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ocf_trace_prep_io_event(struct ocf_event_io *ev,
|
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, req->sid,
|
||||||
|
req->timestamp, sizeof(*ev));
|
||||||
ocf_event_init_hdr(&ev->hdr, ocf_event_type_io, io->sid,
|
|
||||||
io->timestamp, sizeof(*ev));
|
|
||||||
|
|
||||||
ev->addr = req->byte_position;
|
ev->addr = req->byte_position;
|
||||||
if (op == ocf_event_operation_discard)
|
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->operation = op;
|
||||||
ev->core_id = ocf_core_get_id(req->core);
|
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)
|
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);
|
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_event_io ev;
|
||||||
struct ocf_request *req;
|
|
||||||
|
|
||||||
if (!cache->trace.trace_callback)
|
if (!req->cache->trace.trace_callback)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
req = io->req;
|
ocf_trace_prep_io_event(&ev, req, dir);
|
||||||
ocf_trace_prep_io_event(&ev, io, dir);
|
|
||||||
|
|
||||||
ocf_trace_push(req->io_queue, &ev, sizeof(ev));
|
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_event_io_cmpl ev;
|
||||||
struct ocf_request *req;
|
|
||||||
|
|
||||||
if (!cache->trace.trace_callback)
|
if (!req->cache->trace.trace_callback)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
req = io->req;
|
|
||||||
ocf_event_init_hdr(&ev.hdr, ocf_event_type_io_cmpl,
|
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()),
|
env_ticks_to_nsecs(env_get_tick_count()),
|
||||||
sizeof(ev));
|
sizeof(ev));
|
||||||
ev.rsid = io->sid;
|
ev.rsid = req->sid;
|
||||||
ev.is_hit = ocf_engine_is_hit(req);
|
ev.is_hit = ocf_engine_is_hit(req);
|
||||||
|
|
||||||
ocf_trace_push(req->io_queue, &ev, sizeof(ev));
|
ocf_trace_push(req->io_queue, &ev, sizeof(ev));
|
||||||
|
@ -16,9 +16,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int ocf_volume_type_init(struct ocf_volume_type **type,
|
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;
|
const struct ocf_volume_ops *ops = &properties->ops;
|
||||||
|
ocf_io_allocator_type_t allocator_type;
|
||||||
struct ocf_volume_type *new_type;
|
struct ocf_volume_type *new_type;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -34,12 +36,15 @@ int ocf_volume_type_init(struct ocf_volume_type **type,
|
|||||||
if (!new_type)
|
if (!new_type)
|
||||||
return -OCF_ERR_NO_MEM;
|
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);
|
properties->io_priv_size, properties->name);
|
||||||
if (!new_type->allocator) {
|
if (ret)
|
||||||
ret = -OCF_ERR_NO_MEM;
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
|
||||||
|
|
||||||
new_type->properties = properties;
|
new_type->properties = properties;
|
||||||
|
|
||||||
@ -54,7 +59,7 @@ err:
|
|||||||
|
|
||||||
void ocf_volume_type_deinit(struct ocf_volume_type *type)
|
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);
|
env_free(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,47 +232,55 @@ int ocf_volume_is_atomic(ocf_volume_t volume)
|
|||||||
return volume->type->properties->caps.atomic_writes;
|
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)
|
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->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)
|
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);
|
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);
|
ocf_io_end(io, 0);
|
||||||
return;
|
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)
|
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);
|
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);
|
ocf_io_end(io, 0);
|
||||||
return;
|
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)
|
int ocf_volume_open(ocf_volume_t volume, void *volume_params)
|
||||||
|
@ -9,10 +9,15 @@
|
|||||||
#include "ocf_env.h"
|
#include "ocf_env.h"
|
||||||
#include "ocf_io_priv.h"
|
#include "ocf_io_priv.h"
|
||||||
#include "utils/utils_refcnt.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 {
|
struct ocf_volume_type {
|
||||||
const struct ocf_volume_properties *properties;
|
const struct ocf_volume_properties *properties;
|
||||||
env_allocator *allocator;
|
struct ocf_io_allocator allocator;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ocf_volume {
|
struct ocf_volume {
|
||||||
@ -31,7 +36,8 @@ struct ocf_volume {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int ocf_volume_type_init(struct ocf_volume_type **type,
|
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);
|
void ocf_volume_type_deinit(struct ocf_volume_type *type);
|
||||||
|
|
||||||
@ -42,16 +48,20 @@ void ocf_volume_set_uuid(ocf_volume_t volume,
|
|||||||
|
|
||||||
static inline void ocf_volume_submit_metadata(struct ocf_io *io)
|
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)
|
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__ */
|
#endif /*__OCF_VOLUME_PRIV_H__ */
|
||||||
|
@ -270,16 +270,14 @@ static int _ocf_cleaner_fire_flush_cache(struct ocf_request *req)
|
|||||||
|
|
||||||
OCF_DEBUG_TRACE(req->cache);
|
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) {
|
if (!io) {
|
||||||
ocf_metadata_error(req->cache);
|
ocf_metadata_error(req->cache);
|
||||||
req->error = -OCF_ERR_NO_MEM;
|
req->error = -OCF_ERR_NO_MEM;
|
||||||
return -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_cmpl(io, req, NULL, _ocf_cleaner_flush_cache_io_end);
|
||||||
ocf_io_set_queue(io, req->io_queue);
|
|
||||||
|
|
||||||
ocf_volume_submit_flush(io);
|
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;
|
ocf_core_id_t core_id = OCF_CORE_MAX;
|
||||||
struct ocf_cache *cache = req->cache;
|
struct ocf_cache *cache = req->cache;
|
||||||
struct ocf_map_info *iter = req->map;
|
struct ocf_map_info *iter = req->map;
|
||||||
|
ocf_core_t core;
|
||||||
struct ocf_io *io;
|
struct ocf_io *io;
|
||||||
|
|
||||||
OCF_DEBUG_TRACE(req->cache);
|
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);
|
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) {
|
if (!io) {
|
||||||
_ocf_cleaner_flush_cores_io_end(iter, req, -OCF_ERR_NO_MEM);
|
_ocf_cleaner_flush_cores_io_end(iter, req, -OCF_ERR_NO_MEM);
|
||||||
continue;
|
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_cmpl(io, iter, req, _ocf_cleaner_flush_cores_io_cmpl);
|
||||||
ocf_io_set_queue(io, req->io_queue);
|
|
||||||
|
|
||||||
ocf_volume_submit_flush(io);
|
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;
|
uint64_t addr, offset;
|
||||||
int err;
|
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_io *io;
|
||||||
struct ocf_counters_block *core_stats =
|
struct ocf_counters_block *core_stats =
|
||||||
&cache->core[iter->core_id].counters->core_blocks;
|
&cache->core[iter->core_id].counters->core_blocks;
|
||||||
ocf_part_id_t part_id = ocf_metadata_get_partition_id(cache,
|
ocf_part_id_t part_id = ocf_metadata_get_partition_id(cache,
|
||||||
iter->coll_idx);
|
iter->coll_idx);
|
||||||
|
|
||||||
io = ocf_new_core_io(cache, iter->core_id);
|
|
||||||
if (!io)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
addr = (ocf_line_size(cache) * iter->core_line)
|
addr = (ocf_line_size(cache) * iter->core_line)
|
||||||
+ SECTORS_TO_BYTES(begin);
|
+ SECTORS_TO_BYTES(begin);
|
||||||
offset = (ocf_line_size(cache) * iter->hash_key)
|
offset = (ocf_line_size(cache) * iter->hash_key)
|
||||||
+ SECTORS_TO_BYTES(begin);
|
+ SECTORS_TO_BYTES(begin);
|
||||||
|
|
||||||
ocf_io_configure(io, addr, SECTORS_TO_BYTES(end - begin), OCF_WRITE,
|
io = ocf_new_core_io(core, req->io_queue, addr,
|
||||||
part_id, 0);
|
SECTORS_TO_BYTES(end - begin), OCF_WRITE, part_id, 0);
|
||||||
ocf_io_set_queue(io, req->io_queue);
|
if (!io)
|
||||||
|
goto error;
|
||||||
|
|
||||||
err = ocf_io_set_data(io, req->data, offset);
|
err = ocf_io_set_data(io, req->data, offset);
|
||||||
if (err) {
|
if (err) {
|
||||||
ocf_io_put(io);
|
ocf_io_put(io);
|
||||||
@ -660,14 +658,6 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req)
|
|||||||
cache_stats = &cache->core[iter->core_id].
|
cache_stats = &cache->core[iter->core_id].
|
||||||
counters->cache_blocks;
|
counters->cache_blocks;
|
||||||
|
|
||||||
io = ocf_new_cache_io(cache);
|
|
||||||
if (!io) {
|
|
||||||
/* Allocation error */
|
|
||||||
iter->invalid = true;
|
|
||||||
_ocf_cleaner_set_error(req);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
OCF_DEBUG_PARAM(req->cache, "Cache read, line = %u",
|
OCF_DEBUG_PARAM(req->cache, "Cache read, line = %u",
|
||||||
iter->coll_idx);
|
iter->coll_idx);
|
||||||
|
|
||||||
@ -680,10 +670,17 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req)
|
|||||||
|
|
||||||
part_id = ocf_metadata_get_partition_id(cache, iter->coll_idx);
|
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);
|
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);
|
err = ocf_io_set_data(io, req->data, offset);
|
||||||
if (err) {
|
if (err) {
|
||||||
ocf_io_put(io);
|
ocf_io_put(io);
|
||||||
|
@ -31,11 +31,10 @@ void ocf_submit_volume_flush(ocf_volume_t volume,
|
|||||||
{
|
{
|
||||||
struct ocf_io *io;
|
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)
|
if (!io)
|
||||||
OCF_CMPL_RET(priv, -OCF_ERR_NO_MEM);
|
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_io_set_cmpl(io, cmpl, priv, _ocf_volume_flush_end);
|
||||||
|
|
||||||
ocf_volume_submit_flush(io);
|
ocf_volume_submit_flush(io);
|
||||||
@ -74,7 +73,10 @@ void ocf_submit_volume_discard(ocf_volume_t volume, uint64_t addr,
|
|||||||
context->priv = priv;
|
context->priv = priv;
|
||||||
|
|
||||||
while (length) {
|
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) {
|
if (!io) {
|
||||||
context->error = -OCF_ERR_NO_MEM;
|
context->error = -OCF_ERR_NO_MEM;
|
||||||
break;
|
break;
|
||||||
@ -82,9 +84,6 @@ void ocf_submit_volume_discard(ocf_volume_t volume, uint64_t addr,
|
|||||||
|
|
||||||
env_atomic_inc(&context->req_remaining);
|
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_io_set_cmpl(io, context, NULL, ocf_submit_volume_end);
|
||||||
ocf_volume_submit_discard(io);
|
ocf_volume_submit_discard(io);
|
||||||
|
|
||||||
@ -116,7 +115,10 @@ void ocf_submit_write_zeros(ocf_volume_t volume, uint64_t addr,
|
|||||||
context->priv = priv;
|
context->priv = priv;
|
||||||
|
|
||||||
while (length) {
|
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) {
|
if (!io) {
|
||||||
context->error = -OCF_ERR_NO_MEM;
|
context->error = -OCF_ERR_NO_MEM;
|
||||||
break;
|
break;
|
||||||
@ -124,9 +126,6 @@ void ocf_submit_write_zeros(ocf_volume_t volume, uint64_t addr,
|
|||||||
|
|
||||||
env_atomic_inc(&context->req_remaining);
|
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_io_set_cmpl(io, context, NULL, ocf_submit_volume_end);
|
||||||
ocf_volume_submit_write_zeroes(io);
|
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->cmpl = cmpl;
|
||||||
context->priv = priv;
|
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) {
|
if (!io) {
|
||||||
result = -OCF_ERR_NO_MEM;
|
result = -OCF_ERR_NO_MEM;
|
||||||
goto err_io;
|
goto err_io;
|
||||||
@ -200,7 +199,6 @@ void ocf_submit_cache_page(ocf_cache_t cache, uint64_t addr, int dir,
|
|||||||
if (result)
|
if (result)
|
||||||
goto err_set_data;
|
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_io_set_cmpl(io, context, NULL, ocf_submit_cache_page_end);
|
||||||
|
|
||||||
ocf_volume_submit_io(io);
|
ocf_volume_submit_io(io);
|
||||||
@ -230,8 +228,8 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache,
|
|||||||
uint64_t size, unsigned int reqs, ocf_req_end_t callback)
|
uint64_t size, unsigned int reqs, ocf_req_end_t callback)
|
||||||
{
|
{
|
||||||
struct ocf_counters_block *cache_stats;
|
struct ocf_counters_block *cache_stats;
|
||||||
uint64_t flags = req->io ? req->io->flags : 0;
|
uint64_t flags = req->ioi.io.flags;
|
||||||
uint32_t class = req->io ? req->io->io_class : 0;
|
uint32_t class = req->ioi.io.io_class;
|
||||||
uint64_t addr, bytes, total_bytes = 0;
|
uint64_t addr, bytes, total_bytes = 0;
|
||||||
struct ocf_io *io;
|
struct ocf_io *io;
|
||||||
int err;
|
int err;
|
||||||
@ -245,12 +243,6 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache,
|
|||||||
cache_stats = &req->core->counters->cache_blocks;
|
cache_stats = &req->core->counters->cache_blocks;
|
||||||
|
|
||||||
if (reqs == 1) {
|
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,
|
addr = ocf_metadata_map_lg2phy(cache,
|
||||||
req->map[first_cl].coll_idx);
|
req->map[first_cl].coll_idx);
|
||||||
addr *= ocf_line_size(cache);
|
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));
|
addr += ((req->byte_position + offset) % ocf_line_size(cache));
|
||||||
bytes = size;
|
bytes = size;
|
||||||
|
|
||||||
ocf_io_configure(io, addr, bytes, dir, class, flags);
|
io = ocf_new_cache_io(cache, req->io_queue,
|
||||||
ocf_io_set_queue(io, 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);
|
ocf_io_set_cmpl(io, req, callback, ocf_submit_volume_req_cmpl);
|
||||||
|
|
||||||
err = ocf_io_set_data(io, req->data, offset);
|
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. */
|
/* Issue requests to cache. */
|
||||||
for (i = 0; i < reqs; i++) {
|
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,
|
addr = ocf_metadata_map_lg2phy(cache,
|
||||||
req->map[first_cl + i].coll_idx);
|
req->map[first_cl + i].coll_idx);
|
||||||
addr *= ocf_line_size(cache);
|
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);
|
bytes = OCF_MIN(bytes, size - total_bytes);
|
||||||
ENV_BUG_ON(bytes == 0);
|
ENV_BUG_ON(bytes == 0);
|
||||||
|
|
||||||
ocf_io_configure(io, addr, bytes, dir, class, flags);
|
io = ocf_new_cache_io(cache, req->io_queue,
|
||||||
ocf_io_set_queue(io, 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);
|
ocf_io_set_cmpl(io, req, callback, ocf_submit_volume_req_cmpl);
|
||||||
|
|
||||||
err = ocf_io_set_data(io, req->data, offset + total_bytes);
|
err = ocf_io_set_data(io, req->data, offset + total_bytes);
|
||||||
@ -338,8 +333,8 @@ void ocf_submit_volume_req(ocf_volume_t volume, struct ocf_request *req,
|
|||||||
ocf_req_end_t callback)
|
ocf_req_end_t callback)
|
||||||
{
|
{
|
||||||
struct ocf_counters_block *core_stats;
|
struct ocf_counters_block *core_stats;
|
||||||
uint64_t flags = req->io ? req->io->flags : 0;
|
uint64_t flags = req->ioi.io.flags;
|
||||||
uint32_t class = req->io ? req->io->io_class : 0;
|
uint32_t class = req->ioi.io.io_class;
|
||||||
int dir = req->rw;
|
int dir = req->rw;
|
||||||
struct ocf_io *io;
|
struct ocf_io *io;
|
||||||
int err;
|
int err;
|
||||||
@ -350,15 +345,13 @@ void ocf_submit_volume_req(ocf_volume_t volume, struct ocf_request *req,
|
|||||||
else if (dir == OCF_READ)
|
else if (dir == OCF_READ)
|
||||||
env_atomic64_add(req->byte_length, &core_stats->read_bytes);
|
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) {
|
if (!io) {
|
||||||
callback(req, -OCF_ERR_NO_MEM);
|
callback(req, -OCF_ERR_NO_MEM);
|
||||||
return;
|
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);
|
ocf_io_set_cmpl(io, req, callback, ocf_submit_volume_req_cmpl);
|
||||||
err = ocf_io_set_data(io, req->data, 0);
|
err = ocf_io_set_data(io, req->data, 0);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -64,17 +64,21 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache,
|
|||||||
struct ocf_request *req, int dir, uint64_t offset,
|
struct ocf_request *req, int dir, uint64_t offset,
|
||||||
uint64_t size, unsigned int reqs, ocf_req_end_t callback);
|
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,
|
static inline struct ocf_io *ocf_new_core_io(ocf_core_t core,
|
||||||
ocf_core_id_t core_id)
|
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(ocf_core_get_volume(core), queue,
|
||||||
|
addr, bytes, dir, io_class, flags);
|
||||||
return ocf_volume_new_io(&cache->core[core_id].volume);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* UTILS_IO_H_ */
|
#endif /* UTILS_IO_H_ */
|
||||||
|
62
src/utils/utils_io_allocator.h
Normal file
62
src/utils/utils_io_allocator.h
Normal file
@ -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__ */
|
@ -11,9 +11,10 @@ from ctypes import (
|
|||||||
c_int,
|
c_int,
|
||||||
c_uint8,
|
c_uint8,
|
||||||
c_uint16,
|
c_uint16,
|
||||||
|
c_uint32,
|
||||||
|
c_uint64,
|
||||||
c_char_p,
|
c_char_p,
|
||||||
c_bool,
|
c_bool,
|
||||||
c_uint32,
|
|
||||||
cast,
|
cast,
|
||||||
byref,
|
byref,
|
||||||
create_string_buffer,
|
create_string_buffer,
|
||||||
@ -22,6 +23,7 @@ from datetime import timedelta
|
|||||||
|
|
||||||
from .data import Data
|
from .data import Data
|
||||||
from .io import Io, IoDir
|
from .io import Io, IoDir
|
||||||
|
from .queue import Queue
|
||||||
from .shared import Uuid, OcfCompletion, OcfError, SeqCutOffPolicy
|
from .shared import Uuid, OcfCompletion, OcfError, SeqCutOffPolicy
|
||||||
from .stats.core import CoreStats
|
from .stats.core import CoreStats
|
||||||
from .stats.shared import UsageStats, RequestsStats, BlocksStats, ErrorsStats
|
from .stats.shared import UsageStats, RequestsStats, BlocksStats, ErrorsStats
|
||||||
@ -92,17 +94,25 @@ class Core:
|
|||||||
def get_handle(self):
|
def get_handle(self):
|
||||||
return self.handle
|
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:
|
if not self.cache:
|
||||||
raise Exception("Core isn't attached to any 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)
|
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()
|
lib = OcfLib.getInstance()
|
||||||
core = lib.ocf_core_get_volume(self.handle)
|
volume = lib.ocf_core_get_volume(self.handle)
|
||||||
io = lib.ocf_volume_new_io(core)
|
io = lib.ocf_volume_new_io(
|
||||||
|
volume, queue.handle, addr, length, direction, io_class, flags)
|
||||||
return Io.from_pointer(io)
|
return Io.from_pointer(io)
|
||||||
|
|
||||||
def get_stats(self):
|
def get_stats(self):
|
||||||
@ -166,10 +176,9 @@ class Core:
|
|||||||
|
|
||||||
position = 0
|
position = 0
|
||||||
while position < read_buffer_all.size:
|
while position < read_buffer_all.size:
|
||||||
io = self.new_io()
|
io = self.new_io(self.cache.get_default_queue(), position,
|
||||||
io.configure(position, cache_line_size, IoDir.READ, 0, 0)
|
cache_line_size, IoDir.READ, 0, 0)
|
||||||
io.set_data(read_buffer)
|
io.set_data(read_buffer)
|
||||||
io.set_queue(self.cache.get_default_queue())
|
|
||||||
|
|
||||||
cmpl = OcfCompletion([("err", c_int)])
|
cmpl = OcfCompletion([("err", c_int)])
|
||||||
io.callback = cmpl.callback
|
io.callback = cmpl.callback
|
||||||
@ -187,7 +196,15 @@ class Core:
|
|||||||
|
|
||||||
lib = OcfLib.getInstance()
|
lib = OcfLib.getInstance()
|
||||||
lib.ocf_core_get_volume.restype = c_void_p
|
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_volume_new_io.restype = c_void_p
|
||||||
lib.ocf_core_get_volume.argtypes = [c_void_p]
|
lib.ocf_core_get_volume.argtypes = [c_void_p]
|
||||||
lib.ocf_core_get_volume.restype = 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_stats_collect_core.restype = c_int
|
||||||
lib.ocf_core_get_stats.argtypes = [c_void_p, c_void_p]
|
lib.ocf_core_get_stats.argtypes = [c_void_p, c_void_p]
|
||||||
lib.ocf_core_get_stats.restype = c_int
|
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
|
||||||
|
@ -18,7 +18,6 @@ from enum import IntEnum
|
|||||||
|
|
||||||
from ..ocf import OcfLib
|
from ..ocf import OcfLib
|
||||||
from .data import Data
|
from .data import Data
|
||||||
from .queue import Queue
|
|
||||||
|
|
||||||
|
|
||||||
class IoDir(IntEnum):
|
class IoDir(IntEnum):
|
||||||
@ -37,8 +36,6 @@ class Io(Structure):
|
|||||||
|
|
||||||
_instances_ = {}
|
_instances_ = {}
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
("_volume", c_void_p),
|
|
||||||
("_ops", POINTER(IoOps)),
|
|
||||||
("_addr", c_uint64),
|
("_addr", c_uint64),
|
||||||
("_flags", c_uint64),
|
("_flags", c_uint64),
|
||||||
("_bytes", c_uint32),
|
("_bytes", c_uint32),
|
||||||
@ -101,19 +98,9 @@ class Io(Structure):
|
|||||||
def submit(self):
|
def submit(self):
|
||||||
return OcfLib.getInstance().ocf_core_submit_io_wrapper(byref(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):
|
def set_data(self, data: Data, offset: int = 0):
|
||||||
self.data = data
|
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)
|
|
||||||
|
|
||||||
|
|
||||||
IoOps.SET_DATA = CFUNCTYPE(c_int, POINTER(Io), c_void_p, c_uint32)
|
IoOps.SET_DATA = CFUNCTYPE(c_int, POINTER(Io), c_void_p, c_uint32)
|
||||||
@ -122,22 +109,10 @@ IoOps.GET_DATA = CFUNCTYPE(c_void_p, POINTER(Io))
|
|||||||
IoOps._fields_ = [("_set_data", IoOps.SET_DATA), ("_get_data", IoOps.GET_DATA)]
|
IoOps._fields_ = [("_set_data", IoOps.SET_DATA), ("_get_data", IoOps.GET_DATA)]
|
||||||
|
|
||||||
lib = OcfLib.getInstance()
|
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_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.argtypes = [c_void_p]
|
||||||
lib.ocf_core_new_io_wrapper.restype = 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.argtypes = [POINTER(Io), c_void_p, c_uint32]
|
||||||
lib.ocf_io_set_data_wrapper.restype = c_int
|
lib.ocf_io_set_data.restype = c_int
|
||||||
|
|
||||||
lib.ocf_io_set_queue_wrapper.argtypes = [POINTER(Io), c_void_p]
|
|
||||||
|
@ -145,7 +145,9 @@ class Volume(Structure):
|
|||||||
@VolumeOps.SUBMIT_IO
|
@VolumeOps.SUBMIT_IO
|
||||||
def _submit_io(io):
|
def _submit_io(io):
|
||||||
io_structure = cast(io, POINTER(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)
|
volume.submit_io(io_structure)
|
||||||
|
|
||||||
@ -153,7 +155,9 @@ class Volume(Structure):
|
|||||||
@VolumeOps.SUBMIT_FLUSH
|
@VolumeOps.SUBMIT_FLUSH
|
||||||
def _submit_flush(flush):
|
def _submit_flush(flush):
|
||||||
io_structure = cast(flush, POINTER(Io))
|
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)
|
volume.submit_flush(io_structure)
|
||||||
|
|
||||||
@ -166,7 +170,9 @@ class Volume(Structure):
|
|||||||
@VolumeOps.SUBMIT_DISCARD
|
@VolumeOps.SUBMIT_DISCARD
|
||||||
def _submit_discard(discard):
|
def _submit_discard(discard):
|
||||||
io_structure = cast(discard, POINTER(Io))
|
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)
|
volume.submit_discard(io_structure)
|
||||||
|
|
||||||
@ -273,11 +279,11 @@ class Volume(Structure):
|
|||||||
offset = io_priv.contents._offset
|
offset = io_priv.contents._offset
|
||||||
|
|
||||||
if io.contents._dir == IoDir.WRITE:
|
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
|
src = Data.get_instance(src_ptr.value).handle.value + offset
|
||||||
dst = self._storage + io.contents._addr
|
dst = self._storage + io.contents._addr
|
||||||
elif io.contents._dir == IoDir.READ:
|
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
|
dst = Data.get_instance(dst_ptr.value).handle.value + offset
|
||||||
src = self._storage + io.contents._addr
|
src = self._storage + io.contents._addr
|
||||||
|
|
||||||
@ -342,3 +348,7 @@ class TraceDevice(Volume):
|
|||||||
|
|
||||||
lib = OcfLib.getInstance()
|
lib = OcfLib.getInstance()
|
||||||
lib.ocf_io_get_priv.restype = POINTER(VolumeIoPriv)
|
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
|
||||||
|
@ -6,15 +6,11 @@
|
|||||||
#include "ocf/ocf_io.h"
|
#include "ocf/ocf_io.h"
|
||||||
#include "ocf/ocf_core.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);
|
return ocf_core_new_io(core, queue, addr, bytes, dir, io_class, flags);
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ocf_io_set_cmpl_wrapper(struct ocf_io *io, void *context,
|
void ocf_io_set_cmpl_wrapper(struct ocf_io *io, void *context,
|
||||||
@ -33,22 +29,6 @@ void ocf_io_set_handle_wrapper(struct ocf_io *io, ocf_handle_io_t fn)
|
|||||||
ocf_io_set_handle(io, 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ocf_core_submit_io_wrapper(struct ocf_io *io)
|
void ocf_core_submit_io_wrapper(struct ocf_io *io)
|
||||||
{
|
{
|
||||||
ocf_core_submit_io(io);
|
ocf_core_submit_io(io);
|
||||||
|
@ -32,10 +32,9 @@ def test_simple_wt_write(pyocf_ctx):
|
|||||||
core_device.reset_stats()
|
core_device.reset_stats()
|
||||||
|
|
||||||
write_data = Data.from_string("This is test data")
|
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.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)])
|
cmpl = OcfCompletion([("err", c_int)])
|
||||||
io.callback = cmpl.callback
|
io.callback = cmpl.callback
|
||||||
|
@ -19,8 +19,6 @@ from pyocf.types.shared import OcfCompletion
|
|||||||
|
|
||||||
def __io(io, queue, address, size, data, direction):
|
def __io(io, queue, address, size, data, direction):
|
||||||
io.set_data(data, 0)
|
io.set_data(data, 0)
|
||||||
io.configure(address, size, direction, 0, 0)
|
|
||||||
io.set_queue(queue)
|
|
||||||
completion = OcfCompletion([("err", c_int)])
|
completion = OcfCompletion([("err", c_int)])
|
||||||
io.callback = completion.callback
|
io.callback = completion.callback
|
||||||
io.submit()
|
io.submit()
|
||||||
@ -28,7 +26,8 @@ def __io(io, queue, address, size, data, direction):
|
|||||||
return int(completion.results['err'])
|
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:
|
if direction == IoDir.READ:
|
||||||
_data = Data.from_bytes(bytes(size))
|
_data = Data.from_bytes(bytes(size))
|
||||||
else:
|
else:
|
||||||
@ -40,12 +39,12 @@ def _io(io, queue, address, size, data, offset, direction):
|
|||||||
|
|
||||||
|
|
||||||
def io_to_core(core, 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)
|
data, offset, direction)
|
||||||
|
|
||||||
|
|
||||||
def io_to_exp_obj(core, 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)
|
offset, direction)
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,10 +101,10 @@ def test_10add_remove_with_io(pyocf_ctx):
|
|||||||
assert stats["conf"]["core_count"] == 1
|
assert stats["conf"]["core_count"] == 1
|
||||||
|
|
||||||
write_data = Data.from_string("Test data")
|
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.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)])
|
cmpl = OcfCompletion([("err", c_int)])
|
||||||
io.callback = cmpl.callback
|
io.callback = cmpl.callback
|
||||||
|
@ -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):
|
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.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)])
|
completion = OcfCompletion([("err", c_int)])
|
||||||
io.callback = completion.callback
|
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):
|
def io_from_exported_object(exported_obj: Core, buffer_size: int, offset: int):
|
||||||
read_buffer = Data(buffer_size)
|
read_buffer = Data(buffer_size)
|
||||||
io = exported_obj.new_io()
|
io = exported_obj.new_io(exported_obj.cache.get_default_queue(), offset,
|
||||||
io.configure(offset, read_buffer.size, IoDir.READ, 0, 0)
|
read_buffer.size, IoDir.READ, 0, 0)
|
||||||
io.set_data(read_buffer)
|
io.set_data(read_buffer)
|
||||||
io.set_queue(exported_obj.cache.get_default_queue())
|
|
||||||
|
|
||||||
completion = OcfCompletion([("err", c_int)])
|
completion = OcfCompletion([("err", c_int)])
|
||||||
io.callback = completion.callback
|
io.callback = completion.callback
|
||||||
|
@ -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):
|
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.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)])
|
completion = OcfCompletion([("err", c_int)])
|
||||||
io.callback = completion.callback
|
io.callback = completion.callback
|
||||||
|
@ -87,10 +87,10 @@ def test_secure_erase_simple_io_read_misses(cache_mode):
|
|||||||
cache.add_core(core)
|
cache.add_core(core)
|
||||||
|
|
||||||
write_data = Data.from_string("This is test data")
|
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.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)])
|
cmpl = OcfCompletion([("err", c_int)])
|
||||||
io.callback = cmpl.callback
|
io.callback = cmpl.callback
|
||||||
@ -100,12 +100,11 @@ def test_secure_erase_simple_io_read_misses(cache_mode):
|
|||||||
cmpls = []
|
cmpls = []
|
||||||
for i in range(100):
|
for i in range(100):
|
||||||
read_data = Data(500)
|
read_data = Data(500)
|
||||||
io = core.new_io()
|
io = core.new_io(
|
||||||
io.set_data(read_data)
|
cache.get_default_queue(), (i * 1259) % int(core_device.size),
|
||||||
io.configure(
|
read_data.size, IoDir.READ, 0, 0
|
||||||
(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)])
|
cmpl = OcfCompletion([("err", c_int)])
|
||||||
io.callback = cmpl.callback
|
io.callback = cmpl.callback
|
||||||
@ -116,10 +115,10 @@ def test_secure_erase_simple_io_read_misses(cache_mode):
|
|||||||
c.wait()
|
c.wait()
|
||||||
|
|
||||||
write_data = Data.from_string("TEST DATA" * 100)
|
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.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)])
|
cmpl = OcfCompletion([("err", c_int)])
|
||||||
io.callback = cmpl.callback
|
io.callback = cmpl.callback
|
||||||
@ -169,12 +168,11 @@ def test_secure_erase_simple_io_cleaning():
|
|||||||
cmpls = []
|
cmpls = []
|
||||||
for i in range(10000):
|
for i in range(10000):
|
||||||
read_data = Data(S.from_KiB(120))
|
read_data = Data(S.from_KiB(120))
|
||||||
io = core.new_io()
|
io = core.new_io(
|
||||||
io.set_data(read_data)
|
cache.get_default_queue(), (i * 1259) % int(core_device.size),
|
||||||
io.configure(
|
read_data.size, IoDir.WRITE, 0, 0
|
||||||
(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)])
|
cmpl = OcfCompletion([("err", c_int)])
|
||||||
io.callback = cmpl.callback
|
io.callback = cmpl.callback
|
||||||
|
Loading…
Reference in New Issue
Block a user