linux-stable/drivers/gpu/drm/i915/i915_scheduler.h
Chris Wilson 253a774bb0 drm/i915/execlists: Don't merely skip submission if maybe timeslicing
Normally, we try and skip submission if ELSP[1] is filled. However, we
may desire to enable timeslicing due to the queue priority, even if
ELSP[1] itself does not require timeslicing. That is the queue is equal
priority to ELSP[0] and higher priority then ELSP[1]. Previously, we
would wait until the context switch to preempt the current ELSP[1], but
with timeslicing, we want to preempt ELSP[0] and replace it with the
queue.

In writing the test case, it become quickly apparent that we were also
suppressing the tasklet during promotion and so failing to notice when
the queue started requiring timeslicing.

Fixes: 2229adc813 ("drm/i915/execlist: Trim immediate timeslice expiry")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191018072027.31948-1-chris@chris-wilson.co.uk
2019-10-18 11:23:26 +01:00

55 lines
1.5 KiB
C

/*
* SPDX-License-Identifier: MIT
*
* Copyright © 2018 Intel Corporation
*/
#ifndef _I915_SCHEDULER_H_
#define _I915_SCHEDULER_H_
#include <linux/bitops.h>
#include <linux/list.h>
#include <linux/kernel.h>
#include "i915_scheduler_types.h"
#define priolist_for_each_request(it, plist, idx) \
for (idx = 0; idx < ARRAY_SIZE((plist)->requests); idx++) \
list_for_each_entry(it, &(plist)->requests[idx], sched.link)
#define priolist_for_each_request_consume(it, n, plist, idx) \
for (; \
(plist)->used ? (idx = __ffs((plist)->used)), 1 : 0; \
(plist)->used &= ~BIT(idx)) \
list_for_each_entry_safe(it, n, \
&(plist)->requests[idx], \
sched.link)
void i915_sched_node_init(struct i915_sched_node *node);
bool __i915_sched_node_add_dependency(struct i915_sched_node *node,
struct i915_sched_node *signal,
struct i915_dependency *dep,
unsigned long flags);
int i915_sched_node_add_dependency(struct i915_sched_node *node,
struct i915_sched_node *signal);
void i915_sched_node_fini(struct i915_sched_node *node);
void i915_schedule(struct i915_request *request,
const struct i915_sched_attr *attr);
void i915_schedule_bump_priority(struct i915_request *rq, unsigned int bump);
struct list_head *
i915_sched_lookup_priolist(struct intel_engine_cs *engine, int prio);
void __i915_priolist_free(struct i915_priolist *p);
static inline void i915_priolist_free(struct i915_priolist *p)
{
if (p->priority != I915_PRIORITY_NORMAL)
__i915_priolist_free(p);
}
#endif /* _I915_SCHEDULER_H_ */