diff --git a/examples/interrupt_tgt/interrupt_plugin.py b/examples/interrupt_tgt/interrupt_plugin.py new file mode 100644 index 000000000..284cf8955 --- /dev/null +++ b/examples/interrupt_tgt/interrupt_plugin.py @@ -0,0 +1,15 @@ +from rpc.client import print_json + + +def reactor_set_interrupt_mode(args): + params = {'lcore': args.lcore, 'disable_interrupt': args.disable_interrupt} + return args.client.call('reactor_set_interrupt_mode', params) + + +def spdk_rpc_plugin_initialize(subparsers): + p = subparsers.add_parser('reactor_set_interrupt_mode', + help="""Set reactor to interrupt or back to poll mode.""") + p.add_argument('lcore', type=int, help='lcore of the reactor') + p.add_argument('-d', '--disable-interrupt', dest='disable_interrupt', action='store_true', + help='Set reactor back to poll mode') + p.set_defaults(func=reactor_set_interrupt_mode) diff --git a/examples/interrupt_tgt/interrupt_tgt.c b/examples/interrupt_tgt/interrupt_tgt.c index e63a58153..2733ed3e4 100644 --- a/examples/interrupt_tgt/interrupt_tgt.c +++ b/examples/interrupt_tgt/interrupt_tgt.c @@ -35,6 +35,69 @@ #include "spdk/conf.h" #include "spdk/event.h" #include "spdk/vhost.h" +#include "spdk/json.h" +#include "spdk/jsonrpc.h" +#include "spdk/rpc.h" +#include "spdk/env.h" + +#include "spdk_internal/event.h" + +struct rpc_reactor_set_interrupt_mode { + int32_t lcore; + bool disable_interrupt; +}; + +static const struct spdk_json_object_decoder rpc_reactor_set_interrupt_mode_decoders[] = { + {"lcore", offsetof(struct rpc_reactor_set_interrupt_mode, lcore), spdk_json_decode_int32}, + {"disable_interrupt", offsetof(struct rpc_reactor_set_interrupt_mode, disable_interrupt), spdk_json_decode_bool}, +}; + +static void +rpc_reactor_set_interrupt_mode_cb(void *cb_arg) +{ + struct spdk_jsonrpc_request *request = cb_arg; + + SPDK_NOTICELOG("complete reactor switch\n"); + + spdk_jsonrpc_send_bool_response(request, true); +} + +static void +rpc_reactor_set_interrupt_mode(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct rpc_reactor_set_interrupt_mode req = {}; + int rc; + + if (spdk_json_decode_object(params, rpc_reactor_set_interrupt_mode_decoders, + SPDK_COUNTOF(rpc_reactor_set_interrupt_mode_decoders), + &req)) { + SPDK_ERRLOG("spdk_json_decode_object failed\n"); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, + "spdk_json_decode_object failed"); + return; + } + + SPDK_NOTICELOG("RPC Start to %s interrupt mode on reactor %d.\n", + req.disable_interrupt ? "disable" : "enable", req.lcore); + if (req.lcore >= (int64_t)spdk_env_get_first_core() && + req.lcore <= (int64_t)spdk_env_get_last_core()) { + rc = spdk_reactor_set_interrupt_mode(req.lcore, !req.disable_interrupt, + rpc_reactor_set_interrupt_mode_cb, request); + if (rc) { + goto err; + } + } else { + goto err; + } + + return; + +err: + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, + "Invalid parameters"); +} +SPDK_RPC_REGISTER("reactor_set_interrupt_mode", rpc_reactor_set_interrupt_mode, SPDK_RPC_RUNTIME) static void interrupt_tgt_usage(void)