Commit 4bb9dcdb authored by Ben Walker's avatar Ben Walker Committed by Jim Harris
Browse files

test: Add test_iobuf.c to mock the iobuf library



Use it in all of the places that were previously hooking
spdk_mempool_get.

Change-Id: I311f75fb9601b4f987b106160eb0a0014d3327cd
Signed-off-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16329


Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 9bc7d6b3
Loading
Loading
Loading
Loading
+135 −0
Original line number Diff line number Diff line
/*   SPDX-License-Identifier: BSD-3-Clause
 *   Copyright (C) 2023 Intel Corporation.
 *   All rights reserved.
 */
#include "spdk/stdinc.h"

#include "spdk_internal/mock.h"

#include "spdk/thread.h"

DEFINE_STUB(spdk_iobuf_initialize, int, (void), 0);
DEFINE_STUB(spdk_iobuf_register_module, int, (const char *name), 0);
DEFINE_STUB(spdk_iobuf_unregister_module, int, (const char *name), 0);
DEFINE_STUB_V(spdk_iobuf_channel_fini, (struct spdk_iobuf_channel *ch));
DEFINE_STUB(spdk_iobuf_for_each_entry, int, (struct spdk_iobuf_channel *ch,
		struct spdk_iobuf_pool *pool, spdk_iobuf_for_each_entry_fn cb_fn, void *cb_ctx), 0);
DEFINE_STUB_V(spdk_iobuf_entry_abort, (struct spdk_iobuf_channel *ch,
				       struct spdk_iobuf_entry *entry, uint64_t len));

struct ut_iobuf {
	struct spdk_iobuf_opts	opts;
	uint32_t		small_pool_count;
	uint32_t		large_pool_count;
};

static struct ut_iobuf g_iobuf = {
	.small_pool_count = 32,
	.large_pool_count = 32
};
static spdk_iobuf_entry_stailq_t g_iobuf_entries;

int
spdk_iobuf_set_opts(const struct spdk_iobuf_opts *opts)
{
	g_iobuf.opts = *opts;
	g_iobuf.small_pool_count = opts->small_pool_count;
	g_iobuf.large_pool_count = opts->large_pool_count;
	return 0;
}

void
spdk_iobuf_get_opts(struct spdk_iobuf_opts *opts)
{
	*opts = g_iobuf.opts;
}

void
spdk_iobuf_finish(spdk_iobuf_finish_cb cb_fn, void *cb_arg)
{
	cb_fn(cb_arg);
}

int
spdk_iobuf_channel_init(struct spdk_iobuf_channel *ch, const char *name,
			uint32_t small_cache_size, uint32_t large_cache_size)
{
	STAILQ_INIT(&g_iobuf_entries);
	ch->small.cache_count = small_cache_size;
	ch->small.cache_size = small_cache_size;
	ch->large.cache_count = large_cache_size;
	ch->large.cache_size = large_cache_size;
	return 0;
}

DEFINE_RETURN_MOCK(spdk_iobuf_get, void *);
void *
spdk_iobuf_get(struct spdk_iobuf_channel *ch, uint64_t len,
	       struct spdk_iobuf_entry *entry, spdk_iobuf_get_cb cb_fn)
{
	struct spdk_iobuf_pool *pool;
	uint32_t *count;
	void *buf;

	HANDLE_RETURN_MOCK(spdk_iobuf_get);

	if (len > g_iobuf.opts.small_bufsize) {
		pool = &ch->large;
		count = &g_iobuf.large_pool_count;
	} else {
		pool = &ch->small;
		count = &g_iobuf.small_pool_count;
	}

	if (pool->cache_count > 0) {
		buf = calloc(1, len);
		CU_ASSERT(buf != NULL);
		pool->cache_count--;
		return buf;
	}

	if (*count == 0) {
		if (entry) {
			entry->cb_fn = cb_fn;
			STAILQ_INSERT_TAIL(&g_iobuf_entries, entry, stailq);
		}

		return NULL;
	}

	buf = calloc(1, len);
	CU_ASSERT(buf != NULL);
	(*count)--;
	return buf;
}

