Introduce OCF IO allocator
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
		| @@ -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__ */ | ||||||
		Reference in New Issue
	
	Block a user
	 Robert Baldyga
					Robert Baldyga