xref: /spdk/include/spdk_internal/event.h (revision 671ee5e075565cae5d7a23767c887600496be6f0)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2017 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #ifndef SPDK_INTERNAL_EVENT_H
7 #define SPDK_INTERNAL_EVENT_H
8 
9 #include "spdk/stdinc.h"
10 
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14 
15 #include "spdk/event.h"
16 #include "spdk/json.h"
17 #include "spdk/thread.h"
18 #include "spdk/util.h"
19 
20 struct spdk_event {
21 	uint32_t		lcore;
22 	spdk_event_fn		fn;
23 	void			*arg1;
24 	void			*arg2;
25 };
26 
27 enum spdk_reactor_state {
28 	SPDK_REACTOR_STATE_UNINITIALIZED = 0,
29 	SPDK_REACTOR_STATE_INITIALIZED = 1,
30 	SPDK_REACTOR_STATE_RUNNING = 2,
31 	SPDK_REACTOR_STATE_EXITING = 3,
32 	SPDK_REACTOR_STATE_SHUTDOWN = 4,
33 };
34 
35 struct spdk_lw_thread;
36 
37 /**
38  * Completion callback to set reactor into interrupt mode or poll mode.
39  *
40  * \param cb_arg Argument to pass to the callback function.
41  */
42 typedef void (*spdk_reactor_set_interrupt_mode_cb)(void *cb_arg1, void *cb_arg2);
43 
44 struct spdk_reactor {
45 	/* Lightweight threads running on this reactor */
46 	TAILQ_HEAD(, spdk_lw_thread)			threads;
47 	uint32_t					thread_count;
48 
49 	/* Logical core number for this reactor. */
50 	uint32_t					lcore;
51 
52 	struct {
53 		uint32_t				is_valid : 1;
54 		uint32_t				reserved : 31;
55 	} flags;
56 
57 	uint64_t					tsc_last;
58 
59 	struct spdk_ring				*events;
60 	int						events_fd;
61 
62 	/* The last known rusage values */
63 	struct rusage					rusage;
64 	uint64_t					last_rusage;
65 
66 	uint64_t					busy_tsc;
67 	uint64_t					idle_tsc;
68 
69 	/* Each bit of cpuset indicates whether a reactor probably requires event notification */
70 	struct spdk_cpuset				notify_cpuset;
71 	/* Indicate whether this reactor currently runs in interrupt */
72 	bool						in_interrupt;
73 	bool						set_interrupt_mode_in_progress;
74 	bool						new_in_interrupt;
75 	spdk_reactor_set_interrupt_mode_cb		set_interrupt_mode_cb_fn;
76 	void						*set_interrupt_mode_cb_arg;
77 
78 	struct spdk_fd_group				*fgrp;
79 	int						resched_fd;
80 	uint16_t					trace_id;
81 } __attribute__((aligned(SPDK_CACHE_LINE_SIZE)));
82 
83 int spdk_reactors_init(size_t msg_mempool_size);
84 void spdk_reactors_fini(void);
85 
86 void spdk_reactors_start(void);
87 void spdk_reactors_stop(void *arg1);
88 
89 struct spdk_reactor *spdk_reactor_get(uint32_t lcore);
90 
91 extern bool g_scheduling_in_progress;
92 
93 /**
94  * Allocate and pass an event to each reactor, serially.
95  *
96  * The allocated event is processed asynchronously - i.e. spdk_for_each_reactor
97  * will return prior to `fn` being called on each reactor.
98  *
99  * \param fn This is the function that will be called on each reactor.
100  * \param arg1 Argument will be passed to fn when called.
101  * \param arg2 Argument will be passed to fn when called.
102  * \param cpl This will be called on the originating reactor after `fn` has been
103  * called on each reactor.
104  */
105 void spdk_for_each_reactor(spdk_event_fn fn, void *arg1, void *arg2, spdk_event_fn cpl);
106 
107 /**
108  * Set reactor into interrupt mode or back to poll mode.
109  *
110  * Currently, this function is only permitted within spdk application thread.
111  * Also it requires the corresponding reactor does not have any spdk_thread.
112  *
113  * \param lcore CPU core index of specified reactor.
114  * \param new_in_interrupt Set interrupt mode for true, or poll mode for false.
115  * \param cb_fn This will be called on spdk application thread after setting interrupt mode.
116  * \param cb_arg Argument will be passed to cb_fn when called.
117  *
118  * \return 0 on success, negative errno on failure.
119  */
120 int spdk_reactor_set_interrupt_mode(uint32_t lcore, bool new_in_interrupt,
121 				    spdk_reactor_set_interrupt_mode_cb cb_fn, void *cb_arg);
122 
123 #ifdef __cplusplus
124 }
125 #endif
126 
127 #endif /* SPDK_INTERNAL_EVENT_H */
128