void
spdk_iobuf_put(struct spdk_iobuf_channel *ch, void *buf, uint64_t len)
{
	struct spdk_iobuf_entry *entry;
	struct spdk_iobuf_pool *pool;
	uint32_t *count;

	if (len > g_iobuf.opts.small_bufsize) {
		pool = &ch->large;
		count = &g_iobuf.large_pool_count;
	} else {
		pool = &ch->small;
		count = &g_iobuf.small_pool_count;
	}

	if (!STAILQ_EMPTY(&g_iobuf_entries)) {
		entry = STAILQ_FIRST(&g_iobuf_entries);
		STAILQ_REMOVE_HEAD(&g_iobuf_entries, stailq);
		entry->cb_fn(entry, buf);
		return;
	}

	if (pool->cache_count < pool->cache_size) {
		pool->cache_count++;
	} else {
		(*count)++;
	}

	free(buf);
}
+1 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ lib/idxd/idxd_kernel

# These files all represent c files that are only compiled by direct inclusion in other files.
test/common/lib/test_env
test/common/lib/test_iobuf
test/common/lib/test_sock
test/common/lib/ut_multithread
test/common/lib/test_rdma
+27 −14
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include "spdk_internal/accel_module.h"
#include "thread/thread_internal.h"
#include "common/lib/ut_multithread.c"
#include "common/lib/test_iobuf.c"
#include "accel/accel.c"
#include "accel/accel_sw.c"
#include "unit/lib/json_mock.c"
@@ -1929,6 +1930,16 @@ test_sequence_accel_buffers(void)
	spdk_iobuf_buffer_stailq_t small_cache;
	uint32_t small_cache_count;
	int i, rc, completed;
	struct spdk_iobuf_opts opts_iobuf = {};

	/* Set up the iobuf to always use the "small" pool */
	opts_iobuf.large_bufsize = 0x20000;
	opts_iobuf.large_pool_count = 0;
	opts_iobuf.small_bufsize = 0x10000;
	opts_iobuf.small_pool_count = 32;

	rc = spdk_iobuf_set_opts(&opts_iobuf);
	CU_ASSERT(rc == 0);

	ioch = spdk_accel_get_io_channel();
	SPDK_CU_ASSERT_FATAL(ioch != NULL);
@@ -2223,7 +2234,8 @@ test_sequence_accel_buffers(void)
	STAILQ_INIT(&small_cache);
	STAILQ_SWAP(&accel_ch->iobuf.small.cache, &small_cache, spdk_iobuf_buffer);
	accel_ch->iobuf.small.cache_count = 0;
	MOCK_SET(spdk_mempool_get, NULL);
	accel_ch->iobuf.small.cache_size = 0;
	g_iobuf.small_pool_count = 0;

	/* First allocate a single buffer used by two operations */
	memset(srcbuf, 0x0, 4096);
@@ -2258,10 +2270,10 @@ test_sequence_accel_buffers(void)
	CU_ASSERT(!ut_seq.complete);

	/* Get a buffer and return it to the pool to trigger the sequence to finish */
	MOCK_CLEAR(spdk_mempool_get);
	g_iobuf.small_pool_count = 1;
	iobuf_buf = spdk_iobuf_get(&accel_ch->iobuf, 4096, NULL, NULL);
	CU_ASSERT_PTR_NOT_NULL(iobuf_buf);
	MOCK_SET(spdk_mempool_get, NULL);
	CU_ASSERT(g_iobuf.small_pool_count == 0);
	spdk_iobuf_put(&accel_ch->iobuf, iobuf_buf, 4096);

	poll_threads();
@@ -2280,6 +2292,7 @@ test_sequence_accel_buffers(void)
		small_cache_count++;
	}
	accel_ch->iobuf.small.cache_count = 0;
	g_iobuf.small_pool_count = 0;

	/* Check a bit more complex scenario, with two buffers in the sequence */
	memset(srcbuf, 0x0, 4096);
