event: define scheduler API
Add structures and function for new scheduler API. Change-Id: I8e379db62189eb7c36092265c137f07368650e9b Signed-off-by: Vitaliy Mysak <vitaliy.mysak@intel.com> Signed-off-by: Maciej Szwed <maciej.szwed@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4053 Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
9e89645b61
commit
2a146cd936
@ -62,8 +62,11 @@ enum spdk_reactor_state {
|
||||
|
||||
struct spdk_lw_thread {
|
||||
TAILQ_ENTRY(spdk_lw_thread) link;
|
||||
bool resched;
|
||||
uint64_t tsc_start;
|
||||
uint32_t lcore;
|
||||
uint32_t new_lcore;
|
||||
bool resched;
|
||||
struct spdk_thread_stats current_stats;
|
||||
};
|
||||
|
||||
struct spdk_reactor {
|
||||
@ -76,7 +79,8 @@ struct spdk_reactor {
|
||||
|
||||
struct {
|
||||
uint32_t is_valid : 1;
|
||||
uint32_t reserved : 31;
|
||||
uint32_t is_scheduling : 1;
|
||||
uint32_t reserved : 30;
|
||||
} flags;
|
||||
|
||||
uint64_t tsc_last;
|
||||
@ -171,6 +175,79 @@ void spdk_subsystem_config_json(struct spdk_json_write_ctx *w, struct spdk_subsy
|
||||
void spdk_rpc_initialize(const char *listen_addr);
|
||||
void spdk_rpc_finish(void);
|
||||
|
||||
/**
|
||||
* A list of cores and threads which is used for scheduling.
|
||||
*/
|
||||
struct spdk_scheduler_core_info {
|
||||
uint64_t core_idle_tsc;
|
||||
uint64_t core_busy_tsc;
|
||||
uint32_t lcore;
|
||||
uint32_t threads_count;
|
||||
struct spdk_lw_thread **threads;
|
||||
};
|
||||
|
||||
/**
|
||||
* Scheduler balance function type.
|
||||
* Accepts array of core_info which is of size 'count' and returns updated array.
|
||||
*/
|
||||
typedef void (*spdk_scheduler_balance_fn)(struct spdk_scheduler_core_info *core_info, int count);
|
||||
|
||||
/**
|
||||
* Scheduler init function type.
|
||||
* Called on scheduler module initialization.
|
||||
*/
|
||||
typedef int (*spdk_scheduler_init_fn)(void);
|
||||
|
||||
/**
|
||||
* Scheduler deinitialization function type.
|
||||
* Called on reactor fini.
|
||||
*/
|
||||
typedef int (*spdk_scheduler_deinit_fn)(void);
|
||||
|
||||
/** Thread scheduler */
|
||||
struct spdk_scheduler {
|
||||
char *name;
|
||||
spdk_scheduler_init_fn init;
|
||||
spdk_scheduler_deinit_fn deinit;
|
||||
spdk_scheduler_balance_fn balance;
|
||||
TAILQ_ENTRY(spdk_scheduler) link;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the given scheduler to the list of registered schedulers.
|
||||
* This function should be invoked by referencing the macro
|
||||
* SPDK_SCHEDULER_REGISTER in the scheduler c file.
|
||||
*
|
||||
* \param scheduler Scheduler to be added.
|
||||
*/
|
||||
void _spdk_scheduler_list_add(struct spdk_scheduler *scheduler);
|
||||
|
||||
/**
|
||||
* Change current scheduler.
|
||||
*
|
||||
* \param name Name of the scheduler to be used.
|
||||
*
|
||||
* \return 0 on success or non-zero on failure.
|
||||
*/
|
||||
int _spdk_scheduler_set(char *name);
|
||||
|
||||
/**
|
||||
* Change current scheduling period.
|
||||
*
|
||||
* \param period New period (ticks).
|
||||
* Use spdk_get_ticks_hz() to translate seconds to ticks.
|
||||
*/
|
||||
void _spdk_scheduler_period_set(uint32_t period);
|
||||
|
||||
/*
|
||||
* Macro used to register new reactor balancer.
|
||||
*/
|
||||
#define SPDK_SCHEDULER_REGISTER(scheduler) \
|
||||
static void __attribute__((constructor)) _spdk_scheduler_register_##name(void) \
|
||||
{ \
|
||||
spdk_scheduler_list_add(scheduler); \
|
||||
} \
|
||||
|
||||
/**
|
||||
* \brief Register a new subsystem
|
||||
*/
|
||||
|
@ -62,9 +62,61 @@ static bool g_framework_context_switch_monitor_enabled = true;
|
||||
|
||||
static struct spdk_mempool *g_spdk_event_mempool = NULL;
|
||||
|
||||
TAILQ_HEAD(, spdk_scheduler) g_scheduler_list
|
||||
= TAILQ_HEAD_INITIALIZER(g_scheduler_list);
|
||||
|
||||
static struct spdk_scheduler *g_scheduler;
|
||||
static uint32_t g_scheduler_period;
|
||||
|
||||
static int reactor_interrupt_init(struct spdk_reactor *reactor);
|
||||
static void reactor_interrupt_fini(struct spdk_reactor *reactor);
|
||||
|
||||
static struct spdk_scheduler *
|
||||
_scheduler_find(char *name)
|
||||
{
|
||||
struct spdk_scheduler *tmp;
|
||||
|
||||
TAILQ_FOREACH(tmp, &g_scheduler_list, link) {
|
||||
if (strcmp(name, tmp->name) == 0) {
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
_spdk_scheduler_set(char *name)
|
||||
{
|
||||
struct spdk_scheduler *scheduler;
|
||||
|
||||
scheduler = _scheduler_find(name);
|
||||
if (scheduler == NULL) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
g_scheduler = scheduler;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
_spdk_scheduler_period_set(uint32_t period)
|
||||
{
|
||||
g_scheduler_period = period;
|
||||
}
|
||||
|
||||
void
|
||||
_spdk_scheduler_list_add(struct spdk_scheduler *scheduler)
|
||||
{
|
||||
if (_scheduler_find(scheduler->name)) {
|
||||
SPDK_ERRLOG("scheduler named '%s' already registered.\n", scheduler->name);
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
TAILQ_INSERT_TAIL(&g_scheduler_list, scheduler, link);
|
||||
}
|
||||
|
||||
static void
|
||||
reactor_construct(struct spdk_reactor *reactor, uint32_t lcore)
|
||||
{
|
||||
@ -689,6 +741,7 @@ _reactor_request_thread_reschedule(struct spdk_thread *thread)
|
||||
assert(lw_thread != NULL);
|
||||
|
||||
lw_thread->resched = true;
|
||||
lw_thread->lcore = SPDK_ENV_LCORE_ID_ANY;
|
||||
|
||||
current_core = spdk_env_get_current_core();
|
||||
reactor = spdk_reactor_get(current_core);
|
||||
|
Loading…
Reference in New Issue
Block a user