diff --git a/doc/jsonrpc.md b/doc/jsonrpc.md index 27254b2d3..bcb12f8c7 100644 --- a/doc/jsonrpc.md +++ b/doc/jsonrpc.md @@ -441,6 +441,7 @@ Example response: "framework_get_subsystems", "framework_monitor_context_switch", "spdk_kill_instance", + "accel_set_options", "accel_set_driver", "accel_crypto_key_create", "accel_crypto_key_destroy", @@ -1943,6 +1944,43 @@ Example response: } ~~~ +### accel_set_options {#rpc_accel_set_options} + +Set accel framework's options. + +#### Parameters + +Name | Optional | Type | Description +----------------------- |----------| ----------- | ----------------- +small_cache_size | Optional | number | Size of the small iobuf cache +large_cache_size | Optional | number | Size of the large iobuf cache + +#### Example + +Example request: + +~~~json +{ + "jsonrpc": "2.0", + "method": "accel_set_options", + "id": 1, + "params": { + "small_cache_size": 128, + "large_cache_size": 32 + } +} +~~~ + +Example response: + +~~~json +{ + "jsonrpc": "2.0", + "id": 1, + "result": true +} +~~~ + ### compressdev_scan_accel_module {#rpc_compressdev_scan_accel_module} Set config and enable compressdev accel module offload. diff --git a/include/spdk/accel.h b/include/spdk/accel.h index 27de986c0..d1ea9bb6c 100644 --- a/include/spdk/accel.h +++ b/include/spdk/accel.h @@ -641,6 +641,31 @@ int spdk_accel_set_driver(const char *name); */ struct spdk_memory_domain *spdk_accel_get_memory_domain(void); +struct spdk_accel_opts { + /** Size of this structure */ + size_t size; + /** Size of the small iobuf cache */ + uint32_t small_cache_size; + /** Size of the large iobuf cache */ + uint32_t large_cache_size; +} __attribute__((packed)); + +/** + * Set the options for the accel framework. + * + * \param opts Accel options. + * + * \return 0 on success, negative errno otherwise. + */ +int spdk_accel_set_opts(const struct spdk_accel_opts *opts); + +/** + * Get the options for the accel framework. + * + * \param opts Accel options. + */ +void spdk_accel_get_opts(struct spdk_accel_opts *opts); + #ifdef __cplusplus } #endif diff --git a/lib/accel/accel.c b/lib/accel/accel.c index 8b955e72b..3f5c4a832 100644 --- a/lib/accel/accel.c +++ b/lib/accel/accel.c @@ -62,6 +62,10 @@ static struct accel_module g_modules_opc[ACCEL_OPC_LAST] = {}; static char *g_modules_opc_override[ACCEL_OPC_LAST] = {}; TAILQ_HEAD(, spdk_accel_driver) g_accel_drivers = TAILQ_HEAD_INITIALIZER(g_accel_drivers); static struct spdk_accel_driver *g_accel_driver; +static struct spdk_accel_opts g_opts = { + .small_cache_size = ACCEL_SMALL_CACHE_SIZE, + .large_cache_size = ACCEL_LARGE_CACHE_SIZE, +}; static const char *g_opcode_strings[ACCEL_OPC_LAST] = { "copy", "fill", "dualcast", "compare", "crc32c", "copy_crc32c", @@ -2137,8 +2141,8 @@ accel_create_channel(void *io_device, void *ctx_buf) } } - rc = spdk_iobuf_channel_init(&accel_ch->iobuf, "accel", ACCEL_SMALL_CACHE_SIZE, - ACCEL_LARGE_CACHE_SIZE); + rc = spdk_iobuf_channel_init(&accel_ch->iobuf, "accel", g_opts.small_cache_size, + g_opts.large_cache_size); if (rc != 0) { SPDK_ERRLOG("Failed to initialize iobuf accel channel\n"); goto err; @@ -2341,6 +2345,18 @@ _accel_crypto_key_write_config_json(struct spdk_json_write_ctx *w, spdk_json_write_object_end(w); } +static void +accel_write_options(struct spdk_json_write_ctx *w) +{ + spdk_json_write_object_begin(w); + spdk_json_write_named_string(w, "method", "accel_set_options"); + spdk_json_write_named_object_begin(w, "params"); + spdk_json_write_named_uint32(w, "small_cache_size", g_opts.small_cache_size); + spdk_json_write_named_uint32(w, "large_cache_size", g_opts.large_cache_size); + spdk_json_write_object_end(w); + spdk_json_write_object_end(w); +} + static void _accel_crypto_keys_write_config_json(struct spdk_json_write_ctx *w, bool full_dump) { @@ -2369,11 +2385,9 @@ spdk_accel_write_config_json(struct spdk_json_write_ctx *w) struct spdk_accel_module_if *accel_module; int i; - /* - * The accel fw has no config, there may be some in - * the modules though. - */ spdk_json_write_array_begin(w); + accel_write_options(w); + TAILQ_FOREACH(accel_module, &spdk_accel_module_list, tailq) { if (accel_module->write_config_json) { accel_module->write_config_json(w); @@ -2483,4 +2497,27 @@ spdk_accel_driver_register(struct spdk_accel_driver *driver) TAILQ_INSERT_TAIL(&g_accel_drivers, driver, tailq); } +int +spdk_accel_set_opts(const struct spdk_accel_opts *opts) +{ + if (opts->size > sizeof(*opts)) { + return -EINVAL; + } + + memcpy(&g_opts, opts, opts->size); + + return 0; +} + +void +spdk_accel_get_opts(struct spdk_accel_opts *opts) +{ + size_t size = opts->size; + + assert(size <= sizeof(*opts)); + + memcpy(opts, &g_opts, spdk_min(sizeof(*opts), size)); + opts->size = size; +} + SPDK_LOG_REGISTER_COMPONENT(accel) diff --git a/lib/accel/accel_rpc.c b/lib/accel/accel_rpc.c index 83595ea43..eef91eb2d 100644 --- a/lib/accel/accel_rpc.c +++ b/lib/accel/accel_rpc.c @@ -354,3 +354,46 @@ cleanup: free_rpc_accel_set_driver(&req); } SPDK_RPC_REGISTER("accel_set_driver", rpc_accel_set_driver, SPDK_RPC_STARTUP) + +struct rpc_accel_opts { + uint32_t small_cache_size; + uint32_t large_cache_size; +}; + +static const struct spdk_json_object_decoder rpc_accel_set_options_decoders[] = { + {"small_cache_size", offsetof(struct rpc_accel_opts, small_cache_size), spdk_json_decode_uint32, true}, + {"large_cache_size", offsetof(struct rpc_accel_opts, large_cache_size), spdk_json_decode_uint32, true}, +}; + +static void +rpc_accel_set_options(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params) +{ + struct spdk_accel_opts opts = { .size = sizeof(opts) }; + struct rpc_accel_opts rpc_opts; + int rc; + + /* We can't pass spdk_accel_opts directly to spdk_json_decode_object(), because that + * structure is packed, leading undefined behavior due to misaligned pointer access */ + spdk_accel_get_opts(&opts); + rpc_opts.small_cache_size = opts.small_cache_size; + rpc_opts.large_cache_size = opts.large_cache_size; + + if (spdk_json_decode_object(params, rpc_accel_set_options_decoders, + SPDK_COUNTOF(rpc_accel_set_options_decoders), &rpc_opts)) { + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR, + "spdk_json_decode_object failed"); + return; + } + + opts.small_cache_size = rpc_opts.small_cache_size; + opts.large_cache_size = rpc_opts.large_cache_size; + + rc = spdk_accel_set_opts(&opts); + if (rc != 0) { + spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); + return; + } + + spdk_jsonrpc_send_bool_response(request, true); +} +SPDK_RPC_REGISTER("accel_set_options", rpc_accel_set_options, SPDK_RPC_STARTUP) diff --git a/lib/accel/spdk_accel.map b/lib/accel/spdk_accel.map index b7fcd0fa7..57af10866 100644 --- a/lib/accel/spdk_accel.map +++ b/lib/accel/spdk_accel.map @@ -36,6 +36,8 @@ spdk_accel_crypto_key_get; spdk_accel_set_driver; spdk_accel_get_memory_domain; + spdk_accel_set_opts; + spdk_accel_get_opts; # functions needed by modules spdk_accel_module_list_add; diff --git a/python/spdk/rpc/accel.py b/python/spdk/rpc/accel.py index 00aab9a1b..7a9690524 100644 --- a/python/spdk/rpc/accel.py +++ b/python/spdk/rpc/accel.py @@ -88,3 +88,15 @@ def accel_set_driver(client, name): name: name of the driver """ return client.call('accel_set_driver', {'name': name}) + + +def accel_set_options(client, small_cache_size, large_cache_size): + """Set accel framework's options.""" + params = {} + + if small_cache_size is not None: + params['small_cache_size'] = small_cache_size + if large_cache_size is not None: + params['large_cache_size'] = large_cache_size + + return client.call('accel_set_options', params) diff --git a/scripts/rpc.py b/scripts/rpc.py index 44d2750c9..b077075d0 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -2866,6 +2866,14 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse p.add_argument('name', help='name of the platform driver') p.set_defaults(func=accel_set_driver) + def accel_set_options(args): + rpc.accel.accel_set_options(args.client, args.small_cache_size, args.large_cache_size) + + p = subparsers.add_parser('accel_set_options', help='Set accel framework\'s options') + p.add_argument('--small-cache-size', type=int, help='Size of the small iobuf cache') + p.add_argument('--large-cache-size', type=int, help='Size of the large iobuf cache') + p.set_defaults(func=accel_set_options) + # ioat def ioat_scan_accel_module(args): rpc.ioat.ioat_scan_accel_module(args.client) diff --git a/test/json_config/config_filter.py b/test/json_config/config_filter.py index f911ae8b7..f9e1f8f33 100755 --- a/test/json_config/config_filter.py +++ b/test/json_config/config_filter.py @@ -43,6 +43,7 @@ def filter_methods(do_remove_global_rpcs): 'framework_set_scheduler', 'accel_crypto_key_create', 'accel_assign_opc', + 'accel_set_options', 'dpdk_cryptodev_scan_accel_module', 'dpdk_cryptodev_set_driver', 'virtio_blk_create_transport',