xref: /spdk/examples/interrupt_tgt/interrupt_tgt.c (revision 11ff66fecb2ffbc583e7dfe2d88ac141683b71fa)
1488570ebSJim Harris /*   SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse  *   Copyright (C) 2020 Intel Corporation.
3d8618de0SLiu Xiaodong  *   All rights reserved.
4d8618de0SLiu Xiaodong  */
5d8618de0SLiu Xiaodong 
6d8618de0SLiu Xiaodong #include "spdk/stdinc.h"
7d8618de0SLiu Xiaodong #include "spdk/conf.h"
8d8618de0SLiu Xiaodong #include "spdk/event.h"
95568355eSLiu Xiaodong #include "spdk/vhost.h"
1074db63dcSLiu Xiaodong #include "spdk/json.h"
1174db63dcSLiu Xiaodong #include "spdk/jsonrpc.h"
1274db63dcSLiu Xiaodong #include "spdk/rpc.h"
1374db63dcSLiu Xiaodong #include "spdk/env.h"
14f470a0dcSJim Harris #include "spdk/scheduler.h"
1574db63dcSLiu Xiaodong 
1674db63dcSLiu Xiaodong #include "spdk_internal/event.h"
1774db63dcSLiu Xiaodong 
1874db63dcSLiu Xiaodong struct rpc_reactor_set_interrupt_mode {
1974db63dcSLiu Xiaodong 	int32_t lcore;
2074db63dcSLiu Xiaodong 	bool disable_interrupt;
21f470a0dcSJim Harris 	int rc;
22f470a0dcSJim Harris 	struct spdk_thread *rpc_thread;
23f470a0dcSJim Harris 	struct spdk_jsonrpc_request *request;
2474db63dcSLiu Xiaodong };
2574db63dcSLiu Xiaodong 
2674db63dcSLiu Xiaodong static const struct spdk_json_object_decoder rpc_reactor_set_interrupt_mode_decoders[] = {
2774db63dcSLiu Xiaodong 	{"lcore", offsetof(struct rpc_reactor_set_interrupt_mode, lcore), spdk_json_decode_int32},
2874db63dcSLiu Xiaodong 	{"disable_interrupt", offsetof(struct rpc_reactor_set_interrupt_mode, disable_interrupt), spdk_json_decode_bool},
2974db63dcSLiu Xiaodong };
3074db63dcSLiu Xiaodong 
3174db63dcSLiu Xiaodong static void
3274db63dcSLiu Xiaodong rpc_reactor_set_interrupt_mode_cb(void *cb_arg)
3374db63dcSLiu Xiaodong {
34f470a0dcSJim Harris 	struct rpc_reactor_set_interrupt_mode *req = cb_arg;
3574db63dcSLiu Xiaodong 
3674db63dcSLiu Xiaodong 	SPDK_NOTICELOG("complete reactor switch\n");
3774db63dcSLiu Xiaodong 
38f470a0dcSJim Harris 	spdk_jsonrpc_send_bool_response(req->request, true);
39f470a0dcSJim Harris 	free(req);
40f470a0dcSJim Harris }
41f470a0dcSJim Harris 
42f470a0dcSJim Harris static void
43*11ff66feSsyeon.shin set_interrupt_mode_cb(void *arg1, void *arg2)
44f470a0dcSJim Harris {
45*11ff66feSsyeon.shin 	struct rpc_reactor_set_interrupt_mode *req = arg1;
46f470a0dcSJim Harris 
47f470a0dcSJim Harris 	spdk_thread_send_msg(req->rpc_thread, rpc_reactor_set_interrupt_mode_cb, req);
48f470a0dcSJim Harris }
49f470a0dcSJim Harris 
50f470a0dcSJim Harris static void
51f470a0dcSJim Harris set_interrupt_mode(void *arg1, void *arg2)
52f470a0dcSJim Harris {
53f470a0dcSJim Harris 	struct rpc_reactor_set_interrupt_mode *req = arg1;
54f470a0dcSJim Harris 	int rc;
55f470a0dcSJim Harris 
56f470a0dcSJim Harris 	rc = spdk_reactor_set_interrupt_mode(req->lcore, !req->disable_interrupt,
57f470a0dcSJim Harris 					     set_interrupt_mode_cb, req);
58f470a0dcSJim Harris 	if (rc)	{
59f470a0dcSJim Harris 		req->rc = rc;
60*11ff66feSsyeon.shin 		set_interrupt_mode_cb(req, NULL);
61f470a0dcSJim Harris 	}
6274db63dcSLiu Xiaodong }
6374db63dcSLiu Xiaodong 
6474db63dcSLiu Xiaodong static void
6574db63dcSLiu Xiaodong rpc_reactor_set_interrupt_mode(struct spdk_jsonrpc_request *request,
6674db63dcSLiu Xiaodong 			       const struct spdk_json_val *params)
6774db63dcSLiu Xiaodong {
68f470a0dcSJim Harris 	struct rpc_reactor_set_interrupt_mode *req;
69f470a0dcSJim Harris 
70f470a0dcSJim Harris 	req = calloc(1, sizeof(*req));
71f470a0dcSJim Harris 	if (req == NULL) {
72f470a0dcSJim Harris 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
73f470a0dcSJim Harris 						 "Out of memory");
74f470a0dcSJim Harris 		return;
75f470a0dcSJim Harris 	}
76f470a0dcSJim Harris 
77f470a0dcSJim Harris 	req->request = request;
78f470a0dcSJim Harris 	req->rpc_thread = spdk_get_thread();
7974db63dcSLiu Xiaodong 
8074db63dcSLiu Xiaodong 	if (spdk_json_decode_object(params, rpc_reactor_set_interrupt_mode_decoders,
8174db63dcSLiu Xiaodong 				    SPDK_COUNTOF(rpc_reactor_set_interrupt_mode_decoders),
82f470a0dcSJim Harris 				    req)) {
8374db63dcSLiu Xiaodong 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
8474db63dcSLiu Xiaodong 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
8574db63dcSLiu Xiaodong 						 "spdk_json_decode_object failed");
86f470a0dcSJim Harris 		free(req);
8774db63dcSLiu Xiaodong 		return;
8874db63dcSLiu Xiaodong 	}
8974db63dcSLiu Xiaodong 
909a0bd78bSZiye Yang 	if (!spdk_interrupt_mode_is_enabled()) {
919a0bd78bSZiye Yang 		SPDK_ERRLOG("Interrupt mode is not set when staring the application\n");
929a0bd78bSZiye Yang 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
939a0bd78bSZiye Yang 						 "spdk_json_decode_object failed");
94f470a0dcSJim Harris 		free(req);
959a0bd78bSZiye Yang 		return;
969a0bd78bSZiye Yang 	}
979a0bd78bSZiye Yang 
989a0bd78bSZiye Yang 
9974db63dcSLiu Xiaodong 	SPDK_NOTICELOG("RPC Start to %s interrupt mode on reactor %d.\n",
100f470a0dcSJim Harris 		       req->disable_interrupt ? "disable" : "enable", req->lcore);
101f470a0dcSJim Harris 	if (req->lcore >= (int64_t)spdk_env_get_first_core() &&
102f470a0dcSJim Harris 	    req->lcore <= (int64_t)spdk_env_get_last_core()) {
103f470a0dcSJim Harris 		struct spdk_event *e;
104f470a0dcSJim Harris 
105f470a0dcSJim Harris 		e = spdk_event_allocate(spdk_scheduler_get_scheduling_lcore(),
106f470a0dcSJim Harris 					set_interrupt_mode, req, NULL);
107f470a0dcSJim Harris 		spdk_event_call(e);
10874db63dcSLiu Xiaodong 	} else {
109f470a0dcSJim Harris 		free(req);
11074db63dcSLiu Xiaodong 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
11174db63dcSLiu Xiaodong 						 "Invalid parameters");
11274db63dcSLiu Xiaodong 	}
113f470a0dcSJim Harris }
114a8d70041STomasz Zawadzki /* private */ SPDK_RPC_REGISTER("reactor_set_interrupt_mode", rpc_reactor_set_interrupt_mode,
115a8d70041STomasz Zawadzki 				SPDK_RPC_RUNTIME)
116d8618de0SLiu Xiaodong 
117d8618de0SLiu Xiaodong static void
118d8618de0SLiu Xiaodong interrupt_tgt_usage(void)
119d8618de0SLiu Xiaodong {
120d8618de0SLiu Xiaodong 	printf(" -E                        Set interrupt mode\n");
1215568355eSLiu Xiaodong 	printf(" -S <path>                 directory where to create vhost sockets (default: pwd)\n");
122d8618de0SLiu Xiaodong }
123d8618de0SLiu Xiaodong 
124d8618de0SLiu Xiaodong static int
125d8618de0SLiu Xiaodong interrupt_tgt_parse_arg(int ch, char *arg)
126d8618de0SLiu Xiaodong {
127d8618de0SLiu Xiaodong 	switch (ch) {
1285568355eSLiu Xiaodong 	case 'S':
1295568355eSLiu Xiaodong 		spdk_vhost_set_socket_path(arg);
1305568355eSLiu Xiaodong 		break;
131d8618de0SLiu Xiaodong 	case 'E':
132d8618de0SLiu Xiaodong 		spdk_interrupt_mode_enable();
133d8618de0SLiu Xiaodong 		break;
134d8618de0SLiu Xiaodong 	default:
135d8618de0SLiu Xiaodong 		return -EINVAL;
136d8618de0SLiu Xiaodong 	}
137d8618de0SLiu Xiaodong 	return 0;
138d8618de0SLiu Xiaodong }
139d8618de0SLiu Xiaodong 
140d8618de0SLiu Xiaodong static void
141d8618de0SLiu Xiaodong interrupt_tgt_started(void *arg1)
142d8618de0SLiu Xiaodong {
143d8618de0SLiu Xiaodong }
144d8618de0SLiu Xiaodong 
145d8618de0SLiu Xiaodong int
146d8618de0SLiu Xiaodong main(int argc, char *argv[])
147d8618de0SLiu Xiaodong {
148d8618de0SLiu Xiaodong 	struct spdk_app_opts opts = {};
149d8618de0SLiu Xiaodong 	int rc;
150d8618de0SLiu Xiaodong 
15148701bd9SZiye Yang 	spdk_app_opts_init(&opts, sizeof(opts));
152d8618de0SLiu Xiaodong 	opts.name = "interrupt_tgt";
153d8618de0SLiu Xiaodong 
1545568355eSLiu Xiaodong 	if ((rc = spdk_app_parse_args(argc, argv, &opts, "S:E", NULL,
155d8618de0SLiu Xiaodong 				      interrupt_tgt_parse_arg, interrupt_tgt_usage)) !=
156d8618de0SLiu Xiaodong 	    SPDK_APP_PARSE_ARGS_SUCCESS) {
157d8618de0SLiu Xiaodong 		exit(rc);
158d8618de0SLiu Xiaodong 	}
159d8618de0SLiu Xiaodong 
160d8618de0SLiu Xiaodong 	/* Blocks until the application is exiting */
161d8618de0SLiu Xiaodong 	rc = spdk_app_start(&opts, interrupt_tgt_started, NULL);
162d8618de0SLiu Xiaodong 
163d8618de0SLiu Xiaodong 	spdk_app_fini();
164d8618de0SLiu Xiaodong 
165d8618de0SLiu Xiaodong 	return rc;
166d8618de0SLiu Xiaodong }
167