diff --git a/sys/dev/drm/include/drm/ttm/ttm_bo_driver.h b/sys/dev/drm/include/drm/ttm/ttm_bo_driver.h index ca05c2a..596cef6 100644 --- a/sys/dev/drm/include/drm/ttm/ttm_bo_driver.h +++ b/sys/dev/drm/include/drm/ttm/ttm_bo_driver.h @@ -37,6 +37,7 @@ #include #include #include +#include struct ttm_backend_func { /** @@ -561,6 +562,7 @@ struct ttm_bo_device { * Internal protection. */ + struct mtx wq_mtx; struct timeout_task wq; bool need_dma32; diff --git a/sys/dev/drm/ttm/ttm_bo.c b/sys/dev/drm/ttm/ttm_bo.c index c743361..2c4939b 100644 --- a/sys/dev/drm/ttm/ttm_bo.c +++ b/sys/dev/drm/ttm/ttm_bo.c @@ -592,8 +592,10 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) driver->sync_obj_flush(sync_obj); driver->sync_obj_unref(&sync_obj); } + mtx_lock(&bdev->wq_mtx); taskqueue_enqueue_timeout(taskqueue_thread[0], &bdev->wq, ((hz / 100) < 1) ? 1 : hz / 100); + mtx_unlock(&bdev->wq_mtx); } /** @@ -753,8 +755,10 @@ static void ttm_bo_delayed_workqueue(void *arg, int pending __unused) struct ttm_bo_device *bdev = arg; if (ttm_bo_delayed_delete(bdev, false)) { + mtx_lock(&bdev->wq_mtx); taskqueue_enqueue_timeout(taskqueue_thread[0], &bdev->wq, ((hz / 100) < 1) ? 1 : hz / 100); + mtx_unlock(&bdev->wq_mtx); } } @@ -819,8 +823,9 @@ int ttm_bo_lock_delayed_workqueue(struct ttm_bo_device *bdev) int pending; taskqueue_cancel_timeout(taskqueue_thread[0], &bdev->wq, &pending); - if (pending) + if (pending) { taskqueue_drain_timeout(taskqueue_thread[0], &bdev->wq); + } return (pending); } EXPORT_SYMBOL(ttm_bo_lock_delayed_workqueue); @@ -828,8 +833,10 @@ EXPORT_SYMBOL(ttm_bo_lock_delayed_workqueue); void ttm_bo_unlock_delayed_workqueue(struct ttm_bo_device *bdev, int resched) { if (resched) { + mtx_lock(&bdev->wq_mtx); taskqueue_enqueue_timeout(taskqueue_thread[0], &bdev->wq, ((hz / 100) < 1) ? 1 : hz / 100); + mtx_unlock(&bdev->wq_mtx); } } EXPORT_SYMBOL(ttm_bo_unlock_delayed_workqueue); @@ -1608,8 +1615,9 @@ int ttm_bo_device_release(struct ttm_bo_device *bdev) list_del(&bdev->device_list); lockmgr(&glob->device_list_mutex, LK_RELEASE); - if (taskqueue_cancel_timeout(taskqueue_thread[0], &bdev->wq, NULL)) + if (taskqueue_cancel_timeout(taskqueue_thread[0], &bdev->wq, NULL)) { taskqueue_drain_timeout(taskqueue_thread[0], &bdev->wq); + } while (ttm_bo_delayed_delete(bdev, true)) ; @@ -1657,6 +1665,7 @@ int ttm_bo_device_init(struct ttm_bo_device *bdev, if (unlikely(ret != 0)) goto out_no_addr_mm; + mtx_init(&bdev->wq_mtx); TIMEOUT_TASK_INIT(taskqueue_thread[0], &bdev->wq, 0, ttm_bo_delayed_workqueue, bdev); INIT_LIST_HEAD(&bdev->ddestroy);