diff options
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 18 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_panic.c | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_gem.c | 14 |
3 files changed, 32 insertions, 12 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 63ead8ba6756..5295ec122e0d 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -154,11 +154,8 @@ static void drm_crtc_crc_fini(struct drm_crtc *crtc) #endif } -static const struct dma_fence_ops drm_crtc_fence_ops; - static struct drm_crtc *fence_to_crtc(struct dma_fence *fence) { - BUG_ON(rcu_access_pointer(fence->ops) != &drm_crtc_fence_ops); return container_of(fence->extern_lock, struct drm_crtc, fence_lock); } @@ -493,14 +490,23 @@ EXPORT_SYMBOL(__drmm_crtc_alloc_with_planes); * drm_crtc_cleanup - Clean up the core crtc usage * @crtc: CRTC to cleanup * - * This function cleans up @crtc and removes it from the DRM mode setting - * core. Note that the function does *not* free the crtc structure itself, - * this is the responsibility of the caller. + * This function cleans up @crtc and removes it from the DRM mode setting core, + * after first waiting an RCU grace period to ensure @crtc->dev can safely be + * dereferenced by our dma_fence_ops. + * + * Note that the function does *not* free the crtc structure itself, this is the + * responsibility of the caller. */ void drm_crtc_cleanup(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; + /* Ensure our dma_fence_ops remain valid for an RCU grace period after + * the fence is signaled. This is necessary because our dma_fence_ops + * dereference crtc->dev. + */ + synchronize_rcu(); + /* Note that the crtc_list is considered to be static; should we * remove the drm_crtc at runtime we would have to decrement all * the indices on the drm_crtc after us in the crtc_list. diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c index e576c4791861..5109bfd5d889 100644 --- a/drivers/gpu/drm/drm_panic.c +++ b/drivers/gpu/drm/drm_panic.c @@ -556,7 +556,8 @@ static void draw_panic_screen_kmsg(struct drm_scanout_buffer *sb) const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL); struct drm_rect r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height); struct kmsg_dump_iter iter; - char kmsg_buf[512]; + /* the size printk formats one record into, too big for the stack */ + static char kmsg_buf[2048]; size_t kmsg_len; struct drm_panic_line line; int yoffset; @@ -570,10 +571,15 @@ static void draw_panic_screen_kmsg(struct drm_scanout_buffer *sb) drm_panic_fill(sb, &r_screen, bg_color); kmsg_dump_rewind(&iter); - while (kmsg_dump_get_buffer(&iter, false, kmsg_buf, sizeof(kmsg_buf), &kmsg_len)) { + while (yoffset >= 0 && kmsg_dump_get_buffer(&iter, false, kmsg_buf, + sizeof(kmsg_buf), &kmsg_len)) { char *start; char *end; + /* a record that does not fit comes back empty, every time */ + if (!kmsg_len) + break; + /* ignore terminating NUL and newline */ start = kmsg_buf + kmsg_len - 2; end = kmsg_buf + kmsg_len - 1; @@ -834,7 +840,7 @@ static int drm_panic_type_set(const char *val, const struct kernel_param *kp) unsigned int i; for (i = 0; i < ARRAY_SIZE(drm_panic_type_map); i++) { - if (!strcmp(val, drm_panic_type_map[i])) { + if (sysfs_streq(val, drm_panic_type_map[i])) { drm_panic_type = i; return 0; } diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index 6ee4bd77d433..0fef9b48d3c6 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c @@ -639,13 +639,14 @@ vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec, fence->seqno = exec->seqno; exec->fence = &fence->base; + /* The job can complete and drop exec->fence as soon as job_lock is + * released, so hold our own reference. + */ if (out_sync) - drm_syncobj_replace_fence(out_sync, exec->fence); + dma_fence_get(&fence->base); vc4_attach_fences(exec); - drm_exec_fini(exec_ctx); - list_add_tail(&exec->head, &vc4->bin_job_list); /* If no bin job was executing and if the render job (if any) has the @@ -662,6 +663,13 @@ vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec, spin_unlock_irqrestore(&vc4->job_lock, irqflags); + drm_exec_fini(exec_ctx); + + if (out_sync) { + drm_syncobj_replace_fence(out_sync, &fence->base); + dma_fence_put(&fence->base); + } + return 0; } |
