/*
* Copyright 2015 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
/**
* DOC: Overview
*
* The GPU scheduler provides entities which allow userspace to push jobs
* into software queues which are then scheduled on a hardware run queue.
* The software queues have a priority among them. The scheduler selects the entities
* from the run queue using a FIFO. The scheduler provides dependency handling
* features among jobs. The driver is supposed to provide callback functions for
* backend operations to the scheduler like submitting a job to hardware run queue,
* returning the dependencies of a job etc.
*
* The organisation of the scheduler is the following:
*
* 1. Each hw run queue has one scheduler
* 2. Each scheduler has multiple run queues with different priorities
* (e.g., HIGH_HW,HIGH_SW, KERNEL, NORMAL)
* 3. Each scheduler run queue has a queue of entities to schedule
* 4. Entities themselves maintain a queue of jobs that will be scheduled on
* the hardware.
*
* The jobs in a entity are always scheduled in the order that they were pushed.
*
* Note that once a job was taken from the entities queue and pushed to the
* hardware, i.e. the pending queue, the entity must not be referenced anymore
* through the jobs entity pointer.
*/
/**
* DOC: Flow Control
*
* The DRM GPU scheduler provides a flow control mechanism to regulate the rate
* in which the jobs fetched from scheduler entities are executed.
*
* In this context the &drm_gpu_scheduler keeps track of a driver specified
* credit limit representing the capacity of this scheduler and a credit count;
* every &drm_sched_job carries a driver specified number of credits.
*
* Once a job is executed (but not yet finished), the job's credits contribute
* to the scheduler's credit count until the job is finished. If by executing
* one more job the scheduler's credit count would exceed the scheduler's
* credit limit, the job won't be executed. Instead, the scheduler will wait
* until the credit count has decreased enough to not overflow its credit limit.
* This implies waiting for previously executed jobs.
*
* Optionally, drivers may register a callback (update_job_credits) provided by
* struct drm_sched_backend_ops to update the job's credits dynamically. The
* scheduler executes this callback every time the scheduler considers a job for
* execution and subsequently checks whether the job fits the scheduler's credit
* limit.
*/
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/completion.h>
#include <linux/dma-resv.h>
#include <uapi/linux/sched/types.h>
#include <drm/drm_print.h>
#include <drm/drm_gem.h>
#include <drm/drm_syncobj.h>
#include <drm/gpu_scheduler.h>
#include <drm/spsc_queue.h>
#define CREAT