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: Ben Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16329
Community-CI: Mellanox Build Bot
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Ben Walker 2023-01-17 10:33:33 -07:00 committed by David Ko
parent 03e4522ed3
commit 818ec14e70
3 changed files with 163 additions and 14 deletions

View File

@ -0,0 +1,135 @@
/* 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);
}

View File

@ -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

View File

@ -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;