[RFC PATCH 001/162] drm/i915/selftest: also consider non-contiguous objects
In igt_ppgtt_sanity_check we should also exercise the non-contiguous option for LMEM, since this will give us slightly different sg layouts and alignment. Signed-off-by: Matthew Auld --- drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index 1f35e71429b4..0bf93947d89d 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -1333,6 +1333,7 @@ static int igt_ppgtt_sanity_check(void *arg) unsigned int flags; } backends[] = { { igt_create_system, 0,}, + { igt_create_local, 0,}, { igt_create_local, I915_BO_ALLOC_CONTIGUOUS, }, }; struct { -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 000/162] DG1 + LMEM enabling
This series includes a version of Maarten' series[1], which converts more of the driver locking over to dma-resv. On top of this we now implement things like LMEM eviction, which has a dependency on this new locking design. In terms of new uAPI we have gem_create_ext, which offers extensions support for gem_create. For now the only extension we add is giving userspace the ability to optionally provide a priority list of potential placements for the object. The other bit of new uAPI is the query interface for memory regions, which describes the supported memory regions for the device. What this reports can then be fed into gem_create_ext to specify where an object might reside, like device local memory. Note that the class/instance complexity in the uAPI is not very relevant for DG1, but is in preparation for the Xe HP multi-tile architecture with multiple memory regions. The series still includes relocation support, but that's purely for CI, until we have completed all the IGT rework[2] and so will not be merged. Likewise for pread/pwrite, which will also be dropped from DG1+. [1] https://patchwork.freedesktop.org/series/82337/ [2] https://patchwork.freedesktop.org/series/82954/ Abdiel Janulgue (3): drm/i915/query: Expose memory regions through the query uAPI drm/i915: Provide a way to disable PCIe relaxed write ordering drm/i915: Reintroduce mem->reserved Animesh Manna (2): drm/i915/lmem: reset the lmem buffer created by fbdev drm/i915/dsb: Enable lmem for dsb Anshuman Gupta (1): drm/i915/oprom: Basic sanitization Anusha Srivatsa (1): drm/i915/lmem: Bypass aperture when lmem is available Bommu Krishnaiah (1): drm/i915/gem: Update shmem available memory CQ Tang (13): drm/i915/dg1: Fix occasional migration error drm/i915: i915 returns -EBUSY on thread contention drm/i915: setup GPU device lmem region drm/i915: Fix object page offset within a region drm/i915: add i915_gem_object_is_devmem() function drm/i915: finish memory region support for stolen objects. drm/i915: Create stolen memory region from local memory drm/i915/dg1: intel_memory_region_evict() changes for eviction drm/i915/dg1: i915_gem_object_memcpy(..) infrastructure drm/i915/dg1: Eviction logic drm/i915/dg1: Add enable_eviction modparam drm/i915/dg1: Add lmem_size modparam drm/i915: need consider system BO snoop for dgfx Chris Wilson (2): drm/i915/gt: Move move context layout registers and offsets to lrc_reg.h drm/i915/gt: Rename lrc.c to execlists_submission.c Clint Taylor (3): drm/i915/dg1: Read OPROM via SPI controller drm/i915/dg1: Compute MEM Bandwidth using MCHBAR drm/i915/dg1: Double memory bandwidth available Daniele Ceraolo Spurio (5): drm/i915: split gen8+ flush and bb_start emission functions to their own file drm/i915: split wa_bb code to its own file drm/i915: Make intel_init_workaround_bb more compatible with ww locking. drm/i915/guc: put all guc objects in lmem when available drm/i915: WA for zero memory channel Imre Deak (1): drm/i915/dg1: Reserve first 1MB of local memory Kui Wen (1): drm/i915/dg1: Do not check r->sgt.pfn for NULL Lucas De Marchi (2): drm/i915: move eviction to prepare hook drm/i915/dg1: allow pci to auto probe Maarten Lankhorst (60): drm/i915: Pin timeline map after first timeline pin, v5. drm/i915: Move cmd parser pinning to execbuffer drm/i915: Add missing -EDEADLK handling to execbuf pinning, v2. drm/i915: Ensure we hold the object mutex in pin correctly v2 drm/i915: Add gem object locking to madvise. drm/i915: Move HAS_STRUCT_PAGE to obj->flags drm/i915: Rework struct phys attachment handling drm/i915: Convert i915_gem_object_attach_phys() to ww locking, v2. drm/i915: make lockdep slightly happier about execbuf. drm/i915: Disable userptr pread/pwrite support. drm/i915: No longer allow exporting userptr through dma-buf drm/i915: Reject more ioctls for userptr drm/i915: Reject UNSYNCHRONIZED for userptr, v2. drm/i915: Make compilation of userptr code depend on MMU_NOTIFIER. drm/i915: Fix userptr so we do not have to worry about obj->mm.lock, v5. drm/i915: Flatten obj->mm.lock drm/i915: Populate logical context during first pin. drm/i915: Make ring submission compatible with obj->mm.lock removal, v2. drm/i915: Handle ww locking in init_status_page drm/i915: Rework clflush to work correctly without obj->mm.lock. drm/i915: Pass ww ctx to intel_pin_to_display_plane drm/i915: Add object locking to vm_fault_cpu drm/i915: Move pinning to inside engine_wa_list_verify() drm/i915: Take reservation lock around i915_vma_pin. drm/i915: Make __engine_unpark() compatible with ww locking v2 drm/i915: Take obj lock around set_domain ioctl drm/i915: Defer pin calls in buffer pool until first use by caller. drm/i915: Fix pread/pwrite to work with new locking rules. drm/i915: Fix workarounds selftest, part 1 drm/i915: Add igt_spinner_pin() to allow for ww locking
[RFC PATCH 003/162] drm/i915/selftest: handle local-memory in perf_memcpy
We currently only support WC when mapping device local-memory, which is returned as a generic -ENOMEM when mapping the object with an unsupported type. Try to handle that case also, although it's starting to get pretty ugly in there. Signed-off-by: Matthew Auld --- drivers/gpu/drm/i915/selftests/intel_memory_region.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c index 0aeba8e3af28..27389fb19951 100644 --- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c +++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c @@ -681,6 +681,8 @@ create_region_for_mapping(struct intel_memory_region *mr, u64 size, u32 type, i915_gem_object_put(obj); if (PTR_ERR(addr) == -ENXIO) return ERR_PTR(-ENODEV); + if (PTR_ERR(addr) == -ENOMEM) /* WB local-memory */ + return ERR_PTR(-ENODEV); return addr; } -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 005/162] drm/i915/gt: Rename lrc.c to execlists_submission.c
From: Chris Wilson We want to separate the utility functions for controlling the logical ring context from the execlists submission mechanism (which is an overgrown scheduler). This is similar to Daniele's work to split up the files, but being selfish I wanted to base it after my own changes to intel_lrc.c petered out. Signed-off-by: Chris Wilson Cc: Daniele Ceraolo Spurio Cc: Tvrtko Ursulin Reviewed-by: Daniele Ceraolo Spurio Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/Makefile | 2 +- drivers/gpu/drm/i915/gem/i915_gem_context.c | 1 + drivers/gpu/drm/i915/gt/intel_context_sseu.c | 2 +- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 1 + ...tel_lrc.c => intel_execlists_submission.c} | 30 ++ ...tel_lrc.h => intel_execlists_submission.h} | 31 +++ drivers/gpu/drm/i915/gt/intel_mocs.c | 2 +- .../{selftest_lrc.c => selftest_execlists.c} | 0 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 1 + .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 1 + drivers/gpu/drm/i915/gvt/scheduler.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/i915_perf.c | 1 + 13 files changed, 16 insertions(+), 58 deletions(-) rename drivers/gpu/drm/i915/gt/{intel_lrc.c => intel_execlists_submission.c} (99%) rename drivers/gpu/drm/i915/gt/{intel_lrc.h => intel_execlists_submission.h} (57%) rename drivers/gpu/drm/i915/gt/{selftest_lrc.c => selftest_execlists.c} (100%) diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index e5574e506a5c..aedbd8f52be8 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -91,6 +91,7 @@ gt-y += \ gt/intel_engine_heartbeat.o \ gt/intel_engine_pm.o \ gt/intel_engine_user.o \ + gt/intel_execlists_submission.o \ gt/intel_ggtt.o \ gt/intel_ggtt_fencing.o \ gt/intel_gt.o \ @@ -102,7 +103,6 @@ gt-y += \ gt/intel_gt_requests.o \ gt/intel_gtt.o \ gt/intel_llc.o \ - gt/intel_lrc.o \ gt/intel_mocs.o \ gt/intel_ppgtt.o \ gt/intel_rc6.o \ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index a6299da64de4..ad136d009d9b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -72,6 +72,7 @@ #include "gt/intel_context_param.h" #include "gt/intel_engine_heartbeat.h" #include "gt/intel_engine_user.h" +#include "gt/intel_execlists_submission.h" /* virtual_engine */ #include "gt/intel_ring.h" #include "i915_gem_context.h" diff --git a/drivers/gpu/drm/i915/gt/intel_context_sseu.c b/drivers/gpu/drm/i915/gt/intel_context_sseu.c index b9c8163978a3..5f94b44022dc 100644 --- a/drivers/gpu/drm/i915/gt/intel_context_sseu.c +++ b/drivers/gpu/drm/i915/gt/intel_context_sseu.c @@ -8,7 +8,7 @@ #include "intel_context.h" #include "intel_engine_pm.h" #include "intel_gpu_commands.h" -#include "intel_lrc.h" +#include "intel_execlists_submission.h" #include "intel_lrc_reg.h" #include "intel_ring.h" #include "intel_sseu.h" diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 02ea16b29c9f..97ceaf7116e8 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -33,6 +33,7 @@ #include "intel_engine.h" #include "intel_engine_pm.h" #include "intel_engine_user.h" +#include "intel_execlists_submission.h" #include "intel_gt.h" #include "intel_gt_requests.h" #include "intel_gt_pm.h" diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c similarity index 99% rename from drivers/gpu/drm/i915/gt/intel_lrc.c rename to drivers/gpu/drm/i915/gt/intel_execlists_submission.c index 43703efb36d1..fc330233ea20 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c @@ -1,31 +1,6 @@ +// SPDX-License-Identifier: MIT /* * Copyright © 2014 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR
[RFC PATCH 004/162] drm/i915/gt: Move move context layout registers and offsets to lrc_reg.h
From: Chris Wilson Cleanup intel_lrc.h by moving some of the residual common register definitions into intel_lrc_reg.h, prior to rebranding and splitting off the submission backends. v2: keep the SCHEDULE enum in the old file, since it is specific to the gvt usage of the execlists submission backend (John) Signed-off-by: Chris Wilson Signed-off-by: Daniele Ceraolo Spurio #v2 Cc: John Harrison Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 2 +- drivers/gpu/drm/i915/gt/intel_gt_irq.c| 1 + drivers/gpu/drm/i915/gt/intel_lrc.h | 39 --- drivers/gpu/drm/i915/gt/intel_lrc_reg.h | 39 +++ drivers/gpu/drm/i915/gvt/mmio_context.h | 2 ++ 5 files changed, 43 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index d4e988b2816a..02ea16b29c9f 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -36,7 +36,7 @@ #include "intel_gt.h" #include "intel_gt_requests.h" #include "intel_gt_pm.h" -#include "intel_lrc.h" +#include "intel_lrc_reg.h" #include "intel_reset.h" #include "intel_ring.h" diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c index 257063a57101..9830342aa6f4 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c @@ -11,6 +11,7 @@ #include "intel_breadcrumbs.h" #include "intel_gt.h" #include "intel_gt_irq.h" +#include "intel_lrc_reg.h" #include "intel_uncore.h" #include "intel_rps.h" diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.h b/drivers/gpu/drm/i915/gt/intel_lrc.h index 802585a308e9..9116b46844a2 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.h +++ b/drivers/gpu/drm/i915/gt/intel_lrc.h @@ -34,45 +34,6 @@ struct i915_request; struct intel_context; struct intel_engine_cs; -/* Execlists regs */ -#define RING_ELSP(base)_MMIO((base) + 0x230) -#define RING_EXECLIST_STATUS_LO(base) _MMIO((base) + 0x234) -#define RING_EXECLIST_STATUS_HI(base) _MMIO((base) + 0x234 + 4) -#define RING_CONTEXT_CONTROL(base) _MMIO((base) + 0x244) -#define CTX_CTRL_INHIBIT_SYN_CTX_SWITCH (1 << 3) -#define CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT (1 << 0) -#define CTX_CTRL_RS_CTX_ENABLE (1 << 1) -#define CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT (1 << 2) -#define GEN12_CTX_CTRL_OAR_CONTEXT_ENABLE (1 << 8) -#define RING_CONTEXT_STATUS_PTR(base) _MMIO((base) + 0x3a0) -#define RING_EXECLIST_SQ_CONTENTS(base)_MMIO((base) + 0x510) -#define RING_EXECLIST_CONTROL(base)_MMIO((base) + 0x550) - -#define EL_CTRL_LOAD (1 << 0) - -/* The docs specify that the write pointer wraps around after 5h, "After status - * is written out to the last available status QW at offset 5h, this pointer - * wraps to 0." - * - * Therefore, one must infer than even though there are 3 bits available, 6 and - * 7 appear to be * reserved. - */ -#define GEN8_CSB_ENTRIES 6 -#define GEN8_CSB_PTR_MASK 0x7 -#define GEN8_CSB_READ_PTR_MASK (GEN8_CSB_PTR_MASK << 8) -#define GEN8_CSB_WRITE_PTR_MASK (GEN8_CSB_PTR_MASK << 0) - -#define GEN11_CSB_ENTRIES 12 -#define GEN11_CSB_PTR_MASK 0xf -#define GEN11_CSB_READ_PTR_MASK (GEN11_CSB_PTR_MASK << 8) -#define GEN11_CSB_WRITE_PTR_MASK (GEN11_CSB_PTR_MASK << 0) - -#define MAX_CONTEXT_HW_ID (1<<21) /* exclusive */ -#define MAX_GUC_CONTEXT_HW_ID (1 << 20) /* exclusive */ -#define GEN11_MAX_CONTEXT_HW_ID (1<<11) /* exclusive */ -/* in Gen12 ID 0x7FF is reserved to indicate idle */ -#define GEN12_MAX_CONTEXT_HW_ID(GEN11_MAX_CONTEXT_HW_ID - 1) - enum { INTEL_CONTEXT_SCHEDULE_IN = 0, INTEL_CONTEXT_SCHEDULE_OUT, diff --git a/drivers/gpu/drm/i915/gt/intel_lrc_reg.h b/drivers/gpu/drm/i915/gt/intel_lrc_reg.h index 1b51f7b9a5c3..b2e03ce35599 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc_reg.h +++ b/drivers/gpu/drm/i915/gt/intel_lrc_reg.h @@ -52,4 +52,43 @@ #define GEN8_EXECLISTS_STATUS_BUF 0x370 #define GEN11_EXECLISTS_STATUS_BUF2 0x3c0 +/* Execlists regs */ +#define RING_ELSP(base)_MMIO((base) + 0x230) +#define RING_EXECLIST_STATUS_LO(base) _MMIO((base) + 0x234) +#define RING_EXECLIST_STATUS_HI(base) _MMIO((base) + 0x234 + 4) +#define RING_CONTEXT_CONTROL(base) _MMIO((base) + 0x244) +#define CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT REG_BIT(0) +#define CTX_CTRL_RS_CTX_ENABLE REG_BIT(1) +#define CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT REG_BIT(2) +#define CTX_CTRL_INHIBIT_SYN_CTX_SWITCH REG_BIT(3) +#define GEN12_CTX_CTRL_OAR_CONTEXT_ENABLE REG_BIT(8) +#define RING_CONTEXT_STATUS_PTR(base) _MMIO((base) + 0x3a0) +#define RING_EXECLIST_SQ_CONTENTS(base)_MMIO((base) +
[RFC PATCH 002/162] drm/i915/selftest: assert we get 2M GTT pages
For the LMEM case if we have suitable alignment and 2M physical pages we should always get 2M GTT pages within the constraints of the hugepages selftest. If we don't then something might be wrong in our construction of the backing pages. Signed-off-by: Matthew Auld --- .../gpu/drm/i915/gem/selftests/huge_pages.c | 21 +++ 1 file changed, 21 insertions(+) diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index 0bf93947d89d..77a13527a7e6 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -368,6 +368,27 @@ static int igt_check_page_sizes(struct i915_vma *vma) err = -EINVAL; } + + /* +* The dma-api is like a box of chocolates when it comes to the +* alignment of dma addresses, however for LMEM we have total control +* and so can guarantee alignment, likewise when we allocate our blocks +* they should appear in descending order, and if we know that we align +* to the largest page size for the GTT address, we should be able to +* assert that if we see 2M physical pages then we should also get 2M +* GTT pages. If we don't then something might be wrong in our +* construction of the backing pages. +*/ + if (i915_gem_object_is_lmem(obj) && + IS_ALIGNED(vma->node.start, SZ_2M) && + vma->page_sizes.sg & SZ_2M && + vma->page_sizes.gtt < SZ_2M) { + pr_err("gtt pages mismatch for LMEM, expected 2M GTT pages, sg(%u), gtt(%u)\n", + vma->page_sizes.sg, vma->page_sizes.gtt); + err = -EINVAL; + } + + if (obj->mm.page_sizes.gtt) { pr_err("obj->page_sizes.gtt(%u) should never be set\n", obj->mm.page_sizes.gtt); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 153/162] drm/i915: Implement eviction locking v2
From: Maarten Lankhorst Use a separate acquire context list and a separate locking function for objects that are locked for eviction. These objects are then properly referenced while on the list and can be unlocked early in the ww transaction. Co-developed-by: Thomas Hellström Signed-off-by: Thomas Hellström Signed-off-by: Maarten Lankhorst Cc: Matthew Auld --- drivers/gpu/drm/i915/gem/i915_gem_object.h| 67 +-- .../gpu/drm/i915/gem/i915_gem_object_types.h | 5 ++ drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 14 +++- drivers/gpu/drm/i915/i915_gem_ww.c| 51 ++ drivers/gpu/drm/i915/i915_gem_ww.h| 3 + 5 files changed, 122 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index 52a36b4052f0..e237b0fb0e79 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -158,6 +158,32 @@ static inline void assert_object_held_shared(struct drm_i915_gem_object *obj) assert_object_held(obj); } +static inline int +i915_gem_object_lock_to_evict(struct drm_i915_gem_object *obj, + struct i915_gem_ww_ctx *ww) +{ + int ret; + + if (ww->intr) + ret = dma_resv_lock_interruptible(obj->base.resv, >ctx); + else + ret = dma_resv_lock(obj->base.resv, >ctx); + + if (!ret) { + list_add_tail(>obj_link, >eviction_list); + i915_gem_object_get(obj); + obj->evict_locked = true; + } + + GEM_WARN_ON(ret == -EALREADY); + if (ret == -EDEADLK) { + ww->contended_evict = true; + ww->contended = i915_gem_object_get(obj); + } + + return ret; +} + static inline int __i915_gem_object_lock(struct drm_i915_gem_object *obj, struct i915_gem_ww_ctx *ww, bool intr) @@ -169,13 +195,25 @@ static inline int __i915_gem_object_lock(struct drm_i915_gem_object *obj, else ret = dma_resv_lock(obj->base.resv, ww ? >ctx : NULL); - if (!ret && ww) + if (!ret && ww) { list_add_tail(>obj_link, >obj_list); - if (ret == -EALREADY) - ret = 0; + obj->evict_locked = false; + } - if (ret == -EDEADLK) + if (ret == -EALREADY) { + ret = 0; + /* We've already evicted an object needed for this batch. */ + if (obj->evict_locked) { + list_move_tail(>obj_link, >obj_list); + i915_gem_object_put(obj); + obj->evict_locked = false; + } + } + + if (ret == -EDEADLK) { + ww->contended_evict = false; ww->contended = i915_gem_object_get(obj); + } return ret; } @@ -580,6 +618,27 @@ i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj, __i915_gem_object_invalidate_frontbuffer(obj, origin); } +/** + * i915_gem_get_locking_ctx - Get the locking context of a locked object + * if any. + * + * @obj: The object to get the locking ctx from + * + * RETURN: The locking context if the object was locked using a context. + * NULL otherwise. + */ +static inline struct i915_gem_ww_ctx * +i915_gem_get_locking_ctx(const struct drm_i915_gem_object *obj) +{ + struct ww_acquire_ctx *ctx; + + ctx = obj->base.resv->lock.ctx; + if (!ctx) + return NULL; + + return container_of(ctx, struct i915_gem_ww_ctx, ctx); +} + #ifdef CONFIG_MMU_NOTIFIER static inline bool i915_gem_object_is_userptr(struct drm_i915_gem_object *obj) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h index 331d113f7d5b..c42c0d3d5d67 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h @@ -142,6 +142,11 @@ struct drm_i915_gem_object { */ struct list_head obj_link; + /** +* @evict_locked: Whether @obj_link sits on the eviction_list +*/ + bool evict_locked; + /** Stolen memory for this object, instead of being backed by shmem. */ struct drm_mm_node *stolen; union { diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c index 27674048f17d..59d0f14b90ea 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c @@ -100,6 +100,7 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww, unsigned long *nr_scanned, unsigned int shrink) { + struct drm_i915_gem_object *obj; const struct { struct list_head *list; unsigned int bit; @@ -164,7 +165,6 @@
[RFC PATCH 154/162] drm/i915: Support ww eviction
From: Thomas Hellström Use sleeping ww locks if we're in a ww transaction. Trylock otherwise. We unlock the evicted objects either when eviction failed or when we've reached the target. The ww ticket locks will then ensure we will eventually succeed reaching the target if there is evictable space available. However another process may still steal the evicted memory before we have a chance to allocate it. To ensure we eventually succeed we need to move the evict unlock until after get pages succeeds. That's considered a TODO for now. Signed-off-by: Thomas Hellström Cc: Matthew Auld --- drivers/gpu/drm/i915/gem/i915_gem_region.c | 7 ++- drivers/gpu/drm/i915/intel_memory_region.c | 57 -- drivers/gpu/drm/i915/intel_memory_region.h | 2 + 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c index 1ec6528498c8..8ec59fbaa3e6 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_region.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c @@ -204,6 +204,7 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj) struct scatterlist *sg; unsigned int sg_page_sizes; int ret; + struct i915_gem_ww_ctx *ww = i915_gem_get_locking_ctx(obj); /* XXX: Check if we have any post. This is nasty hack, see gem_create */ if (obj->mm.gem_create_posted_err) @@ -222,7 +223,8 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj) if (obj->flags & I915_BO_ALLOC_CONTIGUOUS) flags |= I915_ALLOC_CONTIGUOUS; - ret = __intel_memory_region_get_pages_buddy(mem, size, flags, blocks); + ret = __intel_memory_region_get_pages_buddy(mem, ww, size, flags, + blocks); if (ret) goto err_free_sg; @@ -277,7 +279,8 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj) if (ret) { /* swapin failed, free the pages */ __intel_memory_region_put_pages_buddy(mem, blocks); - ret = -ENXIO; + if (ret != -EDEADLK && ret != -EINTR) + ret = -ENXIO; goto err_free_sg; } } else if (obj->flags & I915_BO_ALLOC_CPU_CLEAR) { diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c index 57f01ef16628..6b26b6cd5958 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.c +++ b/drivers/gpu/drm/i915/intel_memory_region.c @@ -96,6 +96,7 @@ __intel_memory_region_put_block_buddy(struct i915_buddy_block *block) } static int intel_memory_region_evict(struct intel_memory_region *mem, +struct i915_gem_ww_ctx *ww, resource_size_t target) { struct drm_i915_private *i915 = mem->i915; @@ -109,6 +110,7 @@ static int intel_memory_region_evict(struct intel_memory_region *mem, struct list_head **phase; resource_size_t found; int pass; + int err = 0; intel_gt_retire_requests(>gt); @@ -126,10 +128,11 @@ static int intel_memory_region_evict(struct intel_memory_region *mem, mm.region_link))) { list_move_tail(>mm.region_link, _in_list); - if (!i915_gem_object_has_pages(obj)) + if (i915_gem_object_is_framebuffer(obj)) continue; - if (i915_gem_object_is_framebuffer(obj)) + /* Already locked this object? */ + if (ww && ww == i915_gem_get_locking_ctx(obj)) continue; /* @@ -147,34 +150,51 @@ static int intel_memory_region_evict(struct intel_memory_region *mem, mutex_unlock(>objects.lock); + if (ww) { + err = i915_gem_object_lock_to_evict(obj, ww); + if (err) + goto put; + } else { + if (!i915_gem_object_trylock(obj)) + goto put; + } + + if (!i915_gem_object_has_pages(obj)) + goto unlock; + /* tell callee to do swapping */ if (i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_IOMEM) && pass == 1) obj->do_swapping = true; if (!i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE)) { - if (i915_gem_object_trylock(obj)) { - __i915_gem_object_put_pages(obj); - /* May arrive from get_pages on another bo */ - if (!i915_gem_object_has_pages(obj)) { - found +=
[RFC PATCH 157/162] drm/i915: Improve accuracy of eviction stats
From: Tvrtko Ursulin Current code uses jiffie time to do the accounting and then does: diff = jiffies - start; msec = diff * 1000 / HZ; ... atomic_long_add(msec, >time_swap_out_ms); If we assume jiffie can be as non-granular as 10ms and that the current accounting records all evictions faster than one jiffie as infinite speed, we can end up over-estimating the reported eviction throughput. Fix this by accumulating ktime_t and only dividing to more user friendly granularity at presentation time (debugfs read). At the same time consolidate the code a bit and convert from multiple atomics to single seqlock per stat. Signed-off-by: Tvrtko Ursulin Cc: CQ Tang Cc: Sudeep Dutt Cc: Mika Kuoppala --- drivers/gpu/drm/i915/gem/i915_gem_region.c | 67 ++-- drivers/gpu/drm/i915/i915_debugfs.c| 73 +++--- drivers/gpu/drm/i915/i915_drv.h| 25 +--- drivers/gpu/drm/i915/i915_gem.c| 5 ++ 4 files changed, 90 insertions(+), 80 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c index 8ec59fbaa3e6..1a390e502d5a 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_region.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c @@ -9,14 +9,29 @@ #include "i915_trace.h" #include "i915_gem_mman.h" +static void +__update_stat(struct i915_mm_swap_stat *stat, + unsigned long pages, + ktime_t start) +{ + if (stat) { + start = ktime_get() - start; + + write_seqlock(>lock); + stat->time = ktime_add(stat->time, start); + stat->pages += pages; + write_sequnlock(>lock); + } +} + static int i915_gem_object_swapout_pages(struct drm_i915_gem_object *obj, struct sg_table *pages, unsigned int sizes) { struct drm_i915_private *i915 = to_i915(obj->base.dev); + struct i915_mm_swap_stat *stat = NULL; struct drm_i915_gem_object *dst, *src; - unsigned long start, diff, msec; - bool blt_completed = false; + ktime_t start = ktime_get(); int err = -EINVAL; GEM_BUG_ON(obj->swapto); @@ -26,7 +41,6 @@ i915_gem_object_swapout_pages(struct drm_i915_gem_object *obj, GEM_BUG_ON(!i915->params.enable_eviction); assert_object_held(obj); - start = jiffies; /* create a shadow object on smem region */ dst = i915_gem_object_create_shmem(i915, obj->base.size); @@ -58,10 +72,14 @@ i915_gem_object_swapout_pages(struct drm_i915_gem_object *obj, if (i915->params.enable_eviction >= 2) { err = i915_window_blt_copy(dst, src); if (!err) - blt_completed = true; + stat = >mm.blt_swap_stats.out; } - if (err && i915->params.enable_eviction != 2) + + if (err && i915->params.enable_eviction != 2) { err = i915_gem_object_memcpy(dst, src); + if (!err) + stat = >mm.memcpy_swap_stats.out; + } __i915_gem_object_unpin_pages(src); __i915_gem_object_unset_pages(src); @@ -73,18 +91,7 @@ i915_gem_object_swapout_pages(struct drm_i915_gem_object *obj, else i915_gem_object_put(dst); - if (!err) { - diff = jiffies - start; - msec = diff * 1000 / HZ; - if (blt_completed) { - atomic_long_add(sizes, >num_bytes_swapped_out); - atomic_long_add(msec, >time_swap_out_ms); - } else { - atomic_long_add(sizes, - >num_bytes_swapped_out_memcpy); - atomic_long_add(msec, >time_swap_out_ms_memcpy); - } - } + __update_stat(stat, sizes >> PAGE_SHIFT, start); return err; } @@ -94,9 +101,9 @@ i915_gem_object_swapin_pages(struct drm_i915_gem_object *obj, struct sg_table *pages, unsigned int sizes) { struct drm_i915_private *i915 = to_i915(obj->base.dev); + struct i915_mm_swap_stat *stat = NULL; struct drm_i915_gem_object *dst, *src; - unsigned long start, diff, msec; - bool blt_completed = false; + ktime_t start = ktime_get(); int err = -EINVAL; GEM_BUG_ON(!obj->swapto); @@ -106,7 +113,6 @@ i915_gem_object_swapin_pages(struct drm_i915_gem_object *obj, GEM_BUG_ON(!i915->params.enable_eviction); assert_object_held(obj); - start = jiffies; src = obj->swapto; @@ -134,10 +140,14 @@ i915_gem_object_swapin_pages(struct drm_i915_gem_object *obj, if (i915->params.enable_eviction >= 2) { err = i915_window_blt_copy(dst, src); if (!err) - blt_completed = true; + stat = >mm.blt_swap_stats.in; } - if (err
[RFC PATCH 156/162] drm/i915: Use a ww transaction in i915_gem_object_pin_map_unlocked()
From: Thomas Hellström By using a ww transaction, anybody using this function and ending up evicting objects can use sleeping waits when locking objects to evict. Signed-off-by: Thomas Hellström Cc: Matthew Auld --- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 17 ++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index d0f3da0925f5..0c20f9b18956 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -425,11 +425,22 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, void *i915_gem_object_pin_map_unlocked(struct drm_i915_gem_object *obj, enum i915_map_type type) { + struct i915_gem_ww_ctx ww; void *ret; + int err; - i915_gem_object_lock(obj, NULL); - ret = i915_gem_object_pin_map(obj, type); - i915_gem_object_unlock(obj); + for_i915_gem_ww(, err, false) { + err = i915_gem_object_lock(obj, ); + if (err) + continue; + + ret = i915_gem_object_pin_map(obj, type); + if (IS_ERR(ret)) + err = PTR_ERR(ret); + /* Implicit unlock */ + } + if (err) + return ERR_PTR(err); return ret; } -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 155/162] drm/i915: Use a ww transaction in the fault handler
From: Thomas Hellström Prefer a ww transaction rather than a single object lock to enable sleeping lock eviction if reached by the fault handler. Signed-off-by: Thomas Hellström Cc: Matthew Auld --- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 45 +--- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c index 33ccd4d665d4..a9526cc309d3 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c @@ -238,6 +238,7 @@ static vm_fault_t vm_fault_cpu(struct vm_fault *vmf) struct vm_area_struct *area = vmf->vma; struct i915_mmap_offset *mmo = area->vm_private_data; struct drm_i915_gem_object *obj = mmo->obj; + struct i915_gem_ww_ctx ww; resource_size_t iomap; int err; @@ -246,33 +247,35 @@ static vm_fault_t vm_fault_cpu(struct vm_fault *vmf) area->vm_flags & VM_WRITE)) return VM_FAULT_SIGBUS; - if (i915_gem_object_lock_interruptible(obj, NULL)) - return VM_FAULT_NOPAGE; + for_i915_gem_ww(, err, true) { + err = i915_gem_object_lock(obj, ); + if (err) + continue; - err = i915_gem_object_pin_pages(obj); - if (err) - goto out; + err = i915_gem_object_pin_pages(obj); + if (err) + continue; - iomap = -1; - if (!i915_gem_object_has_struct_page(obj)) { - iomap = obj->mm.region->iomap.base; - iomap -= obj->mm.region->region.start; - } + iomap = -1; + if (!i915_gem_object_has_struct_page(obj)) { + iomap = obj->mm.region->iomap.base; + iomap -= obj->mm.region->region.start; + } - /* PTEs are revoked in obj->ops->put_pages() */ - err = remap_io_sg(area, - area->vm_start, area->vm_end - area->vm_start, - obj->mm.pages->sgl, iomap); + /* PTEs are revoked in obj->ops->put_pages() */ + err = remap_io_sg(area, + area->vm_start, area->vm_end - area->vm_start, + obj->mm.pages->sgl, iomap); - if (area->vm_flags & VM_WRITE) { - GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); - obj->mm.dirty = true; - } + if (area->vm_flags & VM_WRITE) { + GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); + obj->mm.dirty = true; + } - i915_gem_object_unpin_pages(obj); + i915_gem_object_unpin_pages(obj); + /* Implicit unlock */ + } -out: - i915_gem_object_unlock(obj); return i915_error_to_vmf_fault(err); } -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 158/162] drm/i915: Support ww locks in suspend/resume
From: Venkata Ramana Nayana Add ww locks during suspend/resume. Signed-off-by: Venkata Ramana Nayana --- drivers/gpu/drm/i915/i915_drv.c | 33 ++--- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index b7d40a9c00bf..c41865d5bf1e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1099,7 +1099,7 @@ static int i915_drm_prepare(struct drm_device *dev) struct drm_i915_private *i915 = to_i915(dev); if (HAS_LMEM(i915)) { - struct intel_gt *gt= >gt; + struct intel_gt *gt = >gt; long timeout = I915_GEM_IDLE_TIMEOUT; int ret; @@ -1182,7 +1182,8 @@ static int intel_dmem_evict_buffers(struct drm_device *dev, bool in_suspend, struct drm_i915_private *i915 = to_i915(dev); struct drm_i915_gem_object *obj; struct intel_memory_region *mem; - int id, ret = 0; + struct i915_gem_ww_ctx ww; + int id, ret = 0, err = 0; for_each_memory_region(mem, i915, id) { struct list_head still_in_list; @@ -1204,19 +1205,20 @@ static int intel_dmem_evict_buffers(struct drm_device *dev, bool in_suspend, mutex_unlock(>objects.lock); + i915_gem_ww_ctx_init (, true); +retry: + err = i915_gem_object_lock(obj, ); + if (err) + goto out_err; + if (in_suspend) { obj->swapto = NULL; obj->evicted = false; ret = i915_gem_object_unbind(obj, 0); if (ret || i915_gem_object_has_pinned_pages(obj)) { - if (!i915_gem_object_trylock(obj)) { - ret = -EBUSY; - goto next; - } ret = i915_gem_perma_pinned_object_swapout(obj); - i915_gem_object_unlock(obj); - goto next; + goto out_err; } obj->do_swapping = true; @@ -1228,13 +1230,7 @@ static int intel_dmem_evict_buffers(struct drm_device *dev, bool in_suspend, obj->evicted = true; } else { if (i915_gem_object_has_pinned_pages(obj) && perma_pin) { - if (!i915_gem_object_trylock(obj)) { - ret = -EBUSY; - goto next; - } ret = i915_gem_perma_pinned_object_swapin(obj); - /* FIXME: Where is this error message taken care of? */ - i915_gem_object_unlock(obj); } if (obj->swapto && obj->evicted && !perma_pin) { @@ -1247,7 +1243,14 @@ static int intel_dmem_evict_buffers(struct drm_device *dev, bool in_suspend, } } } -next: +out_err: + if (err == -EDEADLK) { + err = i915_gem_ww_ctx_backoff(); + if (!err) + goto retry; + } + i915_gem_ww_ctx_fini(); + mutex_lock(>objects.lock); if (ret) break; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 159/162] drm/i915/dg1: Fix mapping type for default state object
From: Venkata Ramana Nayana Use I915_MAP_WC when default state object is allocated on LMEM. Signed-off-by: Venkata Ramana Nayana --- drivers/gpu/drm/i915/gt/shmem_utils.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c b/drivers/gpu/drm/i915/gt/shmem_utils.c index 041e2a50160d..1fbc070a4651 100644 --- a/drivers/gpu/drm/i915/gt/shmem_utils.c +++ b/drivers/gpu/drm/i915/gt/shmem_utils.c @@ -8,6 +8,7 @@ #include #include "gem/i915_gem_object.h" +#include "gem/i915_gem_lmem.h" #include "shmem_utils.h" struct file *shmem_create_from_data(const char *name, void *data, size_t len) @@ -39,7 +40,8 @@ struct file *shmem_create_from_object(struct drm_i915_gem_object *obj) return file; } - ptr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB); + ptr = i915_gem_object_pin_map_unlocked(obj, i915_gem_object_is_lmem(obj) ? + I915_MAP_WC : I915_MAP_WB); if (IS_ERR(ptr)) return ERR_CAST(ptr); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 160/162] drm/i915/dg1: Fix GPU hang due to shmemfs page drop
From: Venkata Ramana Nayana This is to fix a bug in upstream commit a6326a4f8ffb ("drm/i915/gt: Keep a no-frills swappable copy of the default context state") We allocate context state obj ce->state from lmem, so in __engines_record_defaults(), we call shmem_create_from_object(). Because it is lmem object, this call will create a new shmemfs file, copy the contents into it, and return the file pointer and assign to engine->default_state. Of course ce->state lmem object is freed at the end of function __engines_record_redefaults(). Because a new shmemfs file is create for engine->default_state, and more importantly, we DON'T mark the pages dirty after we write into it, the OS page cache eviction will drop these pages. Now with the test move forward, it will create new request/context, and will copy the saved engine->default_state into ce->state. If the default_state pages are dropped during page cache eviction, the copying will get new pages, and copy garbage from the new pages. Next, ce->state will have wrong instruction and causes GPU to hang. The fixing is very simple, we just mark the shmemfs pages to be dirty when writing into it, and also mark the pages to accessed when read/write to them. Fixes: a6326a4f8ffb("drm/i915/gt: Keep a no-frills swappable copy of the default context state") Cc: Sudeep Dutt Cc: Matthew Auld Cc: Tvrtko Ursulin Cc: Ramalingam C Cc: Chris Wilson Signed-off-by: CQ Tang Signed-off-by: Venkata Ramana Nayana --- drivers/gpu/drm/i915/gt/shmem_utils.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c b/drivers/gpu/drm/i915/gt/shmem_utils.c index 1fbc070a4651..e24c2c2342bb 100644 --- a/drivers/gpu/drm/i915/gt/shmem_utils.c +++ b/drivers/gpu/drm/i915/gt/shmem_utils.c @@ -105,10 +105,13 @@ static int __shmem_rw(struct file *file, loff_t off, return PTR_ERR(page); vaddr = kmap(page); - if (write) + if (write) { memcpy(vaddr + offset_in_page(off), ptr, this); - else + set_page_dirty(page); + } else { memcpy(ptr, vaddr + offset_in_page(off), this); + } + mark_page_accessed(page); kunmap(page); put_page(page); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 161/162] drm/i915/dg1: allow pci to auto probe
From: Lucas De Marchi Signed-off-by: Lucas De Marchi --- drivers/gpu/drm/i915/i915_pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index c3d9b36ef651..603976b9a973 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -1001,6 +1001,7 @@ static const struct pci_device_id pciidlist[] = { INTEL_JSL_IDS(_info), INTEL_TGL_12_IDS(_info), INTEL_RKL_IDS(_info), + INTEL_DG1_IDS(_info), {0, 0, 0} }; MODULE_DEVICE_TABLE(pci, pciidlist); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 162/162] drm/i915: drop fake lmem
Signed-off-by: Matthew Auld --- drivers/gpu/drm/i915/i915_drv.c| 15 drivers/gpu/drm/i915/i915_params.c | 5 -- drivers/gpu/drm/i915/i915_params.h | 1 - drivers/gpu/drm/i915/intel_memory_region.c | 11 +-- drivers/gpu/drm/i915/intel_region_lmem.c | 96 -- drivers/gpu/drm/i915/intel_region_lmem.h | 3 - 6 files changed, 1 insertion(+), 130 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c41865d5bf1e..ee7272abc2b4 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -836,21 +836,6 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (!i915->params.nuclear_pageflip && match_info->gen < 5) i915->drm.driver_features &= ~DRIVER_ATOMIC; - /* -* Check if we support fake LMEM -- for now we only unleash this for -* the live selftests(test-and-exit). -*/ -#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) - if (IS_ENABLED(CONFIG_DRM_I915_UNSTABLE_FAKE_LMEM)) { - if (INTEL_GEN(i915) >= 9 && i915_selftest.live < 0 && - i915->params.fake_lmem_start) { - mkwrite_device_info(i915)->memory_regions = - REGION_SMEM | REGION_LMEM | REGION_STOLEN_SMEM; - GEM_BUG_ON(!HAS_LMEM(i915)); - } - } -#endif - ret = pci_enable_device(pdev); if (ret) goto out_fini; diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 9fa58ed76614..819341f77488 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -192,11 +192,6 @@ i915_param_named(enable_gvt, bool, 0400, "Enable support for Intel GVT-g graphics virtualization host support(default:false)"); #endif -#if IS_ENABLED(CONFIG_DRM_I915_UNSTABLE_FAKE_LMEM) -i915_param_named_unsafe(fake_lmem_start, ulong, 0400, - "Fake LMEM start offset (default: 0)"); -#endif - i915_param_named_unsafe(enable_eviction, uint, 0600, "Enable eviction which does not rely on DMA resv refactoring " "0=disabled, 1=memcpy based only, 2=blt based only, " diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index c835e592ee5f..ea6e99735ff2 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -70,7 +70,6 @@ struct drm_printer; param(int, fastboot, -1, 0600) \ param(int, enable_dpcd_backlight, -1, 0600) \ param(char *, force_probe, CONFIG_DRM_I915_FORCE_PROBE, 0400) \ - param(unsigned long, fake_lmem_start, 0, 0400) \ param(unsigned int, lmem_size, 0, 0400) \ param(unsigned int, enable_eviction, 3, 0600) \ /* leave bools at the end to not create holes */ \ diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c index 6b26b6cd5958..045efb9b01d9 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.c +++ b/drivers/gpu/drm/i915/intel_memory_region.c @@ -447,16 +447,7 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915) mem = i915_gem_stolen_setup(i915); break; case INTEL_MEMORY_LOCAL: -#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) - if (IS_ENABLED(CONFIG_DRM_I915_UNSTABLE_FAKE_LMEM)) { - if (INTEL_GEN(i915) >= 9 && i915_selftest.live < 0 && - i915->params.fake_lmem_start) - mem = intel_setup_fake_lmem(i915); - } -#endif - - if (IS_ERR(mem)) - mem = i915_gem_setup_lmem(i915); + mem = i915_gem_setup_lmem(i915); break; } diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c b/drivers/gpu/drm/i915/intel_region_lmem.c index 1cdb6354b968..e3f5ca619318 100644 --- a/drivers/gpu/drm/i915/intel_region_lmem.c +++ b/drivers/gpu/drm/i915/intel_region_lmem.c @@ -9,64 +9,9 @@ #include "gem/i915_gem_region.h" #include "intel_region_lmem.h" -static int init_fake_lmem_bar(struct intel_memory_region *mem) -{ - struct drm_i915_private *i915 = mem->i915; - struct i915_ggtt *ggtt = >ggtt; - unsigned long n; - int ret; - - /* We want to 1:1 map the mappable aperture to our reserved region */ - - mem->fake_mappable.start = 0; - mem->fake_mappable.size = resource_size(>region); - mem->fake_mappable.color = I915_COLOR_UNEVICTABLE; - - ret = drm_mm_reserve_node(>vm.mm, >fake_mappable); - if (ret) - return ret; - - mem->remap_addr = dma_map_resource(>drm.pdev->dev, - mem->region.start, -
[RFC PATCH 150/162] drm/i915: need consider system BO snoop for dgfx
From: CQ Tang When cache_level is NONE, we check HAS_LLC(i915). But additionally for DGFX, we also need to check HAS_SNOOP(i915) on system memory object to use I915_BO_CACHE_COHERENT_FOR_READ. on dg1, has_llc=0, and has_snoop=1. Otherwise, we set obj->cache_choerent=0 and have performance impact. Cc: Chris P Wilson Cc: Ramalingam C Cc: Sudeep Dutt Cc: Matthew Auld Signed-off-by: CQ Tang --- drivers/gpu/drm/i915/gem/i915_gem_object.c | 16 +++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c index ddb448f275eb..be603171c444 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c @@ -95,6 +95,20 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, mutex_init(>mm.get_dma_page.lock); } +static bool i915_gem_object_use_llc(struct drm_i915_gem_object *obj) +{ + struct drm_i915_private *i915 = to_i915(obj->base.dev); + + if (HAS_LLC(i915)) + return true; + + if (IS_DGFX(i915) && HAS_SNOOP(i915) && + !i915_gem_object_is_lmem(obj)) + return true; + + return false; +} + /** * Mark up the object's coherency levels for a given cache_level * @obj: #drm_i915_gem_object @@ -108,7 +122,7 @@ void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj, if (cache_level != I915_CACHE_NONE) obj->cache_coherent = (I915_BO_CACHE_COHERENT_FOR_READ | I915_BO_CACHE_COHERENT_FOR_WRITE); - else if (HAS_LLC(to_i915(obj->base.dev))) + else if (i915_gem_object_use_llc(obj)) obj->cache_coherent = I915_BO_CACHE_COHERENT_FOR_READ; else obj->cache_coherent = 0; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 148/162] drm/i915: suspend/resume enable blitter eviction
From: Venkata Ramana Nayana In suspend mode use blitter eviction before disable the runtime interrupts and in resume use blitter after the gem resume happens. Signed-off-by: Venkata Ramana Nayana Cc: Prathap Kumar Valsan --- drivers/gpu/drm/i915/i915_drv.c | 36 + 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 7115f4db5043..eb5383e4a30b 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1110,13 +1110,6 @@ static int intel_dmem_evict_buffers(struct drm_device *dev, bool in_suspend) struct intel_memory_region *mem; int id, ret = 0; - /* -* FIXME: Presently using memcpy, -* will replace with blitter once -* fix the issues. -*/ - i915->params.enable_eviction = 1; - for_each_memory_region(mem, i915, id) { struct list_head still_in_list; INIT_LIST_HEAD(_in_list); @@ -1173,7 +1166,6 @@ static int intel_dmem_evict_buffers(struct drm_device *dev, bool in_suspend) mutex_unlock(>objects.lock); } } - i915->params.enable_eviction = 3; return ret; } @@ -1235,6 +1227,18 @@ static int i915_drm_suspend(struct drm_device *dev) intel_dp_mst_suspend(dev_priv); + if (HAS_LMEM(dev_priv)) { + ret = intel_dmem_evict_buffers(dev, true); + if (ret) + return ret; + + i915_teardown_blt_windows(dev_priv); + + ret = i915_gem_suspend_ppgtt_mappings(dev_priv); + if (ret) + return ret; + } + intel_runtime_pm_disable_interrupts(dev_priv); intel_hpd_cancel_work(dev_priv); @@ -1251,18 +1255,6 @@ static int i915_drm_suspend(struct drm_device *dev) intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED, true); - if (HAS_LMEM(dev_priv)) { - ret = intel_dmem_evict_buffers(dev, true); - if (ret) - return ret; - - i915_teardown_blt_windows(dev_priv); - - ret = i915_gem_suspend_ppgtt_mappings(dev_priv); - if (ret) - return ret; - } - dev_priv->suspend_count++; intel_csr_ucode_suspend(dev_priv); @@ -1418,6 +1410,8 @@ static int i915_drm_resume(struct drm_device *dev) drm_mode_config_reset(dev); + i915_gem_resume(dev_priv); + if (HAS_LMEM(dev_priv)) { i915_gem_restore_ppgtt_mappings(dev_priv); @@ -1430,8 +1424,6 @@ static int i915_drm_resume(struct drm_device *dev) DRM_ERROR("i915_resume:i915_gem_object_pin_pages failed with err=%d\n", ret); } - i915_gem_resume(dev_priv); - intel_modeset_init_hw(dev_priv); intel_init_clock_gating(dev_priv); intel_hpd_init(dev_priv); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 152/162] drm/i915: Perform execbuffer object locking as a separate step
From: Thomas Hellström This is important to help avoid evicting already resident buffers from the batch we're processing. Signed-off-by: Thomas Hellström Cc: Matthew Auld --- .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 25 --- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index e73a761a7d1f..c988f8ffd39f 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -918,21 +918,38 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb) return err; } -static int eb_validate_vmas(struct i915_execbuffer *eb) +static int eb_lock_vmas(struct i915_execbuffer *eb) { unsigned int i; int err; - INIT_LIST_HEAD(>unbound); - for (i = 0; i < eb->buffer_count; i++) { - struct drm_i915_gem_exec_object2 *entry = >exec[i]; struct eb_vma *ev = >vma[i]; struct i915_vma *vma = ev->vma; err = i915_gem_object_lock(vma->obj, >ww); if (err) return err; + } + + return 0; +} + +static int eb_validate_vmas(struct i915_execbuffer *eb) +{ + unsigned int i; + int err; + + INIT_LIST_HEAD(>unbound); + + err = eb_lock_vmas(eb); + if (err) + return err; + + for (i = 0; i < eb->buffer_count; i++) { + struct drm_i915_gem_exec_object2 *entry = >exec[i]; + struct eb_vma *ev = >vma[i]; + struct i915_vma *vma = ev->vma; err = eb_pin_vma(eb, entry, ev); if (err == -EDEADLK) -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 149/162] drm/i915: suspend/resume handling of perma-pinned objects
From: Venkata Ramana Nayana The objects which are perma-pinned (like guc), use memcpy to evict these objects. Since the objects are always have pinned pages, so can't use present existing swapout/swapin functions. Signed-off-by: Venkata Ramana Nayana Cc: Prathap Kumar Valsan --- drivers/gpu/drm/i915/i915_drv.c | 105 +++- 1 file changed, 89 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index eb5383e4a30b..c8af68227020 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1103,7 +1103,54 @@ static int i915_drm_prepare(struct drm_device *dev) return 0; } -static int intel_dmem_evict_buffers(struct drm_device *dev, bool in_suspend) +static int i915_gem_perma_pinned_object_swapout(struct drm_i915_gem_object *obj) +{ + struct drm_i915_private *i915 = to_i915(obj->base.dev); + struct drm_i915_gem_object *dst; + int err = -EINVAL; + + assert_object_held(obj); + dst = i915_gem_object_create_shmem(i915, obj->base.size); + if (IS_ERR(dst)) + return PTR_ERR(dst); + + i915_gem_object_lock_isolated(dst); + err = i915_gem_object_memcpy(dst, obj); + i915_gem_object_unlock(dst); + + if (!err) { + obj->swapto = dst; + obj->evicted = true; + } else + i915_gem_object_put(dst); + + return err; +} + +static int i915_gem_perma_pinned_object_swapin(struct drm_i915_gem_object *obj) +{ + struct drm_i915_gem_object *src; + int err = -EINVAL; + + assert_object_held(obj); + src = obj->swapto; + + if (WARN_ON(!i915_gem_object_trylock(src))) + return -EBUSY; + + err = i915_gem_object_memcpy(obj, src); + i915_gem_object_unlock(src); + + if (!err) { + obj->swapto = NULL; + obj->evicted = false; + i915_gem_object_put(src); + } + return err; +} + +static int intel_dmem_evict_buffers(struct drm_device *dev, bool in_suspend, + bool perma_pin) { struct drm_i915_private *i915 = to_i915(dev); struct drm_i915_gem_object *obj; @@ -1133,24 +1180,37 @@ static int intel_dmem_evict_buffers(struct drm_device *dev, bool in_suspend) if (in_suspend) { obj->swapto = NULL; obj->evicted = false; - obj->do_swapping = true; - i915_gem_object_unbind(obj, 0); + ret = i915_gem_object_unbind(obj, 0); + if (ret || i915_gem_object_has_pinned_pages(obj)) { + if (!i915_gem_object_trylock(obj)) { + ret = -EBUSY; + goto next; + } + ret = i915_gem_perma_pinned_object_swapout(obj); + i915_gem_object_unlock(obj); + goto next; + } + obj->do_swapping = true; ret = __i915_gem_object_put_pages(obj); obj->do_swapping = false; - if (ret) { - /* -* FIXME: internal ctx objects still pinned -* returning as BUSY. Presently just evicting -* the user objects, will fix it later -*/ + if (ret) obj->evicted = false; - ret = 0; - } else + else obj->evicted = true; } else { - if (obj->swapto && obj->evicted) { + if (i915_gem_object_has_pinned_pages(obj) && perma_pin) { + if (!i915_gem_object_trylock(obj)) { + ret = -EBUSY; + goto next; + } + ret = i915_gem_perma_pinned_object_swapin(obj); +
[RFC PATCH 151/162] drm/i915: move eviction to prepare hook
From: Lucas De Marchi Signed-off-by: Lucas De Marchi --- drivers/gpu/drm/i915/i915_drv.c | 40 ++--- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c8af68227020..b7d40a9c00bf 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -68,6 +68,7 @@ #include "gt/intel_gt.h" #include "gt/intel_gt_pm.h" #include "gt/intel_rc6.h" +#include "gt/intel_gt_requests.h" #include "i915_debugfs.h" #include "i915_drv.h" @@ -1088,10 +1089,36 @@ static bool suspend_to_idle(struct drm_i915_private *dev_priv) return false; } +static int i915_gem_suspend_ppgtt_mappings(struct drm_i915_private *i915); + +static int intel_dmem_evict_buffers(struct drm_device *dev, bool in_suspend, + bool perma_pin); + static int i915_drm_prepare(struct drm_device *dev) { struct drm_i915_private *i915 = to_i915(dev); + if (HAS_LMEM(i915)) { + struct intel_gt *gt= >gt; + long timeout = I915_GEM_IDLE_TIMEOUT; + int ret; + + if (intel_gt_wait_for_idle(gt, timeout) == -ETIME) { + intel_gt_set_wedged(gt); + intel_gt_retire_requests(gt); + } + + ret = intel_dmem_evict_buffers(dev, true, false); + if (ret) + return ret; + + i915_teardown_blt_windows(i915); + + ret = i915_gem_suspend_ppgtt_mappings(i915); + if (ret) + return ret; + } + /* * NB intel_display_suspend() may issue new requests after we've * ostensibly marked the GPU as ready-to-sleep here. We need to @@ -1274,7 +1301,6 @@ static int i915_drm_suspend(struct drm_device *dev) struct drm_i915_private *dev_priv = to_i915(dev); struct pci_dev *pdev = dev_priv->drm.pdev; pci_power_t opregion_target_state; - int ret = 0; disable_rpm_wakeref_asserts(_priv->runtime_pm); @@ -1290,18 +1316,6 @@ static int i915_drm_suspend(struct drm_device *dev) intel_dp_mst_suspend(dev_priv); - if (HAS_LMEM(dev_priv)) { - ret = intel_dmem_evict_buffers(dev, true, false); - if (ret) - return ret; - - i915_teardown_blt_windows(dev_priv); - - ret = i915_gem_suspend_ppgtt_mappings(dev_priv); - if (ret) - return ret; - } - intel_runtime_pm_disable_interrupts(dev_priv); intel_hpd_cancel_work(dev_priv); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/omap: sdi: fix bridge enable/disable
When the SDI output was converted to DRM bridge, the atomic versions of enable and disable funcs were used. This was not intended, as that would require implementing other atomic funcs too. This leads to: WARNING: CPU: 0 PID: 18 at drivers/gpu/drm/drm_bridge.c:708 drm_atomic_helper_commit_modeset_enables+0x134/0x268 and display not working. Fix this by using the legacy enable/disable funcs. Signed-off-by: Tomi Valkeinen Reported-by: Aaro Koskinen Fixes: 8bef8a6d5da81b909a190822b96805a47348146f ("drm/omap: sdi: Register a drm_bridge") Cc: sta...@vger.kernel.org # v5.7+ Tested-by: Ivaylo Dimitrov --- drivers/gpu/drm/omapdrm/dss/sdi.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c index 033fd30074b0..282e4c837cd9 100644 --- a/drivers/gpu/drm/omapdrm/dss/sdi.c +++ b/drivers/gpu/drm/omapdrm/dss/sdi.c @@ -195,8 +195,7 @@ static void sdi_bridge_mode_set(struct drm_bridge *bridge, sdi->pixelclock = adjusted_mode->clock * 1000; } -static void sdi_bridge_enable(struct drm_bridge *bridge, - struct drm_bridge_state *bridge_state) +static void sdi_bridge_enable(struct drm_bridge *bridge) { struct sdi_device *sdi = drm_bridge_to_sdi(bridge); struct dispc_clock_info dispc_cinfo; @@ -259,8 +258,7 @@ static void sdi_bridge_enable(struct drm_bridge *bridge, regulator_disable(sdi->vdds_sdi_reg); } -static void sdi_bridge_disable(struct drm_bridge *bridge, - struct drm_bridge_state *bridge_state) +static void sdi_bridge_disable(struct drm_bridge *bridge) { struct sdi_device *sdi = drm_bridge_to_sdi(bridge); @@ -278,8 +276,8 @@ static const struct drm_bridge_funcs sdi_bridge_funcs = { .mode_valid = sdi_bridge_mode_valid, .mode_fixup = sdi_bridge_mode_fixup, .mode_set = sdi_bridge_mode_set, - .atomic_enable = sdi_bridge_enable, - .atomic_disable = sdi_bridge_disable, + .enable = sdi_bridge_enable, + .disable = sdi_bridge_disable, }; static void sdi_bridge_init(struct sdi_device *sdi) -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PULL] drm-misc-next
Hi Dave and Daniel, here's this week's PR for drm-misc-next. Many fixes and updates. The most important change is probably the amdgpu fix that unbreaks TTM multihop. Best regards Thomas drm-misc-next-2020-11-27-1: drm-misc-next for 5.11: UAPI Changes: Cross-subsystem Changes: * char/agp: Disable frontend without CONFIG_DRM_LEGACY * mm: Fix fput in mmap error path; Introduce vma_set_file() to change vma->vm_file Core Changes: * dma-buf: Use sgtables in system heap; Move heap helpers to CMA-heap code; Skip sync for unmapped buffers; Alloc higher order pages is available; Respect num_fences when initializing shared fence list * doc: Improvements around DRM modes and SCALING_FILTER * Pass full state to connector atomic functions + callee updates * Cleanups * shmem: Map pages with caching by default; Cleanups * ttm: Fix DMA32 for global page pool * fbdev: Cleanups * fb-helper: Update framebuffer after userspace writes; Unmap console buffer during shutdown; Rework damage handling of shadow framebuffer Driver Changes: * amdgpu: Multi-hop fixes, Clenaups * imx: Fix rotation for Vivante tiled formats; Support nearest-neighour skaling; Cleanups * mcde: Fix RGB formats; Support DPI output; Cleanups * meson: HDMI clock fixes * panel: Add driver and bindings for Innolux N125HCE-GN1 * panel/s6e63m0: More backlight levels; Fix init; Cleanups * via: Clenunps * virtio: Use fence ID for handling fences; Cleanups The following changes since commit fa388231fec99b60346319d56495ae531b666275: drm/docs: Fix todo.rst (2020-11-18 11:51:58 +0100) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-next-2020-11-27-1 for you to fetch changes up to 05faf1559de52465f1e753e31883aa294e6179c1: drm/imx/dcss: allow using nearest neighbor interpolation scaling (2020-11-26 11:29:44 +0100) drm-misc-next for 5.11: UAPI Changes: Cross-subsystem Changes: * char/agp: Disable frontend without CONFIG_DRM_LEGACY * mm: Fix fput in mmap error path; Introduce vma_set_file() to change vma->vm_file Core Changes: * dma-buf: Use sgtables in system heap; Move heap helpers to CMA-heap code; Skip sync for unmapped buffers; Alloc higher order pages is available; Respect num_fences when initializing shared fence list * doc: Improvements around DRM modes and SCALING_FILTER * Pass full state to connector atomic functions + callee updates * Cleanups * shmem: Map pages with caching by default; Cleanups * ttm: Fix DMA32 for global page pool * fbdev: Cleanups * fb-helper: Update framebuffer after userspace writes; Unmap console buffer during shutdown; Rework damage handling of shadow framebuffer Driver Changes: * amdgpu: Multi-hop fixes, Clenaups * imx: Fix rotation for Vivante tiled formats; Support nearest-neighour skaling; Cleanups * mcde: Fix RGB formats; Support DPI output; Cleanups * meson: HDMI clock fixes * panel: Add driver and bindings for Innolux N125HCE-GN1 * panel/s6e63m0: More backlight levels; Fix init; Cleanups * via: Clenunps * virtio: Use fence ID for handling fences; Cleanups Anthoine Bourgeois (3): drm/virtio: suffix create blob call with _ioctl like any ioctl drm/virtio: fix a file name comment reference virtio-gpu api: Add a comment on VIRTIO_GPU_SHM_ID_HOST_VISIBLE Bernard Zhao (1): drm/via: fix assignment in if condition Christian König (4): drm/amdgpu: fix check order in amdgpu_bo_move mm: mmap: fix fput in error path v2 mm: introduce vma_set_file function v5 drm/ttm: fix DMA32 handling in the global page pool Colin Ian King (1): drm/mcde: fix masking and bitwise-or on variable val Daniel Vetter (1): char/agp: Disable frontend without CONFIG_DRM_LEGACY Gurchetan Singh (2): drm/virtio: use fence_id when processing fences drm/virtio: rename sync_seq and last_seq Gustavo A. R. Silva (4): drm: Fix fall-through warnings for Clang drm/via: Fix fall-through warnings for Clang video: fbdev: lxfb_ops: Fix fall-through warnings for Clang video: fbdev: pm2fb: Fix fall-through warnings for Clang John Stultz (5): dma-buf: system_heap: Rework system heap to use sgtables instead of pagelists dma-buf: heaps: Move heap-helper logic into the cma_heap implementation dma-buf: heaps: Remove heap-helpers code dma-buf: heaps: Skip sync if not mapped dma-buf: system_heap: Allocate higher order pages if available Laurentiu Palcu (3): drm/imx/dcss: fix rotations for Vivante tiled formats drm/imx/dcss: fix coccinelle warning drm/imx/dcss: allow using nearest neighbor interpolation scaling Linus Walleij (7): drm/panel: s6e63m0: Fix and extend MCS table drm/panel: s6e63m0: Implement 28 backlight levels drm/panel: s6e63m0: Fix init
Re: [PATCH] drm/panfrost: fix reference leak in panfrost_job_hw_submit
On 27/11/2020 09:44, Qinglang Miao wrote: pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in a reference leak here. A new function pm_runtime_resume_and_get is introduced in [0] to keep usage counter balanced. So We fix the reference leak by replacing it with new funtion. [0] dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") Fixes: f3ba91228e8e ("drm/panfrost: Add initial panfrost driver") Reported-by: Hulk Robot Signed-off-by: Qinglang Miao --- drivers/gpu/drm/panfrost/panfrost_job.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c index 30e7b7196..04cf3bb67 100644 --- a/drivers/gpu/drm/panfrost/panfrost_job.c +++ b/drivers/gpu/drm/panfrost/panfrost_job.c @@ -147,7 +147,7 @@ static void panfrost_job_hw_submit(struct panfrost_job *job, int js) panfrost_devfreq_record_busy(>pfdevfreq); - ret = pm_runtime_get_sync(pfdev->dev); + ret = pm_runtime_resume_and_get(pfdev->dev); Sorry, but in this case this change isn't correct. panfrost_job_hw_submit() is expected to be unbalanced (the PM reference count is expected to be incremented on return). In the case where pm_runtime_get_sync() fails, the job will eventually timeout, and there's a corresponding pm_runtime_put_noidle() in panfrost_reset(). Potentially this could be handled better (e.g. without waiting for the timeout to occur), but equally this isn't something we expect to happen in normal operation). Steve if (ret < 0) return; ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH drm/hisilicon 1/3] drm/hisilicon: Code refactoring for hibmc_drm_drv
Use the devm_drm_dev_alloc provided by the drm framework to alloc a struct hibmc_drm_private. Signed-off-by: Tian Tao --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 51 +++- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c | 8 ++-- 5 files changed, 31 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c index ea962ac..096eea9 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c @@ -499,7 +499,7 @@ static const struct drm_crtc_helper_funcs hibmc_crtc_helper_funcs = { int hibmc_de_init(struct hibmc_drm_private *priv) { - struct drm_device *dev = priv->dev; + struct drm_device *dev = >dev; struct drm_crtc *crtc = >crtc; struct drm_plane *plane = >primary_plane; int ret; diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index d845657..ea3d81b 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -80,30 +80,31 @@ static const struct dev_pm_ops hibmc_pm_ops = { static int hibmc_kms_init(struct hibmc_drm_private *priv) { int ret; + struct drm_device *dev = >dev; - drm_mode_config_init(priv->dev); + drm_mode_config_init(dev); priv->mode_config_initialized = true; - priv->dev->mode_config.min_width = 0; - priv->dev->mode_config.min_height = 0; - priv->dev->mode_config.max_width = 1920; - priv->dev->mode_config.max_height = 1200; + dev->mode_config.min_width = 0; + dev->mode_config.min_height = 0; + dev->mode_config.max_width = 1920; + dev->mode_config.max_height = 1200; - priv->dev->mode_config.fb_base = priv->fb_base; - priv->dev->mode_config.preferred_depth = 32; - priv->dev->mode_config.prefer_shadow = 1; + dev->mode_config.fb_base = priv->fb_base; + dev->mode_config.preferred_depth = 32; + dev->mode_config.prefer_shadow = 1; - priv->dev->mode_config.funcs = (void *)_mode_funcs; + dev->mode_config.funcs = (void *)_mode_funcs; ret = hibmc_de_init(priv); if (ret) { - drm_err(priv->dev, "failed to init de: %d\n", ret); + drm_err(dev, "failed to init de: %d\n", ret); return ret; } ret = hibmc_vdac_init(priv); if (ret) { - drm_err(priv->dev, "failed to init vdac: %d\n", ret); + drm_err(dev, "failed to init vdac: %d\n", ret); return ret; } @@ -113,7 +114,7 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) static void hibmc_kms_fini(struct hibmc_drm_private *priv) { if (priv->mode_config_initialized) { - drm_mode_config_cleanup(priv->dev); + drm_mode_config_cleanup(>dev); priv->mode_config_initialized = false; } } @@ -202,7 +203,7 @@ static void hibmc_hw_config(struct hibmc_drm_private *priv) static int hibmc_hw_map(struct hibmc_drm_private *priv) { - struct drm_device *dev = priv->dev; + struct drm_device *dev = >dev; struct pci_dev *pdev = dev->pdev; resource_size_t addr, size, ioaddr, iosize; @@ -258,17 +259,9 @@ static int hibmc_unload(struct drm_device *dev) static int hibmc_load(struct drm_device *dev) { - struct hibmc_drm_private *priv; + struct hibmc_drm_private *priv = dev->dev_private; int ret; - priv = drmm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - drm_err(dev, "no memory to allocate for hibmc_drm_private\n"); - return -ENOMEM; - } - dev->dev_private = priv; - priv->dev = dev; - ret = hibmc_hw_init(priv); if (ret) goto err; @@ -310,6 +303,7 @@ static int hibmc_load(struct drm_device *dev) static int hibmc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + struct hibmc_drm_private *priv; struct drm_device *dev; int ret; @@ -318,19 +312,22 @@ static int hibmc_pci_probe(struct pci_dev *pdev, if (ret) return ret; - dev = drm_dev_alloc(_driver, >dev); - if (IS_ERR(dev)) { + priv = devm_drm_dev_alloc(>dev, _driver, + struct hibmc_drm_private, dev); + if (IS_ERR(priv)) { DRM_ERROR("failed to allocate drm_device\n"); - return PTR_ERR(dev); + return PTR_ERR(priv); } + dev = >dev; + dev->dev_private = priv; dev->pdev = pdev; pci_set_drvdata(pdev, dev);
[PULL] drm-misc-fixes
Hi Dave, Daniel, Here's this week round of fixes for drm-misc Maxime drm-misc-fixes-2020-11-26: A bunch of fixes for vc4 fixing some coexistence issue between wifi and HDMI, unsupported modes, and vblank timeouts, a fix for ast to reload the gamma LUT after changing the plane format and a double-free fix for nouveau The following changes since commit cdf117d6d38a127026e74114d63f32972f620c06: Merge tag 'drm/sun4i-dma-fix-pull-request' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/mripard/linux into drm-misc-fixes (2020-11-19 09:26:07 +0100) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-fixes-2020-11-26 for you to fetch changes up to 2be65641642ef423f82162c3a5f28c754d1637d2: drm/nouveau: fix relocations applying logic and a double-free (2020-11-26 08:04:19 +0100) A bunch of fixes for vc4 fixing some coexistence issue between wifi and HDMI, unsupported modes, and vblank timeouts, a fix for ast to reload the gamma LUT after changing the plane format and a double-free fix for nouveau Matti Hamalainen (1): drm/nouveau: fix relocations applying logic and a double-free Maxime Ripard (11): drm/vc4: hdmi: Make sure our clock rate is within limits drm/vc4: hdmi: Block odd horizontal timings drm/vc4: kms: Switch to drmm_add_action_or_reset drm/vc4: kms: Remove useless define drm/vc4: kms: Rename NUM_CHANNELS drm/vc4: kms: Split the HVS muxing check in a separate function drm/vc4: kms: Document the muxing corner cases dt-bindings: display: Add a property to deal with WiFi coexistence drm/vc4: hdmi: Disable Wifi Frequencies drm/vc4: kms: Store the unassigned channel list in the state drm/vc4: kms: Don't disable the muxing of an active CRTC Thomas Zimmermann (1): drm/ast: Reload gamma LUT after changing primary plane's color format .../bindings/display/brcm,bcm2711-hdmi.yaml| 6 + drivers/gpu/drm/ast/ast_mode.c | 17 +- drivers/gpu/drm/nouveau/nouveau_gem.c | 8 +- drivers/gpu/drm/vc4/vc4_drv.h | 4 + drivers/gpu/drm/vc4/vc4_hdmi.c | 48 drivers/gpu/drm/vc4/vc4_hdmi.h | 11 + drivers/gpu/drm/vc4/vc4_kms.c | 246 +++-- 7 files changed, 272 insertions(+), 68 deletions(-) signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm: rcar-du: fix reference leak in amdgpu_debugfs_gfxoff_read
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in a reference leak here. A new function pm_runtime_resume_and_get is introduced in [0] to keep usage counter balanced. So We fix the reference leak by replacing it with new funtion. [0] dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") Fixes: e08e934d6c28 ("drm: rcar-du: Add support for CMM") Reported-by: Hulk Robot Signed-off-by: Qinglang Miao --- drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index 2d125b8b1..05de69a97 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -1096,7 +1096,7 @@ static ssize_t amdgpu_debugfs_gfxoff_read(struct file *f, char __user *buf, if (size & 0x3 || *pos & 0x3) return -EINVAL; - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); + r = pm_runtime_resume_and_get(adev_to_drm(adev)->dev); if (r < 0) return r; -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/armada: Remove redundant null check before clk_disable_unprepare
Because clk_disable_unprepare() already checked NULL clock parameter, so the additional check is unnecessary, just remove it. Signed-off-by: Xu Wang --- drivers/gpu/drm/armada/armada_510.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_510.c b/drivers/gpu/drm/armada/armada_510.c index 93d5c0a2d49a..05fe97900b13 100644 --- a/drivers/gpu/drm/armada/armada_510.c +++ b/drivers/gpu/drm/armada/armada_510.c @@ -132,10 +132,8 @@ static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc, static void armada510_crtc_disable(struct armada_crtc *dcrtc) { - if (dcrtc->clk) { - clk_disable_unprepare(dcrtc->clk); - dcrtc->clk = NULL; - } + clk_disable_unprepare(dcrtc->clk); + dcrtc->clk = NULL; } static void armada510_crtc_enable(struct armada_crtc *dcrtc, -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/2] drm/bridge/lontium-lt9611uxc: fix waiting for EDID to become available
- Call wake_up() when EDID ready event is received to wake wait_event_interruptible_timeout() - Increase waiting timeout, reading EDID can take longer than 100ms, so let's be on a safe side. - Return NULL pointer from get_edid() callback rather than ERR_PTR() pointer, as DRM code does NULL checks rather than IS_ERR(). Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index 0c98d27f84ac..b708700e182d 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -145,8 +145,10 @@ static irqreturn_t lt9611uxc_irq_thread_handler(int irq, void *dev_id) lt9611uxc_unlock(lt9611uxc); - if (irq_status & BIT(0)) + if (irq_status & BIT(0)) { lt9611uxc->edid_read = !!(hpd_status & BIT(0)); + wake_up_all(>wq); + } if (irq_status & BIT(1)) { if (lt9611uxc->connector.dev) @@ -465,7 +467,7 @@ static enum drm_connector_status lt9611uxc_bridge_detect(struct drm_bridge *brid static int lt9611uxc_wait_for_edid(struct lt9611uxc *lt9611uxc) { return wait_event_interruptible_timeout(lt9611uxc->wq, lt9611uxc->edid_read, - msecs_to_jiffies(100)); + msecs_to_jiffies(500)); } static int lt9611uxc_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len) @@ -503,7 +505,10 @@ static struct edid *lt9611uxc_bridge_get_edid(struct drm_bridge *bridge, ret = lt9611uxc_wait_for_edid(lt9611uxc); if (ret < 0) { dev_err(lt9611uxc->dev, "wait for EDID failed: %d\n", ret); - return ERR_PTR(ret); + return NULL; + } else if (ret == 0) { + dev_err(lt9611uxc->dev, "wait for EDID timeout\n"); + return NULL; } return drm_do_get_edid(connector, lt9611uxc_get_edid_block, lt9611uxc); -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/lima: fix reference leak in lima_pm_busy
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in a reference leak here. A new function pm_runtime_resume_and_get is introduced in [0] to keep usage counter balanced. So We fix the reference leak by replacing it with new funtion. [0] dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") Fixes: 50de2e9ebbc0 ("drm/lima: enable runtime pm") Reported-by: Hulk Robot Signed-off-by: Qinglang Miao --- drivers/gpu/drm/lima/lima_sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c index dc6df9e9a..f6e7a88a5 100644 --- a/drivers/gpu/drm/lima/lima_sched.c +++ b/drivers/gpu/drm/lima/lima_sched.c @@ -200,7 +200,7 @@ static int lima_pm_busy(struct lima_device *ldev) int ret; /* resume GPU if it has been suspended by runtime PM */ - ret = pm_runtime_get_sync(ldev->dev); + ret = pm_runtime_resume_and_get(ldev->dev); if (ret < 0) return ret; -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH drm/hisilicon 3/3] drm/hisilicon: Use the new api devm_drm_irq_install
Use devm_drm_irq_install to register interrupts so that drm_irq_uninstall is not called when hibmc is removed. Signed-off-by: Tian Tao --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index ea3d81b..77792e3 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -247,9 +247,6 @@ static int hibmc_unload(struct drm_device *dev) drm_atomic_helper_shutdown(dev); - if (dev->irq_enabled) - drm_irq_uninstall(dev); - pci_disable_msi(dev->pdev); hibmc_kms_fini(priv); hibmc_mm_fini(priv); @@ -284,7 +281,7 @@ static int hibmc_load(struct drm_device *dev) if (ret) { drm_warn(dev, "enabling MSI failed: %d\n", ret); } else { - ret = drm_irq_install(dev, dev->pdev->irq); + ret = devm_drm_irq_install(dev, dev->pdev->irq); if (ret) drm_warn(dev, "install irq failed: %d\n", ret); } -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/mediatek: fix reference leak in mtk_crtc_ddp_hw_init
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in a reference leak here. A new function pm_runtime_resume_and_get is introduced in [0] to keep usage counter balanced. So We fix the reference leak by replacing it with new funtion. [0] dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.") Reported-by: Hulk Robot Signed-off-by: Qinglang Miao --- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index ac0385721..dfd5ed15a 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -274,7 +274,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc) drm_connector_list_iter_end(_iter); } - ret = pm_runtime_get_sync(crtc->dev->dev); + ret = pm_runtime_resume_and_get(crtc->dev->dev); if (ret < 0) { DRM_ERROR("Failed to enable power domain: %d\n", ret); return ret; -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/msm: Fix use-after-free in msm_gem with carveout
When using gem with vram carveout the page allocation is managed via drm_mm. The necessary drm_mm_node is allocated in add_vma, but it freed before the drm_mm_node has been deallocated leading to use-after-free on every single vram allocation. Currently put_iova is called before free_object. put_iova -> del_vma -> kfree(vma) // vma holds drm_mm_node free_object -> put_pages -> put_pages_vram -> drm_mm_remove_node It looks like del_vma does nothing else other than freeing the vma object and removing it from it's list, so delaying the deletion should be harmless. This patch splits put_iova in put_iova_spaces and put_iova_vmas, so the vma can be freed after the mm_node has been deallocated with the mm. Signed-off-by: Iskren Chernev --- drivers/gpu/drm/msm/msm_gem.c | 27 ++- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 15715a156620f..b83247202ea5d 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -355,18 +355,31 @@ static void del_vma(struct msm_gem_vma *vma) /* Called with msm_obj locked */ static void -put_iova(struct drm_gem_object *obj) +put_iova_spaces(struct drm_gem_object *obj) { struct msm_gem_object *msm_obj = to_msm_bo(obj); - struct msm_gem_vma *vma, *tmp; + struct msm_gem_vma *vma; WARN_ON(!msm_gem_is_locked(obj)); - list_for_each_entry_safe(vma, tmp, _obj->vmas, list) { + list_for_each_entry(vma, _obj->vmas, list) { if (vma->aspace) { msm_gem_purge_vma(vma->aspace, vma); msm_gem_close_vma(vma->aspace, vma); } + } +} + +/* Called with msm_obj locked */ +static void +put_iova_vmas(struct drm_gem_object *obj) +{ + struct msm_gem_object *msm_obj = to_msm_bo(obj); + struct msm_gem_vma *vma, *tmp; + + WARN_ON(!mutex_is_locked(_obj->lock)); + + list_for_each_entry_safe(vma, tmp, _obj->vmas, list) { del_vma(vma); } } @@ -688,12 +701,14 @@ void msm_gem_purge(struct drm_gem_object *obj) WARN_ON(!is_purgeable(msm_obj)); WARN_ON(obj->import_attach); - put_iova(obj); + put_iova_spaces(obj); msm_gem_vunmap(obj); put_pages(obj); + put_iova_vmas(obj); + msm_obj->madv = __MSM_MADV_PURGED; drm_vma_node_unmap(>vma_node, dev->anon_inode->i_mapping); @@ -942,7 +957,7 @@ void msm_gem_free_object(struct drm_gem_object *obj) msm_gem_lock(obj); - put_iova(obj); + put_iova_spaces(obj); if (obj->import_attach) { WARN_ON(msm_obj->vaddr); @@ -965,6 +980,8 @@ void msm_gem_free_object(struct drm_gem_object *obj) msm_gem_unlock(obj); } + put_iova_vma(obj); + drm_gem_object_release(obj); kfree(msm_obj); base-commit: 6147c83fd749d19a0d3ccc2f64d12138ab010b47 -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm: bridge: adv7511: Remove redundant null check before clk_disable_unprepare
Because clk_disable_unprepare() already checked NULL clock parameter, so the additional check is unnecessary, just remove them. Signed-off-by: Xu Wang --- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index a0d392c338da..76555ae64e9c 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1292,8 +1292,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) err_unregister_cec: i2c_unregister_device(adv7511->i2c_cec); - if (adv7511->cec_clk) - clk_disable_unprepare(adv7511->cec_clk); + clk_disable_unprepare(adv7511->cec_clk); err_i2c_unregister_packet: i2c_unregister_device(adv7511->i2c_packet); err_i2c_unregister_edid: @@ -1311,8 +1310,7 @@ static int adv7511_remove(struct i2c_client *i2c) if (adv7511->type == ADV7533 || adv7511->type == ADV7535) adv7533_detach_dsi(adv7511); i2c_unregister_device(adv7511->i2c_cec); - if (adv7511->cec_clk) - clk_disable_unprepare(adv7511->cec_clk); + clk_disable_unprepare(adv7511->cec_clk); adv7511_uninit_regulators(adv7511); -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/panfrost: fix reference leak in panfrost_job_hw_submit
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in a reference leak here. A new function pm_runtime_resume_and_get is introduced in [0] to keep usage counter balanced. So We fix the reference leak by replacing it with new funtion. [0] dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") Fixes: f3ba91228e8e ("drm/panfrost: Add initial panfrost driver") Reported-by: Hulk Robot Signed-off-by: Qinglang Miao --- drivers/gpu/drm/panfrost/panfrost_job.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c index 30e7b7196..04cf3bb67 100644 --- a/drivers/gpu/drm/panfrost/panfrost_job.c +++ b/drivers/gpu/drm/panfrost/panfrost_job.c @@ -147,7 +147,7 @@ static void panfrost_job_hw_submit(struct panfrost_job *job, int js) panfrost_devfreq_record_busy(>pfdevfreq); - ret = pm_runtime_get_sync(pfdev->dev); + ret = pm_runtime_resume_and_get(pfdev->dev); if (ret < 0) return; -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] fbdev: aty: SPARC64 requires FB_ATY_CT
On 11/26/20 12:29 AM, Geert Uytterhoeven wrote: > Hi Randy, > > On Thu, Nov 26, 2020 at 1:40 AM Randy Dunlap wrote: >> It looks like SPARC64 requires FB_ATY_CT to build without errors, >> so adjust the Kconfig entry of FB_ATY_CT so that it is always 'y' >> for SPARC64 && PCI by disabling the prompt for SPARC64 && PCI. >> >> As it currently is, FB_ATY_CT can be disabled, resulting in build >> errors: >> >> ERROR: modpost: "aty_postdividers" [drivers/video/fbdev/aty/atyfb.ko] >> undefined! >> ERROR: modpost: "aty_ld_pll_ct" [drivers/video/fbdev/aty/atyfb.ko] undefined! >> >> Fixes: f7018c213502 ("video: move fbdev to drivers/video/fbdev") >> Signed-off-by: Randy Dunlap > > Thanks for your patch! > >> --- linux-next-20201124.orig/drivers/video/fbdev/Kconfig >> +++ linux-next-20201124/drivers/video/fbdev/Kconfig >> @@ -1277,7 +1277,7 @@ config FB_ATY >> module will be called atyfb. >> >> config FB_ATY_CT >> - bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support" >> + bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support" if !(SPARC64 && >> PCI) >> depends on PCI && FB_ATY >> default y if SPARC64 && PCI >> help > > What about letting FB_ATY select FB_ATY_CT if SPARC64 && PCI, and > dropping the "default y"-line, instead? Sure, I'll try it that way and repost. thanks. -- ~Randy ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 066/162] drm/i915/selftests: Prepare i915_request tests for obj->mm.lock removal
From: Maarten Lankhorst Straightforward conversion by using unlocked versions. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/selftests/i915_request.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c index e424a6d1a68c..514fa109e40f 100644 --- a/drivers/gpu/drm/i915/selftests/i915_request.c +++ b/drivers/gpu/drm/i915/selftests/i915_request.c @@ -619,7 +619,7 @@ static struct i915_vma *empty_batch(struct drm_i915_private *i915) if (IS_ERR(obj)) return ERR_CAST(obj); - cmd = i915_gem_object_pin_map(obj, I915_MAP_WB); + cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB); if (IS_ERR(cmd)) { err = PTR_ERR(cmd); goto err; @@ -781,7 +781,7 @@ static struct i915_vma *recursive_batch(struct drm_i915_private *i915) if (err) goto err; - cmd = i915_gem_object_pin_map(obj, I915_MAP_WC); + cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC); if (IS_ERR(cmd)) { err = PTR_ERR(cmd); goto err; @@ -816,7 +816,7 @@ static int recursive_batch_resolve(struct i915_vma *batch) { u32 *cmd; - cmd = i915_gem_object_pin_map(batch->obj, I915_MAP_WC); + cmd = i915_gem_object_pin_map_unlocked(batch->obj, I915_MAP_WC); if (IS_ERR(cmd)) return PTR_ERR(cmd); @@ -1069,8 +1069,8 @@ static int live_sequential_engines(void *arg) if (!request[idx]) break; - cmd = i915_gem_object_pin_map(request[idx]->batch->obj, - I915_MAP_WC); + cmd = i915_gem_object_pin_map_unlocked(request[idx]->batch->obj, + I915_MAP_WC); if (!IS_ERR(cmd)) { *cmd = MI_BATCH_BUFFER_END; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 064/162] drm/i915/selftests: Prepare ring submission for obj->mm.lock removal
From: Maarten Lankhorst Use unlocked versions when the ww lock is not held. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gt/selftest_ring_submission.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/selftest_ring_submission.c b/drivers/gpu/drm/i915/gt/selftest_ring_submission.c index 3350e7c995bc..99609271c3a7 100644 --- a/drivers/gpu/drm/i915/gt/selftest_ring_submission.c +++ b/drivers/gpu/drm/i915/gt/selftest_ring_submission.c @@ -35,7 +35,7 @@ static struct i915_vma *create_wally(struct intel_engine_cs *engine) return ERR_PTR(err); } - cs = i915_gem_object_pin_map(obj, I915_MAP_WC); + cs = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC); if (IS_ERR(cs)) { i915_gem_object_put(obj); return ERR_CAST(cs); @@ -212,7 +212,7 @@ static int __live_ctx_switch_wa(struct intel_engine_cs *engine) if (IS_ERR(bb)) return PTR_ERR(bb); - result = i915_gem_object_pin_map(bb->obj, I915_MAP_WC); + result = i915_gem_object_pin_map_unlocked(bb->obj, I915_MAP_WC); if (IS_ERR(result)) { intel_context_put(bb->private); i915_vma_unpin_and_release(, 0); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 070/162] drm/i915: Finally remove obj->mm.lock.
From: Maarten Lankhorst With all callers and selftests fixed to use ww locking, we can now finally remove this lock. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_object.c| 2 - drivers/gpu/drm/i915/gem/i915_gem_object.h| 7 ++-- .../gpu/drm/i915/gem/i915_gem_object_types.h | 1 - drivers/gpu/drm/i915/gem/i915_gem_pages.c | 38 --- drivers/gpu/drm/i915/gem/i915_gem_phys.c | 34 - drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 37 +- drivers/gpu/drm/i915/gem/i915_gem_shrinker.h | 4 +- drivers/gpu/drm/i915/gem/i915_gem_tiling.c| 2 - drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 3 +- drivers/gpu/drm/i915/i915_debugfs.c | 4 +- drivers/gpu/drm/i915/i915_gem.c | 8 +--- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- 13 files changed, 54 insertions(+), 90 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c index 028a556ab1a5..08d806bbf48e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c @@ -62,8 +62,6 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, const struct drm_i915_gem_object_ops *ops, struct lock_class_key *key, unsigned flags) { - mutex_init(>mm.lock); - spin_lock_init(>vma.lock); INIT_LIST_HEAD(>vma.list); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index 1d4b44151e0c..d0cc62d1c65e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -136,7 +136,7 @@ static inline void assert_object_held_shared(struct drm_i915_gem_object *obj) */ if (IS_ENABLED(CONFIG_LOCKDEP) && kref_read(>base.refcount) > 0) - lockdep_assert_held(>mm.lock); + assert_object_held(obj); } static inline int __i915_gem_object_lock(struct drm_i915_gem_object *obj, @@ -350,11 +350,11 @@ int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj); static inline int __must_check i915_gem_object_pin_pages(struct drm_i915_gem_object *obj) { - might_lock(>mm.lock); - if (atomic_inc_not_zero(>mm.pages_pin_count)) return 0; + assert_object_held(obj); + return __i915_gem_object_get_pages(obj); } @@ -396,7 +396,6 @@ i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj) } int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj); -int __i915_gem_object_put_pages_locked(struct drm_i915_gem_object *obj); void i915_gem_object_truncate(struct drm_i915_gem_object *obj); void i915_gem_object_writeback(struct drm_i915_gem_object *obj); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h index 5234c1ed62d4..b172e8cc53ab 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h @@ -209,7 +209,6 @@ struct drm_i915_gem_object { * Protects the pages and their use. Do not use directly, but * instead go through the pin/unpin interfaces. */ - struct mutex lock; atomic_t pages_pin_count; atomic_t shrink_pin; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index 79336735a6e4..4a8be759832b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -67,7 +67,7 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, struct list_head *list; unsigned long flags; - lockdep_assert_held(>mm.lock); + assert_object_held(obj); spin_lock_irqsave(>mm.obj_lock, flags); i915->mm.shrink_count++; @@ -114,9 +114,7 @@ int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj) { int err; - err = mutex_lock_interruptible(>mm.lock); - if (err) - return err; + assert_object_held(obj); assert_object_held_shared(obj); @@ -125,15 +123,13 @@ int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj) err = i915_gem_object_get_pages(obj); if (err) - goto unlock; + return err; smp_mb__before_atomic(); } atomic_inc(>mm.pages_pin_count); -unlock: - mutex_unlock(>mm.lock); - return err; + return 0; } int i915_gem_object_pin_pages_unlocked(struct drm_i915_gem_object *obj) @@ -220,7 +216,7 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj) return pages; } -int
[RFC PATCH 068/162] drm/i915/selftests: Prepare cs engine tests for obj->mm.lock removal
From: Maarten Lankhorst Same as other tests, use pin_map_unlocked. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gt/selftest_engine_cs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/selftest_engine_cs.c b/drivers/gpu/drm/i915/gt/selftest_engine_cs.c index 729c3c7b11e2..853d1f02131a 100644 --- a/drivers/gpu/drm/i915/gt/selftest_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/selftest_engine_cs.c @@ -72,7 +72,7 @@ static struct i915_vma *create_empty_batch(struct intel_context *ce) if (IS_ERR(obj)) return ERR_CAST(obj); - cs = i915_gem_object_pin_map(obj, I915_MAP_WB); + cs = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB); if (IS_ERR(cs)) { err = PTR_ERR(cs); goto err_put; @@ -208,7 +208,7 @@ static struct i915_vma *create_nop_batch(struct intel_context *ce) if (IS_ERR(obj)) return ERR_CAST(obj); - cs = i915_gem_object_pin_map(obj, I915_MAP_WB); + cs = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB); if (IS_ERR(cs)) { err = PTR_ERR(cs); goto err_put; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 069/162] drm/i915/selftests: Prepare gtt tests for obj->mm.lock removal
From: Maarten Lankhorst We need to lock the global gtt dma_resv, use i915_vm_lock_objects to handle this correctly. Add ww handling for this where required. Add the object lock around unpin/put pages, and use the unlocked versions of pin_pages and pin_map where required. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 92 ++- 1 file changed, 67 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index 2cfe99c79034..d07dd6780005 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c @@ -129,7 +129,7 @@ fake_dma_object(struct drm_i915_private *i915, u64 size) obj->cache_level = I915_CACHE_NONE; /* Preallocate the "backing storage" */ - if (i915_gem_object_pin_pages(obj)) + if (i915_gem_object_pin_pages_unlocked(obj)) goto err_obj; i915_gem_object_unpin_pages(obj); @@ -145,6 +145,7 @@ static int igt_ppgtt_alloc(void *arg) { struct drm_i915_private *dev_priv = arg; struct i915_ppgtt *ppgtt; + struct i915_gem_ww_ctx ww; u64 size, last, limit; int err = 0; @@ -170,6 +171,12 @@ static int igt_ppgtt_alloc(void *arg) limit = totalram_pages() << PAGE_SHIFT; limit = min(ppgtt->vm.total, limit); + i915_gem_ww_ctx_init(, false); +retry: + err = i915_vm_lock_objects(>vm, ); + if (err) + goto err_ppgtt_cleanup; + /* Check we can allocate the entire range */ for (size = 4096; size <= limit; size <<= 2) { struct i915_vm_pt_stash stash = {}; @@ -214,6 +221,13 @@ static int igt_ppgtt_alloc(void *arg) } err_ppgtt_cleanup: + if (err == -EDEADLK) { + err = i915_gem_ww_ctx_backoff(); + if (!err) + goto retry; + } + i915_gem_ww_ctx_fini(); + i915_vm_put(>vm); return err; } @@ -275,7 +289,7 @@ static int lowlevel_hole(struct i915_address_space *vm, GEM_BUG_ON(obj->base.size != BIT_ULL(size)); - if (i915_gem_object_pin_pages(obj)) { + if (i915_gem_object_pin_pages_unlocked(obj)) { i915_gem_object_put(obj); kfree(order); break; @@ -296,20 +310,36 @@ static int lowlevel_hole(struct i915_address_space *vm, if (vm->allocate_va_range) { struct i915_vm_pt_stash stash = {}; + struct i915_gem_ww_ctx ww; + int err; + + i915_gem_ww_ctx_init(, false); +retry: + err = i915_vm_lock_objects(vm, ); + if (err) + goto alloc_vm_end; + err = -ENOMEM; if (i915_vm_alloc_pt_stash(vm, , BIT_ULL(size))) - break; - - if (i915_vm_pin_pt_stash(vm, )) { - i915_vm_free_pt_stash(vm, ); - break; - } + goto alloc_vm_end; - vm->allocate_va_range(vm, , - addr, BIT_ULL(size)); + err = i915_vm_pin_pt_stash(vm, ); + if (!err) + vm->allocate_va_range(vm, , + addr, BIT_ULL(size)); i915_vm_free_pt_stash(vm, ); +alloc_vm_end: + if (err == -EDEADLK) { + err = i915_gem_ww_ctx_backoff(); + if (!err) + goto retry; + } + i915_gem_ww_ctx_fini(); + + if (err) + break; } mock_vma->pages = obj->mm.pages; @@ -1165,7 +1195,7 @@ static int igt_ggtt_page(void *arg) if (IS_ERR(obj)) return PTR_ERR(obj); - err = i915_gem_object_pin_pages(obj); + err = i915_gem_object_pin_pages_unlocked(obj); if (err) goto out_free; @@ -1332,7 +1362,7 @@ static int igt_gtt_reserve(void *arg) goto out; } - err = i915_gem_object_pin_pages(obj); + err = i915_gem_object_pin_pages_unlocked(obj);
[RFC PATCH 073/162] drm/i915: Reference contending lock objects
From: Thomas Hellström When we lock objects in leaf functions, for example during eviction, they may disappear as soon as we unreference them, and the locking context contended pointer then points to a free object. Fix this by taking a reference on that object, and also unlock the contending object as soon as we've done the ww transaction relaxation: The restarted transaction may not even need the contending object, and keeping the lock is not needed to prevent starvation. Keeping that lock will unnecessarily requiring us to reference count all locks on the list and also creates locking confusion around -EALREADY. Signed-off-by: Thomas Hellström Cc: Matthew Auld --- drivers/gpu/drm/i915/gem/i915_gem_object.h | 2 +- drivers/gpu/drm/i915/i915_gem.c| 9 - 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index d56643b3b518..60e27738c39d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -163,7 +163,7 @@ static inline int __i915_gem_object_lock(struct drm_i915_gem_object *obj, ret = 0; if (ret == -EDEADLK) - ww->contended = obj; + ww->contended = i915_gem_object_get(obj); return ret; } diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ef66c0926af6..2248e65cf5f9 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1370,9 +1370,16 @@ int __must_check i915_gem_ww_ctx_backoff(struct i915_gem_ww_ctx *ww) else dma_resv_lock_slow(ww->contended->base.resv, >ctx); + /* +* Unlocking the contended lock again, as might not need it in +* the retried transaction. This does not increase starvation, +* but it's opening up for a wakeup flood if there are many +* transactions relaxing on this object. +*/ if (!ret) - list_add_tail(>contended->obj_link, >obj_list); + dma_resv_unlock(ww->contended->base.resv); + i915_gem_object_put(ww->contended); ww->contended = NULL; return ret; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 074/162] drm/i915: Break out dma_resv ww locking utilities to separate files
From: Thomas Hellström As we're about to add more ww-related functionality, break out the dma_resv ww locking utilities to their own files Signed-off-by: Thomas Hellström Cc: Matthew Auld --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/gem/i915_gem_object.h | 1 + drivers/gpu/drm/i915/gt/intel_renderstate.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 59 -- drivers/gpu/drm/i915/i915_gem.h | 12 drivers/gpu/drm/i915/i915_gem_ww.c | 66 + drivers/gpu/drm/i915/i915_gem_ww.h | 21 +++ 7 files changed, 90 insertions(+), 71 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_gem_ww.c create mode 100644 drivers/gpu/drm/i915/i915_gem_ww.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 5112e5d79316..ec361d61230b 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -45,6 +45,7 @@ i915-y += i915_drv.o \ i915_switcheroo.o \ i915_sysfs.o \ i915_utils.o \ + i915_gem_ww.o \ intel_device_info.o \ intel_dram.o \ intel_memory_region.o \ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index 60e27738c39d..c6c7ab181a65 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -15,6 +15,7 @@ #include "i915_gem_object_types.h" #include "i915_gem_gtt.h" #include "i915_vma_types.h" +#include "i915_gem_ww.h" void i915_gem_init__objects(struct drm_i915_private *i915); diff --git a/drivers/gpu/drm/i915/gt/intel_renderstate.h b/drivers/gpu/drm/i915/gt/intel_renderstate.h index 713aa1e86c80..d9db833b873b 100644 --- a/drivers/gpu/drm/i915/gt/intel_renderstate.h +++ b/drivers/gpu/drm/i915/gt/intel_renderstate.h @@ -26,6 +26,7 @@ #include #include "i915_gem.h" +#include "i915_gem_ww.h" struct i915_request; struct intel_context; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 2248e65cf5f9..2662d679db6e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1326,65 +1326,6 @@ int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file) return ret; } -void i915_gem_ww_ctx_init(struct i915_gem_ww_ctx *ww, bool intr) -{ - ww_acquire_init(>ctx, _ww_class); - INIT_LIST_HEAD(>obj_list); - ww->intr = intr; - ww->contended = NULL; -} - -static void i915_gem_ww_ctx_unlock_all(struct i915_gem_ww_ctx *ww) -{ - struct drm_i915_gem_object *obj; - - while ((obj = list_first_entry_or_null(>obj_list, struct drm_i915_gem_object, obj_link))) { - list_del(>obj_link); - i915_gem_object_unlock(obj); - } -} - -void i915_gem_ww_unlock_single(struct drm_i915_gem_object *obj) -{ - list_del(>obj_link); - i915_gem_object_unlock(obj); -} - -void i915_gem_ww_ctx_fini(struct i915_gem_ww_ctx *ww) -{ - i915_gem_ww_ctx_unlock_all(ww); - WARN_ON(ww->contended); - ww_acquire_fini(>ctx); -} - -int __must_check i915_gem_ww_ctx_backoff(struct i915_gem_ww_ctx *ww) -{ - int ret = 0; - - if (WARN_ON(!ww->contended)) - return -EINVAL; - - i915_gem_ww_ctx_unlock_all(ww); - if (ww->intr) - ret = dma_resv_lock_slow_interruptible(ww->contended->base.resv, >ctx); - else - dma_resv_lock_slow(ww->contended->base.resv, >ctx); - - /* -* Unlocking the contended lock again, as might not need it in -* the retried transaction. This does not increase starvation, -* but it's opening up for a wakeup flood if there are many -* transactions relaxing on this object. -*/ - if (!ret) - dma_resv_unlock(ww->contended->base.resv); - - i915_gem_object_put(ww->contended); - ww->contended = NULL; - - return ret; -} - #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) #include "selftests/mock_gem_device.c" #include "selftests/i915_gem.c" diff --git a/drivers/gpu/drm/i915/i915_gem.h b/drivers/gpu/drm/i915/i915_gem.h index a4cad3f154ca..f333e88a2b6e 100644 --- a/drivers/gpu/drm/i915/i915_gem.h +++ b/drivers/gpu/drm/i915/i915_gem.h @@ -116,16 +116,4 @@ static inline bool __tasklet_is_scheduled(struct tasklet_struct *t) return test_bit(TASKLET_STATE_SCHED, >state); } -struct i915_gem_ww_ctx { - struct ww_acquire_ctx ctx; - struct list_head obj_list; - bool intr; - struct drm_i915_gem_object *contended; -}; - -void i915_gem_ww_ctx_init(struct i915_gem_ww_ctx *ctx, bool intr); -void i915_gem_ww_ctx_fini(struct i915_gem_ww_ctx *ctx); -int __must_check i915_gem_ww_ctx_backoff(struct i915_gem_ww_ctx *ctx); -void i915_gem_ww_unlock_single(struct drm_i915_gem_object *obj); - #endif /* __I915_GEM_H__ */ diff --git a/drivers/gpu/drm/i915/i915_gem_ww.c
[RFC PATCH 086/162] drm/i915: Add blit functions that can be called from within a WW transaction
From: Thomas Hellström We want to be able to blit from within a ww transaction, so add blit functions that are able to do that. Also take care to unlock the blit batch-buffer after use so it isn't recycled locked. Signed-off-by: Thomas Hellström Cc: Matthew Auld --- .../gpu/drm/i915/gem/i915_gem_object_blt.c| 91 +-- .../gpu/drm/i915/gem/i915_gem_object_blt.h| 10 ++ 2 files changed, 72 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_blt.c b/drivers/gpu/drm/i915/gem/i915_gem_object_blt.c index e0b873c3f46a..b41b076f6864 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_blt.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_blt.c @@ -145,11 +145,11 @@ move_obj_to_gpu(struct drm_i915_gem_object *obj, return i915_request_await_object(rq, obj, write); } -int i915_gem_object_fill_blt(struct drm_i915_gem_object *obj, -struct intel_context *ce, -u32 value) +int i915_gem_object_ww_fill_blt(struct drm_i915_gem_object *obj, + struct i915_gem_ww_ctx *ww, + struct intel_context *ce, + u32 value) { - struct i915_gem_ww_ctx ww; struct i915_request *rq; struct i915_vma *batch; struct i915_vma *vma; @@ -159,22 +159,16 @@ int i915_gem_object_fill_blt(struct drm_i915_gem_object *obj, if (IS_ERR(vma)) return PTR_ERR(vma); - i915_gem_ww_ctx_init(, true); intel_engine_pm_get(ce->engine); -retry: - err = i915_gem_object_lock(obj, ); + err = intel_context_pin_ww(ce, ww); if (err) goto out; - err = intel_context_pin_ww(ce, ); - if (err) - goto out; - - err = i915_vma_pin_ww(vma, , 0, 0, PIN_USER); + err = i915_vma_pin_ww(vma, ww, 0, 0, PIN_USER); if (err) goto out_ctx; - batch = intel_emit_vma_fill_blt(ce, vma, , value); + batch = intel_emit_vma_fill_blt(ce, vma, ww, value); if (IS_ERR(batch)) { err = PTR_ERR(batch); goto out_vma; @@ -210,22 +204,43 @@ int i915_gem_object_fill_blt(struct drm_i915_gem_object *obj, i915_request_add(rq); out_batch: + i915_gem_ww_unlock_single(batch->obj); intel_emit_vma_release(ce, batch); out_vma: i915_vma_unpin(vma); out_ctx: intel_context_unpin(ce); out: + intel_engine_pm_put(ce->engine); + return err; +} + +int i915_gem_object_fill_blt(struct drm_i915_gem_object *obj, + struct intel_context *ce, + u32 value) +{ + struct i915_gem_ww_ctx ww; + int err; + + i915_gem_ww_ctx_init(, true); +retry: + err = i915_gem_object_lock(obj, ); + if (err) + goto out_err; + + err = i915_gem_object_ww_fill_blt(obj, , ce, value); +out_err: if (err == -EDEADLK) { err = i915_gem_ww_ctx_backoff(); if (!err) goto retry; } i915_gem_ww_ctx_fini(); - intel_engine_pm_put(ce->engine); + return err; } + /* Wa_1209644611:icl,ehl */ static bool wa_1209644611_applies(struct drm_i915_private *i915, u32 size) { @@ -354,13 +369,13 @@ struct i915_vma *intel_emit_vma_copy_blt(struct intel_context *ce, return ERR_PTR(err); } -int i915_gem_object_copy_blt(struct drm_i915_gem_object *src, -struct drm_i915_gem_object *dst, -struct intel_context *ce) +int i915_gem_object_ww_copy_blt(struct drm_i915_gem_object *src, + struct drm_i915_gem_object *dst, + struct i915_gem_ww_ctx *ww, + struct intel_context *ce) { struct i915_address_space *vm = ce->vm; struct i915_vma *vma[2], *batch; - struct i915_gem_ww_ctx ww; struct i915_request *rq; int err, i; @@ -372,26 +387,20 @@ int i915_gem_object_copy_blt(struct drm_i915_gem_object *src, if (IS_ERR(vma[1])) return PTR_ERR(vma[1]); - i915_gem_ww_ctx_init(, true); intel_engine_pm_get(ce->engine); -retry: - err = i915_gem_object_lock(src, ); - if (!err) - err = i915_gem_object_lock(dst, ); - if (!err) - err = intel_context_pin_ww(ce, ); + err = intel_context_pin_ww(ce, ww); if (err) goto out; - err = i915_vma_pin_ww(vma[0], , 0, 0, PIN_USER); + err = i915_vma_pin_ww(vma[0], ww, 0, 0, PIN_USER); if (err) goto out_ctx; - err = i915_vma_pin_ww(vma[1], , 0, 0, PIN_USER); + err = i915_vma_pin_ww(vma[1], ww, 0, 0, PIN_USER); if (unlikely(err)) goto out_unpin_src; - batch = intel_emit_vma_copy_blt(ce, ,
[RFC PATCH 085/162] drm/i915/region: support basic eviction
Support basic eviction for regions. Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Abdiel Janulgue --- .../gpu/drm/i915/gem/i915_gem_object_types.h | 1 + drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 59 ++ drivers/gpu/drm/i915/gem/i915_gem_shrinker.h | 4 + drivers/gpu/drm/i915/i915_gem.c | 17 + drivers/gpu/drm/i915/intel_memory_region.c| 24 +- .../drm/i915/selftests/intel_memory_region.c | 76 +++ 6 files changed, 178 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h index b172e8cc53ab..6d101275bc9d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h @@ -226,6 +226,7 @@ struct drm_i915_gem_object { * region->obj_lock. */ struct list_head region_link; + struct list_head tmp_link; struct sg_table *pages; void *mapping; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c index e42192834c88..4d346df8fd5b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c @@ -16,6 +16,7 @@ #include "gt/intel_gt_requests.h" #include "i915_trace.h" +#include "gt/intel_gt_requests.h" static bool swap_available(void) { @@ -271,6 +272,64 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private *i915) return freed; } +int i915_gem_shrink_memory_region(struct intel_memory_region *mem, + resource_size_t target) +{ + struct drm_i915_private *i915 = mem->i915; + struct drm_i915_gem_object *obj; + resource_size_t purged; + LIST_HEAD(purgeable); + int err = -ENOSPC; + + intel_gt_retire_requests(>gt); + + purged = 0; + + mutex_lock(>objects.lock); + + while ((obj = list_first_entry_or_null(>objects.purgeable, + typeof(*obj), + mm.region_link))) { + list_move_tail(>mm.region_link, ); + + if (!i915_gem_object_has_pages(obj)) + continue; + + if (i915_gem_object_is_framebuffer(obj)) + continue; + + if (!kref_get_unless_zero(>base.refcount)) + continue; + + mutex_unlock(>objects.lock); + + if (!i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE)) { + if (i915_gem_object_trylock(obj)) { + __i915_gem_object_put_pages(obj); + if (!i915_gem_object_has_pages(obj)) { + purged += obj->base.size; + if (!i915_gem_object_is_volatile(obj)) + obj->mm.madv = __I915_MADV_PURGED; + } + i915_gem_object_unlock(obj); + } + } + + i915_gem_object_put(obj); + + mutex_lock(>objects.lock); + + if (purged >= target) { + err = 0; + break; + } + } + + list_splice_tail(, >objects.purgeable); + mutex_unlock(>objects.lock); + return err; +} + static unsigned long i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) { diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.h b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.h index 8512470f6fd6..c945f3b587d6 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.h @@ -7,10 +7,12 @@ #define __I915_GEM_SHRINKER_H__ #include +#include struct drm_i915_private; struct i915_gem_ww_ctx; struct mutex; +struct intel_memory_region; /* i915_gem_shrinker.c */ unsigned long i915_gem_shrink(struct i915_gem_ww_ctx *ww, @@ -29,5 +31,7 @@ void i915_gem_driver_register__shrinker(struct drm_i915_private *i915); void i915_gem_driver_unregister__shrinker(struct drm_i915_private *i915); void i915_gem_shrinker_taints_mutex(struct drm_i915_private *i915, struct mutex *mutex); +int i915_gem_shrink_memory_region(struct intel_memory_region *mem, + resource_size_t target); #endif /* __I915_GEM_SHRINKER_H__ */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 2662d679db6e..ef2124c17a7f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1104,6 +1104,23 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, !i915_gem_object_has_pages(obj)) i915_gem_object_truncate(obj); + if
[RFC PATCH 081/162] HAX drm/i915/lmem: support CPU relocations
** DO NOT MERGE. RELOCATION SUPPORT WILL BE DROPPED FROM DG1+ ** Add LMEM support for the CPU reloc path. When doing relocations we have both a GPU and CPU reloc path, as well as some debugging options to force a particular path. The GPU reloc path is preferred when the object is not currently idle, otherwise we use the CPU reloc path. Since we can't kmap the object, and the mappable aperture might not be available, add support for mapping it through LMEMBAR. Signed-off-by: Matthew Auld Signed-off-by: Thomas Hellström Cc: Joonas Lahtinen Cc: Abdiel Janulgue Cc: Rodrigo Vivi --- .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 53 +-- drivers/gpu/drm/i915/gem/i915_gem_lmem.c | 12 + drivers/gpu/drm/i915/gem/i915_gem_lmem.h | 4 ++ 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 91f0c3fd9a4b..e73a761a7d1f 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -14,6 +14,7 @@ #include "display/intel_frontbuffer.h" #include "gem/i915_gem_ioctls.h" +#include "gem/i915_gem_lmem.h" #include "gt/intel_context.h" #include "gt/intel_gt.h" #include "gt/intel_gt_buffer_pool.h" @@ -278,6 +279,7 @@ struct i915_execbuffer { bool has_llc : 1; bool has_fence : 1; bool needs_unfenced : 1; + bool is_lmem : 1; struct i915_request *rq; u32 *rq_cmd; @@ -1049,6 +1051,7 @@ static void reloc_cache_init(struct reloc_cache *cache, cache->has_fence = cache->gen < 4; cache->needs_unfenced = INTEL_INFO(i915)->unfenced_needs_alignment; cache->node.flags = 0; + cache->is_lmem = false; reloc_cache_clear(cache); } @@ -1128,10 +1131,14 @@ static void reloc_cache_reset(struct reloc_cache *cache, struct i915_execbuffer } else { struct i915_ggtt *ggtt = cache_to_ggtt(cache); - intel_gt_flush_ggtt_writes(ggtt->vm.gt); + if (!cache->is_lmem) + intel_gt_flush_ggtt_writes(ggtt->vm.gt); io_mapping_unmap_atomic((void __iomem *)vaddr); - if (drm_mm_node_allocated(>node)) { + if (cache->is_lmem) { + i915_gem_object_unpin_pages((struct drm_i915_gem_object *)cache->node.mm); + cache->is_lmem = false; + } else if (drm_mm_node_allocated(>node)) { ggtt->vm.clear_range(>vm, cache->node.start, cache->node.size); @@ -1184,6 +1191,40 @@ static void *reloc_kmap(struct drm_i915_gem_object *obj, return vaddr; } +static void *reloc_lmem(struct drm_i915_gem_object *obj, + struct reloc_cache *cache, + unsigned long page) +{ + void *vaddr; + int err; + + GEM_BUG_ON(use_cpu_reloc(cache, obj)); + + if (cache->vaddr) { + io_mapping_unmap_atomic((void __force __iomem *) unmask_page(cache->vaddr)); + } else { + err = i915_gem_object_pin_pages(obj); + if (err) + return ERR_PTR(err); + + err = i915_gem_object_set_to_wc_domain(obj, true); + if (err) { + i915_gem_object_unpin_pages(obj); + return ERR_PTR(err); + } + + cache->node.mm = (void *)obj; + cache->is_lmem = true; + } + + vaddr = i915_gem_object_lmem_io_map_page_atomic(obj, page); + + cache->vaddr = (unsigned long)vaddr; + cache->page = page; + + return vaddr; +} + static void *reloc_iomap(struct drm_i915_gem_object *obj, struct i915_execbuffer *eb, unsigned long page) @@ -1262,8 +1303,12 @@ static void *reloc_vaddr(struct drm_i915_gem_object *obj, vaddr = unmask_page(cache->vaddr); } else { vaddr = NULL; - if ((cache->vaddr & KMAP) == 0) - vaddr = reloc_iomap(obj, eb, page); + if ((cache->vaddr & KMAP) == 0) { + if (i915_gem_object_is_lmem(obj)) + vaddr = reloc_lmem(obj, cache, page); + else + vaddr = reloc_iomap(obj, eb, page); + } if (!vaddr) vaddr = reloc_kmap(obj, cache, page); } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c index e953965f8263..f6c4d5998ff9 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c @@ -17,6 +17,18 @@ const struct drm_i915_gem_object_ops
[RFC PATCH 084/162] drm/i915: introduce kernel blitter_context
We may be without a context to perform various internal blitter operations, for example when performing object migration. Piggybacking off the kernel_context is probably a bad idea, since it has other uses. Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Abdiel Janulgue --- drivers/gpu/drm/i915/gt/intel_engine.h | 2 + drivers/gpu/drm/i915/gt/intel_engine_cs.c| 40 +++- drivers/gpu/drm/i915/gt/intel_engine_types.h | 1 + 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h index 760fefdfe392..188c5ff6dc64 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine.h +++ b/drivers/gpu/drm/i915/gt/intel_engine.h @@ -186,6 +186,8 @@ intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value) #define I915_GEM_HWS_PREEMPT_ADDR (I915_GEM_HWS_PREEMPT * sizeof(u32)) #define I915_GEM_HWS_SEQNO 0x40 #define I915_GEM_HWS_SEQNO_ADDR(I915_GEM_HWS_SEQNO * sizeof(u32)) +#define I915_GEM_HWS_BLITTER 0x42 +#define I915_GEM_HWS_BLITTER_ADDR (I915_GEM_HWS_BLITTER * sizeof(u32)) #define I915_GEM_HWS_SCRATCH 0x80 #define I915_HWS_CSB_BUF0_INDEX0x10 diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 677c97ded81d..0ba020346566 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -819,6 +819,7 @@ create_pinned_context(struct intel_engine_cs *engine, int err; ce = intel_context_create(engine); + if (IS_ERR(ce)) return ce; @@ -851,6 +852,20 @@ create_kernel_context(struct intel_engine_cs *engine) , "kernel_context"); } +static struct intel_context * +create_blitter_context(struct intel_engine_cs *engine) +{ + static struct lock_class_key blitter; + struct intel_context *ce; + + ce = create_pinned_context(engine, I915_GEM_HWS_BLITTER_ADDR, , + "blitter_context"); + if (IS_ERR(ce)) + return ce; + + return ce; +} + /** * intel_engines_init_common - initialize cengine state which might require hw access * @engine: Engine to initialize. @@ -881,17 +896,33 @@ static int engine_init_common(struct intel_engine_cs *engine) if (IS_ERR(ce)) return PTR_ERR(ce); + engine->kernel_context = ce; ret = measure_breadcrumb_dw(ce); if (ret < 0) goto err_context; engine->emit_fini_breadcrumb_dw = ret; - engine->kernel_context = ce; + + /* +* The blitter context is used to quickly memset or migrate objects +* in local memory, so it has to always be available. +*/ + if (engine->class == COPY_ENGINE_CLASS) { + ce = create_blitter_context(engine); + if (IS_ERR(ce)) { + ret = PTR_ERR(ce); + goto err_unpin; + } + + engine->blitter_context = ce; + } return 0; +err_unpin: + intel_context_unpin(engine->kernel_context); err_context: - intel_context_put(ce); + intel_context_put(engine->kernel_context); return ret; } @@ -947,6 +978,11 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine) if (engine->default_state) fput(engine->default_state); + if (engine->blitter_context) { + intel_context_unpin(engine->blitter_context); + intel_context_put(engine->blitter_context); + } + if (engine->kernel_context) { intel_context_unpin(engine->kernel_context); intel_context_put(engine->kernel_context); diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h index ee6312601c56..cb2de4bf86ba 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h @@ -347,6 +347,7 @@ struct intel_engine_cs { struct llist_head barrier_tasks; struct intel_context *kernel_context; /* pinned */ + struct intel_context *blitter_context; /* pinned; exists for BCS only */ intel_engine_mask_t saturated; /* submitting semaphores too late? */ -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 083/162] drm/i915: Update the helper to set correct mapping
From: Venkata Sandeep Dhanalakota Determine the possible coherent map type based on object location, and if target has llc or if user requires an always coherent mapping. Cc: Matthew Auld Cc: CQ Tang Suggested-by: Michal Wajdeczko Signed-off-by: Venkata Sandeep Dhanalakota Cc: Matthew Auld --- drivers/gpu/drm/i915/gt/intel_engine_cs.c| 3 ++- drivers/gpu/drm/i915/gt/intel_engine_pm.c| 2 +- drivers/gpu/drm/i915/gt/intel_execlists_submission.c | 4 ++-- drivers/gpu/drm/i915/gt/intel_ring.c | 9 ++--- drivers/gpu/drm/i915/gt/intel_timeline.c | 8 ++-- drivers/gpu/drm/i915/gt/selftest_context.c | 3 ++- drivers/gpu/drm/i915/gt/selftest_execlists.c | 3 ++- drivers/gpu/drm/i915/gt/selftest_hangcheck.c | 4 ++-- drivers/gpu/drm/i915/gt/uc/intel_guc.c | 4 +++- drivers/gpu/drm/i915/gt/uc/intel_huc.c | 4 +++- drivers/gpu/drm/i915/i915_drv.h | 11 +-- drivers/gpu/drm/i915/selftests/igt_spinner.c | 4 ++-- 12 files changed, 40 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 420c6a35f3ed..677c97ded81d 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -680,7 +680,8 @@ static int init_status_page(struct intel_engine_cs *engine) if (ret) goto err; - vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); + vaddr = i915_gem_object_pin_map(obj, + i915_coherent_map_type(engine->i915, obj, true)); if (IS_ERR(vaddr)) { ret = PTR_ERR(vaddr); goto err_unpin; diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c b/drivers/gpu/drm/i915/gt/intel_engine_pm.c index 5d51144ef074..1b2009b4dcb7 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c @@ -24,7 +24,7 @@ static void dbg_poison_ce(struct intel_context *ce) if (ce->state) { struct drm_i915_gem_object *obj = ce->state->obj; - int type = i915_coherent_map_type(ce->engine->i915); + int type = i915_coherent_map_type(ce->engine->i915, obj, true); void *map; if (!i915_gem_object_trylock(ce->state->obj)) diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c index 7eec42b27bc1..582a9044727e 100644 --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c @@ -3535,8 +3535,8 @@ __execlists_context_pre_pin(struct intel_context *ce, GEM_BUG_ON(!i915_vma_is_pinned(ce->state)); *vaddr = i915_gem_object_pin_map(ce->state->obj, - i915_coherent_map_type(ce->engine->i915) | - I915_MAP_OVERRIDE); + i915_coherent_map_type(ce->engine->i915, ce->state->obj, false) | +I915_MAP_OVERRIDE); if (IS_ERR(*vaddr)) return PTR_ERR(*vaddr); diff --git a/drivers/gpu/drm/i915/gt/intel_ring.c b/drivers/gpu/drm/i915/gt/intel_ring.c index 4034a4bac7f0..d636c6ed88b7 100644 --- a/drivers/gpu/drm/i915/gt/intel_ring.c +++ b/drivers/gpu/drm/i915/gt/intel_ring.c @@ -51,9 +51,12 @@ int intel_ring_pin(struct intel_ring *ring, struct i915_gem_ww_ctx *ww) if (i915_vma_is_map_and_fenceable(vma)) addr = (void __force *)i915_vma_pin_iomap(vma); - else - addr = i915_gem_object_pin_map(vma->obj, - i915_coherent_map_type(vma->vm->i915)); + else { + int type = i915_coherent_map_type(vma->vm->i915, vma->obj, false); + + addr = i915_gem_object_pin_map(vma->obj, type); + } + if (IS_ERR(addr)) { ret = PTR_ERR(addr); goto err_ring; diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c index b2d04717db20..065943781586 100644 --- a/drivers/gpu/drm/i915/gt/intel_timeline.c +++ b/drivers/gpu/drm/i915/gt/intel_timeline.c @@ -31,6 +31,7 @@ static int __hwsp_alloc(struct intel_gt *gt, struct intel_timeline_hwsp *hwsp) { struct drm_i915_private *i915 = gt->i915; struct drm_i915_gem_object *obj; + int type; int ret; obj = i915_gem_object_create_internal(i915, PAGE_SIZE); @@ -47,7 +48,8 @@ static int __hwsp_alloc(struct intel_gt *gt, struct intel_timeline_hwsp *hwsp) } /* Pin early so we can call i915_ggtt_pin_unlocked(). */ - hwsp->vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); + type = i915_coherent_map_type(i915, obj, true); + hwsp->vaddr =
[RFC PATCH 079/162] drm/i915/dmabuf: Disallow LMEM objects from dma-buf
From: "Michael J. Ruhl" The dma-buf interface for i915 does not currently support LMEM backed objects. Check imported objects to see if they are from i915 and if they are LMEM. If they are, reject the import. This check is needed in two places, once on import, and then a recheck in the mapping path in the off chance that an object was migrated to LMEM after import. Signed-off-by: Michael J. Ruhl --- drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c index c4b01e819786..018d02cc4af5 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c @@ -9,6 +9,7 @@ #include #include "i915_drv.h" +#include "i915_gem_lmem.h" #include "i915_gem_object.h" #include "i915_scatterlist.h" @@ -25,6 +26,11 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme struct scatterlist *src, *dst; int ret, i; + if (i915_gem_object_is_lmem(obj)) { + ret = -ENOTSUPP; + goto err; + } + ret = i915_gem_object_pin_pages(obj); if (ret) goto err; @@ -248,6 +254,10 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev, */ return _gem_object_get(obj)->base; } + + /* not our device, but still a i915 object? */ + if (i915_gem_object_is_lmem(obj)) + return ERR_PTR(-ENOTSUPP); } /* need to attach */ -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 082/162] HAX drm/i915/lmem: support pread and pwrite
** DO NOT MERGE. PREAD/WRITE SUPPORT WILL BE DROPPED FROM DG1+ ** We need to add support for pread'ing and pwriting an LMEM object. Cc: Joonas Lahtinen Cc: Abdiel Janulgue Signed-off-by: Matthew Auld Signed-off-by: Steve Hampson Signed-off-by: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_lmem.c | 186 +++ drivers/gpu/drm/i915/gem/i915_gem_lmem.h | 2 + 2 files changed, 188 insertions(+) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c index f6c4d5998ff9..840b68eb10d3 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c @@ -8,6 +8,177 @@ #include "gem/i915_gem_lmem.h" #include "i915_drv.h" +static int +i915_ww_pin_lock_interruptible(struct drm_i915_gem_object *obj) +{ + struct i915_gem_ww_ctx ww; + int ret; + + for_i915_gem_ww(, ret, true) { + ret = i915_gem_object_lock(obj, ); + if (ret) + continue; + + ret = i915_gem_object_pin_pages(obj); + if (ret) + continue; + + ret = i915_gem_object_set_to_wc_domain(obj, false); + if (ret) + goto out_unpin; + + ret = i915_gem_object_wait(obj, + I915_WAIT_INTERRUPTIBLE, + MAX_SCHEDULE_TIMEOUT); + if (!ret) + continue; + +out_unpin: + i915_gem_object_unpin_pages(obj); + + /* Unlocking is done implicitly */ + } + + return ret; +} + +int i915_gem_object_lmem_pread(struct drm_i915_gem_object *obj, + const struct drm_i915_gem_pread *arg) +{ + struct drm_i915_private *i915 = to_i915(obj->base.dev); + struct intel_runtime_pm *rpm = >runtime_pm; + intel_wakeref_t wakeref; + char __user *user_data; + unsigned int offset; + unsigned long idx; + u64 remain; + int ret; + + ret = i915_gem_object_wait(obj, + I915_WAIT_INTERRUPTIBLE, + MAX_SCHEDULE_TIMEOUT); + if (ret) + return ret; + + ret = i915_ww_pin_lock_interruptible(obj); + if (ret) + return ret; + + wakeref = intel_runtime_pm_get(rpm); + + remain = arg->size; + user_data = u64_to_user_ptr(arg->data_ptr); + offset = offset_in_page(arg->offset); + for (idx = arg->offset >> PAGE_SHIFT; remain; idx++) { + unsigned long unwritten; + void __iomem *vaddr; + int length; + + length = remain; + if (offset + length > PAGE_SIZE) + length = PAGE_SIZE - offset; + + vaddr = i915_gem_object_lmem_io_map_page_atomic(obj, idx); + if (!vaddr) { + ret = -ENOMEM; + goto out_put; + } + unwritten = __copy_to_user_inatomic(user_data, + (void __force *)vaddr + offset, + length); + io_mapping_unmap_atomic(vaddr); + if (unwritten) { + vaddr = i915_gem_object_lmem_io_map_page(obj, idx); + unwritten = copy_to_user(user_data, +(void __force *)vaddr + offset, +length); + io_mapping_unmap(vaddr); + } + if (unwritten) { + ret = -EFAULT; + goto out_put; + } + + remain -= length; + user_data += length; + offset = 0; + } + +out_put: + intel_runtime_pm_put(rpm, wakeref); + i915_gem_object_unpin_pages(obj); + + return ret; +} + +static int i915_gem_object_lmem_pwrite(struct drm_i915_gem_object *obj, + const struct drm_i915_gem_pwrite *arg) +{ + struct drm_i915_private *i915 = to_i915(obj->base.dev); + struct intel_runtime_pm *rpm = >runtime_pm; + intel_wakeref_t wakeref; + char __user *user_data; + unsigned int offset; + unsigned long idx; + u64 remain; + int ret; + + ret = i915_gem_object_wait(obj, + I915_WAIT_INTERRUPTIBLE, + MAX_SCHEDULE_TIMEOUT); + if (ret) + return ret; + + ret = i915_ww_pin_lock_interruptible(obj); + if (ret) + return ret; + + wakeref = intel_runtime_pm_get(rpm); + + remain = arg->size; + user_data = u64_to_user_ptr(arg->data_ptr); + offset = offset_in_page(arg->offset); + for (idx = arg->offset
[RFC PATCH 072/162] drm/i915: Avoid some false positives in assert_object_held()
From: Thomas Hellström In a ww transaction where we've already locked a reservation object, assert_object_held() might not throw a splat even if the object is unlocked. Improve on that situation by asserting that the reservation object's ww mutex is indeed locked. Signed-off-by: Thomas Hellström Cc: Matthew Auld --- drivers/gpu/drm/i915/gem/i915_gem_object.h | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index d0cc62d1c65e..d56643b3b518 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -117,7 +117,14 @@ i915_gem_object_put(struct drm_i915_gem_object *obj) __drm_gem_object_put(>base); } -#define assert_object_held(obj) dma_resv_assert_held((obj)->base.resv) +#ifdef CONFIG_LOCKDEP +#define assert_object_held(obj) do { \ + dma_resv_assert_held((obj)->base.resv); \ + WARN_ON(!ww_mutex_is_locked(&(obj)->base.resv->lock)); \ + } while (0) +#else +#define assert_object_held(obj) do { } while (0) +#endif #define object_is_isolated(obj)\ (!IS_ENABLED(CONFIG_LOCKDEP) || \ -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 076/162] drm/i915: Untangle the vma pages_mutex
From: Thomas Hellström Move the vma pages_mutex out of the way from the object ww locks. Signed-off-by: Thomas Hellström Cc: Matthew Auld --- drivers/gpu/drm/i915/i915_vma.c | 30 -- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 0c7e4191811a..7243ab593aec 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -792,28 +792,30 @@ static int vma_get_pages(struct i915_vma *vma) if (atomic_add_unless(>pages_count, 1, 0)) return 0; + if (vma->obj) { + err = i915_gem_object_pin_pages(vma->obj); + if (err) + return err; + } + /* Allocations ahoy! */ - if (mutex_lock_interruptible(>pages_mutex)) - return -EINTR; + if (mutex_lock_interruptible(>pages_mutex)) { + err = -EINTR; + goto unpin; + } if (!atomic_read(>pages_count)) { - if (vma->obj) { - err = i915_gem_object_pin_pages(vma->obj); - if (err) - goto unlock; - } - err = vma->ops->set_pages(vma); - if (err) { - if (vma->obj) - i915_gem_object_unpin_pages(vma->obj); + if (err) goto unlock; - } } atomic_inc(>pages_count); unlock: mutex_unlock(>pages_mutex); +unpin: + if (err && vma->obj) + __i915_gem_object_unpin_pages(vma->obj); return err; } @@ -826,10 +828,10 @@ static void __vma_put_pages(struct i915_vma *vma, unsigned int count) if (atomic_sub_return(count, >pages_count) == 0) { vma->ops->clear_pages(vma); GEM_BUG_ON(vma->pages); - if (vma->obj) - i915_gem_object_unpin_pages(vma->obj); } mutex_unlock(>pages_mutex); + if (vma->obj) + i915_gem_object_unpin_pages(vma->obj); } static void vma_put_pages(struct i915_vma *vma) -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 080/162] drm/i915/lmem: Fail driver init if LMEM training failed
From: Matt Roper Boot firmware performs memory training and health assessment during startup. If the memory training fails, the firmware will consider the GPU unusable and will instruct the punit to keep the GT powered down. If this happens, our driver will be unable to communicate with the GT (all GT registers will read back as 0, forcewake requests will timeout, etc.) so we should abort driver initialization if this happens. We can confirm that LMEM was initialized successfully via sgunit register GU_CNTL. Bspec: 53111 Signed-off-by: Matt Roper Cc: Caz Yokoyama --- drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_uncore.c | 12 2 files changed, 15 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5375b219cc3b..bf9ba1e361bb 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -487,6 +487,9 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define GAB_CTL_MMIO(0x24000) #define GAB_CTL_CONT_AFTER_PAGEFAULT (1 << 8) +#define GU_CNTL_MMIO(0x101010) +#define LMEM_INITREG_BIT(7) + #define GEN6_STOLEN_RESERVED _MMIO(0x1082C0) #define GEN6_STOLEN_RESERVED_ADDR_MASK (0xFFF << 20) #define GEN7_STOLEN_RESERVED_ADDR_MASK (0x3FFF << 18) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 1c14a07eba7d..1630452e82b8 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1901,6 +1901,18 @@ int intel_uncore_init_mmio(struct intel_uncore *uncore) if (ret) return ret; + /* +* The boot firmware initializes local memory and assesses its health. +* If memory training fails, the punit will have been instructed to +* keep the GT powered down; we won't be able to communicate with it +* and we should not continue with driver initialization. +*/ + if (IS_DGFX(i915) && + !(__raw_uncore_read32(uncore, GU_CNTL) & LMEM_INIT)) { + drm_err(>drm, "LMEM not initialized by firmware\n"); + return -ENODEV; + } + if (INTEL_GEN(i915) > 5 && !intel_vgpu_active(i915)) uncore->flags |= UNCORE_HAS_FORCEWAKE; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 077/162] drm/i915/fbdev: Use lmem physical addresses for fb_mmap() on discrete
From: Mohammed Khajapasha use local memory io BAR address for fbdev's fb_mmap() operation on discrete, fbdev uses the physical address of our framebuffer for its fb_mmap() fn. Signed-off-by: Mohammed Khajapasha Cc: Ramalingam C --- drivers/gpu/drm/i915/display/intel_fbdev.c | 27 +- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index bdf44e923cc0..831e99e0785c 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -178,6 +178,7 @@ static int intelfb_create(struct drm_fb_helper *helper, unsigned long flags = 0; bool prealloc = false; void __iomem *vaddr; + struct drm_i915_gem_object *obj; int ret; if (intel_fb && @@ -232,13 +233,27 @@ static int intelfb_create(struct drm_fb_helper *helper, info->fbops = _ops; /* setup aperture base/size for vesafb takeover */ - info->apertures->ranges[0].base = ggtt->gmadr.start; - info->apertures->ranges[0].size = ggtt->mappable_end; + obj = intel_fb_obj(_fb->base); + if (HAS_LMEM(dev_priv) && i915_gem_object_is_lmem(obj)) { + struct intel_memory_region *mem = obj->mm.region; + + info->apertures->ranges[0].base = mem->io_start; + info->apertures->ranges[0].size = mem->total; + + /* Use fbdev's framebuffer from lmem for discrete */ + info->fix.smem_start = + (unsigned long)(mem->io_start + + i915_gem_object_get_dma_address(obj, 0)); + info->fix.smem_len = obj->base.size; + } else { + info->apertures->ranges[0].base = ggtt->gmadr.start; + info->apertures->ranges[0].size = ggtt->mappable_end; - /* Our framebuffer is the entirety of fbdev's system memory */ - info->fix.smem_start = - (unsigned long)(ggtt->gmadr.start + vma->node.start); - info->fix.smem_len = vma->node.size; + /* Our framebuffer is the entirety of fbdev's system memory */ + info->fix.smem_start = + (unsigned long)(ggtt->gmadr.start + vma->node.start); + info->fix.smem_len = vma->node.size; + } vaddr = i915_vma_pin_iomap(vma); if (IS_ERR(vaddr)) { -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 071/162] drm/i915: Keep userpointer bindings if seqcount is unchanged, v2.
From: Maarten Lankhorst Instead of force unbinding and rebinding every time, we try to check if our notifier seqcount is still correct when pages are bound. This way we only rebind userptr when we need to, and prevent stalls. Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 27 ++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c index fb4bc30fbd9a..d1ecc31b5e90 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c @@ -275,12 +275,33 @@ int i915_gem_object_userptr_submit_init(struct drm_i915_gem_object *obj) if (ret) return ret; - /* Make sure userptr is unbound for next attempt, so we don't use stale pages. */ - ret = i915_gem_object_userptr_unbind(obj, false); + /* optimistically try to preserve current pages while unlocked */ + if (i915_gem_object_has_pages(obj) && + !mmu_interval_check_retry(>userptr.notifier, + obj->userptr.notifier_seq)) { + spin_lock(>mm.notifier_lock); + if (obj->userptr.pvec && + !mmu_interval_read_retry(>userptr.notifier, +obj->userptr.notifier_seq)) { + obj->userptr.page_ref++; + + /* We can keep using the current binding, this is the fastpath */ + ret = 1; + } + spin_unlock(>mm.notifier_lock); + } + + if (!ret) { + /* Make sure userptr is unbound for next attempt, so we don't use stale pages. */ + ret = i915_gem_object_userptr_unbind(obj, false); + } i915_gem_object_unlock(obj); - if (ret) + if (ret < 0) return ret; + if (ret > 0) + return 0; + notifier_seq = mmu_interval_read_begin(>userptr.notifier); pvec = kvmalloc_array(num_pages, sizeof(struct page *), GFP_KERNEL); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 075/162] drm/i915: Introduce a for_i915_gem_ww(){}
From: Thomas Hellström Introduce a for_i915_gem_ww(){} utility to help make the code around a ww transaction more readable. Signed-off-by: Thomas Hellström Cc: Matthew Auld --- drivers/gpu/drm/i915/i915_gem_ww.h | 31 +- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_ww.h b/drivers/gpu/drm/i915/i915_gem_ww.h index f2d8769e4118..f6b1a796667b 100644 --- a/drivers/gpu/drm/i915/i915_gem_ww.h +++ b/drivers/gpu/drm/i915/i915_gem_ww.h @@ -11,11 +11,40 @@ struct i915_gem_ww_ctx { struct ww_acquire_ctx ctx; struct list_head obj_list; struct drm_i915_gem_object *contended; - bool intr; + unsigned short intr; + unsigned short loop; }; void i915_gem_ww_ctx_init(struct i915_gem_ww_ctx *ctx, bool intr); void i915_gem_ww_ctx_fini(struct i915_gem_ww_ctx *ctx); int __must_check i915_gem_ww_ctx_backoff(struct i915_gem_ww_ctx *ctx); void i915_gem_ww_unlock_single(struct drm_i915_gem_object *obj); + +/* Internal functions used by the inlines! Don't use. */ +static inline int __i915_gem_ww_fini(struct i915_gem_ww_ctx *ww, int err) +{ + ww->loop = 0; + if (err == -EDEADLK) { + err = i915_gem_ww_ctx_backoff(ww); + if (!err) + ww->loop = 1; + } + + if (!ww->loop) + i915_gem_ww_ctx_fini(ww); + + return err; +} + +static inline void +__i915_gem_ww_init(struct i915_gem_ww_ctx *ww, bool intr) +{ + i915_gem_ww_ctx_init(ww, intr); + ww->loop = 1; +} + +#define for_i915_gem_ww(_ww, _err, _intr) \ + for (__i915_gem_ww_init(_ww, _intr); (_ww)->loop; \ +_err = __i915_gem_ww_fini(_ww, _err)) + #endif -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 078/162] drm/i915: Return error value when bo not in LMEM for discrete
From: Mohammed Khajapasha Return EREMOTE value when frame buffer object is not backed by LMEM for discrete. If Local memory is supported by hardware the framebuffer backing gem objects should be from local memory. Signed-off-by: Mohammed Khajapasha Cc: Michael J. Ruhl Cc: Animesh Manna --- drivers/gpu/drm/i915/display/intel_display.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 8a7945f55278..95ed1e06ea55 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -18054,11 +18054,20 @@ intel_user_framebuffer_create(struct drm_device *dev, struct drm_framebuffer *fb; struct drm_i915_gem_object *obj; struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd; + struct drm_i915_private *i915; obj = i915_gem_object_lookup(filp, mode_cmd.handles[0]); if (!obj) return ERR_PTR(-ENOENT); + /* object is backed with LMEM for discrete */ + i915 = to_i915(obj->base.dev); + if (HAS_LMEM(i915) && !i915_gem_object_is_lmem(obj)) { + /* object is "remote", not in local memory */ + i915_gem_object_put(obj); + return ERR_PTR(-EREMOTE); + } + fb = intel_framebuffer_create(obj, _cmd); i915_gem_object_put(obj); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2] soc / drm: mediatek: cmdq: Remove timeout handler in helper function
Hi Chun-Kuang, On 20/11/2020 00:46, Chun-Kuang Hu wrote: Hi, Matthias: I've provided the example for why of this patch. How do you think about this patch? Patch looks good to me. If you want to take it through your tree you can add my Acked-by: Matthias Brugger Beware that you might need a stable tag for it, so that I can merge it into my soc branch, in case there are more changes to cmdq-helper. Regards, Matthias Regards, Chun-Kuang. Chun-Kuang Hu 於 2020年11月2日 週一 上午8:04寫道: For each client driver, its timeout handler need to dump hardware register or its state machine information, and their way to detect timeout are also different, so remove timeout handler in helper function and let client driver implement its own timeout handler. Signed-off-by: Chun-Kuang Hu --- v1 is one patch in series "Mediatek DRM driver detect CMDQ execution timeout by vblank IRQ", but according to Jassi's suggestion [1], send each patch in different series. [2] is an example that different client has different way to calculate timeout. Some client driver care about each packet's execution time, but some client driver care about the total execution time for all packets. [1] https://patchwork.kernel.org/project/linux-mediatek/cover/20200927230422.11610-1-chunkuang...@kernel.org/ [2] https://patchwork.kernel.org/project/linux-mediatek/patch/20201022094152.17662-1-houlong@mediatek.com/ Changes in v2: 1. Rebase onto Linux 5.10-rc1 --- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 3 +- drivers/soc/mediatek/mtk-cmdq-helper.c | 41 + include/linux/soc/mediatek/mtk-cmdq.h | 10 +- 3 files changed, 3 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index ac038572164d..4be5d1fccf2e 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -824,8 +824,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, #if IS_REACHABLE(CONFIG_MTK_CMDQ) mtk_crtc->cmdq_client = cmdq_mbox_create(mtk_crtc->mmsys_dev, -drm_crtc_index(_crtc->base), -2000); +drm_crtc_index(_crtc->base)); if (IS_ERR(mtk_crtc->cmdq_client)) { dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n", drm_crtc_index(_crtc->base)); diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c index 505651b0d715..280d3bd9f675 100644 --- a/drivers/soc/mediatek/mtk-cmdq-helper.c +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c @@ -70,14 +70,7 @@ int cmdq_dev_get_client_reg(struct device *dev, } EXPORT_SYMBOL(cmdq_dev_get_client_reg); -static void cmdq_client_timeout(struct timer_list *t) -{ - struct cmdq_client *client = from_timer(client, t, timer); - - dev_err(client->client.dev, "cmdq timeout!\n"); -} - -struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 timeout) +struct cmdq_client *cmdq_mbox_create(struct device *dev, int index) { struct cmdq_client *client; @@ -85,12 +78,6 @@ struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 timeout) if (!client) return (struct cmdq_client *)-ENOMEM; - client->timeout_ms = timeout; - if (timeout != CMDQ_NO_TIMEOUT) { - spin_lock_init(>lock); - timer_setup(>timer, cmdq_client_timeout, 0); - } - client->pkt_cnt = 0; client->client.dev = dev; client->client.tx_block = false; client->client.knows_txdone = true; @@ -112,11 +99,6 @@ EXPORT_SYMBOL(cmdq_mbox_create); void cmdq_mbox_destroy(struct cmdq_client *client) { - if (client->timeout_ms != CMDQ_NO_TIMEOUT) { - spin_lock(>lock); - del_timer_sync(>timer); - spin_unlock(>lock); - } mbox_free_channel(client->chan); kfree(client); } @@ -449,18 +431,6 @@ static void cmdq_pkt_flush_async_cb(struct cmdq_cb_data data) struct cmdq_task_cb *cb = >cb; struct cmdq_client *client = (struct cmdq_client *)pkt->cl; - if (client->timeout_ms != CMDQ_NO_TIMEOUT) { - unsigned long flags = 0; - - spin_lock_irqsave(>lock, flags); - if (--client->pkt_cnt == 0) - del_timer(>timer); - else - mod_timer(>timer, jiffies + - msecs_to_jiffies(client->timeout_ms)); - spin_unlock_irqrestore(>lock, flags); - } - dma_sync_single_for_cpu(client->chan->mbox->dev, pkt->pa_base, pkt->cmd_buf_size, DMA_TO_DEVICE); if (cb->cb) { @@ -473,7 +443,6 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb
[RFC PATCH 031/162] drm/i915: Pass ww ctx to intel_pin_to_display_plane
From: Maarten Lankhorst Instead of multiple lockings, lock the object once, and perform the ww dance around attach_phys and pin_pages. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/display/intel_display.c | 69 --- drivers/gpu/drm/i915/display/intel_display.h | 2 +- drivers/gpu/drm/i915/display/intel_fbdev.c| 2 +- drivers/gpu/drm/i915/display/intel_overlay.c | 34 +++-- drivers/gpu/drm/i915/gem/i915_gem_domain.c| 30 ++-- drivers/gpu/drm/i915/gem/i915_gem_object.h| 1 + drivers/gpu/drm/i915/gem/i915_gem_phys.c | 10 +-- .../drm/i915/gem/selftests/i915_gem_phys.c| 2 + 8 files changed, 86 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index f36921a3c4bc..8a7945f55278 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2232,6 +2232,7 @@ static bool intel_plane_uses_fence(const struct intel_plane_state *plane_state) struct i915_vma * intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, + bool phys_cursor, const struct i915_ggtt_view *view, bool uses_fence, unsigned long *out_flags) @@ -2240,14 +2241,19 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_object *obj = intel_fb_obj(fb); intel_wakeref_t wakeref; + struct i915_gem_ww_ctx ww; struct i915_vma *vma; unsigned int pinctl; u32 alignment; + int ret; if (drm_WARN_ON(dev, !i915_gem_object_is_framebuffer(obj))) return ERR_PTR(-EINVAL); - alignment = intel_surf_alignment(fb, 0); + if (phys_cursor) + alignment = intel_cursor_alignment(dev_priv); + else + alignment = intel_surf_alignment(fb, 0); if (drm_WARN_ON(dev, alignment && !is_power_of_2(alignment))) return ERR_PTR(-EINVAL); @@ -2282,14 +2288,26 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, if (HAS_GMCH(dev_priv)) pinctl |= PIN_MAPPABLE; - vma = i915_gem_object_pin_to_display_plane(obj, - alignment, view, pinctl); - if (IS_ERR(vma)) + i915_gem_ww_ctx_init(, true); +retry: + ret = i915_gem_object_lock(obj, ); + if (!ret && phys_cursor) + ret = i915_gem_object_attach_phys(obj, alignment); + if (!ret) + ret = i915_gem_object_pin_pages(obj); + if (ret) goto err; - if (uses_fence && i915_vma_is_map_and_fenceable(vma)) { - int ret; + if (!ret) { + vma = i915_gem_object_pin_to_display_plane(obj, , alignment, + view, pinctl); + if (IS_ERR(vma)) { + ret = PTR_ERR(vma); + goto err_unpin; + } + } + if (uses_fence && i915_vma_is_map_and_fenceable(vma)) { /* * Install a fence for tiled scan-out. Pre-i965 always needs a * fence, whereas 965+ only requires a fence if using @@ -2310,16 +2328,28 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, ret = i915_vma_pin_fence(vma); if (ret != 0 && INTEL_GEN(dev_priv) < 4) { i915_gem_object_unpin_from_display_plane(vma); - vma = ERR_PTR(ret); - goto err; + goto err_unpin; } + ret = 0; - if (ret == 0 && vma->fence) + if (vma->fence) *out_flags |= PLANE_HAS_FENCE; } i915_vma_get(vma); + +err_unpin: + i915_gem_object_unpin_pages(obj); err: + if (ret == -EDEADLK) { + ret = i915_gem_ww_ctx_backoff(); + if (!ret) + goto retry; + } + i915_gem_ww_ctx_fini(); + if (ret) + vma = ERR_PTR(ret); + atomic_dec(_priv->gpu_error.pending_fb_pin); intel_runtime_pm_put(_priv->runtime_pm, wakeref); return vma; @@ -16626,19 +16656,11 @@ static int intel_plane_pin_fb(struct intel_plane_state *plane_state) struct drm_i915_private *dev_priv = to_i915(plane->base.dev); struct drm_framebuffer *fb = plane_state->hw.fb; struct i915_vma *vma; + bool phys_cursor = + plane->id == PLANE_CURSOR && + INTEL_INFO(dev_priv)->display.cursor_needs_physical; - if (plane->id == PLANE_CURSOR && - INTEL_INFO(dev_priv)->display.cursor_needs_physical) { - struct drm_i915_gem_object *obj = intel_fb_obj(fb);
[RFC PATCH 025/162] drm/i915: Fix userptr so we do not have to worry about obj->mm.lock, v5.
From: Maarten Lankhorst Instead of doing what we do currently, which will never work with PROVE_LOCKING, do the same as AMD does, and something similar to relocation slowpath. When all locks are dropped, we acquire the pages for pinning. When the locks are taken, we transfer those pages in .get_pages() to the bo. As a final check before installing the fences, we ensure that the mmu notifier was not called; if it is, we return -EAGAIN to userspace to signal it has to start over. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 101 ++- drivers/gpu/drm/i915/gem/i915_gem_object.h| 35 +- .../gpu/drm/i915/gem/i915_gem_object_types.h | 10 +- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 764 ++ drivers/gpu/drm/i915/i915_drv.h | 9 +- drivers/gpu/drm/i915/i915_gem.c | 5 +- 7 files changed, 344 insertions(+), 582 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 064285a5009b..f5ea49e244ca 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -52,14 +52,16 @@ enum { /* __EXEC_OBJECT_NO_RESERVE is BIT(31), defined in i915_vma.h */ #define __EXEC_OBJECT_HAS_PIN BIT(30) #define __EXEC_OBJECT_HAS_FENCEBIT(29) -#define __EXEC_OBJECT_NEEDS_MAPBIT(28) -#define __EXEC_OBJECT_NEEDS_BIAS BIT(27) -#define __EXEC_OBJECT_INTERNAL_FLAGS (~0u << 27) /* all of the above + */ +#define __EXEC_OBJECT_USERPTR_INIT BIT(28) +#define __EXEC_OBJECT_NEEDS_MAPBIT(27) +#define __EXEC_OBJECT_NEEDS_BIAS BIT(26) +#define __EXEC_OBJECT_INTERNAL_FLAGS (~0u << 26) /* all of the above + */ #define __EXEC_OBJECT_RESERVED (__EXEC_OBJECT_HAS_PIN | __EXEC_OBJECT_HAS_FENCE) #define __EXEC_HAS_RELOC BIT(31) #define __EXEC_ENGINE_PINNED BIT(30) -#define __EXEC_INTERNAL_FLAGS (~0u << 30) +#define __EXEC_USERPTR_USEDBIT(29) +#define __EXEC_INTERNAL_FLAGS (~0u << 29) #define UPDATE PIN_OFFSET_FIXED #define BATCH_OFFSET_BIAS (256*1024) @@ -865,6 +867,26 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb) } eb_add_vma(eb, i, batch, vma); + + if (i915_gem_object_is_userptr(vma->obj)) { + err = i915_gem_object_userptr_submit_init(vma->obj); + if (err) { + if (i + 1 < eb->buffer_count) { + /* +* Execbuffer code expects last vma entry to be NULL, +* since we already initialized this entry, +* set the next value to NULL or we mess up +* cleanup handling. +*/ + eb->vma[i + 1].vma = NULL; + } + + return err; + } + + eb->vma[i].flags |= __EXEC_OBJECT_USERPTR_INIT; + eb->args->flags |= __EXEC_USERPTR_USED; + } } if (unlikely(eb->batch->flags & EXEC_OBJECT_WRITE)) { @@ -966,7 +988,7 @@ eb_get_vma(const struct i915_execbuffer *eb, unsigned long handle) } } -static void eb_release_vmas(struct i915_execbuffer *eb, bool final) +static void eb_release_vmas(struct i915_execbuffer *eb, bool final, bool release_userptr) { const unsigned int count = eb->buffer_count; unsigned int i; @@ -980,6 +1002,11 @@ static void eb_release_vmas(struct i915_execbuffer *eb, bool final) eb_unreserve_vma(ev); + if (release_userptr && ev->flags & __EXEC_OBJECT_USERPTR_INIT) { + ev->flags &= ~__EXEC_OBJECT_USERPTR_INIT; + i915_gem_object_userptr_submit_fini(vma->obj); + } + if (final) i915_vma_put(vma); } @@ -1915,6 +1942,31 @@ static int eb_prefault_relocations(const struct i915_execbuffer *eb) return 0; } +static int eb_reinit_userptr(struct i915_execbuffer *eb) +{ + const unsigned int count = eb->buffer_count; + unsigned int i; + int ret; + + if (likely(!(eb->args->flags & __EXEC_USERPTR_USED))) + return 0; + + for (i = 0; i < count; i++) { + struct eb_vma *ev = >vma[i]; + + if (!i915_gem_object_is_userptr(ev->vma->obj)) + continue; + + ret = i915_gem_object_userptr_submit_init(ev->vma->obj); + if (ret) + return ret; + + ev->flags |= __EXEC_OBJECT_USERPTR_INIT; + } +
[RFC PATCH 028/162] drm/i915: Make ring submission compatible with obj->mm.lock removal, v2.
From: Maarten Lankhorst We map the initial context during first pin. This allows us to remove pin_map from state allocation, which saves us a few retry loops. We won't need this until first pin anyway. intel_ring_submission_setup() is also reworked slightly to do all pinning in a single ww loop. Signed-off-by: Maarten Lankhorst Reported-by: kernel test robot Reported-by: Dan Carpenter Cc: Thomas Hellström --- .../gpu/drm/i915/gt/intel_ring_submission.c | 184 +++--- 1 file changed, 118 insertions(+), 66 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c b/drivers/gpu/drm/i915/gt/intel_ring_submission.c index a41b43f445b8..6b280904db43 100644 --- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c @@ -478,6 +478,26 @@ static void ring_context_destroy(struct kref *ref) intel_context_free(ce); } +static int ring_context_init_default_state(struct intel_context *ce, + struct i915_gem_ww_ctx *ww) +{ + struct drm_i915_gem_object *obj = ce->state->obj; + void *vaddr; + + vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); + if (IS_ERR(vaddr)) + return PTR_ERR(vaddr); + + shmem_read(ce->engine->default_state, 0, + vaddr, ce->engine->context_size); + + i915_gem_object_flush_map(obj); + __i915_gem_object_release_map(obj); + + __set_bit(CONTEXT_VALID_BIT, >flags); + return 0; +} + static int ring_context_pre_pin(struct intel_context *ce, struct i915_gem_ww_ctx *ww, void **unused) @@ -485,6 +505,13 @@ static int ring_context_pre_pin(struct intel_context *ce, struct i915_address_space *vm; int err = 0; + if (ce->engine->default_state && + !test_bit(CONTEXT_VALID_BIT, >flags)) { + err = ring_context_init_default_state(ce, ww); + if (err) + return err; + } + vm = vm_alias(ce->vm); if (vm) err = gen6_ppgtt_pin(i915_vm_to_ppgtt((vm)), ww); @@ -540,22 +567,6 @@ alloc_context_vma(struct intel_engine_cs *engine) if (IS_IVYBRIDGE(i915)) i915_gem_object_set_cache_coherency(obj, I915_CACHE_L3_LLC); - if (engine->default_state) { - void *vaddr; - - vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); - if (IS_ERR(vaddr)) { - err = PTR_ERR(vaddr); - goto err_obj; - } - - shmem_read(engine->default_state, 0, - vaddr, engine->context_size); - - i915_gem_object_flush_map(obj); - __i915_gem_object_release_map(obj); - } - vma = i915_vma_instance(obj, >gt->ggtt->vm, NULL); if (IS_ERR(vma)) { err = PTR_ERR(vma); @@ -587,8 +598,6 @@ static int ring_context_alloc(struct intel_context *ce) return PTR_ERR(vma); ce->state = vma; - if (engine->default_state) - __set_bit(CONTEXT_VALID_BIT, >flags); } return 0; @@ -1184,37 +1193,15 @@ static int gen7_ctx_switch_bb_setup(struct intel_engine_cs * const engine, return gen7_setup_clear_gpr_bb(engine, vma); } -static int gen7_ctx_switch_bb_init(struct intel_engine_cs *engine) +static int gen7_ctx_switch_bb_init(struct intel_engine_cs *engine, + struct i915_gem_ww_ctx *ww, + struct i915_vma *vma) { - struct drm_i915_gem_object *obj; - struct i915_vma *vma; - int size; int err; - size = gen7_ctx_switch_bb_setup(engine, NULL /* probe size */); - if (size <= 0) - return size; - - size = ALIGN(size, PAGE_SIZE); - obj = i915_gem_object_create_internal(engine->i915, size); - if (IS_ERR(obj)) - return PTR_ERR(obj); - - vma = i915_vma_instance(obj, engine->gt->vm, NULL); - if (IS_ERR(vma)) { - err = PTR_ERR(vma); - goto err_obj; - } - - vma->private = intel_context_create(engine); /* dummy residuals */ - if (IS_ERR(vma->private)) { - err = PTR_ERR(vma->private); - goto err_obj; - } - - err = i915_vma_pin(vma, 0, 0, PIN_USER | PIN_HIGH); + err = i915_vma_pin_ww(vma, ww, 0, 0, PIN_USER | PIN_HIGH); if (err) - goto err_private; + return err; err = i915_vma_sync(vma); if (err) @@ -1229,17 +1216,53 @@ static int gen7_ctx_switch_bb_init(struct intel_engine_cs *engine) err_unpin: i915_vma_unpin(vma); -err_private: - intel_context_put(vma->private); -err_obj: - i915_gem_object_put(obj); return err; } +static struct i915_vma
[RFC PATCH 029/162] drm/i915: Handle ww locking in init_status_page
From: Maarten Lankhorst Try to pin to ggtt first, and use a full ww loop to handle eviction correctly. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 37 +++ 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 97ceaf7116e8..420c6a35f3ed 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -618,6 +618,7 @@ static void cleanup_status_page(struct intel_engine_cs *engine) } static int pin_ggtt_status_page(struct intel_engine_cs *engine, + struct i915_gem_ww_ctx *ww, struct i915_vma *vma) { unsigned int flags; @@ -638,12 +639,13 @@ static int pin_ggtt_status_page(struct intel_engine_cs *engine, else flags = PIN_HIGH; - return i915_ggtt_pin(vma, NULL, 0, flags); + return i915_ggtt_pin(vma, ww, 0, flags); } static int init_status_page(struct intel_engine_cs *engine) { struct drm_i915_gem_object *obj; + struct i915_gem_ww_ctx ww; struct i915_vma *vma; void *vaddr; int ret; @@ -667,30 +669,39 @@ static int init_status_page(struct intel_engine_cs *engine) vma = i915_vma_instance(obj, >gt->ggtt->vm, NULL); if (IS_ERR(vma)) { ret = PTR_ERR(vma); - goto err; + goto err_put; } + i915_gem_ww_ctx_init(, true); +retry: + ret = i915_gem_object_lock(obj, ); + if (!ret && !HWS_NEEDS_PHYSICAL(engine->i915)) + ret = pin_ggtt_status_page(engine, , vma); + if (ret) + goto err; + vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); if (IS_ERR(vaddr)) { ret = PTR_ERR(vaddr); - goto err; + goto err_unpin; } engine->status_page.addr = memset(vaddr, 0, PAGE_SIZE); engine->status_page.vma = vma; - if (!HWS_NEEDS_PHYSICAL(engine->i915)) { - ret = pin_ggtt_status_page(engine, vma); - if (ret) - goto err_unpin; - } - - return 0; - err_unpin: - i915_gem_object_unpin_map(obj); + if (ret) + i915_vma_unpin(vma); err: - i915_gem_object_put(obj); + if (ret == -EDEADLK) { + ret = i915_gem_ww_ctx_backoff(); + if (!ret) + goto retry; + } + i915_gem_ww_ctx_fini(); +err_put: + if (ret) + i915_gem_object_put(obj); return ret; } -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 021/162] drm/i915: No longer allow exporting userptr through dma-buf
From: Maarten Lankhorst It doesn't make sense to export a memory address, we will prevent allowing access this way to different address spaces when we rework userptr handling, so best to explicitly disable it. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c index 8c3d1eb2f96a..44af6265948d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c @@ -694,10 +694,9 @@ i915_gem_userptr_release(struct drm_i915_gem_object *obj) static int i915_gem_userptr_dmabuf_export(struct drm_i915_gem_object *obj) { - if (obj->userptr.mmu_object) - return 0; + drm_dbg(obj->base.dev, "Exporting userptr no longer allowed\n"); - return i915_gem_userptr_init__mmu_notifier(obj, 0); + return -EINVAL; } static int -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 012/162] drm/i915: Move cmd parser pinning to execbuffer
From: Maarten Lankhorst We need to get rid of allocations in the cmd parser, because it needs to be called from a signaling context, first move all pinning to execbuf, where we already hold all locks. Allocate jump_whitelist in the execbuffer, and add annotations around intel_engine_cmd_parser(), to ensure we only call the command parser without allocating any memory, or taking any locks we're not supposed to. Because i915_gem_object_get_page() may also allocate memory, add a path to i915_gem_object_get_sg() that prevents memory allocations, and walk the sg list manually. It should be similarly fast. This has the added benefit of being able to catch all memory allocation errors before the point of no return, and return -ENOMEM safely to the execbuf submitter. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 74 - drivers/gpu/drm/i915/gem/i915_gem_object.h| 10 +- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 21 +++- drivers/gpu/drm/i915/gt/intel_ggtt.c | 2 +- drivers/gpu/drm/i915/i915_cmd_parser.c| 104 -- drivers/gpu/drm/i915/i915_drv.h | 7 +- drivers/gpu/drm/i915/i915_memcpy.c| 2 +- drivers/gpu/drm/i915/i915_memcpy.h| 2 +- 8 files changed, 142 insertions(+), 80 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 1904e6e5ea64..60afa6f826d6 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -24,6 +24,7 @@ #include "i915_gem_clflush.h" #include "i915_gem_context.h" #include "i915_gem_ioctls.h" +#include "i915_memcpy.h" #include "i915_sw_fence_work.h" #include "i915_trace.h" #include "i915_user_extensions.h" @@ -2273,24 +2274,45 @@ struct eb_parse_work { struct i915_vma *trampoline; unsigned long batch_offset; unsigned long batch_length; + unsigned long *jump_whitelist; + const void *batch_map; + void *shadow_map; }; static int __eb_parse(struct dma_fence_work *work) { struct eb_parse_work *pw = container_of(work, typeof(*pw), base); + int ret; + bool cookie; - return intel_engine_cmd_parser(pw->engine, - pw->batch, - pw->batch_offset, - pw->batch_length, - pw->shadow, - pw->trampoline); + cookie = dma_fence_begin_signalling(); + ret = intel_engine_cmd_parser(pw->engine, + pw->batch, + pw->batch_offset, + pw->batch_length, + pw->shadow, + pw->jump_whitelist, + pw->shadow_map, + pw->batch_map); + dma_fence_end_signalling(cookie); + + return ret; } static void __eb_parse_release(struct dma_fence_work *work) { struct eb_parse_work *pw = container_of(work, typeof(*pw), base); + if (!IS_ERR_OR_NULL(pw->jump_whitelist)) + kfree(pw->jump_whitelist); + + if (pw->batch_map) + i915_gem_object_unpin_map(pw->batch->obj); + else + i915_gem_object_unpin_pages(pw->batch->obj); + + i915_gem_object_unpin_map(pw->shadow->obj); + if (pw->trampoline) i915_active_release(>trampoline->active); i915_active_release(>shadow->active); @@ -2340,6 +2362,8 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb, struct i915_vma *trampoline) { struct eb_parse_work *pw; + struct drm_i915_gem_object *batch = eb->batch->vma->obj; + bool needs_clflush; int err; GEM_BUG_ON(overflows_type(eb->batch_start_offset, pw->batch_offset)); @@ -2363,6 +2387,34 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb, goto err_shadow; } + pw->shadow_map = i915_gem_object_pin_map(shadow->obj, I915_MAP_FORCE_WB); + if (IS_ERR(pw->shadow_map)) { + err = PTR_ERR(pw->shadow_map); + goto err_trampoline; + } + + needs_clflush = + !(batch->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ); + + pw->batch_map = ERR_PTR(-ENODEV); + if (needs_clflush && i915_has_memcpy_from_wc()) + pw->batch_map = i915_gem_object_pin_map(batch, I915_MAP_WC); + + if (IS_ERR(pw->batch_map)) { + err = i915_gem_object_pin_pages(batch); + if (err) + goto err_unmap_shadow; + pw->batch_map = NULL; + } + + pw->jump_whitelist = +
[RFC PATCH 014/162] drm/i915: Ensure we hold the object mutex in pin correctly v2
From: Maarten Lankhorst Currently we have a lot of places where we hold the gem object lock, but haven't yet been converted to the ww dance. Complain loudly about those places. i915_vma_pin shouldn't have the obj lock held, so we can do a ww dance, while i915_vma_pin_ww should. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gt/intel_renderstate.c | 2 +- drivers/gpu/drm/i915/gt/intel_timeline.c| 4 +- drivers/gpu/drm/i915/i915_vma.c | 46 +++-- drivers/gpu/drm/i915/i915_vma.h | 5 +++ 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_renderstate.c b/drivers/gpu/drm/i915/gt/intel_renderstate.c index ea2a77c7b469..a68e5c23a67c 100644 --- a/drivers/gpu/drm/i915/gt/intel_renderstate.c +++ b/drivers/gpu/drm/i915/gt/intel_renderstate.c @@ -196,7 +196,7 @@ int intel_renderstate_init(struct intel_renderstate *so, if (err) goto err_context; - err = i915_vma_pin(so->vma, 0, 0, PIN_GLOBAL | PIN_HIGH); + err = i915_vma_pin_ww(so->vma, >ww, 0, 0, PIN_GLOBAL | PIN_HIGH); if (err) goto err_context; diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c index 479eb5440bc6..b2d04717db20 100644 --- a/drivers/gpu/drm/i915/gt/intel_timeline.c +++ b/drivers/gpu/drm/i915/gt/intel_timeline.c @@ -46,7 +46,7 @@ static int __hwsp_alloc(struct intel_gt *gt, struct intel_timeline_hwsp *hwsp) goto out_unlock; } - /* Pin early so we can call i915_ggtt_pin unlocked. */ + /* Pin early so we can call i915_ggtt_pin_unlocked(). */ hwsp->vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); if (IS_ERR(hwsp->vaddr)) { ret = PTR_ERR(hwsp->vaddr); @@ -514,7 +514,7 @@ __intel_timeline_get_seqno(struct intel_timeline *tl, goto err_rollback; } - err = i915_ggtt_pin(vma, NULL, 0, PIN_HIGH); + err = i915_ggtt_pin_unlocked(vma, 0, PIN_HIGH); if (err) { __idle_hwsp_free(vma->private, cacheline); goto err_rollback; diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 8e8c80ccbe32..e07621825da9 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -862,7 +862,8 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww, unsigned int bound; int err; - if (IS_ENABLED(CONFIG_PROVE_LOCKING) && debug_locks) { +#ifdef CONFIG_PROVE_LOCKING + if (debug_locks) { bool pinned_bind_wo_alloc = vma->obj && i915_gem_object_has_pinned_pages(vma->obj) && !vma->vm->allocate_va_range; @@ -870,7 +871,10 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww, if (lockdep_is_held(>vm->i915->drm.struct_mutex) && !pinned_bind_wo_alloc) WARN_ON(!ww); + if (ww && vma->resv) + assert_vma_held(vma); } +#endif BUILD_BUG_ON(PIN_GLOBAL != I915_VMA_GLOBAL_BIND); BUILD_BUG_ON(PIN_USER != I915_VMA_LOCAL_BIND); @@ -1017,8 +1021,8 @@ static void flush_idle_contexts(struct intel_gt *gt) intel_gt_wait_for_idle(gt, MAX_SCHEDULE_TIMEOUT); } -int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww, - u32 align, unsigned int flags) +static int __i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww, + u32 align, unsigned int flags, bool unlocked) { struct i915_address_space *vm = vma->vm; int err; @@ -1026,7 +1030,10 @@ int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww, GEM_BUG_ON(!i915_vma_is_ggtt(vma)); do { - err = i915_vma_pin_ww(vma, ww, 0, align, flags | PIN_GLOBAL); + if (ww || unlocked) + err = i915_vma_pin_ww(vma, ww, 0, align, flags | PIN_GLOBAL); + else + err = i915_vma_pin(vma, 0, align, flags | PIN_GLOBAL); if (err != -ENOSPC) { if (!err) { err = i915_vma_wait_for_bind(vma); @@ -1045,6 +1052,37 @@ int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww, } while (1); } +int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww, + u32 align, unsigned int flags) +{ +#ifdef CONFIG_LOCKDEP + WARN_ON(!ww && vma->resv && dma_resv_held(vma->resv)); +#endif + + return __i915_ggtt_pin(vma, ww, align, flags, false); +} + +/** + * i915_ggtt_pin_unlocked - Pin a vma to ggtt without the underlying + * object's dma-resv held, but with object pages pinned. + * + * @vma: The vma to pin. + * @align: ggtt alignment. + * @flags: Pinning flags + * + * RETURN: Zero on success,
[RFC PATCH 006/162] drm/i915: split gen8+ flush and bb_start emission functions to their own file
From: Daniele Ceraolo Spurio These functions are independent from the backend used and can therefore be split out of the exelists submission file, so they can be re-used by the upcoming GuC submission backend. Based on a patch by Chris Wilson. Signed-off-by: Daniele Ceraolo Spurio Cc: Chris P Wilson Cc: Tvrtko Ursulin Reviewed-by: John Harrison --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/gt/gen8_engine_cs.c | 393 ++ drivers/gpu/drm/i915/gt/gen8_engine_cs.h | 26 ++ .../drm/i915/gt/intel_execlists_submission.c | 385 + 4 files changed, 421 insertions(+), 384 deletions(-) create mode 100644 drivers/gpu/drm/i915/gt/gen8_engine_cs.c create mode 100644 drivers/gpu/drm/i915/gt/gen8_engine_cs.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index aedbd8f52be8..f9ef5199b124 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -82,6 +82,7 @@ gt-y += \ gt/gen6_engine_cs.o \ gt/gen6_ppgtt.o \ gt/gen7_renderclear.o \ + gt/gen8_engine_cs.o \ gt/gen8_ppgtt.o \ gt/intel_breadcrumbs.o \ gt/intel_context.o \ diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c new file mode 100644 index ..a96fe108685e --- /dev/null +++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c @@ -0,0 +1,393 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2014 Intel Corporation + */ + +#include "i915_drv.h" +#include "intel_execlists_submission.h" /* XXX */ +#include "intel_gpu_commands.h" +#include "intel_ring.h" + +int gen8_emit_flush_render(struct i915_request *request, u32 mode) +{ + bool vf_flush_wa = false, dc_flush_wa = false; + u32 *cs, flags = 0; + int len; + + flags |= PIPE_CONTROL_CS_STALL; + + if (mode & EMIT_FLUSH) { + flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; + flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; + flags |= PIPE_CONTROL_DC_FLUSH_ENABLE; + flags |= PIPE_CONTROL_FLUSH_ENABLE; + } + + if (mode & EMIT_INVALIDATE) { + flags |= PIPE_CONTROL_TLB_INVALIDATE; + flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_QW_WRITE; + flags |= PIPE_CONTROL_STORE_DATA_INDEX; + + /* +* On GEN9: before VF_CACHE_INVALIDATE we need to emit a NULL +* pipe control. +*/ + if (IS_GEN(request->engine->i915, 9)) + vf_flush_wa = true; + + /* WaForGAMHang:kbl */ + if (IS_KBL_GT_REVID(request->engine->i915, 0, KBL_REVID_B0)) + dc_flush_wa = true; + } + + len = 6; + + if (vf_flush_wa) + len += 6; + + if (dc_flush_wa) + len += 12; + + cs = intel_ring_begin(request, len); + if (IS_ERR(cs)) + return PTR_ERR(cs); + + if (vf_flush_wa) + cs = gen8_emit_pipe_control(cs, 0, 0); + + if (dc_flush_wa) + cs = gen8_emit_pipe_control(cs, PIPE_CONTROL_DC_FLUSH_ENABLE, + 0); + + cs = gen8_emit_pipe_control(cs, flags, LRC_PPHWSP_SCRATCH_ADDR); + + if (dc_flush_wa) + cs = gen8_emit_pipe_control(cs, PIPE_CONTROL_CS_STALL, 0); + + intel_ring_advance(request, cs); + + return 0; +} + +int gen8_emit_flush(struct i915_request *request, u32 mode) +{ + u32 cmd, *cs; + + cs = intel_ring_begin(request, 4); + if (IS_ERR(cs)) + return PTR_ERR(cs); + + cmd = MI_FLUSH_DW + 1; + + /* We always require a command barrier so that subsequent +* commands, such as breadcrumb interrupts, are strictly ordered +* wrt the contents of the write cache being flushed to memory +* (and thus being coherent from the CPU). +*/ + cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW; + + if (mode & EMIT_INVALIDATE) { + cmd |= MI_INVALIDATE_TLB; + if (request->engine->class == VIDEO_DECODE_CLASS) + cmd |= MI_INVALIDATE_BSD; + } + + *cs++ = cmd; + *cs++ = LRC_PPHWSP_SCRATCH_ADDR; + *cs++ = 0; /* upper addr */ + *cs++ = 0; /* value */ + intel_ring_advance(request, cs); + + return 0; +} + +int gen11_emit_flush_render(struct i915_request *request, u32 mode) +{ + if (mode & EMIT_FLUSH) { + u32 *cs; + u32 flags = 0; + + flags |= PIPE_CONTROL_CS_STALL; + + flags
[RFC PATCH 011/162] drm/i915: Pin timeline map after first timeline pin, v5.
From: Maarten Lankhorst We're starting to require the reservation lock for pinning, so wait until we have that. Update the selftests to handle this correctly, and ensure pin is called in live_hwsp_rollover_user() and mock_hwsp_freelist(). Signed-off-by: Maarten Lankhorst Reported-by: kernel test robot Cc: Thomas Hellström --- drivers/gpu/drm/i915/gt/intel_timeline.c | 49 ++ drivers/gpu/drm/i915/gt/intel_timeline.h | 1 + .../gpu/drm/i915/gt/intel_timeline_types.h| 1 + drivers/gpu/drm/i915/gt/mock_engine.c | 24 ++- drivers/gpu/drm/i915/gt/selftest_timeline.c | 64 ++- drivers/gpu/drm/i915/i915_selftest.h | 2 + 6 files changed, 96 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c index a58228d1cd3b..479eb5440bc6 100644 --- a/drivers/gpu/drm/i915/gt/intel_timeline.c +++ b/drivers/gpu/drm/i915/gt/intel_timeline.c @@ -229,13 +229,30 @@ static void cacheline_free(struct intel_timeline_cacheline *cl) i915_active_release(>active); } +I915_SELFTEST_EXPORT int +intel_timeline_pin_map(struct intel_timeline *timeline) +{ + if (!timeline->hwsp_cacheline) { + struct drm_i915_gem_object *obj = timeline->hwsp_ggtt->obj; + u32 ofs = offset_in_page(timeline->hwsp_offset); + void *vaddr; + + vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); + if (IS_ERR(vaddr)) + return PTR_ERR(vaddr); + + timeline->hwsp_map = vaddr; + timeline->hwsp_seqno = memset(vaddr + ofs, 0, CACHELINE_BYTES); + } + + return 0; +} + static int intel_timeline_init(struct intel_timeline *timeline, struct intel_gt *gt, struct i915_vma *hwsp, unsigned int offset) { - void *vaddr; - kref_init(>kref); atomic_set(>pin_count, 0); @@ -260,18 +277,15 @@ static int intel_timeline_init(struct intel_timeline *timeline, timeline->hwsp_cacheline = cl; timeline->hwsp_offset = cacheline * CACHELINE_BYTES; - - vaddr = page_mask_bits(cl->vaddr); + timeline->hwsp_map = page_mask_bits(cl->vaddr); + timeline->hwsp_seqno = + memset(timeline->hwsp_map + timeline->hwsp_offset, 0, + CACHELINE_BYTES); } else { timeline->hwsp_offset = offset; - vaddr = i915_gem_object_pin_map(hwsp->obj, I915_MAP_WB); - if (IS_ERR(vaddr)) - return PTR_ERR(vaddr); + timeline->hwsp_map = NULL; } - timeline->hwsp_seqno = - memset(vaddr + timeline->hwsp_offset, 0, CACHELINE_BYTES); - timeline->hwsp_ggtt = i915_vma_get(hwsp); GEM_BUG_ON(timeline->hwsp_offset >= hwsp->size); @@ -306,7 +320,7 @@ static void intel_timeline_fini(struct intel_timeline *timeline) if (timeline->hwsp_cacheline) cacheline_free(timeline->hwsp_cacheline); - else + else if (timeline->hwsp_map) i915_gem_object_unpin_map(timeline->hwsp_ggtt->obj); i915_vma_put(timeline->hwsp_ggtt); @@ -346,9 +360,18 @@ int intel_timeline_pin(struct intel_timeline *tl, struct i915_gem_ww_ctx *ww) if (atomic_add_unless(>pin_count, 1, 0)) return 0; + if (!tl->hwsp_cacheline) { + err = intel_timeline_pin_map(tl); + if (err) + return err; + } + err = i915_ggtt_pin(tl->hwsp_ggtt, ww, 0, PIN_HIGH); - if (err) + if (err) { + if (!tl->hwsp_cacheline) + i915_gem_object_unpin_map(tl->hwsp_ggtt->obj); return err; + } tl->hwsp_offset = i915_ggtt_offset(tl->hwsp_ggtt) + @@ -360,6 +383,8 @@ int intel_timeline_pin(struct intel_timeline *tl, struct i915_gem_ww_ctx *ww) if (atomic_fetch_inc(>pin_count)) { cacheline_release(tl->hwsp_cacheline); __i915_vma_unpin(tl->hwsp_ggtt); + if (!tl->hwsp_cacheline) + i915_gem_object_unpin_map(tl->hwsp_ggtt->obj); } return 0; diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.h b/drivers/gpu/drm/i915/gt/intel_timeline.h index 634acebd0c4b..725bae16237c 100644 --- a/drivers/gpu/drm/i915/gt/intel_timeline.h +++ b/drivers/gpu/drm/i915/gt/intel_timeline.h @@ -114,5 +114,6 @@ void intel_gt_show_timelines(struct intel_gt *gt, const struct i915_request *rq, const char *prefix, int indent)); +I915_SELFTEST_DECLARE(int intel_timeline_pin_map(struct intel_timeline
[RFC PATCH 007/162] drm/i915: split wa_bb code to its own file
From: Daniele Ceraolo Spurio Continuing the split of back-end independent code from the execlist submission specific file. Based on a patch by Chris Wilson. Signed-off-by: Daniele Ceraolo Spurio Cc: Chris P Wilson Cc: Tvrtko Ursulin Reviewed-by: John Harrison --- drivers/gpu/drm/i915/Makefile | 1 + .../drm/i915/gt/intel_engine_workaround_bb.c | 335 ++ .../drm/i915/gt/intel_engine_workaround_bb.h | 14 + .../drm/i915/gt/intel_execlists_submission.c | 327 + 4 files changed, 352 insertions(+), 325 deletions(-) create mode 100644 drivers/gpu/drm/i915/gt/intel_engine_workaround_bb.c create mode 100644 drivers/gpu/drm/i915/gt/intel_engine_workaround_bb.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index f9ef5199b124..2445cc990e15 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -92,6 +92,7 @@ gt-y += \ gt/intel_engine_heartbeat.o \ gt/intel_engine_pm.o \ gt/intel_engine_user.o \ + gt/intel_engine_workaround_bb.o \ gt/intel_execlists_submission.o \ gt/intel_ggtt.o \ gt/intel_ggtt_fencing.o \ diff --git a/drivers/gpu/drm/i915/gt/intel_engine_workaround_bb.c b/drivers/gpu/drm/i915/gt/intel_engine_workaround_bb.c new file mode 100644 index ..b03bdfc92bb2 --- /dev/null +++ b/drivers/gpu/drm/i915/gt/intel_engine_workaround_bb.c @@ -0,0 +1,335 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2014 Intel Corporation + */ + +#include "i915_drv.h" +#include "intel_engine_types.h" +#include "intel_engine_workaround_bb.h" +#include "intel_execlists_submission.h" /* XXX */ +#include "intel_gpu_commands.h" +#include "intel_gt.h" + +/* + * In this WA we need to set GEN8_L3SQCREG4[21:21] and reset it after + * PIPE_CONTROL instruction. This is required for the flush to happen correctly + * but there is a slight complication as this is applied in WA batch where the + * values are only initialized once so we cannot take register value at the + * beginning and reuse it further; hence we save its value to memory, upload a + * constant value with bit21 set and then we restore it back with the saved value. + * To simplify the WA, a constant value is formed by using the default value + * of this register. This shouldn't be a problem because we are only modifying + * it for a short period and this batch in non-premptible. We can ofcourse + * use additional instructions that read the actual value of the register + * at that time and set our bit of interest but it makes the WA complicated. + * + * This WA is also required for Gen9 so extracting as a function avoids + * code duplication. + */ +static u32 * +gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine, u32 *batch) +{ + /* NB no one else is allowed to scribble over scratch + 256! */ + *batch++ = MI_STORE_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT; + *batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4); + *batch++ = intel_gt_scratch_offset(engine->gt, + INTEL_GT_SCRATCH_FIELD_COHERENTL3_WA); + *batch++ = 0; + + *batch++ = MI_LOAD_REGISTER_IMM(1); + *batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4); + *batch++ = 0x4040 | GEN8_LQSC_FLUSH_COHERENT_LINES; + + batch = gen8_emit_pipe_control(batch, + PIPE_CONTROL_CS_STALL | + PIPE_CONTROL_DC_FLUSH_ENABLE, + 0); + + *batch++ = MI_LOAD_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT; + *batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4); + *batch++ = intel_gt_scratch_offset(engine->gt, + INTEL_GT_SCRATCH_FIELD_COHERENTL3_WA); + *batch++ = 0; + + return batch; +} + +/* + * Typically we only have one indirect_ctx and per_ctx batch buffer which are + * initialized at the beginning and shared across all contexts but this field + * helps us to have multiple batches at different offsets and select them based + * on a criteria. At the moment this batch always start at the beginning of the page + * and at this point we don't have multiple wa_ctx batch buffers. + * + * The number of WA applied are not known at the beginning; we use this field + * to return the no of DWORDS written. + * + * It is to be noted that this batch does not contain MI_BATCH_BUFFER_END + * so it adds NOOPs as padding to make it cacheline aligned. + * MI_BATCH_BUFFER_END will be added to perctx batch and both of them together + * makes a complete batch buffer. + */ +static u32 *gen8_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch) +{ + /* WaDisableCtxRestoreArbitration:bdw,chv */ + *batch++ = MI_ARB_ON_OFF | MI_ARB_DISABLE; + + /* WaFlushCoherentL3CacheLinesAtContextSwitch:bdw */ + if (IS_BROADWELL(engine->i915)) + batch =
[RFC PATCH 017/162] drm/i915: Rework struct phys attachment handling
From: Maarten Lankhorst Instead of creating a separate object type, we make changes to the shmem type, to clear struct page backing. This will allow us to ensure we never run into a race when we exchange obj->ops with other function pointers. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_object.h| 8 ++ drivers/gpu/drm/i915/gem/i915_gem_phys.c | 102 +- drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 22 +++- .../drm/i915/gem/selftests/i915_gem_phys.c| 6 -- 4 files changed, 78 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index 16608bf7a4e9..e549b88693a2 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -37,7 +37,15 @@ void __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj, struct sg_table *pages, bool needs_clflush); +int i915_gem_object_pwrite_phys(struct drm_i915_gem_object *obj, + const struct drm_i915_gem_pwrite *args); +int i915_gem_object_pread_phys(struct drm_i915_gem_object *obj, + const struct drm_i915_gem_pread *args); + int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align); +void i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj, + struct sg_table *pages); + void i915_gem_flush_free_objects(struct drm_i915_private *i915); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_phys.c b/drivers/gpu/drm/i915/gem/i915_gem_phys.c index 965590d3a570..4bdd0429c08b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_phys.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_phys.c @@ -76,6 +76,8 @@ static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) intel_gt_chipset_flush(_i915(obj->base.dev)->gt); + /* We're no longer struct page backed */ + obj->flags &= ~I915_BO_ALLOC_STRUCT_PAGE; __i915_gem_object_set_pages(obj, st, sg->length); return 0; @@ -89,7 +91,7 @@ static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) return -ENOMEM; } -static void +void i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj, struct sg_table *pages) { @@ -134,9 +136,8 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj, vaddr, dma); } -static int -phys_pwrite(struct drm_i915_gem_object *obj, - const struct drm_i915_gem_pwrite *args) +int i915_gem_object_pwrite_phys(struct drm_i915_gem_object *obj, + const struct drm_i915_gem_pwrite *args) { void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset; char __user *user_data = u64_to_user_ptr(args->data_ptr); @@ -165,9 +166,8 @@ phys_pwrite(struct drm_i915_gem_object *obj, return 0; } -static int -phys_pread(struct drm_i915_gem_object *obj, - const struct drm_i915_gem_pread *args) +int i915_gem_object_pread_phys(struct drm_i915_gem_object *obj, + const struct drm_i915_gem_pread *args) { void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset; char __user *user_data = u64_to_user_ptr(args->data_ptr); @@ -186,86 +186,82 @@ phys_pread(struct drm_i915_gem_object *obj, return 0; } -static void phys_release(struct drm_i915_gem_object *obj) +static int i915_gem_object_shmem_to_phys(struct drm_i915_gem_object *obj) { - fput(obj->base.filp); -} + struct sg_table *pages; + int err; -static const struct drm_i915_gem_object_ops i915_gem_phys_ops = { - .name = "i915_gem_object_phys", - .get_pages = i915_gem_object_get_pages_phys, - .put_pages = i915_gem_object_put_pages_phys, + pages = __i915_gem_object_unset_pages(obj); + + err = i915_gem_object_get_pages_phys(obj); + if (err) + goto err_xfer; - .pread = phys_pread, - .pwrite = phys_pwrite, + /* Perma-pin (until release) the physical set of pages */ + __i915_gem_object_pin_pages(obj); - .release = phys_release, -}; + if (!IS_ERR_OR_NULL(pages)) + i915_gem_shmem_ops.put_pages(obj, pages); + + i915_gem_object_release_memory_region(obj); + return 0; + +err_xfer: + if (!IS_ERR_OR_NULL(pages)) { + unsigned int sg_page_sizes = i915_sg_page_sizes(pages->sgl); + + __i915_gem_object_set_pages(obj, pages, sg_page_sizes); + } + return err; +} int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align) { - struct sg_table *pages; int err; if (align > obj->base.size) return -EINVAL; - if (obj->ops == _gem_phys_ops) - return 0; - if (obj->ops !=
[RFC PATCH 015/162] drm/i915: Add gem object locking to madvise.
From: Maarten Lankhorst Doesn't need the full ww lock, only checking if pages are bound. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/i915_gem.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 58276694c848..b03e245640c0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1051,10 +1051,14 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, if (!obj) return -ENOENT; - err = mutex_lock_interruptible(>mm.lock); + err = i915_gem_object_lock_interruptible(obj, NULL); if (err) goto out; + err = mutex_lock_interruptible(>mm.lock); + if (err) + goto out_ww; + if (i915_gem_object_has_pages(obj) && i915_gem_object_is_tiled(obj) && i915->quirks & QUIRK_PIN_SWIZZLED_PAGES) { @@ -1099,6 +1103,8 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, args->retained = obj->mm.madv != __I915_MADV_PURGED; mutex_unlock(>mm.lock); +out_ww: + i915_gem_object_unlock(obj); out: i915_gem_object_put(obj); return err; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 009/162] drm/i915: Introduce drm_i915_lock_isolated
From: Thomas Hellström When an object is just created and not yet put on any lists, there's a single owner and thus trylock will always succeed. Introduce drm_i915_lock_isolated to annotate trylock in this situation. This is similar to TTM's create_locked() functionality. Signed-off-by: Thomas Hellström Cc: Matthew Auld --- drivers/gpu/drm/i915/gem/i915_gem_object.h | 16 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index be14486f63a7..d61194ef484e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -107,6 +107,13 @@ i915_gem_object_put(struct drm_i915_gem_object *obj) #define assert_object_held(obj) dma_resv_assert_held((obj)->base.resv) +#define object_is_isolated(obj)\ + (!IS_ENABLED(CONFIG_LOCKDEP) || \ +((kref_read(>base.refcount) == 0) || \ + ((kref_read(>base.refcount) == 1) && \ + list_empty_careful(>mm.link) && \ + list_empty_careful(>vma.list + static inline int __i915_gem_object_lock(struct drm_i915_gem_object *obj, struct i915_gem_ww_ctx *ww, bool intr) @@ -147,6 +154,15 @@ static inline bool i915_gem_object_trylock(struct drm_i915_gem_object *obj) return dma_resv_trylock(obj->base.resv); } +static inline void i915_gem_object_lock_isolated(struct drm_i915_gem_object *obj) +{ + int ret; + + WARN_ON(!object_is_isolated(obj)); + ret = dma_resv_trylock(obj->base.resv); + GEM_WARN_ON(!ret); +} + static inline void i915_gem_object_unlock(struct drm_i915_gem_object *obj) { dma_resv_unlock(obj->base.resv); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 010/162] drm/i915: Lock hwsp objects isolated for pinning at create time
From: Thomas Hellström We may need to create hwsp objects at request treate time in the middle of a ww transaction. Since we typically don't have easy access to the ww_acquire_context, lock the hwsp objects isolated for pinning/mapping only at create time. For later binding to the ggtt, make sure lockdep allows binding of already pinned pages to the ggtt without the underlying object lock held. Signed-off-by: Thomas Hellström Cc: Matthew Auld --- drivers/gpu/drm/i915/gt/intel_timeline.c | 58 ++-- drivers/gpu/drm/i915/i915_vma.c | 13 -- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c index 512afacd2bdc..a58228d1cd3b 100644 --- a/drivers/gpu/drm/i915/gt/intel_timeline.c +++ b/drivers/gpu/drm/i915/gt/intel_timeline.c @@ -24,25 +24,43 @@ struct intel_timeline_hwsp { struct list_head free_link; struct i915_vma *vma; u64 free_bitmap; + void *vaddr; }; -static struct i915_vma *__hwsp_alloc(struct intel_gt *gt) +static int __hwsp_alloc(struct intel_gt *gt, struct intel_timeline_hwsp *hwsp) { struct drm_i915_private *i915 = gt->i915; struct drm_i915_gem_object *obj; - struct i915_vma *vma; + int ret; obj = i915_gem_object_create_internal(i915, PAGE_SIZE); if (IS_ERR(obj)) - return ERR_CAST(obj); + return PTR_ERR(obj); + i915_gem_object_lock_isolated(obj); i915_gem_object_set_cache_coherency(obj, I915_CACHE_LLC); - vma = i915_vma_instance(obj, >ggtt->vm, NULL); - if (IS_ERR(vma)) - i915_gem_object_put(obj); + hwsp->vma = i915_vma_instance(obj, >ggtt->vm, NULL); + if (IS_ERR(hwsp->vma)) { + ret = PTR_ERR(hwsp->vma); + goto out_unlock; + } + + /* Pin early so we can call i915_ggtt_pin unlocked. */ + hwsp->vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); + if (IS_ERR(hwsp->vaddr)) { + ret = PTR_ERR(hwsp->vaddr); + goto out_unlock; + } + + i915_gem_object_unlock(obj); + return 0; + +out_unlock: + i915_gem_object_unlock(obj); + i915_gem_object_put(obj); - return vma; + return ret; } static struct i915_vma * @@ -59,7 +77,7 @@ hwsp_alloc(struct intel_timeline *timeline, unsigned int *cacheline) hwsp = list_first_entry_or_null(>hwsp_free_list, typeof(*hwsp), free_link); if (!hwsp) { - struct i915_vma *vma; + int ret; spin_unlock_irq(>hwsp_lock); @@ -67,17 +85,16 @@ hwsp_alloc(struct intel_timeline *timeline, unsigned int *cacheline) if (!hwsp) return ERR_PTR(-ENOMEM); - vma = __hwsp_alloc(timeline->gt); - if (IS_ERR(vma)) { + ret = __hwsp_alloc(timeline->gt, hwsp); + if (ret) { kfree(hwsp); - return vma; + return ERR_PTR(ret); } GT_TRACE(timeline->gt, "new HWSP allocated\n"); - vma->private = hwsp; + hwsp->vma->private = hwsp; hwsp->gt = timeline->gt; - hwsp->vma = vma; hwsp->free_bitmap = ~0ull; hwsp->gt_timelines = gt; @@ -113,9 +130,12 @@ static void __idle_hwsp_free(struct intel_timeline_hwsp *hwsp, int cacheline) /* And if no one is left using it, give the page back to the system */ if (hwsp->free_bitmap == ~0ull) { - i915_vma_put(hwsp->vma); list_del(>free_link); + spin_unlock_irqrestore(>hwsp_lock, flags); + i915_gem_object_unpin_map(hwsp->vma->obj); + i915_vma_put(hwsp->vma); kfree(hwsp); + return; } spin_unlock_irqrestore(>hwsp_lock, flags); @@ -134,7 +154,6 @@ static void __idle_cacheline_free(struct intel_timeline_cacheline *cl) { GEM_BUG_ON(!i915_active_is_idle(>active)); - i915_gem_object_unpin_map(cl->hwsp->vma->obj); i915_vma_put(cl->hwsp->vma); __idle_hwsp_free(cl->hwsp, ptr_unmask_bits(cl->vaddr, CACHELINE_BITS)); @@ -165,7 +184,6 @@ static struct intel_timeline_cacheline * cacheline_alloc(struct intel_timeline_hwsp *hwsp, unsigned int cacheline) { struct intel_timeline_cacheline *cl; - void *vaddr; GEM_BUG_ON(cacheline >= BIT(CACHELINE_BITS)); @@ -173,15 +191,9 @@ cacheline_alloc(struct intel_timeline_hwsp *hwsp, unsigned int cacheline) if (!cl) return ERR_PTR(-ENOMEM); - vaddr = i915_gem_object_pin_map(hwsp->vma->obj, I915_MAP_WB); - if (IS_ERR(vaddr)) { - kfree(cl); - return ERR_CAST(vaddr); - } -
[RFC PATCH 008/162] HAX drm/i915: Work around the selftest timeline lock splat workaround
From: Thomas Hellström There is a dirty hack to work around a lockdep splat because incorrect ordering of selftest timeline lock against other locks. However, some selftests recently started to use the same nesting level as the workaround and thus introduced more splats. Add a workaround to the workaround making some selftests aware of the workaround. Signed-off-by: Thomas Hellström Cc: Mattew Auld --- drivers/gpu/drm/i915/gt/intel_context.c | 3 ++- drivers/gpu/drm/i915/gt/intel_context.h | 2 ++ drivers/gpu/drm/i915/gt/selftest_timeline.c | 10 ++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c index 349e7fa1488d..b63a8eb6c1a9 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.c +++ b/drivers/gpu/drm/i915/gt/intel_context.c @@ -495,7 +495,8 @@ struct i915_request *intel_context_create_request(struct intel_context *ce) */ lockdep_unpin_lock(>timeline->mutex, rq->cookie); mutex_release(>timeline->mutex.dep_map, _RET_IP_); - mutex_acquire(>timeline->mutex.dep_map, SINGLE_DEPTH_NESTING, 0, _RET_IP_); + mutex_acquire(>timeline->mutex.dep_map, SELFTEST_WA_NESTING, 0, + _RET_IP_); rq->cookie = lockdep_pin_lock(>timeline->mutex); return rq; diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h index fda2eba81e22..175d505951c7 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.h +++ b/drivers/gpu/drm/i915/gt/intel_context.h @@ -25,6 +25,8 @@ ##__VA_ARGS__);\ } while (0) +#define SELFTEST_WA_NESTING SINGLE_DEPTH_NESTING + struct i915_gem_ww_ctx; void intel_context_init(struct intel_context *ce, diff --git a/drivers/gpu/drm/i915/gt/selftest_timeline.c b/drivers/gpu/drm/i915/gt/selftest_timeline.c index e4285d5a0360..fa3fec049542 100644 --- a/drivers/gpu/drm/i915/gt/selftest_timeline.c +++ b/drivers/gpu/drm/i915/gt/selftest_timeline.c @@ -688,7 +688,7 @@ static int live_hwsp_wrap(void *arg) tl->seqno = -4u; - mutex_lock_nested(>mutex, SINGLE_DEPTH_NESTING); + mutex_lock_nested(>mutex, SELFTEST_WA_NESTING + 1); err = intel_timeline_get_seqno(tl, rq, [0]); mutex_unlock(>mutex); if (err) { @@ -705,7 +705,7 @@ static int live_hwsp_wrap(void *arg) } hwsp_seqno[0] = tl->hwsp_seqno; - mutex_lock_nested(>mutex, SINGLE_DEPTH_NESTING); + mutex_lock_nested(>mutex, SELFTEST_WA_NESTING + 1); err = intel_timeline_get_seqno(tl, rq, [1]); mutex_unlock(>mutex); if (err) { @@ -1037,7 +1037,8 @@ static int live_hwsp_read(void *arg) goto out; } - mutex_lock([0].rq->context->timeline->mutex); + mutex_lock_nested([0].rq->context->timeline->mutex, + SELFTEST_WA_NESTING + 1); err = intel_timeline_read_hwsp(rq, watcher[0].rq, ); if (err == 0) err = emit_read_hwsp(watcher[0].rq, /* before */ @@ -1050,7 +1051,8 @@ static int live_hwsp_read(void *arg) goto out; } - mutex_lock([1].rq->context->timeline->mutex); + mutex_lock_nested([1].rq->context->timeline->mutex, + SELFTEST_WA_NESTING + 1); err = intel_timeline_read_hwsp(rq, watcher[1].rq, ); if (err == 0) err = emit_read_hwsp(watcher[1].rq, /* after */ -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 018/162] drm/i915: Convert i915_gem_object_attach_phys() to ww locking, v2.
From: Maarten Lankhorst Simple adding of i915_gem_object_lock, we may start to pass ww to get_pages() in the future, but that won't be the case here; We override shmem's get_pages() handling by calling i915_gem_object_get_pages_phys(), no ww is needed. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_object.h | 2 ++ drivers/gpu/drm/i915/gem/i915_gem_phys.c | 12 ++-- drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 17 ++--- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index e549b88693a2..47da3aff2a79 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -43,6 +43,8 @@ int i915_gem_object_pread_phys(struct drm_i915_gem_object *obj, const struct drm_i915_gem_pread *args); int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align); +void i915_gem_object_put_pages_shmem(struct drm_i915_gem_object *obj, +struct sg_table *pages); void i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj, struct sg_table *pages); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_phys.c b/drivers/gpu/drm/i915/gem/i915_gem_phys.c index 4bdd0429c08b..144e4940eede 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_phys.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_phys.c @@ -201,7 +201,7 @@ static int i915_gem_object_shmem_to_phys(struct drm_i915_gem_object *obj) __i915_gem_object_pin_pages(obj); if (!IS_ERR_OR_NULL(pages)) - i915_gem_shmem_ops.put_pages(obj, pages); + i915_gem_object_put_pages_shmem(obj, pages); i915_gem_object_release_memory_region(obj); return 0; @@ -232,7 +232,13 @@ int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align) if (err) return err; - mutex_lock_nested(>mm.lock, I915_MM_GET_PAGES); + err = i915_gem_object_lock_interruptible(obj, NULL); + if (err) + return err; + + err = mutex_lock_interruptible_nested(>mm.lock, I915_MM_GET_PAGES); + if (err) + goto err_unlock; if (unlikely(!i915_gem_object_has_struct_page(obj))) goto out; @@ -263,6 +269,8 @@ int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align) out: mutex_unlock(>mm.lock); +err_unlock: + i915_gem_object_unlock(obj); return err; } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c index d590e0c3bd00..7a59fd1ea4e5 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c @@ -296,18 +296,12 @@ __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj, __start_cpu_write(obj); } -static void -shmem_put_pages(struct drm_i915_gem_object *obj, struct sg_table *pages) +void i915_gem_object_put_pages_shmem(struct drm_i915_gem_object *obj, struct sg_table *pages) { struct sgt_iter sgt_iter; struct pagevec pvec; struct page *page; - if (unlikely(!i915_gem_object_has_struct_page(obj))) { - i915_gem_object_put_pages_phys(obj, pages); - return; - } - __i915_gem_object_release_shmem(obj, pages, true); i915_gem_gtt_finish_pages(obj, pages); @@ -336,6 +330,15 @@ shmem_put_pages(struct drm_i915_gem_object *obj, struct sg_table *pages) kfree(pages); } +static void +shmem_put_pages(struct drm_i915_gem_object *obj, struct sg_table *pages) +{ + if (likely(i915_gem_object_has_struct_page(obj))) + i915_gem_object_put_pages_shmem(obj, pages); + else + i915_gem_object_put_pages_phys(obj, pages); +} + static int shmem_pwrite(struct drm_i915_gem_object *obj, const struct drm_i915_gem_pwrite *arg) -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 016/162] drm/i915: Move HAS_STRUCT_PAGE to obj->flags
From: Maarten Lankhorst We want to remove the changing of ops structure for attaching phys pages, so we need to kill off HAS_STRUCT_PAGE from ops->flags, and put it in the bo. This will remove a potential race of dereferencing the wrong obj->ops without ww mutex held. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_internal.c | 6 +++--- drivers/gpu/drm/i915/gem/i915_gem_lmem.c | 4 ++-- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 7 +++ drivers/gpu/drm/i915/gem/i915_gem_object.c | 4 +++- drivers/gpu/drm/i915/gem/i915_gem_object.h | 5 +++-- drivers/gpu/drm/i915/gem/i915_gem_object_types.h | 8 +--- drivers/gpu/drm/i915/gem/i915_gem_pages.c| 5 ++--- drivers/gpu/drm/i915/gem/i915_gem_phys.c | 2 ++ drivers/gpu/drm/i915/gem/i915_gem_region.c | 4 +--- drivers/gpu/drm/i915/gem/i915_gem_region.h | 3 +-- drivers/gpu/drm/i915/gem/i915_gem_shmem.c| 8 drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 4 ++-- drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 6 +++--- drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c | 4 ++-- drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 10 +- drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c | 11 --- drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c | 12 drivers/gpu/drm/i915/gvt/dmabuf.c| 2 +- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c| 2 +- drivers/gpu/drm/i915/selftests/mock_region.c | 4 ++-- 21 files changed, 62 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c index 04e9c04545ad..36e3c2765f4c 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c @@ -258,7 +258,7 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev, } drm_gem_private_object_init(dev, >base, dma_buf->size); - i915_gem_object_init(obj, _gem_object_dmabuf_ops, _class); + i915_gem_object_init(obj, _gem_object_dmabuf_ops, _class, 0); obj->base.import_attach = attach; obj->base.resv = dma_buf->resv; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c index ad22f42541bd..21cc40897ca8 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c @@ -138,8 +138,7 @@ static void i915_gem_object_put_pages_internal(struct drm_i915_gem_object *obj, static const struct drm_i915_gem_object_ops i915_gem_object_internal_ops = { .name = "i915_gem_object_internal", - .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE | -I915_GEM_OBJECT_IS_SHRINKABLE, + .flags = I915_GEM_OBJECT_IS_SHRINKABLE, .get_pages = i915_gem_object_get_pages_internal, .put_pages = i915_gem_object_put_pages_internal, }; @@ -178,7 +177,8 @@ i915_gem_object_create_internal(struct drm_i915_private *i915, return ERR_PTR(-ENOMEM); drm_gem_private_object_init(>drm, >base, size); - i915_gem_object_init(obj, _gem_object_internal_ops, _class); + i915_gem_object_init(obj, _gem_object_internal_ops, _class, +I915_BO_ALLOC_STRUCT_PAGE); /* * Mark the object as volatile, such that the pages are marked as diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c index 932ee21e6609..e953965f8263 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c @@ -45,13 +45,13 @@ __i915_gem_lmem_object_create(struct intel_memory_region *mem, return ERR_PTR(-ENOMEM); drm_gem_private_object_init(>drm, >base, size); - i915_gem_object_init(obj, _gem_lmem_obj_ops, _class); + i915_gem_object_init(obj, _gem_lmem_obj_ops, _class, flags); obj->read_domains = I915_GEM_DOMAIN_WC | I915_GEM_DOMAIN_GTT; i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE); - i915_gem_object_init_memory_region(obj, mem, flags); + i915_gem_object_init_memory_region(obj, mem); return obj; } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c index ec28a6cde49b..c0034d811e50 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c @@ -251,7 +251,7 @@ static vm_fault_t vm_fault_cpu(struct vm_fault *vmf) goto out; iomap = -1; - if (!i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_STRUCT_PAGE)) { + if (!i915_gem_object_has_struct_page(obj)) { iomap = obj->mm.region->iomap.base; iomap -=
[RFC PATCH 013/162] drm/i915: Add missing -EDEADLK handling to execbuf pinning, v2.
From: Maarten Lankhorst i915_vma_pin may fail with -EDEADLK when we start locking page tables, so ensure we handle this correctly. Cc: Matthew Brost Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 35 +-- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 60afa6f826d6..568c8321dc3d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -419,13 +419,14 @@ static u64 eb_pin_flags(const struct drm_i915_gem_exec_object2 *entry, return pin_flags; } -static inline bool +static inline int eb_pin_vma(struct i915_execbuffer *eb, const struct drm_i915_gem_exec_object2 *entry, struct eb_vma *ev) { struct i915_vma *vma = ev->vma; u64 pin_flags; + int err; if (vma->node.size) pin_flags = vma->node.start; @@ -437,24 +438,29 @@ eb_pin_vma(struct i915_execbuffer *eb, pin_flags |= PIN_GLOBAL; /* Attempt to reuse the current location if available */ - /* TODO: Add -EDEADLK handling here */ - if (unlikely(i915_vma_pin_ww(vma, >ww, 0, 0, pin_flags))) { + err = i915_vma_pin_ww(vma, >ww, 0, 0, pin_flags); + if (err == -EDEADLK) + return err; + + if (unlikely(err)) { if (entry->flags & EXEC_OBJECT_PINNED) - return false; + return err; /* Failing that pick any _free_ space if suitable */ - if (unlikely(i915_vma_pin_ww(vma, >ww, + err = i915_vma_pin_ww(vma, >ww, entry->pad_to_size, entry->alignment, eb_pin_flags(entry, ev->flags) | -PIN_USER | PIN_NOEVICT))) - return false; +PIN_USER | PIN_NOEVICT); + if (unlikely(err)) + return err; } if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) { - if (unlikely(i915_vma_pin_fence(vma))) { + err = i915_vma_pin_fence(vma); + if (unlikely(err)) { i915_vma_unpin(vma); - return false; + return err; } if (vma->fence) @@ -462,7 +468,10 @@ eb_pin_vma(struct i915_execbuffer *eb, } ev->flags |= __EXEC_OBJECT_HAS_PIN; - return !eb_vma_misplaced(entry, vma, ev->flags); + if (eb_vma_misplaced(entry, vma, ev->flags)) + return -EBADSLT; + + return 0; } static inline void @@ -900,7 +909,11 @@ static int eb_validate_vmas(struct i915_execbuffer *eb) if (err) return err; - if (eb_pin_vma(eb, entry, ev)) { + err = eb_pin_vma(eb, entry, ev); + if (err == -EDEADLK) + return err; + + if (!err) { if (entry->offset != vma->node.start) { entry->offset = vma->node.start | UPDATE; eb->args->flags |= __EXEC_HAS_RELOC; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 020/162] drm/i915: Disable userptr pread/pwrite support.
From: Maarten Lankhorst Userptr should not need the kernel for a userspace memcpy, userspace needs to call memcpy directly. Specifically, disable i915_gem_pwrite_ioctl() and i915_gem_pread_ioctl(). Still needs an ack from relevant userspace that it won't break, but should be good. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c index 30edc5a0a54e..8c3d1eb2f96a 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c @@ -700,6 +700,24 @@ i915_gem_userptr_dmabuf_export(struct drm_i915_gem_object *obj) return i915_gem_userptr_init__mmu_notifier(obj, 0); } +static int +i915_gem_userptr_pwrite(struct drm_i915_gem_object *obj, + const struct drm_i915_gem_pwrite *args) +{ + drm_dbg(obj->base.dev, "pwrite to userptr no longer allowed\n"); + + return -EINVAL; +} + +static int +i915_gem_userptr_pread(struct drm_i915_gem_object *obj, + const struct drm_i915_gem_pread *args) +{ + drm_dbg(obj->base.dev, "pread from userptr no longer allowed\n"); + + return -EINVAL; +} + static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = { .name = "i915_gem_object_userptr", .flags = I915_GEM_OBJECT_IS_SHRINKABLE | @@ -708,6 +726,8 @@ static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = { .get_pages = i915_gem_userptr_get_pages, .put_pages = i915_gem_userptr_put_pages, .dmabuf_export = i915_gem_userptr_dmabuf_export, + .pwrite = i915_gem_userptr_pwrite, + .pread = i915_gem_userptr_pread, .release = i915_gem_userptr_release, }; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 019/162] drm/i915: make lockdep slightly happier about execbuf.
From: Maarten Lankhorst As soon as we install fences, we should stop allocating memory in order to prevent any potential deadlocks. This is required later on, when we start adding support for dma-fence annotations. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 24 ++- drivers/gpu/drm/i915/i915_active.c| 20 drivers/gpu/drm/i915/i915_vma.c | 8 --- drivers/gpu/drm/i915/i915_vma.h | 3 +++ 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 568c8321dc3d..31e412e5c68a 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -49,11 +49,12 @@ enum { #define DBG_FORCE_RELOC 0 /* choose one of the above! */ }; -#define __EXEC_OBJECT_HAS_PIN BIT(31) -#define __EXEC_OBJECT_HAS_FENCEBIT(30) -#define __EXEC_OBJECT_NEEDS_MAPBIT(29) -#define __EXEC_OBJECT_NEEDS_BIAS BIT(28) -#define __EXEC_OBJECT_INTERNAL_FLAGS (~0u << 28) /* all of the above */ +/* __EXEC_OBJECT_NO_RESERVE is BIT(31), defined in i915_vma.h */ +#define __EXEC_OBJECT_HAS_PIN BIT(30) +#define __EXEC_OBJECT_HAS_FENCEBIT(29) +#define __EXEC_OBJECT_NEEDS_MAPBIT(28) +#define __EXEC_OBJECT_NEEDS_BIAS BIT(27) +#define __EXEC_OBJECT_INTERNAL_FLAGS (~0u << 27) /* all of the above + */ #define __EXEC_OBJECT_RESERVED (__EXEC_OBJECT_HAS_PIN | __EXEC_OBJECT_HAS_FENCE) #define __EXEC_HAS_RELOC BIT(31) @@ -929,6 +930,12 @@ static int eb_validate_vmas(struct i915_execbuffer *eb) } } + if (!(ev->flags & EXEC_OBJECT_WRITE)) { + err = dma_resv_reserve_shared(vma->resv, 1); + if (err) + return err; + } + GEM_BUG_ON(drm_mm_node_allocated(>node) && eb_vma_misplaced(>exec[i], vma, ev->flags)); } @@ -2194,7 +2201,8 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb) } if (err == 0) - err = i915_vma_move_to_active(vma, eb->request, flags); + err = i915_vma_move_to_active(vma, eb->request, + flags | __EXEC_OBJECT_NO_RESERVE); } if (unlikely(err)) @@ -2446,6 +2454,10 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb, if (err) goto err_commit; + err = dma_resv_reserve_shared(shadow->resv, 1); + if (err) + goto err_commit; + /* Wait for all writes (and relocs) into the batch to complete */ err = i915_sw_fence_await_reservation(>base.chain, pw->batch->resv, NULL, false, diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c index 10a865f3dc09..6ba4f878ab0e 100644 --- a/drivers/gpu/drm/i915/i915_active.c +++ b/drivers/gpu/drm/i915/i915_active.c @@ -296,18 +296,13 @@ static struct active_node *__active_lookup(struct i915_active *ref, u64 idx) static struct i915_active_fence * active_instance(struct i915_active *ref, u64 idx) { - struct active_node *node, *prealloc; + struct active_node *node; struct rb_node **p, *parent; node = __active_lookup(ref, idx); if (likely(node)) return >base; - /* Preallocate a replacement, just in case */ - prealloc = kmem_cache_alloc(global.slab_cache, GFP_KERNEL); - if (!prealloc) - return NULL; - spin_lock_irq(>tree_lock); GEM_BUG_ON(i915_active_is_idle(ref)); @@ -317,10 +312,8 @@ active_instance(struct i915_active *ref, u64 idx) parent = *p; node = rb_entry(parent, struct active_node, node); - if (node->timeline == idx) { - kmem_cache_free(global.slab_cache, prealloc); + if (node->timeline == idx) goto out; - } if (node->timeline < idx) p = >rb_right; @@ -328,7 +321,14 @@ active_instance(struct i915_active *ref, u64 idx) p = >rb_left; } - node = prealloc; + /* +* XXX: We should preallocate this before i915_active_ref() is ever +* called, but we cannot call into fs_reclaim() anyway, so use GFP_ATOMIC. +*/ + node = kmem_cache_alloc(global.slab_cache, GFP_ATOMIC); + if (!node) + goto out; + __i915_active_fence_init(>base, NULL, node_retire); node->ref = ref; node->timeline = idx; diff --git a/drivers/gpu/drm/i915/i915_vma.c
[RFC PATCH 022/162] drm/i915: Reject more ioctls for userptr
From: Maarten Lankhorst There are a couple of ioctl's related to tiling and cache placement, that make no sense for userptr, reject those: - i915_gem_set_tiling_ioctl() Tiling should always be linear for userptr. Changing placement will fail with -ENXIO. - i915_gem_set_caching_ioctl() Userptr memory should always be cached. Changing will fail with -ENXIO. - i915_gem_set_domain_ioctl() Changed to be equivalent to gem_wait, which is correct for the cached linear userptr pointers. This is required because we cannot grab a reference to the pages in the rework, but waiting for idle will do the same. Still needs an ack from relevant userspace that it won't break, but should be good. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_domain.c | 4 +++- drivers/gpu/drm/i915/gem/i915_gem_object.h | 6 ++ drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 3 ++- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ba26545392bc..f36921a3c4bc 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -17854,7 +17854,7 @@ static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb, struct drm_i915_gem_object *obj = intel_fb_obj(fb); struct drm_i915_private *i915 = to_i915(obj->base.dev); - if (obj->userptr.mm) { + if (i915_gem_object_is_userptr(obj)) { drm_dbg(>drm, "attempting to use a userptr for a framebuffer, denied\n"); return -EINVAL; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c b/drivers/gpu/drm/i915/gem/i915_gem_domain.c index fcce6909f201..c1d4bf62b3ea 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c @@ -528,7 +528,9 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, * considered to be outside of any cache domain. */ if (i915_gem_object_is_proxy(obj)) { - err = -ENXIO; + /* silently allow userptr to complete */ + if (!i915_gem_object_is_userptr(obj)) + err = -ENXIO; goto out; } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index 47da3aff2a79..95907b8eb4c4 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -551,6 +551,12 @@ void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj, void __i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj, enum fb_op_origin origin); +static inline bool +i915_gem_object_is_userptr(struct drm_i915_gem_object *obj) +{ + return obj->userptr.mm; +} + static inline void i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj, enum fb_op_origin origin) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c index 44af6265948d..64a946d5f753 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c @@ -721,7 +721,8 @@ static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = { .name = "i915_gem_object_userptr", .flags = I915_GEM_OBJECT_IS_SHRINKABLE | I915_GEM_OBJECT_NO_MMAP | -I915_GEM_OBJECT_ASYNC_CANCEL, +I915_GEM_OBJECT_ASYNC_CANCEL | +I915_GEM_OBJECT_IS_PROXY, .get_pages = i915_gem_userptr_get_pages, .put_pages = i915_gem_userptr_put_pages, .dmabuf_export = i915_gem_userptr_dmabuf_export, -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [REGRESSION] omapdrm/N900 display broken
On 25/11/2020 11:07, Daniel Vetter wrote: >> Laurent, does this ring any bells? The WARN comes in >> drm_atomic_bridge_chain_enable() when >> drm_atomic_get_old_bridge_state() returns null for (presumably) sdi bridge. >> >> I'm not sure why the bridge state would not be there. > > Lack of state on first modeset usually means your > drm_mode_config_reset didn't create one. Or whatever it is you're > using. I didn't look whether you're wiring this up correctly or not. > We might even want to add a ->reset function to > drm_private_state_funcs to make this work for everyone. The bridge driver set atomic_enable and atomic_disable, but no other atomic funcs. It was supposed to set the legacy enable & disable. Tomi -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2] fbdev: aty: SPARC64 requires FB_ATY_CT
On Fri, Nov 27, 2020 at 4:18 AM Randy Dunlap wrote: > It looks like SPARC64 requires FB_ATY_CT to build without errors, > so have FB_ATY select FB_ATY_CT if both SPARC64 and PCI are enabled > instead of using "default y if SPARC64 && PCI", which is not strong > enough to prevent build errors. > > As it currently is, FB_ATY_CT can be disabled, resulting in build > errors: > > ERROR: modpost: "aty_postdividers" [drivers/video/fbdev/aty/atyfb.ko] > undefined! > ERROR: modpost: "aty_ld_pll_ct" [drivers/video/fbdev/aty/atyfb.ko] undefined! > > Fixes: f7018c213502 ("video: move fbdev to drivers/video/fbdev") > Signed-off-by: Randy Dunlap Reviewed-by: Geert Uytterhoeven Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/komeda: Handle NULL pointer access code path in error case
From: Carsten Haitzler komeda_component_get_old_state() technically can return a NULL pointer. komeda_compiz_set_input() even warns when this happens, but then proceeeds to use that NULL pointer tocompare memory content there agains the new sate to see if it changed. In this case, it's better to assume that the input changed as there is no old state to compare against and thus assume the changes happen anyway. Signed-off-by: Carsten Haitzler --- drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c index 8f32ae7c25d0..e8b1e15312d8 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c @@ -707,7 +707,8 @@ komeda_compiz_set_input(struct komeda_compiz *compiz, WARN_ON(!old_st); /* compare with old to check if this input has been changed */ - if (memcmp(&(to_compiz_st(old_st)->cins[idx]), cin, sizeof(*cin))) + if (!old_st || + memcmp(&(to_compiz_st(old_st)->cins[idx]), cin, sizeof(*cin))) c_st->changed_active_inputs |= BIT(idx); komeda_component_add_input(c_st, >input, idx); -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/komeda: Remove useless variable assignment
From: Carsten Haitzler ret is not actually read after this (only written in one case then returned), so this assign line is useless. This removes that assignment. Signed-off-by: Carsten Haitzler --- drivers/gpu/drm/arm/display/komeda/komeda_dev.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c index 1d767473ba8a..eea76f51f662 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c @@ -163,7 +163,6 @@ static int komeda_parse_dt(struct device *dev, struct komeda_dev *mdev) ret = of_reserved_mem_device_init(dev); if (ret && ret != -ENODEV) return ret; - ret = 0; for_each_available_child_of_node(np, child) { if (of_node_name_eq(child, "pipeline")) { -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 042/162] drm/i915: Add igt_spinner_pin() to allow for ww locking around spinner.
From: Maarten Lankhorst By default, we assume that it's called inside igt_create_request to keep existing selftests working, but allow for manual pinning when passing a ww context. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/selftests/igt_spinner.c | 136 --- drivers/gpu/drm/i915/selftests/igt_spinner.h | 5 + 2 files changed, 95 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/i915/selftests/igt_spinner.c b/drivers/gpu/drm/i915/selftests/igt_spinner.c index ec0ecb4e4ca6..9c461edb0b73 100644 --- a/drivers/gpu/drm/i915/selftests/igt_spinner.c +++ b/drivers/gpu/drm/i915/selftests/igt_spinner.c @@ -11,8 +11,6 @@ int igt_spinner_init(struct igt_spinner *spin, struct intel_gt *gt) { - unsigned int mode; - void *vaddr; int err; memset(spin, 0, sizeof(*spin)); @@ -23,6 +21,7 @@ int igt_spinner_init(struct igt_spinner *spin, struct intel_gt *gt) err = PTR_ERR(spin->hws); goto err; } + i915_gem_object_set_cache_coherency(spin->hws, I915_CACHE_LLC); spin->obj = i915_gem_object_create_internal(gt->i915, PAGE_SIZE); if (IS_ERR(spin->obj)) { @@ -30,34 +29,83 @@ int igt_spinner_init(struct igt_spinner *spin, struct intel_gt *gt) goto err_hws; } - i915_gem_object_set_cache_coherency(spin->hws, I915_CACHE_LLC); - vaddr = i915_gem_object_pin_map(spin->hws, I915_MAP_WB); - if (IS_ERR(vaddr)) { - err = PTR_ERR(vaddr); - goto err_obj; - } - spin->seqno = memset(vaddr, 0xff, PAGE_SIZE); - - mode = i915_coherent_map_type(gt->i915); - vaddr = i915_gem_object_pin_map(spin->obj, mode); - if (IS_ERR(vaddr)) { - err = PTR_ERR(vaddr); - goto err_unpin_hws; - } - spin->batch = vaddr; - return 0; -err_unpin_hws: - i915_gem_object_unpin_map(spin->hws); -err_obj: - i915_gem_object_put(spin->obj); err_hws: i915_gem_object_put(spin->hws); err: return err; } +static void *igt_spinner_pin_obj(struct intel_context *ce, +struct i915_gem_ww_ctx *ww, +struct drm_i915_gem_object *obj, +unsigned int mode, struct i915_vma **vma) +{ + void *vaddr; + int ret; + + *vma = i915_vma_instance(obj, ce->vm, NULL); + if (IS_ERR(*vma)) + return ERR_CAST(*vma); + + ret = i915_gem_object_lock(obj, ww); + if (ret) + return ERR_PTR(ret); + + vaddr = i915_gem_object_pin_map(obj, mode); + + if (!ww) + i915_gem_object_unlock(obj); + + if (IS_ERR(vaddr)) + return vaddr; + + if (ww) + ret = i915_vma_pin_ww(*vma, ww, 0, 0, PIN_USER); + else + ret = i915_vma_pin(*vma, 0, 0, PIN_USER); + + if (ret) { + i915_gem_object_unpin_map(obj); + return ERR_PTR(ret); + } + + return vaddr; +} + +int igt_spinner_pin(struct igt_spinner *spin, + struct intel_context *ce, + struct i915_gem_ww_ctx *ww) +{ + void *vaddr; + + if (spin->ce && WARN_ON(spin->ce != ce)) + return -ENODEV; + spin->ce = ce; + + if (!spin->seqno) { + vaddr = igt_spinner_pin_obj(ce, ww, spin->hws, I915_MAP_WB, >hws_vma); + if (IS_ERR(vaddr)) + return PTR_ERR(vaddr); + + spin->seqno = memset(vaddr, 0xff, PAGE_SIZE); + } + + if (!spin->batch) { + unsigned int mode = + i915_coherent_map_type(spin->gt->i915); + + vaddr = igt_spinner_pin_obj(ce, ww, spin->obj, mode, >batch_vma); + if (IS_ERR(vaddr)) + return PTR_ERR(vaddr); + + spin->batch = vaddr; + } + + return 0; +} + static unsigned int seqno_offset(u64 fence) { return offset_in_page(sizeof(u32) * fence); @@ -102,27 +150,18 @@ igt_spinner_create_request(struct igt_spinner *spin, if (!intel_engine_can_store_dword(ce->engine)) return ERR_PTR(-ENODEV); - vma = i915_vma_instance(spin->obj, ce->vm, NULL); - if (IS_ERR(vma)) - return ERR_CAST(vma); - - hws = i915_vma_instance(spin->hws, ce->vm, NULL); - if (IS_ERR(hws)) - return ERR_CAST(hws); + if (!spin->batch) { + err = igt_spinner_pin(spin, ce, NULL); + if (err) + return ERR_PTR(err); + } - err = i915_vma_pin(vma, 0, 0, PIN_USER); - if (err) - return ERR_PTR(err); - - err = i915_vma_pin(hws, 0, 0, PIN_USER); - if (err) - goto unpin_vma; + hws = spin->hws_vma; + vma = spin->batch_vma; rq =
[RFC PATCH 057/162] drm/i915/selftests: Prepare object tests for obj->mm.lock removal.
From: Maarten Lankhorst Convert a single pin_pages call to use the unlocked version. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c index bf853c40ec65..740ee8086a27 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c @@ -47,7 +47,7 @@ static int igt_gem_huge(void *arg) if (IS_ERR(obj)) return PTR_ERR(obj); - err = i915_gem_object_pin_pages(obj); + err = i915_gem_object_pin_pages_unlocked(obj); if (err) { pr_err("Failed to allocate %u pages (%lu total), err=%d\n", nreal, obj->base.size / PAGE_SIZE, err); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 059/162] drm/i915/selftests: Prepare igt_gem_utils for obj->mm.lock removal
From: Maarten Lankhorst igt_emit_store_dw needs to use the unlocked version, as it's not holding a lock. This fixes igt_gpu_fill_dw() which is used by some other selftests. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/selftests/igt_gem_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/selftests/igt_gem_utils.c b/drivers/gpu/drm/i915/gem/selftests/igt_gem_utils.c index e21b5023ca7d..f4e85b4a347d 100644 --- a/drivers/gpu/drm/i915/gem/selftests/igt_gem_utils.c +++ b/drivers/gpu/drm/i915/gem/selftests/igt_gem_utils.c @@ -54,7 +54,7 @@ igt_emit_store_dw(struct i915_vma *vma, if (IS_ERR(obj)) return ERR_CAST(obj); - cmd = i915_gem_object_pin_map(obj, I915_MAP_WC); + cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC); if (IS_ERR(cmd)) { err = PTR_ERR(cmd); goto err; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 060/162] drm/i915/selftests: Prepare context selftest for obj->mm.lock removal
From: Maarten Lankhorst Only needs to convert a single call to the unlocked version. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gt/selftest_context.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/selftest_context.c b/drivers/gpu/drm/i915/gt/selftest_context.c index 1f4020e906a8..d9b0ebc938f1 100644 --- a/drivers/gpu/drm/i915/gt/selftest_context.c +++ b/drivers/gpu/drm/i915/gt/selftest_context.c @@ -88,8 +88,8 @@ static int __live_context_size(struct intel_engine_cs *engine) if (err) goto err; - vaddr = i915_gem_object_pin_map(ce->state->obj, - i915_coherent_map_type(engine->i915)); + vaddr = i915_gem_object_pin_map_unlocked(ce->state->obj, + i915_coherent_map_type(engine->i915)); if (IS_ERR(vaddr)) { err = PTR_ERR(vaddr); intel_context_unpin(ce); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 061/162] drm/i915/selftests: Prepare hangcheck for obj->mm.lock removal
From: Maarten Lankhorst Convert a few calls to use the unlocked versions. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gt/selftest_hangcheck.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c index fb5ebf930ab2..e3027cebab5b 100644 --- a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c +++ b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c @@ -80,15 +80,15 @@ static int hang_init(struct hang *h, struct intel_gt *gt) } i915_gem_object_set_cache_coherency(h->hws, I915_CACHE_LLC); - vaddr = i915_gem_object_pin_map(h->hws, I915_MAP_WB); + vaddr = i915_gem_object_pin_map_unlocked(h->hws, I915_MAP_WB); if (IS_ERR(vaddr)) { err = PTR_ERR(vaddr); goto err_obj; } h->seqno = memset(vaddr, 0xff, PAGE_SIZE); - vaddr = i915_gem_object_pin_map(h->obj, - i915_coherent_map_type(gt->i915)); + vaddr = i915_gem_object_pin_map_unlocked(h->obj, + i915_coherent_map_type(gt->i915)); if (IS_ERR(vaddr)) { err = PTR_ERR(vaddr); goto err_unpin_hws; @@ -149,7 +149,7 @@ hang_create_request(struct hang *h, struct intel_engine_cs *engine) return ERR_CAST(obj); } - vaddr = i915_gem_object_pin_map(obj, i915_coherent_map_type(gt->i915)); + vaddr = i915_gem_object_pin_map_unlocked(obj, i915_coherent_map_type(gt->i915)); if (IS_ERR(vaddr)) { i915_gem_object_put(obj); i915_vm_put(vm); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 058/162] drm/i915/selftests: Prepare object blit tests for obj->mm.lock removal.
From: Maarten Lankhorst Use some unlocked versions where we're not holding the ww lock. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c index 23b6e11bbc3e..ee9496f3d11d 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c @@ -262,7 +262,7 @@ static int igt_fill_blt_thread(void *arg) goto err_flush; } - vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); + vaddr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB); if (IS_ERR(vaddr)) { err = PTR_ERR(vaddr); goto err_put; @@ -380,7 +380,7 @@ static int igt_copy_blt_thread(void *arg) goto err_flush; } - vaddr = i915_gem_object_pin_map(src, I915_MAP_WB); + vaddr = i915_gem_object_pin_map_unlocked(src, I915_MAP_WB); if (IS_ERR(vaddr)) { err = PTR_ERR(vaddr); goto err_put_src; @@ -400,7 +400,7 @@ static int igt_copy_blt_thread(void *arg) goto err_put_src; } - vaddr = i915_gem_object_pin_map(dst, I915_MAP_WB); + vaddr = i915_gem_object_pin_map_unlocked(dst, I915_MAP_WB); if (IS_ERR(vaddr)) { err = PTR_ERR(vaddr); goto err_put_dst; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 062/162] drm/i915/selftests: Prepare execlists for obj->mm.lock removal
From: Maarten Lankhorst Convert normal functions to unlocked versions where needed. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gt/selftest_execlists.c | 34 ++-- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/selftest_execlists.c b/drivers/gpu/drm/i915/gt/selftest_execlists.c index 95d41c01d0e0..124011f6fb51 100644 --- a/drivers/gpu/drm/i915/gt/selftest_execlists.c +++ b/drivers/gpu/drm/i915/gt/selftest_execlists.c @@ -1007,7 +1007,7 @@ static int live_timeslice_preempt(void *arg) goto err_obj; } - vaddr = i915_gem_object_pin_map(obj, I915_MAP_WC); + vaddr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC); if (IS_ERR(vaddr)) { err = PTR_ERR(vaddr); goto err_obj; @@ -1315,7 +1315,7 @@ static int live_timeslice_queue(void *arg) goto err_obj; } - vaddr = i915_gem_object_pin_map(obj, I915_MAP_WC); + vaddr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC); if (IS_ERR(vaddr)) { err = PTR_ERR(vaddr); goto err_obj; @@ -1562,7 +1562,7 @@ static int live_busywait_preempt(void *arg) goto err_ctx_lo; } - map = i915_gem_object_pin_map(obj, I915_MAP_WC); + map = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC); if (IS_ERR(map)) { err = PTR_ERR(map); goto err_obj; @@ -2678,7 +2678,7 @@ static int create_gang(struct intel_engine_cs *engine, if (err) goto err_obj; - cs = i915_gem_object_pin_map(obj, I915_MAP_WC); + cs = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC); if (IS_ERR(cs)) goto err_obj; @@ -2960,7 +2960,7 @@ static int live_preempt_gang(void *arg) * it will terminate the next lowest spinner until there * are no more spinners and the gang is complete. */ - cs = i915_gem_object_pin_map(rq->batch->obj, I915_MAP_WC); + cs = i915_gem_object_pin_map_unlocked(rq->batch->obj, I915_MAP_WC); if (!IS_ERR(cs)) { *cs = 0; i915_gem_object_unpin_map(rq->batch->obj); @@ -3025,7 +3025,7 @@ create_gpr_user(struct intel_engine_cs *engine, return ERR_PTR(err); } - cs = i915_gem_object_pin_map(obj, I915_MAP_WC); + cs = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC); if (IS_ERR(cs)) { i915_vma_put(vma); return ERR_CAST(cs); @@ -3235,7 +3235,7 @@ static int live_preempt_user(void *arg) if (IS_ERR(global)) return PTR_ERR(global); - result = i915_gem_object_pin_map(global->obj, I915_MAP_WC); + result = i915_gem_object_pin_map_unlocked(global->obj, I915_MAP_WC); if (IS_ERR(result)) { i915_vma_unpin_and_release(, 0); return PTR_ERR(result); @@ -3628,7 +3628,7 @@ static int live_preempt_smoke(void *arg) goto err_free; } - cs = i915_gem_object_pin_map(smoke.batch, I915_MAP_WB); + cs = i915_gem_object_pin_map_unlocked(smoke.batch, I915_MAP_WB); if (IS_ERR(cs)) { err = PTR_ERR(cs); goto err_batch; @@ -4231,7 +4231,7 @@ static int preserved_virtual_engine(struct intel_gt *gt, goto out_end; } - cs = i915_gem_object_pin_map(scratch->obj, I915_MAP_WB); + cs = i915_gem_object_pin_map_unlocked(scratch->obj, I915_MAP_WB); if (IS_ERR(cs)) { err = PTR_ERR(cs); goto out_end; @@ -5259,7 +5259,7 @@ static int __live_lrc_gpr(struct intel_engine_cs *engine, goto err_rq; } - cs = i915_gem_object_pin_map(scratch->obj, I915_MAP_WB); + cs = i915_gem_object_pin_map_unlocked(scratch->obj, I915_MAP_WB); if (IS_ERR(cs)) { err = PTR_ERR(cs); goto err_rq; @@ -5553,7 +5553,7 @@ store_context(struct intel_context *ce, struct i915_vma *scratch) if (IS_ERR(batch)) return batch; - cs = i915_gem_object_pin_map(batch->obj, I915_MAP_WC); + cs = i915_gem_object_pin_map_unlocked(batch->obj, I915_MAP_WC); if (IS_ERR(cs)) { i915_vma_put(batch); return ERR_CAST(cs); @@ -5717,7 +5717,7 @@ static struct i915_vma *load_context(struct intel_context *ce, u32 poison) if (IS_ERR(batch)) return batch; - cs = i915_gem_object_pin_map(batch->obj, I915_MAP_WC); + cs = i915_gem_object_pin_map_unlocked(batch->obj, I915_MAP_WC); if (IS_ERR(cs)) { i915_vma_put(batch); return ERR_CAST(cs); @@ -5831,29 +5831,29 @@ static int compare_isolation(struct intel_engine_cs *engine, u32 *defaults; int
[RFC PATCH 067/162] drm/i915/selftests: Prepare memory region tests for obj->mm.lock removal
From: Maarten Lankhorst Use the unlocked variants for pin_map and pin_pages, and add lock around unpinning/putting pages. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- .../drm/i915/selftests/intel_memory_region.c | 18 +++--- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c index 27389fb19951..9c20b7065fc5 100644 --- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c +++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c @@ -31,10 +31,12 @@ static void close_objects(struct intel_memory_region *mem, struct drm_i915_gem_object *obj, *on; list_for_each_entry_safe(obj, on, objects, st_link) { + i915_gem_object_lock(obj, NULL); if (i915_gem_object_has_pinned_pages(obj)) i915_gem_object_unpin_pages(obj); /* No polluting the memory region between tests */ __i915_gem_object_put_pages(obj); + i915_gem_object_unlock(obj); list_del(>st_link); i915_gem_object_put(obj); } @@ -69,7 +71,7 @@ static int igt_mock_fill(void *arg) break; } - err = i915_gem_object_pin_pages(obj); + err = i915_gem_object_pin_pages_unlocked(obj); if (err) { i915_gem_object_put(obj); break; @@ -109,7 +111,7 @@ igt_object_create(struct intel_memory_region *mem, if (IS_ERR(obj)) return obj; - err = i915_gem_object_pin_pages(obj); + err = i915_gem_object_pin_pages_unlocked(obj); if (err) goto put; @@ -123,8 +125,10 @@ igt_object_create(struct intel_memory_region *mem, static void igt_object_release(struct drm_i915_gem_object *obj) { + i915_gem_object_lock(obj, NULL); i915_gem_object_unpin_pages(obj); __i915_gem_object_put_pages(obj); + i915_gem_object_unlock(obj); list_del(>st_link); i915_gem_object_put(obj); } @@ -356,7 +360,7 @@ static int igt_cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val) if (err) return err; - ptr = i915_gem_object_pin_map(obj, I915_MAP_WC); + ptr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC); if (IS_ERR(ptr)) return PTR_ERR(ptr); @@ -461,7 +465,7 @@ static int igt_lmem_create(void *arg) if (IS_ERR(obj)) return PTR_ERR(obj); - err = i915_gem_object_pin_pages(obj); + err = i915_gem_object_pin_pages_unlocked(obj); if (err) goto out_put; @@ -500,7 +504,7 @@ static int igt_lmem_write_gpu(void *arg) goto out_file; } - err = i915_gem_object_pin_pages(obj); + err = i915_gem_object_pin_pages_unlocked(obj); if (err) goto out_put; @@ -572,7 +576,7 @@ static int igt_lmem_write_cpu(void *arg) if (IS_ERR(obj)) return PTR_ERR(obj); - vaddr = i915_gem_object_pin_map(obj, I915_MAP_WC); + vaddr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC); if (IS_ERR(vaddr)) { err = PTR_ERR(vaddr); goto out_put; @@ -676,7 +680,7 @@ create_region_for_mapping(struct intel_memory_region *mr, u64 size, u32 type, return obj; } - addr = i915_gem_object_pin_map(obj, type); + addr = i915_gem_object_pin_map_unlocked(obj, type); if (IS_ERR(addr)) { i915_gem_object_put(obj); if (PTR_ERR(addr) == -ENXIO) -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 063/162] drm/i915/selftests: Prepare mocs tests for obj->mm.lock removal
From: Maarten Lankhorst Use pin_map_unlocked when we're not holding locks. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gt/selftest_mocs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/selftest_mocs.c b/drivers/gpu/drm/i915/gt/selftest_mocs.c index 21dcd91cbd62..eadb41b76d33 100644 --- a/drivers/gpu/drm/i915/gt/selftest_mocs.c +++ b/drivers/gpu/drm/i915/gt/selftest_mocs.c @@ -105,7 +105,7 @@ static int live_mocs_init(struct live_mocs *arg, struct intel_gt *gt) if (IS_ERR(arg->scratch)) return PTR_ERR(arg->scratch); - arg->vaddr = i915_gem_object_pin_map(arg->scratch->obj, I915_MAP_WB); + arg->vaddr = i915_gem_object_pin_map_unlocked(arg->scratch->obj, I915_MAP_WB); if (IS_ERR(arg->vaddr)) { err = PTR_ERR(arg->vaddr); goto err_scratch; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 065/162] drm/i915/selftests: Prepare timeline tests for obj->mm.lock removal
From: Maarten Lankhorst We can no longer call intel_timeline_pin with a null argument, so add a ww loop that locks the backing object. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gt/selftest_timeline.c | 28 ++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/selftest_timeline.c b/drivers/gpu/drm/i915/gt/selftest_timeline.c index 7435abf5a703..d468147a03de 100644 --- a/drivers/gpu/drm/i915/gt/selftest_timeline.c +++ b/drivers/gpu/drm/i915/gt/selftest_timeline.c @@ -37,6 +37,26 @@ static unsigned long hwsp_cacheline(struct intel_timeline *tl) return (address + offset_in_page(tl->hwsp_offset)) / CACHELINE_BYTES; } +static int selftest_tl_pin(struct intel_timeline *tl) +{ + struct i915_gem_ww_ctx ww; + int err; + + i915_gem_ww_ctx_init(, false); +retry: + err = i915_gem_object_lock(tl->hwsp_ggtt->obj, ); + if (!err) + err = intel_timeline_pin(tl, ); + + if (err == -EDEADLK) { + err = i915_gem_ww_ctx_backoff(); + if (!err) + goto retry; + } + i915_gem_ww_ctx_fini(); + return err; +} + #define CACHELINES_PER_PAGE (PAGE_SIZE / CACHELINE_BYTES) struct mock_hwsp_freelist { @@ -78,7 +98,7 @@ static int __mock_hwsp_timeline(struct mock_hwsp_freelist *state, if (IS_ERR(tl)) return PTR_ERR(tl); - err = intel_timeline_pin(tl, NULL); + err = selftest_tl_pin(tl); if (err) { intel_timeline_put(tl); return err; @@ -464,7 +484,7 @@ checked_tl_write(struct intel_timeline *tl, struct intel_engine_cs *engine, u32 struct i915_request *rq; int err; - err = intel_timeline_pin(tl, NULL); + err = selftest_tl_pin(tl); if (err) { rq = ERR_PTR(err); goto out; @@ -664,7 +684,7 @@ static int live_hwsp_wrap(void *arg) if (!tl->has_initial_breadcrumb || !tl->hwsp_cacheline) goto out_free; - err = intel_timeline_pin(tl, NULL); + err = selftest_tl_pin(tl); if (err) goto out_free; @@ -811,7 +831,7 @@ static int setup_watcher(struct hwsp_watcher *w, struct intel_gt *gt) if (IS_ERR(obj)) return PTR_ERR(obj); - w->map = i915_gem_object_pin_map(obj, I915_MAP_WB); + w->map = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB); if (IS_ERR(w->map)) { i915_gem_object_put(obj); return PTR_ERR(w->map); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 053/162] drm/i915/selftests: Prepare context tests for obj->mm.lock removal.
From: Maarten Lankhorst Straightforward conversion, just convert a bunch of calls to unlocked versions. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c index d3f87dc4eda3..5fef592390cb 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c @@ -1094,7 +1094,7 @@ __read_slice_count(struct intel_context *ce, if (ret < 0) return ret; - buf = i915_gem_object_pin_map(obj, I915_MAP_WB); + buf = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB); if (IS_ERR(buf)) { ret = PTR_ERR(buf); return ret; @@ -1511,7 +1511,7 @@ static int write_to_scratch(struct i915_gem_context *ctx, if (IS_ERR(obj)) return PTR_ERR(obj); - cmd = i915_gem_object_pin_map(obj, I915_MAP_WB); + cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB); if (IS_ERR(cmd)) { err = PTR_ERR(cmd); goto out; @@ -1622,7 +1622,7 @@ static int read_from_scratch(struct i915_gem_context *ctx, if (err) goto out_vm; - cmd = i915_gem_object_pin_map(obj, I915_MAP_WB); + cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB); if (IS_ERR(cmd)) { err = PTR_ERR(cmd); goto out; @@ -1658,7 +1658,7 @@ static int read_from_scratch(struct i915_gem_context *ctx, if (err) goto out_vm; - cmd = i915_gem_object_pin_map(obj, I915_MAP_WB); + cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB); if (IS_ERR(cmd)) { err = PTR_ERR(cmd); goto out; @@ -1715,7 +1715,7 @@ static int read_from_scratch(struct i915_gem_context *ctx, if (err) goto out_vm; - cmd = i915_gem_object_pin_map(obj, I915_MAP_WB); + cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB); if (IS_ERR(cmd)) { err = PTR_ERR(cmd); goto out_vm; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 052/162] drm/i915/selftests: Prepare coherency tests for obj->mm.lock removal.
From: Maarten Lankhorst Straightforward conversion, just convert a bunch of calls to unlocked versions. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c index 2e439bb269d6..42aa3c5e0621 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c @@ -159,7 +159,7 @@ static int wc_set(struct context *ctx, unsigned long offset, u32 v) if (err) return err; - map = i915_gem_object_pin_map(ctx->obj, I915_MAP_WC); + map = i915_gem_object_pin_map_unlocked(ctx->obj, I915_MAP_WC); if (IS_ERR(map)) return PTR_ERR(map); @@ -182,7 +182,7 @@ static int wc_get(struct context *ctx, unsigned long offset, u32 *v) if (err) return err; - map = i915_gem_object_pin_map(ctx->obj, I915_MAP_WC); + map = i915_gem_object_pin_map_unlocked(ctx->obj, I915_MAP_WC); if (IS_ERR(map)) return PTR_ERR(map); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 050/162] drm/i915/selftests: Prepare huge_pages testcases for obj->mm.lock removal.
From: Maarten Lankhorst Straightforward conversion, just convert a bunch of calls to unlocked versions. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- .../gpu/drm/i915/gem/selftests/huge_pages.c | 28 ++- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index 709c63b9cfc4..586d8bafd7de 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -589,7 +589,7 @@ static int igt_mock_ppgtt_misaligned_dma(void *arg) goto out_put; } - err = i915_gem_object_pin_pages(obj); + err = i915_gem_object_pin_pages_unlocked(obj); if (err) goto out_put; @@ -653,15 +653,19 @@ static int igt_mock_ppgtt_misaligned_dma(void *arg) break; } + i915_gem_object_lock(obj, NULL); i915_gem_object_unpin_pages(obj); __i915_gem_object_put_pages(obj); + i915_gem_object_unlock(obj); i915_gem_object_put(obj); } return 0; out_unpin: + i915_gem_object_lock(obj, NULL); i915_gem_object_unpin_pages(obj); + i915_gem_object_unlock(obj); out_put: i915_gem_object_put(obj); @@ -675,8 +679,10 @@ static void close_object_list(struct list_head *objects, list_for_each_entry_safe(obj, on, objects, st_link) { list_del(>st_link); + i915_gem_object_lock(obj, NULL); i915_gem_object_unpin_pages(obj); __i915_gem_object_put_pages(obj); + i915_gem_object_unlock(obj); i915_gem_object_put(obj); } } @@ -713,7 +719,7 @@ static int igt_mock_ppgtt_huge_fill(void *arg) break; } - err = i915_gem_object_pin_pages(obj); + err = i915_gem_object_pin_pages_unlocked(obj); if (err) { i915_gem_object_put(obj); break; @@ -889,7 +895,7 @@ static int igt_mock_ppgtt_64K(void *arg) if (IS_ERR(obj)) return PTR_ERR(obj); - err = i915_gem_object_pin_pages(obj); + err = i915_gem_object_pin_pages_unlocked(obj); if (err) goto out_object_put; @@ -943,8 +949,10 @@ static int igt_mock_ppgtt_64K(void *arg) } i915_vma_unpin(vma); + i915_gem_object_lock(obj, NULL); i915_gem_object_unpin_pages(obj); __i915_gem_object_put_pages(obj); + i915_gem_object_unlock(obj); i915_gem_object_put(obj); } } @@ -954,7 +962,9 @@ static int igt_mock_ppgtt_64K(void *arg) out_vma_unpin: i915_vma_unpin(vma); out_object_unpin: + i915_gem_object_lock(obj, NULL); i915_gem_object_unpin_pages(obj); + i915_gem_object_unlock(obj); out_object_put: i915_gem_object_put(obj); @@ -1024,7 +1034,7 @@ static int __cpu_check_vmap(struct drm_i915_gem_object *obj, u32 dword, u32 val) if (err) return err; - ptr = i915_gem_object_pin_map(obj, I915_MAP_WC); + ptr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC); if (IS_ERR(ptr)) return PTR_ERR(ptr); @@ -1304,7 +1314,7 @@ static int igt_ppgtt_smoke_huge(void *arg) return err; } - err = i915_gem_object_pin_pages(obj); + err = i915_gem_object_pin_pages_unlocked(obj); if (err) { if (err == -ENXIO || err == -E2BIG) { i915_gem_object_put(obj); @@ -1327,8 +1337,10 @@ static int igt_ppgtt_smoke_huge(void *arg) __func__, size, i); } out_unpin: + i915_gem_object_lock(obj, NULL); i915_gem_object_unpin_pages(obj); __i915_gem_object_put_pages(obj); + i915_gem_object_unlock(obj); out_put: i915_gem_object_put(obj); @@ -1402,7 +1414,7 @@ static int igt_ppgtt_sanity_check(void *arg) return err; } - err = i915_gem_object_pin_pages(obj); + err = i915_gem_object_pin_pages_unlocked(obj); if (err) { i915_gem_object_put(obj); goto out; @@ -1416,8 +1428,10 @@ static int igt_ppgtt_sanity_check(void *arg) err = igt_write_huge(ctx, obj); +
[RFC PATCH 051/162] drm/i915/selftests: Prepare client blit for obj->mm.lock removal.
From: Maarten Lankhorst Straightforward conversion, just convert a bunch of calls to unlocked versions. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c index 4e36d4897ea6..cc782569765f 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c @@ -47,7 +47,7 @@ static int __igt_client_fill(struct intel_engine_cs *engine) goto err_flush; } - vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); + vaddr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB); if (IS_ERR(vaddr)) { err = PTR_ERR(vaddr); goto err_put; @@ -159,7 +159,7 @@ static int prepare_blit(const struct tiled_blits *t, u32 src_pitch, dst_pitch; u32 cmd, *cs; - cs = i915_gem_object_pin_map(batch, I915_MAP_WC); + cs = i915_gem_object_pin_map_unlocked(batch, I915_MAP_WC); if (IS_ERR(cs)) return PTR_ERR(cs); @@ -379,7 +379,7 @@ static int verify_buffer(const struct tiled_blits *t, y = i915_prandom_u32_max_state(t->height, prng); p = y * t->width + x; - vaddr = i915_gem_object_pin_map(buf->vma->obj, I915_MAP_WC); + vaddr = i915_gem_object_pin_map_unlocked(buf->vma->obj, I915_MAP_WC); if (IS_ERR(vaddr)) return PTR_ERR(vaddr); @@ -566,7 +566,7 @@ static int tiled_blits_prepare(struct tiled_blits *t, int err; int i; - map = i915_gem_object_pin_map(t->scratch.vma->obj, I915_MAP_WC); + map = i915_gem_object_pin_map_unlocked(t->scratch.vma->obj, I915_MAP_WC); if (IS_ERR(map)) return PTR_ERR(map); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 046/162] drm/i915: Add ww locking to dma-buf ops.
From: Maarten Lankhorst vmap is using pin_pages, but needs to use ww locking, add pin_pages_unlocked to correctly lock the mapping. Also add ww locking to begin/end cpu access. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 60 -- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c index 36e3c2765f4c..c4b01e819786 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c @@ -82,7 +82,7 @@ static int i915_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); void *vaddr; - vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); + vaddr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB); if (IS_ERR(vaddr)) return PTR_ERR(vaddr); @@ -123,42 +123,48 @@ static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, enum dma_data_dire { struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); bool write = (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE); + struct i915_gem_ww_ctx ww; int err; - err = i915_gem_object_pin_pages(obj); - if (err) - return err; - - err = i915_gem_object_lock_interruptible(obj, NULL); - if (err) - goto out; - - err = i915_gem_object_set_to_cpu_domain(obj, write); - i915_gem_object_unlock(obj); - -out: - i915_gem_object_unpin_pages(obj); + i915_gem_ww_ctx_init(, true); +retry: + err = i915_gem_object_lock(obj, ); + if (!err) + err = i915_gem_object_pin_pages(obj); + if (!err) { + err = i915_gem_object_set_to_cpu_domain(obj, write); + i915_gem_object_unpin_pages(obj); + } + if (err == -EDEADLK) { + err = i915_gem_ww_ctx_backoff(); + if (!err) + goto retry; + } + i915_gem_ww_ctx_fini(); return err; } static int i915_gem_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction) { struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); + struct i915_gem_ww_ctx ww; int err; - err = i915_gem_object_pin_pages(obj); - if (err) - return err; - - err = i915_gem_object_lock_interruptible(obj, NULL); - if (err) - goto out; - - err = i915_gem_object_set_to_gtt_domain(obj, false); - i915_gem_object_unlock(obj); - -out: - i915_gem_object_unpin_pages(obj); + i915_gem_ww_ctx_init(, true); +retry: + err = i915_gem_object_lock(obj, ); + if (!err) + err = i915_gem_object_pin_pages(obj); + if (!err) { + err = i915_gem_object_set_to_gtt_domain(obj, false); + i915_gem_object_unpin_pages(obj); + } + if (err == -EDEADLK) { + err = i915_gem_ww_ctx_backoff(); + if (!err) + goto retry; + } + i915_gem_ww_ctx_fini(); return err; } -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 044/162] drm/i915: Increase ww locking for perf.
From: Maarten Lankhorst We need to lock a few more objects, some temporarily, add ww lock where needed. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/i915_perf.c | 56 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 0b300e0d9561..1f574d29ece5 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -1587,7 +1587,7 @@ static int alloc_oa_buffer(struct i915_perf_stream *stream) stream->oa_buffer.vma = vma; stream->oa_buffer.vaddr = - i915_gem_object_pin_map(bo, I915_MAP_WB); + i915_gem_object_pin_map_unlocked(bo, I915_MAP_WB); if (IS_ERR(stream->oa_buffer.vaddr)) { ret = PTR_ERR(stream->oa_buffer.vaddr); goto err_unpin; @@ -1640,6 +1640,7 @@ static int alloc_noa_wait(struct i915_perf_stream *stream) const u32 base = stream->engine->mmio_base; #define CS_GPR(x) GEN8_RING_CS_GPR(base, x) u32 *batch, *ts0, *cs, *jump; + struct i915_gem_ww_ctx ww; int ret, i; enum { START_TS, @@ -1657,15 +1658,21 @@ static int alloc_noa_wait(struct i915_perf_stream *stream) return PTR_ERR(bo); } + i915_gem_ww_ctx_init(, true); +retry: + ret = i915_gem_object_lock(bo, ); + if (ret) + goto out_ww; + /* * We pin in GGTT because we jump into this buffer now because * multiple OA config BOs will have a jump to this address and it * needs to be fixed during the lifetime of the i915/perf stream. */ - vma = i915_gem_object_ggtt_pin(bo, NULL, 0, 0, PIN_HIGH); + vma = i915_gem_object_ggtt_pin_ww(bo, , NULL, 0, 0, PIN_HIGH); if (IS_ERR(vma)) { ret = PTR_ERR(vma); - goto err_unref; + goto out_ww; } batch = cs = i915_gem_object_pin_map(bo, I915_MAP_WB); @@ -1799,12 +1806,19 @@ static int alloc_noa_wait(struct i915_perf_stream *stream) __i915_gem_object_release_map(bo); stream->noa_wait = vma; - return 0; + goto out_ww; err_unpin: i915_vma_unpin_and_release(, 0); -err_unref: - i915_gem_object_put(bo); +out_ww: + if (ret == -EDEADLK) { + ret = i915_gem_ww_ctx_backoff(); + if (!ret) + goto retry; + } + i915_gem_ww_ctx_fini(); + if (ret) + i915_gem_object_put(bo); return ret; } @@ -1847,6 +1861,7 @@ alloc_oa_config_buffer(struct i915_perf_stream *stream, { struct drm_i915_gem_object *obj; struct i915_oa_config_bo *oa_bo; + struct i915_gem_ww_ctx ww; size_t config_length = 0; u32 *cs; int err; @@ -1867,10 +1882,16 @@ alloc_oa_config_buffer(struct i915_perf_stream *stream, goto err_free; } + i915_gem_ww_ctx_init(, true); +retry: + err = i915_gem_object_lock(obj, ); + if (err) + goto out_ww; + cs = i915_gem_object_pin_map(obj, I915_MAP_WB); if (IS_ERR(cs)) { err = PTR_ERR(cs); - goto err_oa_bo; + goto out_ww; } cs = write_cs_mi_lri(cs, @@ -1898,19 +1919,28 @@ alloc_oa_config_buffer(struct i915_perf_stream *stream, NULL); if (IS_ERR(oa_bo->vma)) { err = PTR_ERR(oa_bo->vma); - goto err_oa_bo; + goto out_ww; } oa_bo->oa_config = i915_oa_config_get(oa_config); llist_add(_bo->node, >oa_config_bos); - return oa_bo; +out_ww: + if (err == -EDEADLK) { + err = i915_gem_ww_ctx_backoff(); + if (!err) + goto retry; + } + i915_gem_ww_ctx_fini(); -err_oa_bo: - i915_gem_object_put(obj); + if (err) + i915_gem_object_put(obj); err_free: - kfree(oa_bo); - return ERR_PTR(err); + if (err) { + kfree(oa_bo); + return ERR_PTR(err); + } + return oa_bo; } static struct i915_vma * -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 055/162] drm/i915/selftests: Prepare execbuf tests for obj->mm.lock removal.
From: Maarten Lankhorst Also quite simple, a single call needs to use the unlocked version. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/selftests/i915_gem_execbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_execbuffer.c index e1d50a5a1477..4df505e4c53a 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_execbuffer.c @@ -116,7 +116,7 @@ static int igt_gpu_reloc(void *arg) if (IS_ERR(scratch)) return PTR_ERR(scratch); - map = i915_gem_object_pin_map(scratch, I915_MAP_WC); + map = i915_gem_object_pin_map_unlocked(scratch, I915_MAP_WC); if (IS_ERR(map)) { err = PTR_ERR(map); goto err_scratch; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel