xref: /spdk/include/spdk_internal/event.h (revision a6dbe3721eb3b5990707fc3e378c95e505dd8ab5)
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 	TAILQ_ENTRY(spdk_lw_thread)	link;
37 	uint64_t			tsc_start;
38 	uint32_t                        lcore;
39 	bool				resched;
40 	/* stats over a lifetime of a thread */
41 	struct spdk_thread_stats	total_stats;
42 	/* stats during the last scheduling period */
43 	struct spdk_thread_stats	current_stats;
44 };
45 
46 /**
47  * Completion callback to set reactor into interrupt mode or poll mode.
48  *
49  * \param cb_arg Argument to pass to the callback function.
50  */
51 typedef void (*spdk_reactor_set_interrupt_mode_cb)(void *cb_arg);
52 
53 struct spdk_reactor {
54 	/* Lightweight threads running on this reactor */
55 	TAILQ_HEAD(, spdk_lw_thread)			threads;
56 	uint32_t					thread_count;
57 
58 	/* Logical core number for this reactor. */
59 	uint32_t					lcore;
60 
61 	struct {
62 		uint32_t				is_valid : 1;
63 		uint32_t				reserved : 31;
64 	} flags;
65 
66 	uint64_t					tsc_last;
67 
68 	struct spdk_ring				*events;
69 	int						events_fd;
70 
71 	/* The last known rusage values */
72 	struct rusage					rusage;
73 	uint64_t					last_rusage;
74 
75 	uint64_t					busy_tsc;
76 	uint64_t					idle_tsc;
77 
78 	/* Each bit of cpuset indicates whether a reactor probably requires event notification */
79 	struct spdk_cpuset				notify_cpuset;
80 	/* Indicate whether this reactor currently runs in interrupt */
81 	bool						in_interrupt;
82 	bool						set_interrupt_mode_in_progress;
83 	bool						new_in_interrupt;
84 	spdk_reactor_set_interrupt_mode_cb		set_interrupt_mode_cb_fn;
85 	void						*set_interrupt_mode_cb_arg;
86 
87 	struct spdk_fd_group				*fgrp;
88 	int						resched_fd;
89 } __attribute__((aligned(SPDK_CACHE_LINE_SIZE)));
90 
91 int spdk_reactors_init(size_t msg_mempool_size);
92 void spdk_reactors_fini(void);
93 
94 void spdk_reactors_start(void);
95 void spdk_reactors_stop(void *arg1);
96 
97 struct spdk_reactor *spdk_reactor_get(uint32_t lcore);
98 
99 extern bool g_scheduling_in_progress;
100 
101 /**
102  * Allocate and pass an event to each reactor, serially.
103  *
104  * The allocated event is processed asynchronously - i.e. spdk_for_each_reactor
105  * will return prior to `fn` being called on each reactor.
106  *
107  * \param fn This is the function that will be called on each reactor.
108  * \param arg1 Argument will be passed to fn when called.
109  * \param arg2 Argument will be passed to fn when called.
110  * \param cpl This will be called on the originating reactor after `fn` has been
111  * called on each reactor.
112  */
113 void spdk_for_each_reactor(spdk_event_fn fn, void *arg1, void *arg2, spdk_event_fn cpl);
114 
115 /**
116  * Set reactor into interrupt mode or back to poll mode.
117  *
118  * Currently, this function is only permitted within spdk application thread.
119  * Also it requires the corresponding reactor does not have any spdk_thread.
120  *
121  * \param lcore CPU core index of specified reactor.
122  * \param new_in_interrupt Set interrupt mode for true, or poll mode for false.
123  * \param cb_fn This will be called on spdk application thread after setting interrupt mode.
124  * \param cb_arg Argument will be passed to cb_fn when called.
125  *
126  * \return 0 on success, negative errno on failure.
127  */
128 int spdk_reactor_set_interrupt_mode(uint32_t lcore, bool new_in_interrupt,
129 				    spdk_reactor_set_interrupt_mode_cb cb_fn, void *cb_arg);
130 
131 /**
132  * Get a handle to spdk application thread.
133  *
134  * \return a pointer to spdk application thread on success or NULL on failure.
135  */
136 struct spdk_thread *_spdk_get_app_thread(void);
137 
138 #ifdef __cplusplus
139 }
140 #endif
141 
142 #endif /* SPDK_INTERNAL_EVENT_H */
143