mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-05 05:28:03 +02:00
Remove an intel-specific hack and replace it with a fence driver callback.
This commit is contained in:
parent
04760563b8
commit
5c9a7b0f94
5 changed files with 80 additions and 51 deletions
|
|
@ -793,10 +793,11 @@ typedef struct drm_fence_driver{
|
|||
uint32_t flush_diff;
|
||||
uint32_t sequence_mask;
|
||||
int lazy_capable;
|
||||
int (*emit) (struct drm_device *dev, uint32_t flags,
|
||||
int (*has_irq) (struct drm_device *dev, uint32_t class, uint32_t flags);
|
||||
int (*emit) (struct drm_device *dev, uint32_t class, uint32_t flags,
|
||||
uint32_t *breadcrumb,
|
||||
uint32_t *native_type);
|
||||
void (*poke_flush) (struct drm_device *dev);
|
||||
void (*poke_flush) (struct drm_device *dev, uint32_t class);
|
||||
} drm_fence_driver_t;
|
||||
|
||||
#define _DRM_FENCE_TYPE_EXE 0x00
|
||||
|
|
@ -1464,7 +1465,8 @@ extern int drm_user_object_unref(drm_file_t *priv, uint32_t user_token, drm_obje
|
|||
* fence objects (drm_fence.c)
|
||||
*/
|
||||
|
||||
extern void drm_fence_handler(drm_device_t *dev, uint32_t breadcrumb, uint32_t type);
|
||||
extern void drm_fence_handler(drm_device_t *dev, uint32_t class,
|
||||
uint32_t sequence, uint32_t type);
|
||||
extern void drm_fence_manager_init(drm_device_t *dev);
|
||||
extern void drm_fence_manager_takedown(drm_device_t *dev);
|
||||
extern void drm_fence_flush_old(drm_device_t *dev, uint32_t sequence);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@
|
|||
* Typically called by the IRQ handler.
|
||||
*/
|
||||
|
||||
void drm_fence_handler(drm_device_t * dev, uint32_t sequence, uint32_t type)
|
||||
void drm_fence_handler(drm_device_t * dev, uint32_t class,
|
||||
uint32_t sequence, uint32_t type)
|
||||
{
|
||||
int wake = 0;
|
||||
uint32_t diff;
|
||||
|
|
@ -156,7 +157,7 @@ static int fence_signaled(drm_device_t * dev, volatile
|
|||
drm_fence_driver_t *driver = dev->driver->fence_driver;
|
||||
|
||||
if (poke_flush)
|
||||
driver->poke_flush(dev);
|
||||
driver->poke_flush(dev, fence->class);
|
||||
read_lock_irqsave(&fm->lock, flags);
|
||||
signaled =
|
||||
(fence->type & mask & fence->signaled) == (fence->type & mask);
|
||||
|
|
@ -177,7 +178,6 @@ static void drm_fence_flush_exe(drm_fence_manager_t * fm,
|
|||
* Last_exe_flush is invalid. Find oldest sequence.
|
||||
*/
|
||||
|
||||
/* list = fm->fence_types[_DRM_FENCE_TYPE_EXE];*/
|
||||
list = &fm->ring;
|
||||
if (list->next == &fm->ring) {
|
||||
return;
|
||||
|
|
@ -234,7 +234,7 @@ int drm_fence_object_flush(drm_device_t * dev,
|
|||
}
|
||||
}
|
||||
write_unlock_irqrestore(&fm->lock, flags);
|
||||
driver->poke_flush(dev);
|
||||
driver->poke_flush(dev, fence->class);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -273,11 +273,37 @@ void drm_fence_flush_old(drm_device_t * dev, uint32_t sequence)
|
|||
|
||||
EXPORT_SYMBOL(drm_fence_flush_old);
|
||||
|
||||
static int drm_fence_lazy_wait(drm_device_t *dev,
|
||||
volatile drm_fence_object_t *fence,
|
||||
int ignore_signals, uint32_t mask)
|
||||
{
|
||||
drm_fence_manager_t *fm = &dev->fm;
|
||||
unsigned long _end = jiffies + 3*DRM_HZ;
|
||||
int ret = 0;
|
||||
|
||||
do {
|
||||
DRM_WAIT_ON(ret, fm->fence_queue, 3 * DRM_HZ,
|
||||
fence_signaled(dev, fence, mask, 1));
|
||||
if (time_after_eq(jiffies, _end))
|
||||
break;
|
||||
} while (ret == -EINTR && ignore_signals);
|
||||
if (time_after_eq(jiffies, _end) && (ret != 0))
|
||||
ret = -EBUSY;
|
||||
if (ret) {
|
||||
if (ret == -EBUSY) {
|
||||
DRM_ERROR("Fence timeout. "
|
||||
"GPU lockup or fence driver was "
|
||||
"taken down.\n");
|
||||
}
|
||||
return ((ret == -EINTR) ? -EAGAIN : ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_fence_object_wait(drm_device_t * dev,
|
||||
volatile drm_fence_object_t * fence,
|
||||
int lazy, int ignore_signals, uint32_t mask)
|
||||
{
|
||||
drm_fence_manager_t *fm = &dev->fm;
|
||||
drm_fence_driver_t *driver = dev->driver->fence_driver;
|
||||
int ret = 0;
|
||||
unsigned long _end;
|
||||
|
|
@ -298,46 +324,32 @@ int drm_fence_object_wait(drm_device_t * dev,
|
|||
|
||||
if (lazy && driver->lazy_capable) {
|
||||
|
||||
do {
|
||||
DRM_WAIT_ON(ret, fm->fence_queue, 3 * DRM_HZ,
|
||||
fence_signaled(dev, fence, mask, 1));
|
||||
if (time_after_eq(jiffies, _end))
|
||||
break;
|
||||
} while (ret == -EINTR && ignore_signals);
|
||||
if (time_after_eq(jiffies, _end) && (ret != 0))
|
||||
ret = -EBUSY;
|
||||
if (ret) {
|
||||
if (ret == -EBUSY) {
|
||||
DRM_ERROR("Fence timeout. "
|
||||
"GPU lockup or fence driver was "
|
||||
"taken down.\n");
|
||||
}
|
||||
return ((ret == -EINTR) ? -EAGAIN : ret);
|
||||
}
|
||||
} else if ((fence->class == 0) && (mask & DRM_FENCE_TYPE_EXE) &&
|
||||
driver->lazy_capable) {
|
||||
|
||||
/*
|
||||
* We use IRQ wait for EXE fence if available to gain
|
||||
* CPU in some cases.
|
||||
*/
|
||||
|
||||
do {
|
||||
DRM_WAIT_ON(ret, fm->fence_queue, 3 * DRM_HZ,
|
||||
fence_signaled(dev, fence,
|
||||
DRM_FENCE_TYPE_EXE, 1));
|
||||
if (time_after_eq(jiffies, _end))
|
||||
break;
|
||||
} while (ret == -EINTR && ignore_signals);
|
||||
if (time_after_eq(jiffies, _end) && (ret != 0))
|
||||
ret = -EBUSY;
|
||||
ret = drm_fence_lazy_wait(dev, fence, ignore_signals, mask);
|
||||
if (ret)
|
||||
return ((ret == -EINTR) ? -EAGAIN : ret);
|
||||
}
|
||||
return ret;
|
||||
|
||||
} else {
|
||||
|
||||
if (driver->has_irq(dev, fence->class,
|
||||
DRM_FENCE_TYPE_EXE)) {
|
||||
ret = drm_fence_lazy_wait(dev, fence, ignore_signals,
|
||||
DRM_FENCE_TYPE_EXE);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (driver->has_irq(dev, fence->class,
|
||||
mask & ~DRM_FENCE_TYPE_EXE)) {
|
||||
ret = drm_fence_lazy_wait(dev, fence, ignore_signals,
|
||||
mask);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (fence_signaled(dev, fence, mask, 0))
|
||||
return 0;
|
||||
|
||||
DRM_ERROR("Busy wait\n");
|
||||
/*
|
||||
* Avoid kernel-space busy-waits.
|
||||
*/
|
||||
|
|
@ -367,7 +379,7 @@ int drm_fence_object_emit(drm_device_t * dev, drm_fence_object_t * fence,
|
|||
int ret;
|
||||
|
||||
drm_fence_unring(dev, &fence->ring);
|
||||
ret = driver->emit(dev, fence_flags, &sequence, &native_type);
|
||||
ret = driver->emit(dev, fence->class, fence_flags, &sequence, &native_type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ static drm_fence_driver_t i915_fence_driver = {
|
|||
.lazy_capable = 1,
|
||||
.emit = i915_fence_emit_sequence,
|
||||
.poke_flush = i915_poke_flush,
|
||||
.has_irq = i915_fence_has_irq,
|
||||
};
|
||||
#endif
|
||||
#ifdef I915_HAVE_BUFFER
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ static void i915_perform_flush(drm_device_t * dev)
|
|||
|
||||
diff = sequence - fm->last_exe_flush;
|
||||
if (diff < driver->wrap_diff && diff != 0) {
|
||||
drm_fence_handler(dev, sequence, DRM_FENCE_TYPE_EXE);
|
||||
drm_fence_handler(dev, 0, sequence, DRM_FENCE_TYPE_EXE);
|
||||
}
|
||||
|
||||
diff = sequence - fm->exe_flush_sequence;
|
||||
|
|
@ -84,7 +84,7 @@ static void i915_perform_flush(drm_device_t * dev)
|
|||
flush_flags = dev_priv->flush_flags;
|
||||
flush_sequence = dev_priv->flush_sequence;
|
||||
dev_priv->flush_pending = 0;
|
||||
drm_fence_handler(dev, flush_sequence, flush_flags);
|
||||
drm_fence_handler(dev, 0, flush_sequence, flush_flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -104,13 +104,13 @@ static void i915_perform_flush(drm_device_t * dev)
|
|||
flush_flags = dev_priv->flush_flags;
|
||||
flush_sequence = dev_priv->flush_sequence;
|
||||
dev_priv->flush_pending = 0;
|
||||
drm_fence_handler(dev, flush_sequence, flush_flags);
|
||||
drm_fence_handler(dev, 0, flush_sequence, flush_flags);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void i915_poke_flush(drm_device_t * dev)
|
||||
void i915_poke_flush(drm_device_t * dev, uint32_t class)
|
||||
{
|
||||
drm_fence_manager_t *fm = &dev->fm;
|
||||
unsigned long flags;
|
||||
|
|
@ -120,7 +120,7 @@ void i915_poke_flush(drm_device_t * dev)
|
|||
write_unlock_irqrestore(&fm->lock, flags);
|
||||
}
|
||||
|
||||
int i915_fence_emit_sequence(drm_device_t * dev, uint32_t flags,
|
||||
int i915_fence_emit_sequence(drm_device_t * dev, uint32_t class, uint32_t flags,
|
||||
uint32_t * sequence, uint32_t * native_type)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
|
|
@ -144,3 +144,15 @@ void i915_fence_handler(drm_device_t * dev)
|
|||
i915_perform_flush(dev);
|
||||
write_unlock(&fm->lock);
|
||||
}
|
||||
|
||||
int i915_fence_has_irq(drm_device_t *dev, uint32_t class, uint32_t flags)
|
||||
{
|
||||
/*
|
||||
* We have an irq that tells us when we have a new breadcrumb.
|
||||
*/
|
||||
|
||||
if (class == 0 && flags == DRM_FENCE_TYPE_EXE)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,10 +178,12 @@ extern void i915_mem_release(drm_device_t * dev,
|
|||
|
||||
|
||||
extern void i915_fence_handler(drm_device_t *dev);
|
||||
extern int i915_fence_emit_sequence(drm_device_t *dev, uint32_t flags,
|
||||
extern int i915_fence_emit_sequence(drm_device_t *dev, uint32_t class,
|
||||
uint32_t flags,
|
||||
uint32_t *sequence,
|
||||
uint32_t *native_type);
|
||||
extern void i915_poke_flush(drm_device_t *dev);
|
||||
extern void i915_poke_flush(drm_device_t *dev, uint32_t class);
|
||||
extern int i915_fence_has_irq(drm_device_t *dev, uint32_t class, uint32_t flags);
|
||||
#endif
|
||||
|
||||
#ifdef I915_HAVE_BUFFER
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue