bdev: allow bdevs to report accel_sequnce support

Modules can now report that they support accel chaining for specific
operations through the accel_sequnce_supported() callback.

The support is reported per IO type.  This allows modules to support
accel sequences for some operations, while relying on the bdev layer to
handle them for other IO types.

Only bdevs without separate metadata buffers are allowed to support this
new mode.  That's because metadata in separate buffer is expected to use
the same memory domain as data buffers.  With an accel sequence, those
data memory domains can change, while metadata's memory domain always
stays the same.  To support bdevs with separate metadata buffers, we'd
need to add separate pointers for metadata's memory domain.  For now,
simply disallow registering bdevs with separate metadata supporting
accel sequences.

Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com>
Change-Id: I0c49cc00096837d70681a69b2633c2cb3dfd4e39
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16971
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Konrad Sztyber 2023-02-02 16:19:36 +01:00 committed by Ben Walker
parent 9beb6b163c
commit 1be4e82d15
2 changed files with 38 additions and 4 deletions

View File

@ -358,6 +358,9 @@ struct spdk_bdev_fn_table {
* Dump I/O statistics specific for this bdev context.
*/
void (*dump_device_stat_json)(void *ctx, struct spdk_json_write_ctx *w);
/** Check if bdev can handle spdk_accel_sequence to handle I/O of specific type. */
bool (*accel_sequence_supported)(void *ctx, enum spdk_bdev_io_type type);
};
/** bdev I/O completion status */

View File

@ -318,6 +318,7 @@ struct spdk_bdev_desc {
bool closed;
bool write;
bool memory_domains_supported;
bool accel_sequence_supported[SPDK_BDEV_NUM_IO_TYPES];
struct spdk_spinlock spinlock;
uint32_t refs;
TAILQ_HEAD(, media_event_entry) pending_media_events;
@ -6827,7 +6828,7 @@ bdev_register(struct spdk_bdev *bdev)
{
char *bdev_name;
char uuid[SPDK_UUID_STRING_LEN];
int ret;
int ret, i;
assert(bdev->module != NULL);
@ -6841,6 +6842,28 @@ bdev_register(struct spdk_bdev *bdev)
return -EINVAL;
}
for (i = 0; i < SPDK_BDEV_NUM_IO_TYPES; ++i) {
if (bdev->fn_table->accel_sequence_supported == NULL) {
continue;
}
if (!bdev->fn_table->accel_sequence_supported(bdev->ctxt,
(enum spdk_bdev_io_type)i)) {
continue;
}
if (spdk_bdev_get_memory_domains(bdev, NULL, 0) <= 0) {
SPDK_ERRLOG("bdev supporting accel sequence is required to support "
"memory domains\n");
return -EINVAL;
}
if (spdk_bdev_is_md_separate(bdev)) {
SPDK_ERRLOG("Separate metadata is currently unsupported for bdevs with "
"accel sequence support\n");
return -EINVAL;
}
}
/* Users often register their own I/O devices using the bdev name. In
* order to avoid conflicts, prepend bdev_. */
bdev_name = spdk_sprintf_alloc("bdev_%s", bdev->name);
@ -7242,7 +7265,7 @@ bdev_desc_alloc(struct spdk_bdev *bdev, spdk_bdev_event_cb_t event_cb, void *eve
struct spdk_bdev_desc **_desc)
{
struct spdk_bdev_desc *desc;
unsigned int event_id;
unsigned int i;
desc = calloc(1, sizeof(*desc));
if (desc == NULL) {
@ -7267,9 +7290,17 @@ bdev_desc_alloc(struct spdk_bdev *bdev, spdk_bdev_event_cb_t event_cb, void *eve
return -ENOMEM;
}
for (event_id = 0; event_id < MEDIA_EVENT_POOL_SIZE; ++event_id) {
for (i = 0; i < MEDIA_EVENT_POOL_SIZE; ++i) {
TAILQ_INSERT_TAIL(&desc->free_media_events,
&desc->media_events_buffer[event_id], tailq);
&desc->media_events_buffer[i], tailq);
}
}
if (bdev->fn_table->accel_sequence_supported != NULL) {
for (i = 0; i < SPDK_BDEV_NUM_IO_TYPES; ++i) {
desc->accel_sequence_supported[i] =
bdev->fn_table->accel_sequence_supported(bdev->ctxt,
(enum spdk_bdev_io_type)i);
}
}