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