[Intel-gfx] [PATCH 4/5] drm/i915: Convert display-port irq worker into a tasklet
Chris Wilson
chris at chris-wilson.co.uk
Thu May 19 07:48:33 UTC 2016
Using a tasklet for an irq bottom-half is the preferred form as it
should ensure minimal latency from the irq to execution of the tasklet.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
---
drivers/gpu/drm/i915/i915_dma.c | 9 +--------
drivers/gpu/drm/i915/i915_drv.h | 11 +----------
drivers/gpu/drm/i915/intel_hotplug.c | 17 +++++++++--------
3 files changed, 11 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index a8c79f6512a4..466d2cd4f656 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1022,19 +1022,13 @@ static int i915_workqueues_init(struct drm_i915_private *dev_priv)
if (dev_priv->wq == NULL)
goto out_err;
- dev_priv->hotplug.dp_wq = alloc_ordered_workqueue("i915-dp", 0);
- if (dev_priv->hotplug.dp_wq == NULL)
- goto out_free_wq;
-
dev_priv->gpu_error.hangcheck_wq =
alloc_ordered_workqueue("i915-hangcheck", 0);
if (dev_priv->gpu_error.hangcheck_wq == NULL)
- goto out_free_dp_wq;
+ goto out_free_wq;
return 0;
-out_free_dp_wq:
- destroy_workqueue(dev_priv->hotplug.dp_wq);
out_free_wq:
destroy_workqueue(dev_priv->wq);
out_err:
@@ -1046,7 +1040,6 @@ out_err:
static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv)
{
destroy_workqueue(dev_priv->gpu_error.hangcheck_wq);
- destroy_workqueue(dev_priv->hotplug.dp_wq);
destroy_workqueue(dev_priv->wq);
}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ce7f30cecb1f..fdb19e2610eb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -279,16 +279,7 @@ struct i915_hotplug {
struct intel_digital_port *irq_port[I915_MAX_PORTS];
u32 long_port_mask;
u32 short_port_mask;
- struct work_struct dig_port_work;
-
- /*
- * if we get a HPD irq from DP and a HPD irq from non-DP
- * the non-DP HPD could block the workqueue on a mode config
- * mutex getting, that userspace may have taken. However
- * userspace is waiting on the DP workqueue to run which is
- * blocked behind the non-DP one.
- */
- struct workqueue_struct *dp_wq;
+ struct tasklet_struct dig_port_task;
};
#define I915_GEM_GPU_DOMAINS \
diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
index 38eeca7a6e72..3c74c2b944cf 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -48,7 +48,7 @@
* further processing to appropriate bottom halves (Display Port specific and
* regular hotplug).
*
- * The Display Port work function i915_digport_work_func() calls into
+ * The Display Port work function i915_digport_task() calls into
* intel_dp_hpd_pulse() via hooks, which handles DP short pulses and DP MST long
* pulses, with failures and non-MST long pulses triggering regular hotplug
* processing on the connector.
@@ -69,7 +69,7 @@
*
* Current implementation expects that hotplug interrupt storm will not be
* seen when display port sink is connected, hence on platforms whose DP
- * callback is handled by i915_digport_work_func reenabling of hpd is not
+ * callback is handled by i915_digport_task reenabling of hpd is not
* performed (it was never expected to be disabled in the first place ;) )
* this is specific to DP sinks handled by this routine and any other display
* such as HDMI or DVI enabled on the same port will have proper logic since
@@ -247,10 +247,9 @@ static bool intel_hpd_irq_event(struct drm_device *dev,
return true;
}
-static void i915_digport_work_func(struct work_struct *work)
+static void i915_digport_task(unsigned long data)
{
- struct drm_i915_private *dev_priv =
- container_of(work, struct drm_i915_private, hotplug.dig_port_work);
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *)data;
u32 long_port_mask, short_port_mask;
struct intel_digital_port *intel_dig_port;
int i;
@@ -436,7 +435,7 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
* deadlock.
*/
if (queue_dig)
- queue_work(dev_priv->hotplug.dp_wq, &dev_priv->hotplug.dig_port_work);
+ tasklet_schedule(&dev_priv->hotplug.dig_port_task);
if (queue_hp)
schedule_work(&dev_priv->hotplug.hotplug_work);
}
@@ -491,7 +490,9 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
void intel_hpd_init_work(struct drm_i915_private *dev_priv)
{
INIT_WORK(&dev_priv->hotplug.hotplug_work, i915_hotplug_work_func);
- INIT_WORK(&dev_priv->hotplug.dig_port_work, i915_digport_work_func);
+ tasklet_init(&dev_priv->hotplug.dig_port_task,
+ i915_digport_task,
+ (unsigned long)dev_priv);
INIT_DELAYED_WORK(&dev_priv->hotplug.reenable_work,
intel_hpd_irq_storm_reenable_work);
}
@@ -506,7 +507,7 @@ void intel_hpd_cancel_work(struct drm_i915_private *dev_priv)
spin_unlock_irq(&dev_priv->irq_lock);
- cancel_work_sync(&dev_priv->hotplug.dig_port_work);
+ tasklet_kill(&dev_priv->hotplug.dig_port_task);
cancel_work_sync(&dev_priv->hotplug.hotplug_work);
cancel_delayed_work_sync(&dev_priv->hotplug.reenable_work);
}
--
2.8.1
More information about the Intel-gfx
mailing list