Files
linux-nvgpu/nvsched/include/nvs/sched.h
Konsta Hölttä bfd7fc8649 nvsched: Initial core data
Add software scheduler and domain data structures for a general
scheduler and bookkeeping code to create, remove and list them and to
keep logs for debugging and development; as a first step, this will only
serve as the heart of nvgpu-internal domain scheduler.

Long term, this code is intended to work in arbitrary configurations -
running on GSP, CPU, or elsewhere, and controlling the GPU or something
else.

Jira NVGPU-6427

Change-Id: I2a1577fa9120bb8ae6b9552dd2a187cb2cdfe504
Signed-off-by: Alex Waterman <alexw@nvidia.com>
Signed-off-by: Konsta Hölttä <kholtta@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2632286
Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
2021-12-07 07:06:49 -08:00

176 lines
6.3 KiB
C

/*
* Copyright (c) 2021 NVIDIA Corporation. All rights reserved.
*
* NVIDIA Corporation and its licensors retain all intellectual property
* and proprietary rights in and to this software, related documentation
* and any modifications thereto. Any use, reproduction, disclosure or
* distribution of this software and related documentation without an express
* license agreement from NVIDIA Corporation is strictly prohibited.
*/
#ifndef NVS_SCHED_H
#define NVS_SCHED_H
/**
* @page NV Scheduler
*
* Overview
* ========
*
* An nvs_sched object defines a _scheduler_, this is an object that contains
* information about the domains and contexts to manage, and some operations
* to interact with the underlying HW. The scheduler is split up into three
* distinct parts:
*
* 1. The implementation operations that allow the scheduler to interact
* with a given piece of hardware. This serves as a hardware abstraction
* since the conceptual framework here is not tied to a specific piece of
* HW such as a GPU.
* 2. Algorithm implementations that pick the next context to actually run.
* 3. A core component that defines the data structures which define the
* domains/contexts. The core component is responsible for linking the
* scheduling algorithm outputs to hardware operations.
*
* Implementation Operations
* =========================
*
* Each concrete implementation of nvsched must provide, at a minimum some
* operations that allow the scheduling logic to interact with the managed
* HW. The two primary operations are preemption and recovery.
*
* Algorithms
* ==========
*
* nvsched splits the data structures from the algorithms. This allows
* multiple algorithms to be supported: for example one implementation could
* use a round-robin approach for picking next domains, but another may wish
* to use a priority based approach.
*
* Core Scheduler
* ==============
*
* The responsibility for the core scheduler is to provide data structures
* that model a two level scheduling model: first there's domains and then
* there's contexts within a domain. An implementation built on top of
* nvsched will need to instantiate domains and contexts and then execute
* some top level operations to trigger scheduling work.
*
* The data structure nesting looks like this:
*
* struct nvs_sched
* +-------------------------+ +---------->+-----------+
* | | | | preempt() |
* | struct nvs_sched_ops +-----+ | recover() |
* | | +-----------+
* | // List of: |
* | struct nvs_domain +---------------->+-----------------+
* | | | Domain 1 |
* | struct nvs_domain_algo +-------+ | Domain Params |
* | | | | Context list +-----+
* +-------------------------+ | +-----------------+ |
* | | Domain ... | |
* +-------------+ | | Domain Params | |
* | Context 1 |<---------+ | | Context list +---+ |
* +-------------+ | | +-----------------+ | |
* | Context 2 |<---------+ | | Domain N | | |
* +-------------+ | | | Domain Params | | |
* | Context ... |<-----+ | | | Context list +-+ | |
* +-------------+ | | | +-----------------+ | | |
* | Context ... |<-----+ | | | | |
* +-------------+ | | +-------->+-----------------+ | | |
* | Context M |<-+ | | | next_domain() | | | |
* +-------------+ | | | | schedule() | | | |
* | | | | init() | | | |
* | | | +-----------------+ | | |
* +---|---|-----------------------------------+ | |
* +---|-------------------------------------+ |
* +---------------------------------------+
*/
#include <nvs/impl-internal.h>
#include <nvs/types-internal.h>
struct nvs_sched;
struct nvs_domain;
struct nvs_domain_algo;
struct nvs_domain_list;
struct nvs_log_buffer;
/**
* @brief Base scheduling operations an implementation will need to provide
* to the scheduling core.
*/
struct nvs_sched_ops {
/**
* @brief Preempt the running context on the device \a sched
* is managing.
*
* @param sched The scheduler.
*/
int (*preempt)(struct nvs_sched *sched);
/**
* @brief Recover the running context in \a sched.
*/
int (*recover)(struct nvs_sched *sched);
};
/**
* @brief Define a top level scheduler object.
*/
struct nvs_sched {
/**
* Ops that let the scheduler interface with the underlying
* hardware.
*/
struct nvs_sched_ops *ops;
/**
* List of domains. Internally stored as a singly linked
* list.
*
* @sa struct nvs_domain_list
*/
struct nvs_domain_list *domain_list;
/**
* Algorithm instance; invoked after a schedule() call.
*/
struct nvs_domain_algo *algorithm;
/**
* Log buffer with log entries.
*/
struct nvs_log_buffer *log;
/**
* Implementation private data.
*/
void *priv;
};
/**
* @brief Create a scheduler and assign the \a ops and \a priv pointers.
*
* @param sched Pointer to an uninitialized struct sched.
* @param ops Ops defining HW interactions.
* @param priv Private pointer for implementation use.
*
* Build a sched struct in the passed memory \a sched. This pointer should
* have at least sizeof(struct nvs_sched) bytes. nvsched cannot do this allocation
* since the nvs_malloc() function relies on the sched object (some APIs require
* an API token of some sort which they may choose to embed in sched->priv.
*
* The ops struct should be in memory that will not be reclaimed until after the
* \a sched memory is reclaimed.
*
* \a priv may be used by implementations where needed. The priv pointer contents
* will never be touched by nvsched.
*/
int nvs_sched_create(struct nvs_sched *sched,
struct nvs_sched_ops *ops, void *priv);
void nvs_sched_close(struct nvs_sched *sched);
#endif