xref: /spdk/test/common/lib/test_iobuf.c (revision f1900e4d82247d979a07b0a33b902c2d4fef693a)
14bb9dcdbSBen Walker /*   SPDX-License-Identifier: BSD-3-Clause
24bb9dcdbSBen Walker  *   Copyright (C) 2023 Intel Corporation.
34bb9dcdbSBen Walker  *   All rights reserved.
44bb9dcdbSBen Walker  */
54bb9dcdbSBen Walker #include "spdk/stdinc.h"
64bb9dcdbSBen Walker 
74bb9dcdbSBen Walker #include "spdk_internal/mock.h"
84bb9dcdbSBen Walker 
94bb9dcdbSBen Walker #include "spdk/thread.h"
104bb9dcdbSBen Walker 
114bb9dcdbSBen Walker DEFINE_STUB(spdk_iobuf_initialize, int, (void), 0);
124bb9dcdbSBen Walker DEFINE_STUB(spdk_iobuf_register_module, int, (const char *name), 0);
134bb9dcdbSBen Walker DEFINE_STUB(spdk_iobuf_unregister_module, int, (const char *name), 0);
144bb9dcdbSBen Walker DEFINE_STUB_V(spdk_iobuf_channel_fini, (struct spdk_iobuf_channel *ch));
154bb9dcdbSBen Walker DEFINE_STUB(spdk_iobuf_for_each_entry, int, (struct spdk_iobuf_channel *ch,
16b82fd48aSJim Harris 		spdk_iobuf_for_each_entry_fn cb_fn, void *cb_ctx), 0);
174bb9dcdbSBen Walker DEFINE_STUB_V(spdk_iobuf_entry_abort, (struct spdk_iobuf_channel *ch,
184bb9dcdbSBen Walker 				       struct spdk_iobuf_entry *entry, uint64_t len));
194bb9dcdbSBen Walker 
204bb9dcdbSBen Walker struct ut_iobuf {
214bb9dcdbSBen Walker 	struct spdk_iobuf_opts	opts;
224bb9dcdbSBen Walker 	uint32_t		small_pool_count;
234bb9dcdbSBen Walker 	uint32_t		large_pool_count;
244bb9dcdbSBen Walker };
254bb9dcdbSBen Walker 
264bb9dcdbSBen Walker static struct ut_iobuf g_iobuf = {
274bb9dcdbSBen Walker 	.small_pool_count = 32,
284bb9dcdbSBen Walker 	.large_pool_count = 32
294bb9dcdbSBen Walker };
304bb9dcdbSBen Walker static spdk_iobuf_entry_stailq_t g_iobuf_entries;
314bb9dcdbSBen Walker 
324bb9dcdbSBen Walker int
334bb9dcdbSBen Walker spdk_iobuf_set_opts(const struct spdk_iobuf_opts *opts)
344bb9dcdbSBen Walker {
354bb9dcdbSBen Walker 	g_iobuf.opts = *opts;
364bb9dcdbSBen Walker 	g_iobuf.small_pool_count = opts->small_pool_count;
374bb9dcdbSBen Walker 	g_iobuf.large_pool_count = opts->large_pool_count;
384bb9dcdbSBen Walker 	return 0;
394bb9dcdbSBen Walker }
404bb9dcdbSBen Walker 
414bb9dcdbSBen Walker void
42194983eeSJohn Levon spdk_iobuf_get_opts(struct spdk_iobuf_opts *opts, size_t opts_size)
434bb9dcdbSBen Walker {
444bb9dcdbSBen Walker 	*opts = g_iobuf.opts;
454bb9dcdbSBen Walker }
464bb9dcdbSBen Walker 
474bb9dcdbSBen Walker void
484bb9dcdbSBen Walker spdk_iobuf_finish(spdk_iobuf_finish_cb cb_fn, void *cb_arg)
494bb9dcdbSBen Walker {
504bb9dcdbSBen Walker 	cb_fn(cb_arg);
514bb9dcdbSBen Walker }
524bb9dcdbSBen Walker 
534bb9dcdbSBen Walker int
544bb9dcdbSBen Walker spdk_iobuf_channel_init(struct spdk_iobuf_channel *ch, const char *name,
554bb9dcdbSBen Walker 			uint32_t small_cache_size, uint32_t large_cache_size)
564bb9dcdbSBen Walker {
57eba178bfSJim Harris 	struct spdk_iobuf_node_cache *cache;
58eba178bfSJim Harris 
59*f1900e4dSJim Harris 	cache = &ch->cache[0];
60eba178bfSJim Harris 
614bb9dcdbSBen Walker 	STAILQ_INIT(&g_iobuf_entries);
62eba178bfSJim Harris 	cache->small.cache_count = small_cache_size;
63eba178bfSJim Harris 	cache->small.cache_size = small_cache_size;
64eba178bfSJim Harris 	cache->large.cache_count = large_cache_size;
65eba178bfSJim Harris 	cache->large.cache_size = large_cache_size;
664bb9dcdbSBen Walker 	return 0;
674bb9dcdbSBen Walker }
684bb9dcdbSBen Walker 
694bb9dcdbSBen Walker DEFINE_RETURN_MOCK(spdk_iobuf_get, void *);
704bb9dcdbSBen Walker void *
714bb9dcdbSBen Walker spdk_iobuf_get(struct spdk_iobuf_channel *ch, uint64_t len,
724bb9dcdbSBen Walker 	       struct spdk_iobuf_entry *entry, spdk_iobuf_get_cb cb_fn)
734bb9dcdbSBen Walker {
74eba178bfSJim Harris 	struct spdk_iobuf_node_cache *cache;
75eba178bfSJim Harris 	struct spdk_iobuf_pool_cache *pool;
764bb9dcdbSBen Walker 	uint32_t *count;
774bb9dcdbSBen Walker 	void *buf;
784bb9dcdbSBen Walker 
794bb9dcdbSBen Walker 	HANDLE_RETURN_MOCK(spdk_iobuf_get);
804bb9dcdbSBen Walker 
81*f1900e4dSJim Harris 	cache = &ch->cache[0];
82eba178bfSJim Harris 
834bb9dcdbSBen Walker 	if (len > g_iobuf.opts.small_bufsize) {
84eba178bfSJim Harris 		pool = &cache->large;
854bb9dcdbSBen Walker 		count = &g_iobuf.large_pool_count;
864bb9dcdbSBen Walker 	} else {
87eba178bfSJim Harris 		pool = &cache->small;
884bb9dcdbSBen Walker 		count = &g_iobuf.small_pool_count;
894bb9dcdbSBen Walker 	}
904bb9dcdbSBen Walker 
914bb9dcdbSBen Walker 	if (pool->cache_count > 0) {
924bb9dcdbSBen Walker 		buf = calloc(1, len);
934bb9dcdbSBen Walker 		CU_ASSERT(buf != NULL);
944bb9dcdbSBen Walker 		pool->cache_count--;
954bb9dcdbSBen Walker 		return buf;
964bb9dcdbSBen Walker 	}
974bb9dcdbSBen Walker 
984bb9dcdbSBen Walker 	if (*count == 0) {
994bb9dcdbSBen Walker 		if (entry) {
1004bb9dcdbSBen Walker 			entry->cb_fn = cb_fn;
1014bb9dcdbSBen Walker 			STAILQ_INSERT_TAIL(&g_iobuf_entries, entry, stailq);
1024bb9dcdbSBen Walker 		}
1034bb9dcdbSBen Walker 
1044bb9dcdbSBen Walker 		return NULL;
1054bb9dcdbSBen Walker 	}
1064bb9dcdbSBen Walker 
1074bb9dcdbSBen Walker 	buf = calloc(1, len);
1084bb9dcdbSBen Walker 	CU_ASSERT(buf != NULL);
1094bb9dcdbSBen Walker 	(*count)--;
1104bb9dcdbSBen Walker 	return buf;
1114bb9dcdbSBen Walker }
1124bb9dcdbSBen Walker 
1134bb9dcdbSBen Walker void
1144bb9dcdbSBen Walker spdk_iobuf_put(struct spdk_iobuf_channel *ch, void *buf, uint64_t len)
1154bb9dcdbSBen Walker {
1164bb9dcdbSBen Walker 	struct spdk_iobuf_entry *entry;
117eba178bfSJim Harris 	struct spdk_iobuf_node_cache *cache;
118eba178bfSJim Harris 	struct spdk_iobuf_pool_cache *pool;
1194bb9dcdbSBen Walker 	uint32_t *count;
1204bb9dcdbSBen Walker 
121*f1900e4dSJim Harris 	cache = &ch->cache[0];
122eba178bfSJim Harris 
1234bb9dcdbSBen Walker 	if (len > g_iobuf.opts.small_bufsize) {
124eba178bfSJim Harris 		pool = &cache->large;
1254bb9dcdbSBen Walker 		count = &g_iobuf.large_pool_count;
1264bb9dcdbSBen Walker 	} else {
127eba178bfSJim Harris 		pool = &cache->small;
1284bb9dcdbSBen Walker 		count = &g_iobuf.small_pool_count;
1294bb9dcdbSBen Walker 	}
1304bb9dcdbSBen Walker 
1314bb9dcdbSBen Walker 	if (!STAILQ_EMPTY(&g_iobuf_entries)) {
1324bb9dcdbSBen Walker 		entry = STAILQ_FIRST(&g_iobuf_entries);
1334bb9dcdbSBen Walker 		STAILQ_REMOVE_HEAD(&g_iobuf_entries, stailq);
1344bb9dcdbSBen Walker 		entry->cb_fn(entry, buf);
1354bb9dcdbSBen Walker 		return;
1364bb9dcdbSBen Walker 	}
1374bb9dcdbSBen Walker 
1384bb9dcdbSBen Walker 	if (pool->cache_count < pool->cache_size) {
1394bb9dcdbSBen Walker 		pool->cache_count++;
1404bb9dcdbSBen Walker 	} else {
1414bb9dcdbSBen Walker 		(*count)++;
1424bb9dcdbSBen Walker 	}
1434bb9dcdbSBen Walker 
1444bb9dcdbSBen Walker 	free(buf);
1454bb9dcdbSBen Walker }
146