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