Skip to content

Commit

Permalink
scheduler: create public API and subsystem for scheduler/governor
Browse files Browse the repository at this point in the history
This patch moves schedueler and governor related API from
the internal event.h to public scheduler.h.

With this it is possible to create subsystem responsible
for handling the schedulers.
Three schedulers and a governor were moved to scheduler modules
from event framework.

This will allow next patch to add JSON RPC configuration
to the whole subsystem.
Along with easier addition of other schedulers.

Removed debug logs from gscheduler, as they serve little purpose.

Signed-off-by: Krzysztof Karas <[email protected]>
Signed-off-by: Tomasz Zawadzki <[email protected]>
Change-Id: I98ca1ea4fb281beb71941656444267842a8875b7
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6995
Community-CI: Broadcom CI <[email protected]>
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <[email protected]>
Reviewed-by: Jim Harris <[email protected]>
Reviewed-by: Shuhei Matsumoto <[email protected]>
  • Loading branch information
tomzawadzki committed Sep 7, 2021
1 parent b518cbe commit a86e40f
Show file tree
Hide file tree
Showing 24 changed files with 672 additions and 295 deletions.
286 changes: 286 additions & 0 deletions include/spdk/scheduler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
/*-
* BSD LICENSE
*
* Copyright (c) Intel Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef SPDK_SCHEDULER_H
#define SPDK_SCHEDULER_H

#include "spdk/stdinc.h"

#ifdef __cplusplus
extern "C" {
#endif

#include "spdk/event.h"
#include "spdk/json.h"
#include "spdk/thread.h"
#include "spdk/util.h"

struct spdk_governor_capabilities {
bool priority; /* Core with higher base frequency */
};

/**
* Cores governor
* Implements core frequency control for schedulers. Functions from this structure
* are invoked from scheduling reactor.
*/
struct spdk_governor {
const char *name;

/**
* Get current frequency of a given core.
*
* \param lcore_id Core number.
*
* \return Currently set core frequency.
*/
uint32_t (*get_core_curr_freq)(uint32_t lcore_id);

/**
* Increase core frequency to next available one.
*
* \param lcore_id Core number.
*
* \return 1 on success, 0 already at max frequency, negative on error.
*/
int (*core_freq_up)(uint32_t lcore_id);

/**
* Decrease core frequency to next available one.
*
* \param lcore_id Core number.
*
* \return 1 on success, 0 already at min frequency, negative on error.
*/
int (*core_freq_down)(uint32_t lcore_id);

/**
* Set core frequency to maximum available.
*
* \param lcore_id Core number.
*
* \return 1 on success, 0 already at max frequency, negative on error.
*/
int (*set_core_freq_max)(uint32_t lcore_id);

/**
* Set core frequency to minimum available.
*
* \param lcore_id Core number.
*
* \return 1 on success, 0 already at min frequency, negative on error.
*/
int (*set_core_freq_min)(uint32_t lcore_id);

/**
* Get capabilities of a given core.
*
* \param lcore_id Core number.
* \param capabilities Structure to fill with capabilities data.
*
* \return 0 on success, negative on error.
*/
int (*get_core_capabilities)(uint32_t lcore_id, struct spdk_governor_capabilities *capabilities);

/**
* Initialize a governor.
*
* \return 0 on success, non-zero on error.
*/
int (*init)(void);

/**
* Deinitialize a governor.
*/
void (*deinit)(void);

TAILQ_ENTRY(spdk_governor) link;
};

/**
* Set the current governor.
*
* Always deinitalizes previously set governor.
* No governor will be set if name parameter is NULL.
* This function should be invoked on scheduling reactor.
*
* \param name Name of the governor to be used.
*
* \return 0 on success or non-zero on failure.
*/
int spdk_governor_set(const char *name);

/**
* Get currently set governor.
*
* \return a pointer to spdk governor or NULL if none is set.
*/
struct spdk_governor *spdk_governor_get(void);

/**
* Add the given governor to the list of registered governors.
* This function should be invoked by referencing the macro
* SPDK_GOVERNOR_REGISTER in the governor c file.
*
* \param governor Governor to be added.
*
* \return 0 on success or non-zero on failure.
*/
void spdk_governor_register(struct spdk_governor *governor);

/**
* Macro used to register new governors.
*/
#define SPDK_GOVERNOR_REGISTER(governor) \
static void __attribute__((constructor)) _spdk_governor_register_ ## governor(void) \
{ \
spdk_governor_register(&governor); \
} \

/**
* Structure representing thread used for scheduling.
*/
struct spdk_scheduler_thread_info {
uint32_t lcore;
uint64_t thread_id;
/* stats over a lifetime of a thread */
struct spdk_thread_stats total_stats;
/* stats during the last scheduling period */
struct spdk_thread_stats current_stats;
};

/**
* A list of cores and threads which is used for scheduling.
*/
struct spdk_scheduler_core_info {
/* stats over a lifetime of a core */
uint64_t total_idle_tsc;
uint64_t total_busy_tsc;
/* stats during the last scheduling period */
uint64_t current_idle_tsc;
uint64_t current_busy_tsc;

uint32_t lcore;
uint32_t threads_count;
bool interrupt_mode;
struct spdk_scheduler_thread_info *thread_infos;
};

/**
* Thread scheduler.
* Functions from this structure are invoked from scheduling reactor.
*/
struct spdk_scheduler {
const char *name;

/**
* This function is called to initialize a scheduler.
*
* \return 0 on success or non-zero on failure.
*/
int (*init)(void);

/**
* This function is called to deinitialize a scheduler.
*/
void (*deinit)(void);

/**
* Function to balance threads across cores by modifying
* the value of their lcore field.
*
* \param core_info Structure describing cores and threads on them.
* \param count Size of the core_info array.
*/
void (*balance)(struct spdk_scheduler_core_info *core_info, uint32_t count);

TAILQ_ENTRY(spdk_scheduler) link;
};

/**
* Change current scheduler. If another scheduler was used prior,
* it will be deinitalized. No scheduler will be set if name parameter
* is NULL.
* This function should be invoked from scheduling reactor.
*
* \param name Name of the scheduler to be used.
*
* \return 0 on success or non-zero on failure.
*/
int spdk_scheduler_set(const char *name);

/**
* Get currently set scheduler.
*
* \return a pointer to spdk scheduler or NULL if none is set.
*/
struct spdk_scheduler *spdk_scheduler_get(void);

/**
* Change current scheduling period.
* Setting period to 0 disables scheduling.
*
* \param period Period to set in microseconds.
*/
void spdk_scheduler_set_period(uint64_t period);

/**
* Get scheduling period of currently set scheduler.
*
* \return Scheduling period in microseconds.
*/
uint64_t spdk_scheduler_get_period(void);

/**
* 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_register(struct spdk_scheduler *scheduler);

/*
* Macro used to register new scheduler.
*/
#define SPDK_SCHEDULER_REGISTER(scheduler) \
static void __attribute__((constructor)) _spdk_scheduler_register_ ## scheduler (void) \
{ \
spdk_scheduler_register(&scheduler); \
} \

#ifdef __cplusplus
}
#endif

#endif /* SPDK_SCHEDULER_H */
Loading

0 comments on commit a86e40f

Please sign in to comment.