Skip to content

Commit 77a0110

Browse files
mbrost05lucasdemarchi
authored andcommitted
drm/xe: Use ordered wq for preempt fence waiting
Preempt fences can sleep waiting for an exec queue suspend operation to complete. If the system_unbound_wq is used for waiting and the number of waiters exceeds max_active this will result in other users of the system_unbound_wq getting starved. Use a device private work queue for preempt fences to avoid starvation of the system_unbound_wq. Even though suspend operations can complete out-of-order, all suspend operations within a VM need to complete before the preempt rebind worker can start. With that, use a device private ordered wq for preempt fence waiting. v2: - Add comment about cleanup on failure (Matt R) - Update commit message (Lucas) Fixes: dd08ebf ("drm/xe: Introduce a new DRM driver for Intel GPUs") Signed-off-by: Matthew Brost <[email protected]> Reviewed-by: Lucas De Marchi <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Signed-off-by: Lucas De Marchi <[email protected]> (cherry picked from commit 37c15c4) Signed-off-by: Lucas De Marchi <[email protected]>
1 parent 3edd52b commit 77a0110

File tree

3 files changed

+14
-2
lines changed

3 files changed

+14
-2
lines changed

drivers/gpu/drm/xe/xe_device.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ static void xe_device_destroy(struct drm_device *dev, void *dummy)
193193
{
194194
struct xe_device *xe = to_xe_device(dev);
195195

196+
if (xe->preempt_fence_wq)
197+
destroy_workqueue(xe->preempt_fence_wq);
198+
196199
if (xe->ordered_wq)
197200
destroy_workqueue(xe->ordered_wq);
198201

@@ -258,9 +261,15 @@ struct xe_device *xe_device_create(struct pci_dev *pdev,
258261
INIT_LIST_HEAD(&xe->pinned.external_vram);
259262
INIT_LIST_HEAD(&xe->pinned.evicted);
260263

264+
xe->preempt_fence_wq = alloc_ordered_workqueue("xe-preempt-fence-wq", 0);
261265
xe->ordered_wq = alloc_ordered_workqueue("xe-ordered-wq", 0);
262266
xe->unordered_wq = alloc_workqueue("xe-unordered-wq", 0, 0);
263-
if (!xe->ordered_wq || !xe->unordered_wq) {
267+
if (!xe->ordered_wq || !xe->unordered_wq ||
268+
!xe->preempt_fence_wq) {
269+
/*
270+
* Cleanup done in xe_device_destroy via
271+
* drmm_add_action_or_reset register above
272+
*/
264273
drm_err(&xe->drm, "Failed to allocate xe workqueues\n");
265274
err = -ENOMEM;
266275
goto err;

drivers/gpu/drm/xe/xe_device_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,9 @@ struct xe_device {
363363
/** @ufence_wq: user fence wait queue */
364364
wait_queue_head_t ufence_wq;
365365

366+
/** @preempt_fence_wq: used to serialize preempt fences */
367+
struct workqueue_struct *preempt_fence_wq;
368+
366369
/** @ordered_wq: used to serialize compute mode resume */
367370
struct workqueue_struct *ordered_wq;
368371

drivers/gpu/drm/xe/xe_preempt_fence.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ static bool preempt_fence_enable_signaling(struct dma_fence *fence)
4949
struct xe_exec_queue *q = pfence->q;
5050

5151
pfence->error = q->ops->suspend(q);
52-
queue_work(system_unbound_wq, &pfence->preempt_work);
52+
queue_work(q->vm->xe->preempt_fence_wq, &pfence->preempt_work);
5353
return true;
5454
}
5555

0 commit comments

Comments
 (0)