diff --git a/include/spdk_internal/accel_engine.h b/include/spdk_internal/accel_engine.h index 974b4b7b11..03725cf2d5 100644 --- a/include/spdk_internal/accel_engine.h +++ b/include/spdk_internal/accel_engine.h @@ -39,6 +39,15 @@ #include "spdk/accel_engine.h" #include "spdk/queue.h" +enum accel_module { + ACCEL_SW = 0, + ACCEL_AUTO, + ACCEL_CBDMA, + ACCEL_MODULE_MAX +}; + +int accel_set_module(enum accel_module *opts); + struct spdk_accel_task { spdk_accel_completion_cb cb; uint8_t offload_ctx[0]; diff --git a/lib/accel/Makefile b/lib/accel/Makefile index 6c351f0fad..a0c0c6e76c 100644 --- a/lib/accel/Makefile +++ b/lib/accel/Makefile @@ -35,6 +35,6 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..) include $(SPDK_ROOT_DIR)/mk/spdk.common.mk LIBNAME = accel -C_SRCS = accel_engine.c +C_SRCS = accel_engine.c accel_engine_rpc.c include $(SPDK_ROOT_DIR)/mk/spdk.lib.mk diff --git a/lib/accel/accel_engine.c b/lib/accel/accel_engine.c index 9d8a12cd29..d30aedfddb 100644 --- a/lib/accel/accel_engine.c +++ b/lib/accel/accel_engine.c @@ -55,6 +55,7 @@ static struct spdk_accel_engine *g_sw_accel_engine = NULL; static struct spdk_accel_module_if *g_accel_engine_module = NULL; static spdk_accel_fini_cb g_fini_cb_fn = NULL; static void *g_fini_cb_arg = NULL; +enum accel_module g_active_accel_module = ACCEL_AUTO; /* Global list of registered accelerator modules */ static TAILQ_HEAD(, spdk_accel_module_if) spdk_accel_module_list = @@ -65,6 +66,14 @@ struct accel_io_channel { struct spdk_io_channel *ch; }; +int +accel_set_module(enum accel_module *opts) +{ + g_active_accel_module = *opts; + + return 0; +} + /* Registration of hw modules (currently supports only 1) */ void spdk_accel_hw_engine_register(struct spdk_accel_engine *accel_engine) @@ -144,17 +153,31 @@ accel_engine_create_cb(void *io_device, void *ctx_buf) { struct accel_io_channel *accel_ch = ctx_buf; - if (g_hw_accel_engine != NULL) { - accel_ch->ch = g_hw_accel_engine->get_io_channel(); - if (accel_ch->ch != NULL) { - accel_ch->engine = g_hw_accel_engine; - return 0; + /* If they specify CBDMA and its not available, fail */ + if (g_active_accel_module == ACCEL_CBDMA && g_hw_accel_engine == NULL) { + SPDK_ERRLOG("CBDMA acceleration engine specified but not available.\n"); + return -EINVAL; + } + + /* For either HW or AUTO */ + if (g_active_accel_module > ACCEL_SW) { + if (g_hw_accel_engine != NULL) { + accel_ch->ch = g_hw_accel_engine->get_io_channel(); + if (accel_ch->ch != NULL) { + accel_ch->engine = g_hw_accel_engine; + SPDK_NOTICELOG("Acceleration framework using module: CBDMA\n"); + return 0; + } } } + /* Choose SW either because auto was selected and there was no HW, + * or because SW was selected. + */ accel_ch->ch = g_sw_accel_engine->get_io_channel(); assert(accel_ch->ch != NULL); accel_ch->engine = g_sw_accel_engine; + SPDK_NOTICELOG("Acceleration framework using module: SOFTWARE\n"); return 0; } diff --git a/lib/accel/accel_engine_rpc.c b/lib/accel/accel_engine_rpc.c new file mode 100644 index 0000000000..7f050a437a --- /dev/null +++ b/lib/accel/accel_engine_rpc.c @@ -0,0 +1,85 @@ +/*- + * BSD LICENSE + * + * Copyright (c) Intel Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "spdk_internal/accel_engine.h" +#include "spdk/rpc.h" +#include "spdk/util.h" +#include "spdk/string.h" +#include "spdk_internal/log.h" + +struct rpc_accel_set_module { + enum accel_module module; +}; + +static const struct spdk_json_object_decoder rpc_accel_set_module_decoder[] = { + {"module", offsetof(struct rpc_accel_set_module, module), spdk_json_decode_uint32}, +}; + +static void +spdk_rpc_accel_set_module(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct rpc_accel_set_module req = {}; + struct spdk_json_write_ctx *w; + int rc = 0; + + if (spdk_json_decode_object(params, rpc_accel_set_module_decoder, + SPDK_COUNTOF(rpc_accel_set_module_decoder), + &req)) { + SPDK_ERRLOG("spdk_json_decode_object failed\n"); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR, + "spdk_json_decode_object failed"); + return; + } + + if (req.module >= ACCEL_MODULE_MAX) { + spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, + "Module value %d should be less than %d", req.module, + ACCEL_MODULE_MAX); + return; + } + + rc = accel_set_module(&req.module); + if (rc) { + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, spdk_strerror(-rc)); + return; + } + + w = spdk_jsonrpc_begin_result(request); + if (w != NULL) { + spdk_json_write_bool(w, true); + spdk_jsonrpc_end_result(request, w); + } +} +SPDK_RPC_REGISTER("accel_set_module", spdk_rpc_accel_set_module, + SPDK_RPC_STARTUP) diff --git a/mk/spdk.lib_deps.mk b/mk/spdk.lib_deps.mk index 9c6f2671e5..cd8a345264 100644 --- a/mk/spdk.lib_deps.mk +++ b/mk/spdk.lib_deps.mk @@ -56,7 +56,7 @@ DEPDIRS-reduce := log util DEPDIRS-thread := log util DEPDIRS-blob := log util thread -DEPDIRS-accel := thread +DEPDIRS-accel := thread log rpc thread util $(JSON_LIBS) DEPDIRS-jsonrpc := log util json DEPDIRS-virtio := log util json thread diff --git a/scripts/rpc.py b/scripts/rpc.py index c0a0b21182..f412a4525b 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -2099,6 +2099,16 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse p.add_argument('name', help='Name of the Open Channel bdev') p.set_defaults(func=bdev_ocssd_delete) + # accel framework + def accel_set_module(args): + rpc.accel.accel_set_module(args.client, + module=args.module) + + p = subparsers.add_parser('accel_set_module', + help='Set module option for the accelerator framework') + p.add_argument('-m', '--module', type=int, help='0 = auto-select, 1= Software, 2 = CBDMA') + p.set_defaults(func=accel_set_module) + # ioat def ioat_scan_accel_engine(args): pci_whitelist = [] diff --git a/scripts/rpc/__init__.py b/scripts/rpc/__init__.py index 403e2ec2e6..065ca83f1f 100644 --- a/scripts/rpc/__init__.py +++ b/scripts/rpc/__init__.py @@ -1,6 +1,7 @@ import json import sys +from . import accel from . import app from . import bdev from . import blobfs diff --git a/scripts/rpc/accel.py b/scripts/rpc/accel.py new file mode 100644 index 0000000000..78bab85d8e --- /dev/null +++ b/scripts/rpc/accel.py @@ -0,0 +1,9 @@ +def accel_set_module(client, module): + """Set the module for the acceleration framework. + + Args: + pmd: 0 = auto-select, 1 = Software, 2 = CBDMA + """ + params = {'module': module} + + return client.call('accel_set_module', params)