mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 09:12:24 +03:00
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>
This commit is contained in:
committed by
mobile promotions
parent
ce7d589a4d
commit
bfd7fc8649
28
nvsched/include/nvs/context.h
Normal file
28
nvsched/include/nvs/context.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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_CONTEXT_H
|
||||
#define NVS_CONTEXT_H
|
||||
|
||||
#include <nvs/types-internal.h>
|
||||
|
||||
struct nvs_context;
|
||||
|
||||
/**
|
||||
* Similar to a nvs_domain_list this is a singly linked list of contexts.
|
||||
* If sub-scheduler algorithms ever want something more sophisticated they'll
|
||||
* likely have the build it themselves.
|
||||
*/
|
||||
struct nvs_context_list {
|
||||
u32 nr;
|
||||
struct nvs_context *contexts;
|
||||
};
|
||||
|
||||
#endif
|
||||
76
nvsched/include/nvs/domain.h
Normal file
76
nvsched/include/nvs/domain.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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_DOMAIN_H
|
||||
#define NVS_DOMAIN_H
|
||||
|
||||
#include <nvs/types-internal.h>
|
||||
|
||||
struct nvs_sched;
|
||||
struct nvs_domain;
|
||||
|
||||
/*
|
||||
* nvsched provides a simple, singly linked list for keeping track of
|
||||
* available domains. If algorithms need something more complex, like a
|
||||
* table of priorities and domains therein, then it will need to build
|
||||
* these data structures during its init().
|
||||
*/
|
||||
struct nvs_domain_list {
|
||||
u32 nr;
|
||||
struct nvs_domain *domains;
|
||||
|
||||
/*
|
||||
* Convenience for adding a domain quickly.
|
||||
*/
|
||||
struct nvs_domain *last;
|
||||
};
|
||||
|
||||
struct nvs_domain {
|
||||
char name[32];
|
||||
|
||||
struct nvs_context_list *ctx_list;
|
||||
|
||||
/*
|
||||
* Internal, singly linked list pointer.
|
||||
*/
|
||||
struct nvs_domain *next;
|
||||
|
||||
/*
|
||||
* Scheduling parameters: specify how long this domain should be scheduled
|
||||
* for and what the grace period the scheduler should give this domain when
|
||||
* preempting. A value of zero is treated as an infinite timeslice or an
|
||||
* infinite grace period.
|
||||
*/
|
||||
u32 timeslice_us;
|
||||
u32 preempt_grace_us;
|
||||
|
||||
/*
|
||||
* Priv pointer for downstream use.
|
||||
*/
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Iterate over the list of domains present in the sched.
|
||||
*/
|
||||
#define nvs_domain_for_each(sched, domain_ptr) \
|
||||
for ((domain_ptr) = (sched)->domain_list->domains; \
|
||||
(domain_ptr) != NULL; \
|
||||
(domain_ptr) = (domain_ptr)->next)
|
||||
|
||||
struct nvs_domain *nvs_domain_create(struct nvs_sched *sched,
|
||||
const char *name, u32 timeslice, u32 preempt_grace,
|
||||
void *priv);
|
||||
void nvs_domain_destroy(struct nvs_sched *sched, struct nvs_domain *dom);
|
||||
void nvs_domain_clear_all(struct nvs_sched *sched);
|
||||
u32 nvs_domain_count(struct nvs_sched *sched);
|
||||
struct nvs_domain *nvs_domain_by_name(struct nvs_sched *sched, const char *name);
|
||||
|
||||
#endif
|
||||
89
nvsched/include/nvs/impl-internal.h
Normal file
89
nvsched/include/nvs/impl-internal.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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_IMPL_INTERNAL_H
|
||||
#define NVS_IMPL_INTERNAL_H
|
||||
|
||||
/*
|
||||
* Each implementation of the nvsched code needs to provide a few basic
|
||||
* functions to use for interaction with the environment. Things such as
|
||||
* memory allocation and de-allocation.
|
||||
*
|
||||
* These should be provided to nvsched as macro definitions as laid out
|
||||
* below. Each implementation should provide an impl.h header file in an
|
||||
* accessible header include path that defines these macros.
|
||||
*/
|
||||
|
||||
#include "impl.h"
|
||||
|
||||
#ifndef nvs_malloc
|
||||
#error "Missing impl def: nvs_malloc()"
|
||||
#else
|
||||
/**
|
||||
* @brief Allocate and return a pointer to memory.
|
||||
*
|
||||
* @param size Size of the memory in bytes.
|
||||
*
|
||||
* @return A void pointer to memory containing \a size
|
||||
* bytes of available memory.
|
||||
*
|
||||
* Implementation notes: This may allocate more memory than is strictly
|
||||
* needed. The \a size argument is an unsigned 64 bit type, u64.
|
||||
*
|
||||
* #define nvs_malloc(sched, size)
|
||||
*/
|
||||
#endif
|
||||
|
||||
#ifndef nvs_free
|
||||
#error "Missing impl def: nvs_free()"
|
||||
#else
|
||||
/**
|
||||
* @brief Free a ptr created with nvs_malloc().
|
||||
*
|
||||
* #define nvs_free(sched, ptr)
|
||||
*/
|
||||
#endif
|
||||
|
||||
#ifndef nvs_memset
|
||||
#error "Missing impl def: nvs_memset()"
|
||||
#else
|
||||
/**
|
||||
* @brief Set contents of \a ptr to \a value.
|
||||
*
|
||||
* #define nvs_memset(ptr, value, size)
|
||||
*/
|
||||
#endif
|
||||
|
||||
#ifndef nvs_timestamp
|
||||
#error "Missing impl def: nvs_timestamp()"
|
||||
#else
|
||||
/**
|
||||
* @brief Return the current time in _nanoseconds_. Expected return is a s64; this
|
||||
* makes it easier on Linux.
|
||||
*
|
||||
* #define nvs_timestamp()
|
||||
*/
|
||||
#endif
|
||||
|
||||
#ifndef nvs_log
|
||||
#error "Missing impl def: nvs_timestamp()"
|
||||
#else
|
||||
/**
|
||||
* @brief Print a log message; log messages are by definition informational. They
|
||||
* are likely going to be printed to a uart or something similar so will be very
|
||||
* slow.
|
||||
*
|
||||
* It is up to the integrator to turn them on and off as needed.
|
||||
*
|
||||
* #define nvs_log(sched, fmt, ...)
|
||||
*/
|
||||
#endif
|
||||
|
||||
#endif
|
||||
71
nvsched/include/nvs/log.h
Normal file
71
nvsched/include/nvs/log.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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_LOG_H
|
||||
#define NVS_LOG_H
|
||||
|
||||
#include <nvs/types-internal.h>
|
||||
|
||||
/*
|
||||
* Default log size; 64K entries at 8 bytes each is 512Kb of space. For a space
|
||||
* constrained system this is obviously a lot. It can be overridden.
|
||||
*/
|
||||
#ifndef NVS_LOG_ENTRIES
|
||||
#define NVS_LOG_ENTRIES (64 * 1024)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Fast and efficient logging, even on microcontrollers, is an absolute
|
||||
* must for nvsched. The logging provided here is binary encoded to take up
|
||||
* a small amount of space and reduce time spent writing the logs.
|
||||
*
|
||||
* An implementation of nvsched should decode the logs later, when not in
|
||||
* a time critical path. The event type can be decoded with nvs_log_event_string().
|
||||
*/
|
||||
enum nvs_event {
|
||||
NVS_EV_NO_EVENT,
|
||||
NVS_EV_CREATE_SCHED,
|
||||
NVS_EV_CREATE_DOMAIN,
|
||||
NVS_EV_REMOVE_DOMAIN,
|
||||
NVS_EV_MAX = 0xffffffff /* Force to 32 bit enum size. */
|
||||
};
|
||||
|
||||
struct nvs_sched;
|
||||
|
||||
/**
|
||||
* @brief A single log event used to track event type, timestamp, etc. Note this
|
||||
* is 8 byte aligned.
|
||||
*/
|
||||
struct nvs_log_event {
|
||||
u64 timestamp;
|
||||
u32 data;
|
||||
enum nvs_event event;
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple circular buffer for putting and getting events.
|
||||
*/
|
||||
struct nvs_log_buffer {
|
||||
struct nvs_log_event *events;
|
||||
u32 entries;
|
||||
|
||||
u32 get;
|
||||
u32 put;
|
||||
|
||||
u64 ts_offset;
|
||||
};
|
||||
|
||||
int nvs_log_init(struct nvs_sched *sched);
|
||||
void nvs_log_destroy(struct nvs_sched *sched);
|
||||
void nvs_log_event(struct nvs_sched *sched, enum nvs_event event, u32 data);
|
||||
void nvs_log_get(struct nvs_sched *sched, struct nvs_log_event *ev);
|
||||
const char *nvs_log_event_string(enum nvs_event ev);
|
||||
|
||||
#endif
|
||||
175
nvsched/include/nvs/sched.h
Normal file
175
nvsched/include/nvs/sched.h
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* 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
|
||||
38
nvsched/include/nvs/types-internal.h
Normal file
38
nvsched/include/nvs/types-internal.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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_TYPES_INTERNAL_H
|
||||
#define NVS_TYPES_INTERNAL_H
|
||||
|
||||
/*
|
||||
* If an implementation decides to it can provide a types.h header that
|
||||
* nvsched will attempt to include. If so then the below define should
|
||||
* be set.
|
||||
*
|
||||
* If no types.h is passed then stdint.h is used to build the expected
|
||||
* types in nvsched.
|
||||
*/
|
||||
#ifdef NVS_USE_IMPL_TYPES
|
||||
#include "types.h"
|
||||
#else
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
typedef int8_t s8;
|
||||
typedef int16_t s16;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t s64;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user