@@ -2327,20 +2340,20 @@ test_sequence_accel_buffers(void)
	CU_ASSERT_EQUAL(completed, 0);
	CU_ASSERT(!ut_seq.complete);

	MOCK_CLEAR(spdk_mempool_get);
	g_iobuf.small_pool_count = 1;
	iobuf_buf = spdk_iobuf_get(&accel_ch->iobuf, 4096, NULL, NULL);
	CU_ASSERT_PTR_NOT_NULL(iobuf_buf);
	MOCK_SET(spdk_mempool_get, NULL);
	g_iobuf.small_pool_count = 0;
	spdk_iobuf_put(&accel_ch->iobuf, iobuf_buf, 4096);

	/* One buffer is not enough to finish the whole sequence */
	poll_threads();
	CU_ASSERT(!ut_seq.complete);

	MOCK_CLEAR(spdk_mempool_get);
	g_iobuf.small_pool_count = 1;
	iobuf_buf = spdk_iobuf_get(&accel_ch->iobuf, 4096, NULL, NULL);
	CU_ASSERT_PTR_NOT_NULL(iobuf_buf);
	MOCK_SET(spdk_mempool_get, NULL);
	g_iobuf.small_pool_count = 0;
	spdk_iobuf_put(&accel_ch->iobuf, iobuf_buf, 4096);

	poll_threads();
@@ -2361,7 +2374,7 @@ test_sequence_accel_buffers(void)
	}
	accel_ch->iobuf.small.cache_count = 0;

	MOCK_CLEAR(spdk_mempool_get);
	g_iobuf.small_pool_count = 32;
	STAILQ_SWAP(&accel_ch->iobuf.small.cache, &small_cache, spdk_iobuf_buffer);
	accel_ch->iobuf.small.cache_count = small_cache_count;

@@ -2574,7 +2587,7 @@ test_sequence_memory_domain(void)
	STAILQ_INIT(&small_cache);
	STAILQ_SWAP(&accel_ch->iobuf.small.cache, &small_cache, spdk_iobuf_buffer);
	accel_ch->iobuf.small.cache_count = 0;
	MOCK_SET(spdk_mempool_get, NULL);
	g_iobuf.small_pool_count = 0;

	src_iovs[0].iov_base = (void *)0xdeadbeef;
	src_iovs[0].iov_len = sizeof(srcbuf);
@@ -2598,20 +2611,20 @@ test_sequence_memory_domain(void)

	/* Get a buffer and return it to the pool to trigger the sequence to resume.  It shouldn't
	 * be able to complete, as it needs two buffers */
	MOCK_CLEAR(spdk_mempool_get);
	g_iobuf.small_pool_count = 1;
	iobuf_buf = spdk_iobuf_get(&accel_ch->iobuf, sizeof(dstbuf), NULL, NULL);
	CU_ASSERT_PTR_NOT_NULL(iobuf_buf);
	MOCK_SET(spdk_mempool_get, NULL);
	g_iobuf.small_pool_count = 0;
	spdk_iobuf_put(&accel_ch->iobuf, iobuf_buf, sizeof(dstbuf));

	CU_ASSERT_EQUAL(completed, 0);
	CU_ASSERT(!ut_seq.complete);

	/* Return another buffer, this time the sequence should finish */
	MOCK_CLEAR(spdk_mempool_get);
	g_iobuf.small_pool_count = 1;
	iobuf_buf = spdk_iobuf_get(&accel_ch->iobuf, sizeof(dstbuf), NULL, NULL);
	CU_ASSERT_PTR_NOT_NULL(iobuf_buf);
	MOCK_SET(spdk_mempool_get, NULL);
	g_iobuf.small_pool_count = 0;
	spdk_iobuf_put(&accel_ch->iobuf, iobuf_buf, sizeof(dstbuf));

	poll_threads();
@@ -2629,7 +2642,7 @@ test_sequence_memory_domain(void)
	}
	accel_ch->iobuf.small.cache_count = 0;

	MOCK_CLEAR(spdk_mempool_get);
	g_iobuf.small_pool_count = 32;
	STAILQ_SWAP(&accel_ch->iobuf.small.cache, &small_cache, spdk_iobuf_buffer);
	accel_ch->iobuf.small.cache_count = small_cache_count;