From 32da70152f0d783ef7887170e1e7e33abf01475d Mon Sep 17 00:00:00 2001 From: Krzysztof Karas Date: Mon, 7 Feb 2022 12:11:34 +0000 Subject: [PATCH] scheduler: create and parse JSON values for dynamic scheduler params Creates a JSON on scheduler side to return after .get_opts is called and parses a JSON on .set_opts call. The JSON passed to dynamic scheduler on .set_stats is a copy of a pointer already available during RPC framework_set_scheduler call. Getting and setting scheduler stats via RPC calls is going to be implemented in the next patch in this series. Change-Id: I62880a71066a140c74336a5725e7b10952008e5c Signed-off-by: Krzysztof Karas Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11448 Tested-by: SPDK CI Jenkins Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Reviewed-by: Jim Harris Reviewed-by: Tomasz Zawadzki --- include/spdk/scheduler.h | 15 ++++++ lib/event/app_rpc.c | 1 + lib/event/scheduler_static.c | 13 ++++++ mk/spdk.lib_deps.mk | 2 +- module/scheduler/dynamic/scheduler_dynamic.c | 49 ++++++++++++++++++++ 5 files changed, 79 insertions(+), 1 deletion(-) diff --git a/include/spdk/scheduler.h b/include/spdk/scheduler.h index f38e51782..0b0ee89ed 100644 --- a/include/spdk/scheduler.h +++ b/include/spdk/scheduler.h @@ -224,6 +224,21 @@ struct spdk_scheduler { */ void (*balance)(struct spdk_scheduler_core_info *core_info, uint32_t count); + /** + * Function to set scheduler parameters like load_limit. + * + * \param opts Pointer to spdk_json_val struct containing values of parameters + * to be set in scheduler. + */ + int (*set_opts)(const struct spdk_json_val *opts); + + /** + * Function to get current scheduler parameters like load_limit. + * + * \param ctx Pointer to spdk_json_write_ctx struct to be filled with current parameters. + */ + void (*get_opts)(struct spdk_json_write_ctx *ctx); + TAILQ_ENTRY(spdk_scheduler) link; }; diff --git a/lib/event/app_rpc.c b/lib/event/app_rpc.c index e7ae733ed..22ea71f99 100644 --- a/lib/event/app_rpc.c +++ b/lib/event/app_rpc.c @@ -40,6 +40,7 @@ #include "spdk/env.h" #include "spdk/scheduler.h" #include "spdk/thread.h" +#include "spdk/json.h" #include "spdk/log.h" #include "spdk_internal/event.h" diff --git a/lib/event/scheduler_static.c b/lib/event/scheduler_static.c index 4941e14cb..679c20066 100644 --- a/lib/event/scheduler_static.c +++ b/lib/event/scheduler_static.c @@ -56,10 +56,23 @@ balance_static(struct spdk_scheduler_core_info *cores, uint32_t core_count) { } +static int +set_opts_static(const struct spdk_json_val *opts) +{ + return 0; +} + +static void +get_opts_static(struct spdk_json_write_ctx *ctx) +{ +} + static struct spdk_scheduler scheduler = { .name = "static", .init = init_static, .deinit = deinit_static, .balance = balance_static, + .set_opts = set_opts_static, + .get_opts = get_opts_static, }; SPDK_SCHEDULER_REGISTER(scheduler); diff --git a/mk/spdk.lib_deps.mk b/mk/spdk.lib_deps.mk index ce18568c2..c849e0608 100644 --- a/mk/spdk.lib_deps.mk +++ b/mk/spdk.lib_deps.mk @@ -129,7 +129,7 @@ DEPDIRS-sock_posix := log sock util DEPDIRS-sock_uring := log sock util # module/scheduler -DEPDIRS-scheduler_dynamic := event log thread util +DEPDIRS-scheduler_dynamic := event log thread util json ifeq ($(SPDK_ROOT_DIR)/lib/env_dpdk,$(CONFIG_ENV)) ifeq ($(OS),Linux) DEPDIRS-scheduler_dpdk_governor := event log diff --git a/module/scheduler/dynamic/scheduler_dynamic.c b/module/scheduler/dynamic/scheduler_dynamic.c index 4f2817697..1689d5f5f 100644 --- a/module/scheduler/dynamic/scheduler_dynamic.c +++ b/module/scheduler/dynamic/scheduler_dynamic.c @@ -376,11 +376,60 @@ balance(struct spdk_scheduler_core_info *cores_info, uint32_t cores_count) } } +struct json_scheduler_opts { + uint8_t load_limit; + uint8_t core_limit; + uint8_t core_busy; +}; + +static const struct spdk_json_object_decoder sched_decoders[] = { + {"load_limit", offsetof(struct json_scheduler_opts, load_limit), spdk_json_decode_uint8, true}, + {"core_limit", offsetof(struct json_scheduler_opts, core_limit), spdk_json_decode_uint8, true}, + {"core_busy", offsetof(struct json_scheduler_opts, core_busy), spdk_json_decode_uint8, true}, +}; + +static int +set_opts(const struct spdk_json_val *opts) +{ + struct json_scheduler_opts scheduler_opts; + + scheduler_opts.load_limit = g_scheduler_load_limit; + scheduler_opts.core_limit = g_scheduler_core_limit; + scheduler_opts.core_busy = g_scheduler_core_busy; + + if (opts != NULL) { + if (spdk_json_decode_object_relaxed(opts, sched_decoders, + SPDK_COUNTOF(sched_decoders), &scheduler_opts)) { + SPDK_ERRLOG("Decoding scheduler opts JSON failed\n"); + return -1; + } + } + + SPDK_NOTICELOG("Setting scheduler load limit to %d\n", scheduler_opts.load_limit); + g_scheduler_load_limit = scheduler_opts.load_limit; + SPDK_NOTICELOG("Setting scheduler core limit to %d\n", scheduler_opts.core_limit); + g_scheduler_core_limit = scheduler_opts.core_limit; + SPDK_NOTICELOG("Setting scheduler core busy to %d\n", scheduler_opts.core_busy); + g_scheduler_core_busy = scheduler_opts.core_busy; + + return 0; +} + +static void +get_opts(struct spdk_json_write_ctx *ctx) +{ + spdk_json_write_named_uint8(ctx, "load_limit", g_scheduler_load_limit); + spdk_json_write_named_uint8(ctx, "core_limit", g_scheduler_core_limit); + spdk_json_write_named_uint8(ctx, "core_busy", g_scheduler_core_busy); +} + static struct spdk_scheduler scheduler_dynamic = { .name = "dynamic", .init = init, .deinit = deinit, .balance = balance, + .set_opts = set_opts, + .get_opts = get_opts, }; SPDK_SCHEDULER_REGISTER(scheduler_dynamic);