Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpu: host1x: hw: intr_hw: Remove create_workqueue

System workqueues have been able to handle high level of concurrency
for a long time now and there's no reason to use dedicated workqueues
just to gain concurrency. Since the workqueue host->intr_wq is involved
in sync point interrupts, and sync point wait and is not being used on
a memory reclaim path, dedicated host->intr_wq has been replaced with the
use of system_wq.

Unlike a dedicated per-cpu workqueue created with create_workqueue(),
system_wq allows multiple work items to overlap executions even on
the same CPU; however, a per-cpu workqueue doesn't have any CPU
locality or global ordering guarantees unless the target CPU is
explicitly specified and thus the increase of local concurrency
shouldn't make any difference.

cancel_work_sync() has been used in _host1x_free_syncpt_irq() to ensure
that no work is pending by the time exit path runs.

Signed-off-by: Bhaktipriya Shridhar <bhaktipriya96@gmail.com>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Thierry Reding <treding@nvidia.com>

authored by

Bhaktipriya Shridhar and committed by
Thierry Reding
57574bd7 dfa7573e

+6 -7
-1
drivers/gpu/host1x/dev.h
··· 109 109 struct clk *clk; 110 110 111 111 struct mutex intr_mutex; 112 - struct workqueue_struct *intr_wq; 113 112 int intr_syncpt_irq; 114 113 115 114 const struct host1x_syncpt_ops *syncpt_op;
+6 -2
drivers/gpu/host1x/hw/intr_hw.c
··· 38 38 host1x_sync_writel(host, BIT_MASK(id), 39 39 HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(BIT_WORD(id))); 40 40 41 - queue_work(host->intr_wq, &syncpt->intr.work); 41 + schedule_work(&syncpt->intr.work); 42 42 } 43 43 44 44 static irqreturn_t syncpt_thresh_isr(int irq, void *dev_id) ··· 127 127 128 128 static int _host1x_free_syncpt_irq(struct host1x *host) 129 129 { 130 + int i; 131 + 130 132 devm_free_irq(host->dev, host->intr_syncpt_irq, host); 131 - flush_workqueue(host->intr_wq); 133 + 134 + for (i = 0; i < host->info->nb_pts; i++) 135 + cancel_work_sync(&host->syncpt[i].intr.work); 132 136 return 0; 133 137 } 134 138
-4
drivers/gpu/host1x/intr.c
··· 277 277 278 278 mutex_init(&host->intr_mutex); 279 279 host->intr_syncpt_irq = irq_sync; 280 - host->intr_wq = create_workqueue("host_syncpt"); 281 - if (!host->intr_wq) 282 - return -ENOMEM; 283 280 284 281 for (id = 0; id < nb_pts; ++id) { 285 282 struct host1x_syncpt *syncpt = host->syncpt + id; ··· 296 299 void host1x_intr_deinit(struct host1x *host) 297 300 { 298 301 host1x_intr_stop(host); 299 - destroy_workqueue(host->intr_wq); 300 302 } 301 303 302 304 void host1x_intr_start(struct host1x *host)