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@xxxxxxxxxxxxxxxxxx> Cc: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> --- 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 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx