Skip to content

Commit

Permalink
drm/radeon/kms: add irq mitigation code for sw interrupt.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dave Airlie committed Dec 2, 2009
1 parent d8f60cf commit 1614f8b
Show file tree
Hide file tree
Showing 13 changed files with 35 additions and 12 deletions.
1 change: 0 additions & 1 deletion drivers/gpu/drm/radeon/r100.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/radeon/r300.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/radeon/r420.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/radeon/r520.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/radeon/r600.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 4 additions & 1 deletion drivers/gpu/drm/radeon/radeon.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/radeon/radeon_fence.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,14 +193,18 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr)
}

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)) {
Expand Down
28 changes: 27 additions & 1 deletion drivers/gpu/drm/radeon/radeon_irq_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

1 change: 0 additions & 1 deletion drivers/gpu/drm/radeon/rs400.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/radeon/rs600.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/radeon/rs690.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/radeon/rv515.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/radeon/rv770.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 1614f8b

Please sign in to comment.