Introduce OCF IO allocator
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
parent
2efd563df1
commit
61414f889e
@ -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
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
48
src/ocf_io.c
48
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,17 +27,49 @@
|
|||||||
* +-------------------------+ <----------------
|
* +-------------------------+ <----------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define OCF_IO_TOTAL_SIZE(priv_size) \
|
#define OCF_IO_TOTAL(priv_size) \
|
||||||
(sizeof(struct ocf_io_internal) + priv_size)
|
(sizeof(struct ocf_io_internal) + priv_size)
|
||||||
|
|
||||||
env_allocator *ocf_io_allocator_create(uint32_t size, const char *name)
|
static int ocf_io_allocator_default_init(ocf_io_allocator_t allocator,
|
||||||
|
uint32_t priv_size, const char *name)
|
||||||
{
|
{
|
||||||
return env_allocator_create(OCF_IO_TOTAL_SIZE(size), name);
|
allocator->priv = env_allocator_create(OCF_IO_TOTAL(priv_size), name);
|
||||||
|
if (!allocator->priv)
|
||||||
|
return -OCF_ERR_NO_MEM;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ocf_io_allocator_destroy(env_allocator *allocator)
|
static void ocf_io_allocator_default_deinit(ocf_io_allocator_t allocator)
|
||||||
{
|
{
|
||||||
env_allocator_destroy(allocator);
|
env_allocator_destroy(allocator->priv);
|
||||||
|
allocator->priv = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *ocf_io_allocator_default_new(ocf_io_allocator_t allocator,
|
||||||
|
ocf_volume_t volume, ocf_queue_t queue,
|
||||||
|
uint64_t addr, uint32_t bytes, uint32_t dir)
|
||||||
|
{
|
||||||
|
return env_allocator_new(allocator->priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ocf_io_allocator_default_del(ocf_io_allocator_t allocator, void *obj)
|
||||||
|
{
|
||||||
|
env_allocator_del(allocator->priv, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct ocf_io_allocator_type type_default = {
|
||||||
|
.ops = {
|
||||||
|
.allocator_init = ocf_io_allocator_default_init,
|
||||||
|
.allocator_deinit = ocf_io_allocator_default_deinit,
|
||||||
|
.allocator_new = ocf_io_allocator_default_new,
|
||||||
|
.allocator_del = ocf_io_allocator_default_del,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
ocf_io_allocator_type_t ocf_io_allocator_get_type_default(void)
|
||||||
|
{
|
||||||
|
return &type_default;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -57,7 +90,8 @@ struct ocf_io *ocf_io_new(ocf_volume_t volume, ocf_queue_t queue,
|
|||||||
if (!ocf_refcnt_inc(&volume->refcnt))
|
if (!ocf_refcnt_inc(&volume->refcnt))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ioi = env_allocator_new(volume->type->allocator);
|
ioi = ocf_io_allocator_new(&volume->type->allocator, volume, queue,
|
||||||
|
addr, bytes, dir);
|
||||||
if (!ioi) {
|
if (!ioi) {
|
||||||
ocf_refcnt_dec(&volume->refcnt);
|
ocf_refcnt_dec(&volume->refcnt);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -116,7 +150,7 @@ void ocf_io_put(struct ocf_io *io)
|
|||||||
|
|
||||||
ocf_refcnt_dec(&ioi->meta.volume->refcnt);
|
ocf_refcnt_dec(&ioi->meta.volume->refcnt);
|
||||||
|
|
||||||
env_allocator_del(ioi->meta.volume->type->allocator, (void *)ioi);
|
ocf_io_allocator_del(&ioi->meta.volume->type->allocator, (void *)ioi);
|
||||||
}
|
}
|
||||||
|
|
||||||
ocf_volume_t ocf_io_get_volume(struct ocf_io *io)
|
ocf_volume_t ocf_io_get_volume(struct ocf_io *io)
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "ocf/ocf.h"
|
#include "ocf/ocf.h"
|
||||||
#include "ocf_request.h"
|
#include "ocf_request.h"
|
||||||
|
#include "utils/utils_io_allocator.h"
|
||||||
|
|
||||||
struct ocf_io_meta {
|
struct ocf_io_meta {
|
||||||
ocf_volume_t volume;
|
ocf_volume_t volume;
|
||||||
@ -21,9 +22,9 @@ struct ocf_io_internal {
|
|||||||
struct ocf_io io;
|
struct ocf_io io;
|
||||||
};
|
};
|
||||||
|
|
||||||
env_allocator *ocf_io_allocator_create(uint32_t size, const char *name);
|
int ocf_io_allocator_init(ocf_io_allocator_t allocator, ocf_io_allocator_type_t type,
|
||||||
|
uint32_t priv_size, const char *name);
|
||||||
|
|
||||||
void ocf_io_allocator_destroy(env_allocator *allocator);
|
|
||||||
|
|
||||||
struct ocf_io *ocf_io_new(ocf_volume_t volume, ocf_queue_t queue,
|
struct ocf_io *ocf_io_new(ocf_volume_t volume, ocf_queue_t queue,
|
||||||
uint64_t addr, uint32_t bytes, uint32_t dir,
|
uint64_t addr, uint32_t bytes, uint32_t dir,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -658,16 +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, req->io_queue,
|
|
||||||
addr, ocf_line_size(cache),
|
|
||||||
OCF_READ, part_id, 0);
|
|
||||||
if (!io) {
|
|
||||||
/* Allocation error */
|
|
||||||
iter->invalid = true;
|
|
||||||
_ocf_cleaner_set_error(req);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
OCF_DEBUG_PARAM(req->cache, "Cache read, line = %u",
|
OCF_DEBUG_PARAM(req->cache, "Cache read, line = %u",
|
||||||
iter->coll_idx);
|
iter->coll_idx);
|
||||||
|
|
||||||
@ -680,6 +670,16 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req)
|
|||||||
|
|
||||||
part_id = ocf_metadata_get_partition_id(cache, iter->coll_idx);
|
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);
|
||||||
err = ocf_io_set_data(io, req->data, offset);
|
err = ocf_io_set_data(io, req->data, offset);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
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__ */
|
Loading…
Reference in New Issue
Block a user