drm/amdkfd: use a high priority workqueue for IH work
authorAndres Rodriguez <andres.rodriguez@amd.com>
Fri, 27 Oct 2017 23:35:34 +0000 (19:35 -0400)
committerOded Gabbay <oded.gabbay@gmail.com>
Fri, 27 Oct 2017 23:35:34 +0000 (19:35 -0400)
In systems under heavy load the IH work may experience significant
scheduling delays.

Under load + system workqueue:
    Max Latency: 7.023695 ms
    Avg Latency: 0.263994 ms

Under load + high priority workqueue:
    Max Latency: 1.162568 ms
    Avg Latency: 0.163213 ms

Further work is required to measure the impact of per-cpu settings on IH
performance.

Signed-off-by: Andres Rodriguez <andres.rodriguez@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Acked-by: Oded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
drivers/gpu/drm/amd/amdkfd/kfd_device.c
drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
drivers/gpu/drm/amd/amdkfd/kfd_priv.h

index 46049f005b02ec8b78cb13833b7bcd2161e172d0..621a3b53a0384e1ff3aa367eeb242aef21b6dbf2 100644 (file)
@@ -403,7 +403,7 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry)
        if (kfd->interrupts_active
            && interrupt_is_wanted(kfd, ih_ring_entry)
            && enqueue_ih_ring_entry(kfd, ih_ring_entry))
-               schedule_work(&kfd->interrupt_work);
+               queue_work(kfd->ih_wq, &kfd->interrupt_work);
 
        spin_unlock(&kfd->interrupt_lock);
 }
index 9c08d4670b7f716fd9657dcdb41864e741549347..035c351f47c5ac0c49018ef49d23f36f6ea8e887 100644 (file)
@@ -61,6 +61,7 @@ int kfd_interrupt_init(struct kfd_dev *kfd)
                return r;
        }
 
+       kfd->ih_wq = alloc_workqueue("KFD IH", WQ_HIGHPRI, 1);
        spin_lock_init(&kfd->interrupt_lock);
 
        INIT_WORK(&kfd->interrupt_work, interrupt_wq);
@@ -95,7 +96,7 @@ void kfd_interrupt_exit(struct kfd_dev *kfd)
         * work-queue items that will access interrupt_ring. New work items
         * can't be created because we stopped interrupt handling above.
         */
-       flush_work(&kfd->interrupt_work);
+       flush_workqueue(kfd->ih_wq);
 
        kfifo_free(&kfd->ih_fifo);
 }
index 0aec5ca8a9649ec18d57f349dc7f569ccc2a25dc..6a91a60c64cf1754344cf48682f01e4f62605c89 100644 (file)
@@ -184,6 +184,7 @@ struct kfd_dev {
 
        /* Interrupts */
        struct kfifo ih_fifo;
+       struct workqueue_struct *ih_wq;
        struct work_struct interrupt_work;
        spinlock_t interrupt_lock;