[RFC PATCH 001/162] drm/i915/selftest: also consider non-contiguous objects

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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()

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Tomi Valkeinen
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

2020-11-27 Thread Thomas Zimmermann
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

2020-11-27 Thread Steven Price

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

2020-11-27 Thread Tian Tao
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

2020-11-27 Thread Maxime Ripard
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

2020-11-27 Thread Qinglang Miao
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

2020-11-27 Thread Xu Wang
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

2020-11-27 Thread Dmitry Baryshkov
- 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

2020-11-27 Thread Qinglang Miao
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

2020-11-27 Thread Tian Tao
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

2020-11-27 Thread Qinglang Miao
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

2020-11-27 Thread Iskren Chernev
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

2020-11-27 Thread Xu Wang
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

2020-11-27 Thread Qinglang Miao
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

2020-11-27 Thread Randy Dunlap
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
** 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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
** 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()

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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(){}

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthias Brugger

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

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Tomi Valkeinen
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

2020-11-27 Thread Geert Uytterhoeven
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

2020-11-27 Thread carsten . haitzler
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

2020-11-27 Thread carsten . haitzler
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.

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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.

2020-11-27 Thread Matthew Auld
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


  1   2   3   4   >