1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2020 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/stdinc.h" 7 #include "spdk/conf.h" 8 #include "spdk/event.h" 9 #include "spdk/vhost.h" 10 #include "spdk/json.h" 11 #include "spdk/jsonrpc.h" 12 #include "spdk/rpc.h" 13 #include "spdk/env.h" 14 15 #include "spdk_internal/event.h" 16 17 struct rpc_reactor_set_interrupt_mode { 18 int32_t lcore; 19 bool disable_interrupt; 20 }; 21 22 static const struct spdk_json_object_decoder rpc_reactor_set_interrupt_mode_decoders[] = { 23 {"lcore", offsetof(struct rpc_reactor_set_interrupt_mode, lcore), spdk_json_decode_int32}, 24 {"disable_interrupt", offsetof(struct rpc_reactor_set_interrupt_mode, disable_interrupt), spdk_json_decode_bool}, 25 }; 26 27 static void 28 rpc_reactor_set_interrupt_mode_cb(void *cb_arg) 29 { 30 struct spdk_jsonrpc_request *request = cb_arg; 31 32 SPDK_NOTICELOG("complete reactor switch\n"); 33 34 spdk_jsonrpc_send_bool_response(request, true); 35 } 36 37 static void 38 rpc_reactor_set_interrupt_mode(struct spdk_jsonrpc_request *request, 39 const struct spdk_json_val *params) 40 { 41 struct rpc_reactor_set_interrupt_mode req = {}; 42 int rc; 43 44 if (spdk_json_decode_object(params, rpc_reactor_set_interrupt_mode_decoders, 45 SPDK_COUNTOF(rpc_reactor_set_interrupt_mode_decoders), 46 &req)) { 47 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 48 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 49 "spdk_json_decode_object failed"); 50 return; 51 } 52 53 if (!spdk_interrupt_mode_is_enabled()) { 54 SPDK_ERRLOG("Interrupt mode is not set when staring the application\n"); 55 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 56 "spdk_json_decode_object failed"); 57 return; 58 } 59 60 61 SPDK_NOTICELOG("RPC Start to %s interrupt mode on reactor %d.\n", 62 req.disable_interrupt ? "disable" : "enable", req.lcore); 63 if (req.lcore >= (int64_t)spdk_env_get_first_core() && 64 req.lcore <= (int64_t)spdk_env_get_last_core()) { 65 rc = spdk_reactor_set_interrupt_mode(req.lcore, !req.disable_interrupt, 66 rpc_reactor_set_interrupt_mode_cb, request); 67 if (rc) { 68 goto err; 69 } 70 } else { 71 goto err; 72 } 73 74 return; 75 76 err: 77 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 78 "Invalid parameters"); 79 } 80 /* private */ SPDK_RPC_REGISTER("reactor_set_interrupt_mode", rpc_reactor_set_interrupt_mode, 81 SPDK_RPC_RUNTIME) 82 83 static void 84 interrupt_tgt_usage(void) 85 { 86 printf(" -E Set interrupt mode\n"); 87 printf(" -S <path> directory where to create vhost sockets (default: pwd)\n"); 88 } 89 90 static int 91 interrupt_tgt_parse_arg(int ch, char *arg) 92 { 93 switch (ch) { 94 case 'S': 95 spdk_vhost_set_socket_path(arg); 96 break; 97 case 'E': 98 spdk_interrupt_mode_enable(); 99 break; 100 default: 101 return -EINVAL; 102 } 103 return 0; 104 } 105 106 static void 107 interrupt_tgt_started(void *arg1) 108 { 109 } 110 111 int 112 main(int argc, char *argv[]) 113 { 114 struct spdk_app_opts opts = {}; 115 int rc; 116 117 spdk_app_opts_init(&opts, sizeof(opts)); 118 opts.name = "interrupt_tgt"; 119 120 if ((rc = spdk_app_parse_args(argc, argv, &opts, "S:E", NULL, 121 interrupt_tgt_parse_arg, interrupt_tgt_usage)) != 122 SPDK_APP_PARSE_ARGS_SUCCESS) { 123 exit(rc); 124 } 125 126 /* Blocks until the application is exiting */ 127 rc = spdk_app_start(&opts, interrupt_tgt_started, NULL); 128 129 spdk_app_fini(); 130 131 return rc; 132 } 133