Commit 92108e0a authored by Yoray Zack's avatar Yoray Zack Committed by Konrad Sztyber
Browse files

fsdev/aio: add support for null IOs



This patch adds support for null IOs in the AIO fsdev by introducing
a new RPC flag (--enable-skip-rw) during fsdev creation.

When enabled, the AIO fsdev will skip read/write operations, similar
to how the null bdev operates in the bdev module.

This feature facilitates performance testing across the entire stack
without actual data read/write operations. Implementing this within
the fsdev/aio module, rather than creating a separate fsdev/null module,
avoids unnecessary code duplication and keeps the AIO fsdev focused as a
comprehensive example demonstrating various features, including null IO
capability.

Change-Id: Id7e84711628f23e6faa9128f9e428f759e0032c9
Signed-off-by: default avatarYoray Zack <yorayz@nvidia.com>
Signed-off-by: default avatarVishwanath Venkatesan <vvenkatesan@nvidia.com>
Signed-off-by: default avatarBen Walker <ben@nvidia.com>
Signed-off-by: default avatarAnton Nayshtut <anayshtut@nvidia.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/24563


Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarChangpeng Liu <changpeliu@tencent.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
parent dcdab59d
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -13807,6 +13807,7 @@ root_path | Required | string | Path on the system directory
enable_xattr            | Optional | bool        | true to enable the extended attributes, false otherwise
enable_writeback_cache  | Optional | bool        | true to enable the writeback cache, false otherwise
max_write               | Optional | int         | Max write size in bytes
skip_rw                 | Optional | bool        | Skip processing read and write requests and complete them successfully immediately. This is useful for benchmarking.

#### Example

@@ -13821,7 +13822,8 @@ Example request:
    "root_path": "/tmp/vfio-test",
    "enable_xattr": false,
    "enable_writeback_cache": true,
    "max_write": 65535
    "max_write": 65535,
    "skip_rw": true
  }
}
~~~
+48 −3
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#define DEFAULT_WRITEBACK_CACHE true
#define DEFAULT_MAX_WRITE 0x00020000
#define DEFAULT_XATTR_ENABLED false
#define DEFAULT_SKIP_RW false
#define DEFAULT_TIMEOUT_MS 0 /* to prevent the attribute caching */

#ifdef SPDK_CONFIG_HAVE_STRUCT_STAT_ST_ATIM
@@ -101,6 +102,7 @@ struct aio_fsdev {
	struct spdk_fsdev_file_object *root;
	TAILQ_ENTRY(aio_fsdev) tailq;
	bool xattr_enabled;
	bool skip_rw;
};

struct aio_fsdev_io {
@@ -113,6 +115,7 @@ struct aio_io_channel {
	struct spdk_poller *poller;
	struct spdk_aio_mgr *mgr;
	TAILQ_HEAD(, aio_fsdev_io) ios_in_progress;
	TAILQ_HEAD(, aio_fsdev_io) ios_to_complete;
};

static TAILQ_HEAD(, aio_fsdev) g_aio_fsdev_head = TAILQ_HEAD_INITIALIZER(
@@ -1083,6 +1086,20 @@ lo_read(struct spdk_io_channel *_ch, struct spdk_fsdev_io *fsdev_io)
		return -EINVAL;
	}

	if (vfsdev->skip_rw) {
		uint32_t i;

		fsdev_io->u_out.read.data_size = 0;

		for (i = 0; i < outcnt; i++, outvec++) {
			fsdev_io->u_out.read.data_size += outvec->iov_len;
		}

		TAILQ_INSERT_TAIL(&ch->ios_to_complete, vfsdev_io, link);

		return IO_STATUS_ASYNC;
	}

	vfsdev_io->aio = spdk_aio_mgr_read(ch->mgr, lo_read_cb, fsdev_io, fhandle->fd, offs, size, outvec,
					   outcnt);
	if (vfsdev_io->aio) {
@@ -1142,6 +1159,19 @@ lo_write(struct spdk_io_channel *_ch, struct spdk_fsdev_io *fsdev_io)
		return -EINVAL;
	}

	if (vfsdev->skip_rw) {
		uint32_t i;

		fsdev_io->u_out.write.data_size = 0;
		for (i = 0; i < incnt; i++, invec++) {
			fsdev_io->u_out.write.data_size += invec->iov_len;
		}

		TAILQ_INSERT_TAIL(&ch->ios_to_complete, vfsdev_io, link);

		return IO_STATUS_ASYNC;
	}

