From: Dave Airlie <airl...@redhat.com>

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 <airl...@redhat.com>
---
 drivers/gpu/drm/radeon/r100.c           |    1 -
 drivers/gpu/drm/radeon/r300.c           |    1 -
 drivers/gpu/drm/radeon/r420.c           |    1 -
 drivers/gpu/drm/radeon/r520.c           |    1 -
 drivers/gpu/drm/radeon/radeon.h         |    5 ++++-
 drivers/gpu/drm/radeon/radeon_fence.c   |    4 ++++
 drivers/gpu/drm/radeon/radeon_irq_kms.c |   28 +++++++++++++++++++++++++++-
 drivers/gpu/drm/radeon/rs400.c          |    1 -
 drivers/gpu/drm/radeon/rs600.c          |    1 -
 drivers/gpu/drm/radeon/rs690.c          |    1 -
 drivers/gpu/drm/radeon/rv515.c          |    1 -
 11 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index b438b52..4f46d58 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -3100,7 +3100,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);
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 2f43ee8..0796df0 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -1199,7 +1199,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);
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 5c7fe52..268a44b 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -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);
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index a555b7b..44f36fb 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -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);
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index ea3efd7..080d47e 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -348,11 +348,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.
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 3beb26d..bfa6006 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -231,14 +231,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)) {
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c 
b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index a0fe623..94e1ad6 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -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;
@@ -114,3 +114,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);
+}
+
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index a769c29..d1c5611 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -393,7 +393,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);
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 942754c..369cdc7 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -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);
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index 025e322..07ca3e5 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -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);
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index 41a34c2..e139d55 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -477,7 +477,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);
-- 
1.6.5.1


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to