drm/radeon/kms: add irq mitigation code for sw interrupt.
We really don't need to process every irq that comes in, we only really want to do SW irq processing when we are actually waiting for a fence to pass. I'm not 100% sure this is race free esp on non-MSI systems so it needs some testing. Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
d8f60cfc93
commit
1614f8b17b
|
@ -3129,7 +3129,6 @@ static int r100_startup(struct radeon_device *rdev)
|
|||
return r;
|
||||
}
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
r100_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
|
|
|
@ -1205,7 +1205,6 @@ static int r300_startup(struct radeon_device *rdev)
|
|||
return r;
|
||||
}
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
r100_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
|
|
|
@ -186,7 +186,6 @@ static int r420_startup(struct radeon_device *rdev)
|
|||
}
|
||||
r420_pipes_init(rdev);
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
r100_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
|
|
|
@ -185,7 +185,6 @@ static int r520_startup(struct radeon_device *rdev)
|
|||
return r;
|
||||
}
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
rs600_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
|
|
|
@ -1571,7 +1571,6 @@ int r600_startup(struct radeon_device *rdev)
|
|||
}
|
||||
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
r = r600_irq_init(rdev);
|
||||
if (r) {
|
||||
DRM_ERROR("radeon: IH init failed (%d).\n", r);
|
||||
|
|
|
@ -352,11 +352,14 @@ struct radeon_irq {
|
|||
bool sw_int;
|
||||
/* FIXME: use a define max crtc rather than hardcode it */
|
||||
bool crtc_vblank_int[2];
|
||||
spinlock_t sw_lock;
|
||||
int sw_refcount;
|
||||
};
|
||||
|
||||
int radeon_irq_kms_init(struct radeon_device *rdev);
|
||||
void radeon_irq_kms_fini(struct radeon_device *rdev);
|
||||
|
||||
void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev);
|
||||
void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev);
|
||||
|
||||
/*
|
||||
* CP & ring.
|
||||
|
|
|
@ -193,14 +193,18 @@ retry:
|
|||
}
|
||||
|
||||
if (intr) {
|
||||
radeon_irq_kms_sw_irq_get(rdev);
|
||||
r = wait_event_interruptible_timeout(rdev->fence_drv.queue,
|
||||
radeon_fence_signaled(fence), timeout);
|
||||
radeon_irq_kms_sw_irq_put(rdev);
|
||||
if (unlikely(r == -ERESTARTSYS)) {
|
||||
return -EBUSY;
|
||||
}
|
||||
} else {
|
||||
radeon_irq_kms_sw_irq_get(rdev);
|
||||
r = wait_event_timeout(rdev->fence_drv.queue,
|
||||
radeon_fence_signaled(fence), timeout);
|
||||
radeon_irq_kms_sw_irq_put(rdev);
|
||||
}
|
||||
if (unlikely(!radeon_fence_signaled(fence))) {
|
||||
if (unlikely(r == 0)) {
|
||||
|
|
|
@ -87,7 +87,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
|
|||
|
||||
if (rdev->flags & RADEON_SINGLE_CRTC)
|
||||
num_crtc = 1;
|
||||
|
||||
spin_lock_init(&rdev->irq.sw_lock);
|
||||
r = drm_vblank_init(rdev->ddev, num_crtc);
|
||||
if (r) {
|
||||
return r;
|
||||
|
@ -122,3 +122,29 @@ void radeon_irq_kms_fini(struct radeon_device *rdev)
|
|||
pci_disable_msi(rdev->pdev);
|
||||
}
|
||||
}
|
||||
|
||||
void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev)
|
||||
{
|
||||
unsigned long irqflags;
|
||||
|
||||
spin_lock_irqsave(&rdev->irq.sw_lock, irqflags);
|
||||
if (rdev->ddev->irq_enabled && (++rdev->irq.sw_refcount == 1)) {
|
||||
rdev->irq.sw_int = true;
|
||||
radeon_irq_set(rdev);
|
||||
}
|
||||
spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags);
|
||||
}
|
||||
|
||||
void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev)
|
||||
{
|
||||
unsigned long irqflags;
|
||||
|
||||
spin_lock_irqsave(&rdev->irq.sw_lock, irqflags);
|
||||
BUG_ON(rdev->ddev->irq_enabled && rdev->irq.sw_refcount <= 0);
|
||||
if (rdev->ddev->irq_enabled && (--rdev->irq.sw_refcount == 0)) {
|
||||
rdev->irq.sw_int = false;
|
||||
radeon_irq_set(rdev);
|
||||
}
|
||||
spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags);
|
||||
}
|
||||
|
||||
|
|
|
@ -394,7 +394,6 @@ static int rs400_startup(struct radeon_device *rdev)
|
|||
if (r)
|
||||
return r;
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
r100_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
|
|
|
@ -388,7 +388,6 @@ static int rs600_startup(struct radeon_device *rdev)
|
|||
if (r)
|
||||
return r;
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
rs600_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
|
|
|
@ -605,7 +605,6 @@ static int rs690_startup(struct radeon_device *rdev)
|
|||
if (r)
|
||||
return r;
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
rs600_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
|
|
|
@ -478,7 +478,6 @@ static int rv515_startup(struct radeon_device *rdev)
|
|||
return r;
|
||||
}
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
rs600_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
|
|
|
@ -888,7 +888,6 @@ static int rv770_startup(struct radeon_device *rdev)
|
|||
}
|
||||
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
r = r600_irq_init(rdev);
|
||||
if (r) {
|
||||
DRM_ERROR("radeon: IH init failed (%d).\n", r);
|
||||
|
|
Loading…
Reference in a new issue