diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2021-01-07 10:46:32 +0100 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2021-01-07 10:46:32 +0100 |
commit | 18589d74f45d6af7e7614b6488543d723ebf236a (patch) | |
tree | a735d6ed4ea46926766d981c3944651fb78e2dc6 /drivers/gpu/drm/virtio/virtgpu_fence.c | |
parent | e71ba9452f0b5b2e8dc8aa5445198cd9214a6a62 (diff) | |
parent | c545781e1c55ab680dcc49c37212d5327b9d6812 (diff) | |
download | linux-18589d74f45d6af7e7614b6488543d723ebf236a.tar.bz2 |
Merge tag 'drm-misc-next-2020-12-17' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v5.12:
UAPI Changes:
- Not necessarily one, but we document that userspace needs to force probe connectors.
Cross-subsystem Changes:
- Require FB_ATY_CT for aty on sparc64.
- video: Fix documentation, and a few compiler warnings.
- Add devicetree bindings for DP connectors.
- dma-buf: Update kernel-doc, and add might_lock for resv objects in begin/end_cpu_access.
Core Changes:
- ttm: Warn when releasing a pinned bo.
- ttm: Cleanup bo size handling.
- cma-helper: Remove prime infix, and implement mmap as GEM CMA functions.
- Split drm_prime_sg_to_page_addr_arrays into 2 functions.
- Add a new api to install irq using devm.
- Update panel kerneldoc to inline style.
- Add DP support to drm/bridge.
- Assorted small fixes to ttm, fb-helper, scheduler.
- Add atomic_commit_setup function callback.
- Automatically use the atomic gamma_set, instead of forcing drivers to declare the default atomic version.
- Allow using degamma for legacy gamma if gamma is not available.
- Clarify that primary/cursor planes are not tied to 1 crtc (depending on possible_crtcs).
- ttm: Cleanup the lru handler.
Driver Changes:
- Add pm support to ingenic.
- Assorted small fixes in radeon, via, rockchip, omap2fb, kmb, gma500, nouveau, virtio, hisilicon, ingenic, s6e63m0 panel, ast, udlfb.
- Add BOE NV110WTM-N61, ys57pss36bh5gq, Khadas TS050 panels.
- Stop using pages with drm_prime_sg_to_page_addr_arrays, and switch all callers to use ttm_sg_tt_init.
- Cleanup compiler and docbook warnings in a lot of fbdev devices.
- Use the drmm_vram_helper in hisilicon.
- Add support for BCM2711 DSI1 in vc4.
- Add support for 8-bit delta RGB panels to ingenic.
- Add documentation on how to test vkms.
- Convert vc4 to atomic helpers.
- Use degamma instead of gamma table in omap, to add support for CTM and color encoding/range properties.
- Rework omap DSI code, and merge all omapdrm modules now that the last omap panel is now a drm panel.
- More refactoring of omap dsi code.
- Enable 10/12 bpc outputs in vc4.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/78381a4f-45fd-aed4-174a-94ba051edd37@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/virtio/virtgpu_fence.c')
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_fence.c | 81 |
1 files changed, 50 insertions, 31 deletions
diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c index 728ca36f6327..d28e25e8409b 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fence.c +++ b/drivers/gpu/drm/virtio/virtgpu_fence.c @@ -27,51 +27,48 @@ #include "virtgpu_drv.h" -#define to_virtio_fence(x) \ +#define to_virtio_gpu_fence(x) \ container_of(x, struct virtio_gpu_fence, f) -static const char *virtio_get_driver_name(struct dma_fence *f) +static const char *virtio_gpu_get_driver_name(struct dma_fence *f) { return "virtio_gpu"; } -static const char *virtio_get_timeline_name(struct dma_fence *f) +static const char *virtio_gpu_get_timeline_name(struct dma_fence *f) { return "controlq"; } -static bool virtio_fence_signaled(struct dma_fence *f) +static bool virtio_gpu_fence_signaled(struct dma_fence *f) { - struct virtio_gpu_fence *fence = to_virtio_fence(f); - - if (WARN_ON_ONCE(fence->f.seqno == 0)) - /* leaked fence outside driver before completing - * initialization with virtio_gpu_fence_emit */ - return false; - if (atomic64_read(&fence->drv->last_fence_id) >= fence->f.seqno) - return true; + /* leaked fence outside driver before completing + * initialization with virtio_gpu_fence_emit. + */ + WARN_ON_ONCE(f->seqno == 0); return false; } -static void virtio_fence_value_str(struct dma_fence *f, char *str, int size) +static void virtio_gpu_fence_value_str(struct dma_fence *f, char *str, int size) { - snprintf(str, size, "%llu", f->seqno); + snprintf(str, size, "[%llu, %llu]", f->context, f->seqno); } -static void virtio_timeline_value_str(struct dma_fence *f, char *str, int size) +static void virtio_gpu_timeline_value_str(struct dma_fence *f, char *str, + int size) { - struct virtio_gpu_fence *fence = to_virtio_fence(f); + struct virtio_gpu_fence *fence = to_virtio_gpu_fence(f); snprintf(str, size, "%llu", (u64)atomic64_read(&fence->drv->last_fence_id)); } -static const struct dma_fence_ops virtio_fence_ops = { - .get_driver_name = virtio_get_driver_name, - .get_timeline_name = virtio_get_timeline_name, - .signaled = virtio_fence_signaled, - .fence_value_str = virtio_fence_value_str, - .timeline_value_str = virtio_timeline_value_str, +static const struct dma_fence_ops virtio_gpu_fence_ops = { + .get_driver_name = virtio_gpu_get_driver_name, + .get_timeline_name = virtio_gpu_get_timeline_name, + .signaled = virtio_gpu_fence_signaled, + .fence_value_str = virtio_gpu_fence_value_str, + .timeline_value_str = virtio_gpu_timeline_value_str, }; struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device *vgdev) @@ -88,7 +85,8 @@ struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device *vgdev) * unknown yet. The fence must not be used outside of the driver * until virtio_gpu_fence_emit is called. */ - dma_fence_init(&fence->f, &virtio_fence_ops, &drv->lock, drv->context, 0); + dma_fence_init(&fence->f, &virtio_gpu_fence_ops, &drv->lock, drv->context, + 0); return fence; } @@ -101,7 +99,7 @@ void virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, unsigned long irq_flags; spin_lock_irqsave(&drv->lock, irq_flags); - fence->f.seqno = ++drv->current_fence_id; + fence->fence_id = fence->f.seqno = ++drv->current_fence_id; dma_fence_get(&fence->f); list_add_tail(&fence->node, &drv->fences); spin_unlock_irqrestore(&drv->lock, irq_flags); @@ -109,24 +107,45 @@ void virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, trace_dma_fence_emit(&fence->f); cmd_hdr->flags |= cpu_to_le32(VIRTIO_GPU_FLAG_FENCE); - cmd_hdr->fence_id = cpu_to_le64(fence->f.seqno); + cmd_hdr->fence_id = cpu_to_le64(fence->fence_id); } void virtio_gpu_fence_event_process(struct virtio_gpu_device *vgdev, u64 fence_id) { struct virtio_gpu_fence_driver *drv = &vgdev->fence_drv; - struct virtio_gpu_fence *fence, *tmp; + struct virtio_gpu_fence *signaled, *curr, *tmp; unsigned long irq_flags; spin_lock_irqsave(&drv->lock, irq_flags); atomic64_set(&vgdev->fence_drv.last_fence_id, fence_id); - list_for_each_entry_safe(fence, tmp, &drv->fences, node) { - if (fence_id < fence->f.seqno) + list_for_each_entry_safe(curr, tmp, &drv->fences, node) { + if (fence_id != curr->fence_id) continue; - dma_fence_signal_locked(&fence->f); - list_del(&fence->node); - dma_fence_put(&fence->f); + + signaled = curr; + + /* + * Signal any fences with a strictly smaller sequence number + * than the current signaled fence. + */ + list_for_each_entry_safe(curr, tmp, &drv->fences, node) { + /* dma-fence contexts must match */ + if (signaled->f.context != curr->f.context) + continue; + + if (!dma_fence_is_later(&signaled->f, &curr->f)) + continue; + + dma_fence_signal_locked(&curr->f); + list_del(&curr->node); + dma_fence_put(&curr->f); + } + + dma_fence_signal_locked(&signaled->f); + list_del(&signaled->node); + dma_fence_put(&signaled->f); + break; } spin_unlock_irqrestore(&drv->lock, irq_flags); } |