#ifndef _DRM_GPU_SCHEDULER_INTERNAL_H_
#define _DRM_GPU_SCHEDULER_INTERNAL_H_
#include <linux/ktime.h>
#include <linux/kref.h>
#include <linux/spinlock.h>
struct drm_sched_entity_stats {
struct kref kref;
spinlock_t lock;
ktime_t runtime;
ktime_t prev_runtime;
ktime_t vruntime;
struct ewma_drm_sched_avgtime avg_job_us;
};
bool drm_sched_can_queue(struct drm_gpu_scheduler *sched,
struct drm_sched_entity *entity);
void drm_sched_wakeup(struct drm_gpu_scheduler *sched);
void drm_sched_rq_init(struct drm_sched_rq *rq);
struct drm_gpu_scheduler *
drm_sched_rq_add_entity(struct drm_sched_entity *entity);
void drm_sched_rq_remove_entity(struct drm_sched_rq *rq,
struct drm_sched_entity *entity);
void drm_sched_rq_pop_entity(struct drm_sched_entity *entity);
struct drm_sched_entity *
drm_sched_select_entity(struct drm_gpu_scheduler *sched);
void drm_sched_entity_select_rq(struct drm_sched_entity *entity);
struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity);
struct drm_sched_fence *drm_sched_fence_alloc(struct drm_sched_entity *s_entity,
void *owner, u64 drm_client_id);
void drm_sched_fence_init(struct drm_sched_fence *fence,
struct drm_sched_entity *entity);
void drm_sched_fence_free(struct drm_sched_fence *fence);
void drm_sched_fence_scheduled(struct drm_sched_fence *fence,
struct dma_fence *parent);
void drm_sched_fence_finished(struct drm_sched_fence *fence, int result);
static inline struct drm_sched_job *
drm_sched_entity_queue_pop(struct drm_sched_entity *entity)
{
struct spsc_node *node;
node = spsc_queue_pop(&entity->job_queue);
if (!node)
return NULL;
return container_of(node, struct drm_sched_job, queue_node);
}
static inline struct drm_sched_job *
drm_sched_entity_queue_peek(struct drm_sched_entity *entity)
{
struct spsc_node *node;
node = spsc_queue_peek(&entity->job_queue);
if (!node)
return NULL;
return container_of(node, struct drm_sched_job, queue_node);
}
static inline bool
drm_sched_entity_is_ready(struct drm_sched_entity *entity)
{
if (!spsc_queue_count(&entity->job_queue))
return false;
if (READ_ONCE(entity->dependency))
return false;
return true;
}
void drm_sched_entity_stats_release(struct kref *kref);
static inline struct drm_sched_entity_stats *
drm_sched_entity_stats_get(struct drm_sched_entity_stats *stats)
{
kref_get(&stats->kref);
return stats;
}
static inline void
drm_sched_entity_stats_put(struct drm_sched_entity_stats *stats)
{
kref_put(&stats->kref, drm_sched_entity_stats_release);
}
ktime_t drm_sched_entity_stats_job_add_gpu_time(struct drm_sched_job *job);
#endif