	vfsdev_io->aio = spdk_aio_mgr_write(ch->mgr, lo_write_cb, fsdev_io,
					    fhandle->fd, offs, size, invec, incnt);
	if (vfsdev_io->aio) {
@@ -1973,11 +2003,21 @@ lo_abort(struct spdk_io_channel *_ch, struct spdk_fsdev_io *fsdev_io)
static int
aio_io_poll(void *arg)
{
	struct aio_fsdev_io *vfsdev_io, *tmp;
	struct aio_io_channel *ch = arg;
	uint32_t num_completions = 0;

	spdk_aio_mgr_poll(ch->mgr);

	return SPDK_POLLER_IDLE;
	TAILQ_FOREACH_SAFE(vfsdev_io, &ch->ios_to_complete, link, tmp) {
		struct spdk_fsdev_io *fsdev_io = aio_to_fsdev_io(vfsdev_io);

		TAILQ_REMOVE(&ch->ios_to_complete, vfsdev_io, link);
		spdk_fsdev_io_complete(fsdev_io, 0);
		num_completions++;
	}

	return num_completions ? SPDK_POLLER_BUSY : SPDK_POLLER_IDLE;
}

static int
@@ -1994,6 +2034,7 @@ aio_fsdev_create_cb(void *io_device, void *ctx_buf)

	ch->poller = SPDK_POLLER_REGISTER(aio_io_poll, ch, 0);
	TAILQ_INIT(&ch->ios_in_progress);
	TAILQ_INIT(&ch->ios_to_complete);

	SPDK_DEBUGLOG(fsdev_aio, "Created aio fsdev IO channel: thread %s, thread id %" PRIu64
		      "\n",
@@ -2233,6 +2274,7 @@ fsdev_aio_write_config_json(struct spdk_fsdev *fsdev, struct spdk_json_write_ctx
	spdk_json_write_named_bool(w, "enable_writeback_cache",
				   !!vfsdev->fsdev.opts.writeback_cache_enabled);
	spdk_json_write_named_uint32(w, "max_write", vfsdev->fsdev.opts.max_write);
	spdk_json_write_named_bool(w, "skip_rw", vfsdev->skip_rw);
	spdk_json_write_object_end(w); /* params */
	spdk_json_write_object_end(w);
}
@@ -2301,6 +2343,7 @@ spdk_fsdev_aio_get_default_opts(struct spdk_fsdev_aio_opts *opts)
	opts->xattr_enabled = DEFAULT_XATTR_ENABLED;
	opts->writeback_cache_enabled = DEFAULT_WRITEBACK_CACHE;
	opts->max_write = DEFAULT_MAX_WRITE;
	opts->skip_rw = DEFAULT_SKIP_RW;
}

int
@@ -2368,12 +2411,14 @@ spdk_fsdev_aio_create(struct spdk_fsdev **fsdev, const char *name, const char *r
	vfsdev->fsdev.opts.writeback_cache_enabled = opts->writeback_cache_enabled;
	vfsdev->fsdev.opts.max_write = opts->max_write;

	vfsdev->skip_rw = opts->skip_rw;

	*fsdev = &(vfsdev->fsdev);
	TAILQ_INSERT_TAIL(&g_aio_fsdev_head, vfsdev, tailq);
	SPDK_DEBUGLOG(fsdev_aio, "Created aio filesystem %s (xattr_enabled=%" PRIu8 " writeback_cache=%"
		      PRIu8 " max_write=%" PRIu32 ")\n",
		      PRIu8 " max_write=%" PRIu32 " skip_rw=%" PRIu8 ")\n",
		      vfsdev->fsdev.name, vfsdev->xattr_enabled, vfsdev->fsdev.opts.writeback_cache_enabled,
		      vfsdev->fsdev.opts.max_write);
		      vfsdev->fsdev.opts.max_write, vfsdev->skip_rw);
	return rc;
}
void
+1 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ struct spdk_fsdev_aio_opts {
	bool xattr_enabled;
	bool writeback_cache_enabled;
	uint32_t max_write;
	bool skip_rw;
};

typedef void (*spdk_delete_aio_fsdev_complete)(void *cb_arg, int fsdeverrno);
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ static const struct spdk_json_object_decoder rpc_aio_create_decoders[] = {
	{"enable_xattr", offsetof(struct rpc_aio_create, opts.xattr_enabled), spdk_json_decode_bool, true},
	{"enable_writeback_cache", offsetof(struct rpc_aio_create, opts.writeback_cache_enabled), spdk_json_decode_bool, true},
	{"max_write", offsetof(struct rpc_aio_create, opts.max_write), spdk_json_decode_uint32, true},
	{"skip_rw", offsetof(struct rpc_aio_create, opts.skip_rw), spdk_json_decode_bool, true},
};

static void
+4 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ def fsdev_set_opts(client, fsdev_io_pool_size: int = None, fsdev_io_cache_size:


def fsdev_aio_create(client, name, root_path, enable_xattr: bool = None,
                     enable_writeback_cache: bool = None, max_write: int = None):
                     enable_writeback_cache: bool = None, max_write: int = None, skip_rw: bool = None):
    """Create a aio filesystem.

    Args:
@@ -42,6 +42,7 @@ def fsdev_aio_create(client, name, root_path, enable_xattr: bool = None,
        xattr_enabled: true if extended attributes should be enabled
        writeback_cache: enable/disable the write cache
        max_write: max write size
        skip_rw: if true skips read/write IOs
    """
    params = {
        'name': name,
@@ -53,6 +54,8 @@ def fsdev_aio_create(client, name, root_path, enable_xattr: bool = None,
        params['enable_writeback_cache'] = enable_writeback_cache
    if max_write is not None:
        params['max_write'] = max_write
    if skip_rw is not None:
        params['skip_rw'] = skip_rw
    return client.call('fsdev_aio_create', params)


Loading