1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 #include "spdk/conf.h" 36 #include "spdk/event.h" 37 #include "spdk/vhost.h" 38 #include "spdk/json.h" 39 #include "spdk/jsonrpc.h" 40 #include "spdk/rpc.h" 41 #include "spdk/env.h" 42 43 #include "spdk_internal/event.h" 44 45 struct rpc_reactor_set_interrupt_mode { 46 int32_t lcore; 47 bool disable_interrupt; 48 }; 49 50 static const struct spdk_json_object_decoder rpc_reactor_set_interrupt_mode_decoders[] = { 51 {"lcore", offsetof(struct rpc_reactor_set_interrupt_mode, lcore), spdk_json_decode_int32}, 52 {"disable_interrupt", offsetof(struct rpc_reactor_set_interrupt_mode, disable_interrupt), spdk_json_decode_bool}, 53 }; 54 55 static void 56 rpc_reactor_set_interrupt_mode_cb(void *cb_arg) 57 { 58 struct spdk_jsonrpc_request *request = cb_arg; 59 60 SPDK_NOTICELOG("complete reactor switch\n"); 61 62 spdk_jsonrpc_send_bool_response(request, true); 63 } 64 65 static void 66 rpc_reactor_set_interrupt_mode(struct spdk_jsonrpc_request *request, 67 const struct spdk_json_val *params) 68 { 69 struct rpc_reactor_set_interrupt_mode req = {}; 70 int rc; 71 72 if (spdk_json_decode_object(params, rpc_reactor_set_interrupt_mode_decoders, 73 SPDK_COUNTOF(rpc_reactor_set_interrupt_mode_decoders), 74 &req)) { 75 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 76 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 77 "spdk_json_decode_object failed"); 78 return; 79 } 80 81 SPDK_NOTICELOG("RPC Start to %s interrupt mode on reactor %d.\n", 82 req.disable_interrupt ? "disable" : "enable", req.lcore); 83 if (req.lcore >= (int64_t)spdk_env_get_first_core() && 84 req.lcore <= (int64_t)spdk_env_get_last_core()) { 85 rc = spdk_reactor_set_interrupt_mode(req.lcore, !req.disable_interrupt, 86 rpc_reactor_set_interrupt_mode_cb, request); 87 if (rc) { 88 goto err; 89 } 90 } else { 91 goto err; 92 } 93 94 return; 95 96 err: 97 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 98 "Invalid parameters"); 99 } 100 /* private */ SPDK_RPC_REGISTER("reactor_set_interrupt_mode", rpc_reactor_set_interrupt_mode, 101 SPDK_RPC_RUNTIME) 102 103 static void 104 interrupt_tgt_usage(void) 105 { 106 printf(" -E Set interrupt mode\n"); 107 printf(" -S <path> directory where to create vhost sockets (default: pwd)\n"); 108 } 109 110 static int 111 interrupt_tgt_parse_arg(int ch, char *arg) 112 { 113 switch (ch) { 114 case 'S': 115 spdk_vhost_set_socket_path(arg); 116 break; 117 case 'E': 118 spdk_interrupt_mode_enable(); 119 break; 120 default: 121 return -EINVAL; 122 } 123 return 0; 124 } 125 126 static void 127 interrupt_tgt_started(void *arg1) 128 { 129 } 130 131 int 132 main(int argc, char *argv[]) 133 { 134 struct spdk_app_opts opts = {}; 135 int rc; 136 137 spdk_app_opts_init(&opts, sizeof(opts)); 138 opts.name = "interrupt_tgt"; 139 140 if ((rc = spdk_app_parse_args(argc, argv, &opts, "S:E", NULL, 141 interrupt_tgt_parse_arg, interrupt_tgt_usage)) != 142 SPDK_APP_PARSE_ARGS_SUCCESS) { 143 exit(rc); 144 } 145 146 /* Blocks until the application is exiting */ 147 rc = spdk_app_start(&opts, interrupt_tgt_started, NULL); 148 149 spdk_app_fini(); 150 151 return rc; 152 } 153