diff options
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 145 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 18 |
5 files changed, 89 insertions, 104 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 0cd776a55f05..53d70f766afe 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -1033,10 +1033,9 @@ struct amdgpu_ctx_mgr { | |||
1033 | struct idr ctx_handles; | 1033 | struct idr ctx_handles; |
1034 | }; | 1034 | }; |
1035 | 1035 | ||
1036 | int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, | 1036 | int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel, |
1037 | uint32_t *id); | 1037 | struct amdgpu_ctx *ctx); |
1038 | int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, | 1038 | void amdgpu_ctx_fini(struct amdgpu_ctx *ctx); |
1039 | uint32_t id); | ||
1040 | 1039 | ||
1041 | struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id); | 1040 | struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id); |
1042 | int amdgpu_ctx_put(struct amdgpu_ctx *ctx); | 1041 | int amdgpu_ctx_put(struct amdgpu_ctx *ctx); |
@@ -2095,7 +2094,7 @@ struct amdgpu_device { | |||
2095 | struct kfd_dev *kfd; | 2094 | struct kfd_dev *kfd; |
2096 | 2095 | ||
2097 | /* kernel conext for IB submission */ | 2096 | /* kernel conext for IB submission */ |
2098 | struct amdgpu_ctx *kernel_ctx; | 2097 | struct amdgpu_ctx kernel_ctx; |
2099 | }; | 2098 | }; |
2100 | 2099 | ||
2101 | bool amdgpu_device_is_px(struct drm_device *dev); | 2100 | bool amdgpu_device_is_px(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index c2290ae20312..08a9292729dc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | |||
@@ -25,82 +25,27 @@ | |||
25 | #include <drm/drmP.h> | 25 | #include <drm/drmP.h> |
26 | #include "amdgpu.h" | 26 | #include "amdgpu.h" |
27 | 27 | ||
28 | static void amdgpu_ctx_do_release(struct kref *ref) | 28 | int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel, |
29 | struct amdgpu_ctx *ctx) | ||
29 | { | 30 | { |
30 | struct amdgpu_ctx *ctx; | ||
31 | struct amdgpu_device *adev; | ||
32 | unsigned i, j; | 31 | unsigned i, j; |
32 | int r; | ||
33 | 33 | ||
34 | ctx = container_of(ref, struct amdgpu_ctx, refcount); | ||
35 | adev = ctx->adev; | ||
36 | |||
37 | |||
38 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) | ||
39 | for (j = 0; j < AMDGPU_CTX_MAX_CS_PENDING; ++j) | ||
40 | fence_put(ctx->rings[i].fences[j]); | ||
41 | |||
42 | if (amdgpu_enable_scheduler) { | ||
43 | for (i = 0; i < adev->num_rings; i++) | ||
44 | amd_context_entity_fini(adev->rings[i]->scheduler, | ||
45 | &ctx->rings[i].c_entity); | ||
46 | } | ||
47 | |||
48 | kfree(ctx); | ||
49 | } | ||
50 | |||
51 | static void amdgpu_ctx_init(struct amdgpu_device *adev, | ||
52 | struct amdgpu_fpriv *fpriv, | ||
53 | struct amdgpu_ctx *ctx) | ||
54 | { | ||
55 | int i; | ||
56 | memset(ctx, 0, sizeof(*ctx)); | 34 | memset(ctx, 0, sizeof(*ctx)); |
57 | ctx->adev = adev; | 35 | ctx->adev = adev; |
58 | kref_init(&ctx->refcount); | 36 | kref_init(&ctx->refcount); |
59 | spin_lock_init(&ctx->ring_lock); | 37 | spin_lock_init(&ctx->ring_lock); |
60 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) | 38 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) |
61 | ctx->rings[i].sequence = 1; | 39 | ctx->rings[i].sequence = 1; |
62 | } | ||
63 | |||
64 | int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, | ||
65 | uint32_t *id) | ||
66 | { | ||
67 | struct amdgpu_ctx *ctx; | ||
68 | int i, j, r; | ||
69 | |||
70 | ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); | ||
71 | if (!ctx) | ||
72 | return -ENOMEM; | ||
73 | if (fpriv) { | ||
74 | struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; | ||
75 | mutex_lock(&mgr->lock); | ||
76 | r = idr_alloc(&mgr->ctx_handles, ctx, 1, 0, GFP_KERNEL); | ||
77 | if (r < 0) { | ||
78 | mutex_unlock(&mgr->lock); | ||
79 | kfree(ctx); | ||
80 | return r; | ||
81 | } | ||
82 | *id = (uint32_t)r; | ||
83 | amdgpu_ctx_init(adev, fpriv, ctx); | ||
84 | mutex_unlock(&mgr->lock); | ||
85 | } else { | ||
86 | if (adev->kernel_ctx) { | ||
87 | DRM_ERROR("kernel cnotext has been created.\n"); | ||
88 | kfree(ctx); | ||
89 | return 0; | ||
90 | } | ||
91 | amdgpu_ctx_init(adev, fpriv, ctx); | ||
92 | |||
93 | adev->kernel_ctx = ctx; | ||
94 | } | ||
95 | 40 | ||
96 | if (amdgpu_enable_scheduler) { | 41 | if (amdgpu_enable_scheduler) { |
97 | /* create context entity for each ring */ | 42 | /* create context entity for each ring */ |
98 | for (i = 0; i < adev->num_rings; i++) { | 43 | for (i = 0; i < adev->num_rings; i++) { |
99 | struct amd_run_queue *rq; | 44 | struct amd_run_queue *rq; |
100 | if (fpriv) | 45 | if (kernel) |
101 | rq = &adev->rings[i]->scheduler->sched_rq; | ||
102 | else | ||
103 | rq = &adev->rings[i]->scheduler->kernel_rq; | 46 | rq = &adev->rings[i]->scheduler->kernel_rq; |
47 | else | ||
48 | rq = &adev->rings[i]->scheduler->sched_rq; | ||
104 | r = amd_context_entity_init(adev->rings[i]->scheduler, | 49 | r = amd_context_entity_init(adev->rings[i]->scheduler, |
105 | &ctx->rings[i].c_entity, | 50 | &ctx->rings[i].c_entity, |
106 | NULL, rq, amdgpu_sched_jobs); | 51 | NULL, rq, amdgpu_sched_jobs); |
@@ -113,33 +58,79 @@ int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, | |||
113 | amd_context_entity_fini(adev->rings[j]->scheduler, | 58 | amd_context_entity_fini(adev->rings[j]->scheduler, |
114 | &ctx->rings[j].c_entity); | 59 | &ctx->rings[j].c_entity); |
115 | kfree(ctx); | 60 | kfree(ctx); |
116 | return -EINVAL; | 61 | return r; |
117 | } | 62 | } |
118 | } | 63 | } |
119 | |||
120 | return 0; | 64 | return 0; |
121 | } | 65 | } |
122 | 66 | ||
123 | int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, uint32_t id) | 67 | void amdgpu_ctx_fini(struct amdgpu_ctx *ctx) |
124 | { | 68 | { |
69 | struct amdgpu_device *adev = ctx->adev; | ||
70 | unsigned i, j; | ||
71 | |||
72 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) | ||
73 | for (j = 0; j < AMDGPU_CTX_MAX_CS_PENDING; ++j) | ||
74 | fence_put(ctx->rings[i].fences[j]); | ||
75 | |||
76 | if (amdgpu_enable_scheduler) { | ||
77 | for (i = 0; i < adev->num_rings; i++) | ||
78 | amd_context_entity_fini(adev->rings[i]->scheduler, | ||
79 | &ctx->rings[i].c_entity); | ||
80 | } | ||
81 | } | ||
82 | |||
83 | static int amdgpu_ctx_alloc(struct amdgpu_device *adev, | ||
84 | struct amdgpu_fpriv *fpriv, | ||
85 | uint32_t *id) | ||
86 | { | ||
87 | struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; | ||
125 | struct amdgpu_ctx *ctx; | 88 | struct amdgpu_ctx *ctx; |
89 | int r; | ||
126 | 90 | ||
127 | if (fpriv) { | 91 | ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); |
128 | struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; | 92 | if (!ctx) |
129 | mutex_lock(&mgr->lock); | 93 | return -ENOMEM; |
130 | ctx = idr_find(&mgr->ctx_handles, id); | 94 | |
131 | if (ctx) { | 95 | mutex_lock(&mgr->lock); |
132 | idr_remove(&mgr->ctx_handles, id); | 96 | r = idr_alloc(&mgr->ctx_handles, ctx, 1, 0, GFP_KERNEL); |
133 | kref_put(&ctx->refcount, amdgpu_ctx_do_release); | 97 | if (r < 0) { |
134 | mutex_unlock(&mgr->lock); | ||
135 | return 0; | ||
136 | } | ||
137 | mutex_unlock(&mgr->lock); | 98 | mutex_unlock(&mgr->lock); |
138 | } else { | 99 | kfree(ctx); |
139 | ctx = adev->kernel_ctx; | 100 | return r; |
101 | } | ||
102 | *id = (uint32_t)r; | ||
103 | r = amdgpu_ctx_init(adev, false, ctx); | ||
104 | mutex_unlock(&mgr->lock); | ||
105 | |||
106 | return r; | ||
107 | } | ||
108 | |||
109 | static void amdgpu_ctx_do_release(struct kref *ref) | ||
110 | { | ||
111 | struct amdgpu_ctx *ctx; | ||
112 | |||
113 | ctx = container_of(ref, struct amdgpu_ctx, refcount); | ||
114 | |||
115 | amdgpu_ctx_fini(ctx); | ||
116 | |||
117 | kfree(ctx); | ||
118 | } | ||
119 | |||
120 | static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id) | ||
121 | { | ||
122 | struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; | ||
123 | struct amdgpu_ctx *ctx; | ||
124 | |||
125 | mutex_lock(&mgr->lock); | ||
126 | ctx = idr_find(&mgr->ctx_handles, id); | ||
127 | if (ctx) { | ||
128 | idr_remove(&mgr->ctx_handles, id); | ||
140 | kref_put(&ctx->refcount, amdgpu_ctx_do_release); | 129 | kref_put(&ctx->refcount, amdgpu_ctx_do_release); |
130 | mutex_unlock(&mgr->lock); | ||
141 | return 0; | 131 | return 0; |
142 | } | 132 | } |
133 | mutex_unlock(&mgr->lock); | ||
143 | return -EINVAL; | 134 | return -EINVAL; |
144 | } | 135 | } |
145 | 136 | ||
@@ -198,7 +189,7 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, | |||
198 | args->out.alloc.ctx_id = id; | 189 | args->out.alloc.ctx_id = id; |
199 | break; | 190 | break; |
200 | case AMDGPU_CTX_OP_FREE_CTX: | 191 | case AMDGPU_CTX_OP_FREE_CTX: |
201 | r = amdgpu_ctx_free(adev, fpriv, id); | 192 | r = amdgpu_ctx_free(fpriv, id); |
202 | break; | 193 | break; |
203 | case AMDGPU_CTX_OP_QUERY_STATE: | 194 | case AMDGPU_CTX_OP_QUERY_STATE: |
204 | r = amdgpu_ctx_query(adev, fpriv, id, &args->out); | 195 | r = amdgpu_ctx_query(adev, fpriv, id, &args->out); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 801ebfc44034..42d1a22c1199 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -1525,13 +1525,10 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1525 | return r; | 1525 | return r; |
1526 | } | 1526 | } |
1527 | 1527 | ||
1528 | if (!adev->kernel_ctx) { | 1528 | r = amdgpu_ctx_init(adev, true, &adev->kernel_ctx); |
1529 | uint32_t id = 0; | 1529 | if (r) { |
1530 | r = amdgpu_ctx_alloc(adev, NULL, &id); | 1530 | dev_err(adev->dev, "failed to create kernel context (%d).\n", r); |
1531 | if (r) { | 1531 | return r; |
1532 | dev_err(adev->dev, "failed to create kernel context (%d).\n", r); | ||
1533 | return r; | ||
1534 | } | ||
1535 | } | 1532 | } |
1536 | r = amdgpu_ib_ring_tests(adev); | 1533 | r = amdgpu_ib_ring_tests(adev); |
1537 | if (r) | 1534 | if (r) |
@@ -1594,7 +1591,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev) | |||
1594 | adev->shutdown = true; | 1591 | adev->shutdown = true; |
1595 | /* evict vram memory */ | 1592 | /* evict vram memory */ |
1596 | amdgpu_bo_evict_vram(adev); | 1593 | amdgpu_bo_evict_vram(adev); |
1597 | amdgpu_ctx_free(adev, NULL, 0); | 1594 | amdgpu_ctx_fini(&adev->kernel_ctx); |
1598 | amdgpu_ib_pool_fini(adev); | 1595 | amdgpu_ib_pool_fini(adev); |
1599 | amdgpu_fence_driver_fini(adev); | 1596 | amdgpu_fence_driver_fini(adev); |
1600 | amdgpu_fbdev_fini(adev); | 1597 | amdgpu_fbdev_fini(adev); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index 9f2f19cc4625..995901b9e428 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | |||
@@ -122,19 +122,17 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, | |||
122 | int r = 0; | 122 | int r = 0; |
123 | if (amdgpu_enable_scheduler) { | 123 | if (amdgpu_enable_scheduler) { |
124 | struct amdgpu_cs_parser *sched_job = | 124 | struct amdgpu_cs_parser *sched_job = |
125 | amdgpu_cs_parser_create(adev, | 125 | amdgpu_cs_parser_create(adev, owner, &adev->kernel_ctx, |
126 | owner, | ||
127 | adev->kernel_ctx, | ||
128 | ibs, 1); | 126 | ibs, 1); |
129 | if(!sched_job) { | 127 | if(!sched_job) { |
130 | return -ENOMEM; | 128 | return -ENOMEM; |
131 | } | 129 | } |
132 | sched_job->free_job = free_job; | 130 | sched_job->free_job = free_job; |
133 | ibs[num_ibs - 1].sequence = amd_sched_push_job(ring->scheduler, | 131 | ibs[num_ibs - 1].sequence = amd_sched_push_job(ring->scheduler, |
134 | &adev->kernel_ctx->rings[ring->idx].c_entity, | 132 | &adev->kernel_ctx.rings[ring->idx].c_entity, |
135 | sched_job); | 133 | sched_job); |
136 | r = amd_sched_wait_emit( | 134 | r = amd_sched_wait_emit( |
137 | &adev->kernel_ctx->rings[ring->idx].c_entity, | 135 | &adev->kernel_ctx.rings[ring->idx].c_entity, |
138 | ibs[num_ibs - 1].sequence, false, -1); | 136 | ibs[num_ibs - 1].sequence, false, -1); |
139 | if (r) | 137 | if (r) |
140 | WARN(true, "emit timeout\n"); | 138 | WARN(true, "emit timeout\n"); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index ab9c65a245ba..78713ae3b158 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -372,16 +372,16 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, | |||
372 | if (amdgpu_enable_scheduler) { | 372 | if (amdgpu_enable_scheduler) { |
373 | int r; | 373 | int r; |
374 | sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM, | 374 | sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM, |
375 | adev->kernel_ctx, ib, 1); | 375 | &adev->kernel_ctx, ib, 1); |
376 | if(!sched_job) | 376 | if(!sched_job) |
377 | goto error_free; | 377 | goto error_free; |
378 | sched_job->job_param.vm.bo = bo; | 378 | sched_job->job_param.vm.bo = bo; |
379 | sched_job->run_job = amdgpu_vm_run_job; | 379 | sched_job->run_job = amdgpu_vm_run_job; |
380 | sched_job->free_job = amdgpu_vm_free_job; | 380 | sched_job->free_job = amdgpu_vm_free_job; |
381 | ib->sequence = amd_sched_push_job(ring->scheduler, | 381 | ib->sequence = amd_sched_push_job(ring->scheduler, |
382 | &adev->kernel_ctx->rings[ring->idx].c_entity, | 382 | &adev->kernel_ctx.rings[ring->idx].c_entity, |
383 | sched_job); | 383 | sched_job); |
384 | r = amd_sched_wait_emit(&adev->kernel_ctx->rings[ring->idx].c_entity, | 384 | r = amd_sched_wait_emit(&adev->kernel_ctx.rings[ring->idx].c_entity, |
385 | ib->sequence, false, -1); | 385 | ib->sequence, false, -1); |
386 | if (r) | 386 | if (r) |
387 | DRM_ERROR("emit timeout\n"); | 387 | DRM_ERROR("emit timeout\n"); |
@@ -517,7 +517,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, | |||
517 | if (amdgpu_enable_scheduler) { | 517 | if (amdgpu_enable_scheduler) { |
518 | int r; | 518 | int r; |
519 | sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM, | 519 | sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM, |
520 | adev->kernel_ctx, | 520 | &adev->kernel_ctx, |
521 | ib, 1); | 521 | ib, 1); |
522 | if(!sched_job) | 522 | if(!sched_job) |
523 | goto error_free; | 523 | goto error_free; |
@@ -525,9 +525,9 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, | |||
525 | sched_job->run_job = amdgpu_vm_run_job; | 525 | sched_job->run_job = amdgpu_vm_run_job; |
526 | sched_job->free_job = amdgpu_vm_free_job; | 526 | sched_job->free_job = amdgpu_vm_free_job; |
527 | ib->sequence = amd_sched_push_job(ring->scheduler, | 527 | ib->sequence = amd_sched_push_job(ring->scheduler, |
528 | &adev->kernel_ctx->rings[ring->idx].c_entity, | 528 | &adev->kernel_ctx.rings[ring->idx].c_entity, |
529 | sched_job); | 529 | sched_job); |
530 | r = amd_sched_wait_emit(&adev->kernel_ctx->rings[ring->idx].c_entity, | 530 | r = amd_sched_wait_emit(&adev->kernel_ctx.rings[ring->idx].c_entity, |
531 | ib->sequence, false, -1); | 531 | ib->sequence, false, -1); |
532 | if (r) | 532 | if (r) |
533 | DRM_ERROR("emit timeout\n"); | 533 | DRM_ERROR("emit timeout\n"); |
@@ -863,7 +863,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
863 | if (amdgpu_enable_scheduler) { | 863 | if (amdgpu_enable_scheduler) { |
864 | int r; | 864 | int r; |
865 | sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM, | 865 | sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM, |
866 | adev->kernel_ctx, ib, 1); | 866 | &adev->kernel_ctx, ib, 1); |
867 | if(!sched_job) | 867 | if(!sched_job) |
868 | goto error_free; | 868 | goto error_free; |
869 | sched_job->job_param.vm_mapping.vm = vm; | 869 | sched_job->job_param.vm_mapping.vm = vm; |
@@ -873,9 +873,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
873 | sched_job->run_job = amdgpu_vm_bo_update_mapping_run_job; | 873 | sched_job->run_job = amdgpu_vm_bo_update_mapping_run_job; |
874 | sched_job->free_job = amdgpu_vm_free_job; | 874 | sched_job->free_job = amdgpu_vm_free_job; |
875 | ib->sequence = amd_sched_push_job(ring->scheduler, | 875 | ib->sequence = amd_sched_push_job(ring->scheduler, |
876 | &adev->kernel_ctx->rings[ring->idx].c_entity, | 876 | &adev->kernel_ctx.rings[ring->idx].c_entity, |
877 | sched_job); | 877 | sched_job); |
878 | r = amd_sched_wait_emit(&adev->kernel_ctx->rings[ring->idx].c_entity, | 878 | r = amd_sched_wait_emit(&adev->kernel_ctx.rings[ring->idx].c_entity, |
879 | ib->sequence, false, -1); | 879 | ib->sequence, false, -1); |
880 | if (r) | 880 | if (r) |
881 | DRM_ERROR("emit timeout\n"); | 881 | DRM_ERROR("emit timeout\n"); |