Re: [Intel-gfx] [PATCH v2 1/2] drm/i915: Prepare for multiple GTs

2022-01-18 Thread Abdiel Janulgue

On 14.1.2022 19.59, Andi Shyti wrote:

Hi Matt,

[...]


-int intel_uncore_setup_mmio(struct intel_uncore *uncore)
+int intel_uncore_setup_mmio(struct intel_uncore *uncore, phys_addr_t phys_addr)
  {
struct drm_i915_private *i915 = uncore->i915;
-   struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
-   int mmio_bar;
int mmio_size;
  
-	mmio_bar = GRAPHICS_VER(i915) == 2 ? 1 : 0;

/*
 * Before gen4, the registers and the GTT are behind different BARs.
 * However, from gen4 onwards, the registers and the GTT are shared
@@ -2044,7 +2041,7 @@ int intel_uncore_setup_mmio(struct intel_uncore *uncore)
else
mmio_size = 2 * 1024 * 1024;
  
-	uncore->regs = pci_iomap(pdev, mmio_bar, mmio_size);

+   uncore->regs = ioremap(phys_addr, mmio_size);


Is there a specific reason we switch to ioremap() instead of
pci_iomap_range()?  I.e., we could pass 'phys_offset' rather than
'phys_addr' and call

 pci_iomap_range(pdev, mmio_bar, phys_offset, mmio_size);

Not that it really matters too much either way as far as I can see;
ioremap()/iounmap() should work fine too.


this was originally changed by Abdiel (I think) and I left as it
is as I tried to change as less as I could from the original
work.


Hey,

It’s been awhile and this code has changed a lot! I remember needing the 
unmapped phys_addr of each tile’s mmio_bar as well when I refactored 
this spot (setup_mmio) so its GGTT portion can be ioremapped according 
to ggtt_probe_common.


Cheers!
Abdiel



Reviewed-by: Matt Roper 


Thank you!

Andi


Re: [Intel-gfx] [PATCH 3/5] drm/i915/gem: Store mmap_offsets in an rbtree rather than a plain list

2020-01-20 Thread Abdiel Janulgue


On 20/01/2020 12.49, Chris Wilson wrote:
> Currently we create a new mmap_offset for every call to
> mmap_offset_ioctl. This exposes ourselves to an abusive client that may
> simply create new mmap_offsets ad infinitum, which will exhaust physical
> memory and the virtual address space. In addition to the exhaustion, a
> very long linear list of mmap_offsets causes other clients using the
> object to incur long list walks -- these long lists can also be
> generated by simply having many clients generate their own mmap_offset.
> 
> However, we can simply use the drm_vma_node itself to manage the file
> association (allow/revoke) dropping our need to keep an mmo per-file.
> Then if we keep a small rbtree of per-type mmap_offsets, we can lookup
> duplicate requests quickly.

As discussed, rbtree does do away with the limitation of the linear list

Reviewed-by: Abdiel Janulgue 

> Fixes: cc662126b413 ("drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET")
> Signed-off-by: Chris Wilson 
> Cc: Abdiel Janulgue 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH i-g-t] i915/gem_mmap_offset: Exercise many, many mmap_offset

2020-01-20 Thread Abdiel Janulgue



On 17/01/2020 23.11, Chris Wilson wrote:
> Just keep on generating a new mmap_offset for the same old buffer, but
> for different handles and so exercise the scaling of the obj->mmo lists.
> 

Reviewed-by: Abdiel Janulgue 

> Signed-off-by: Chris Wilson 
> Cc: Abdiel Janulgue 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 1/3] drm/i915: Introduce remap_io_sg() to prefault discontiguous objects

2019-12-22 Thread Abdiel Janulgue
Provide a way to set the PTE within apply_page_range for discontiguous
objects in addition to the existing method of just incrementing the pfn
for a page range.

Signed-off-by: Abdiel Janulgue 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_drv.h |  3 ++
 drivers/gpu/drm/i915/i915_mm.c  | 67 +
 2 files changed, 70 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 95db8017f138..71a20387f931 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2015,6 +2015,9 @@ int i915_reg_read_ioctl(struct drm_device *dev, void 
*data,
 int remap_io_mapping(struct vm_area_struct *vma,
 unsigned long addr, unsigned long pfn, unsigned long size,
 struct io_mapping *iomap);
+int remap_io_sg(struct vm_area_struct *vma,
+   unsigned long addr, resource_size_t io_start, struct 
scatterlist *sgl,
+   unsigned long size, struct io_mapping *iomap);
 
 static inline int intel_hws_csb_write_index(struct drm_i915_private *i915)
 {
diff --git a/drivers/gpu/drm/i915/i915_mm.c b/drivers/gpu/drm/i915/i915_mm.c
index 318562ce64c0..4ae9ef470ad2 100644
--- a/drivers/gpu/drm/i915/i915_mm.c
+++ b/drivers/gpu/drm/i915/i915_mm.c
@@ -32,7 +32,13 @@
 struct remap_pfn {
struct mm_struct *mm;
unsigned long pfn;
+   unsigned long start_pfn;
+   unsigned long size;
pgprot_t prot;
+
+   resource_size_t io_start;
+   struct sg_dma_page_iter sgiter;
+   struct scatterlist *sgl;
 };
 
 static int remap_pfn(pte_t *pte, unsigned long addr, void *data)
@@ -46,6 +52,31 @@ static int remap_pfn(pte_t *pte, unsigned long addr, void 
*data)
return 0;
 }
 
+static int remap_io(pte_t *pte, unsigned long addr, void *data)
+{
+   struct remap_pfn *r = data;
+   struct sg_dma_page_iter *sgiter = >sgiter;
+   if (!r->pfn)
+   __sg_page_iter_start(>base, r->sgl,
+r->size >> PAGE_SHIFT, 0);
+
+   if (__sg_page_iter_dma_next(sgiter)) {
+   dma_addr_t addr = sg_page_iter_dma_address(sgiter);
+   unsigned long pfn = (r->io_start + addr) >> PAGE_SHIFT;
+
+   if (!r->pfn)
+   r->start_pfn = pfn;
+   r->pfn = pfn;
+   /* Special PTE are not associated with any struct page */
+   set_pte_at(r->mm, addr, pte, pte_mkspecial(pfn_pte(r->pfn, 
r->prot)));
+
+   return 0;
+   }
+
+   GEM_WARN_ON("invalid range");
+   return -EINVAL;
+}
+
 /**
  * remap_io_mapping - remap an IO mapping to userspace
  * @vma: user vma to map to
@@ -80,3 +111,39 @@ int remap_io_mapping(struct vm_area_struct *vma,
 
return 0;
 }
+
+/**
+ * remap_io_sg - remap an IO mapping to userspace
+ * @vma: user vma to map to
+ * @addr: target user address to start at
+ * @io_start: IO start
+ * @sgl: Start sg entry
+ * @size: size of map area
+ * @iomap: the source io_mapping
+ *
+ *  Note: this is only safe if the mm semaphore is held when called.
+ */
+int remap_io_sg(struct vm_area_struct *vma,
+   unsigned long addr, resource_size_t io_start, struct 
scatterlist *sgl,
+   unsigned long size, struct io_mapping *iomap)
+{
+   struct remap_pfn r = { 0 };
+   int err;
+   GEM_BUG_ON((vma->vm_flags & EXPECTED_FLAGS) != EXPECTED_FLAGS);
+
+   /* We rely on prevalidation of the io-mapping to skip track_pfn(). */
+   r.mm = vma->vm_mm;
+   r.size = size;
+   r.io_start = io_start;
+   r.sgl = sgl;
+   r.prot = __pgprot((pgprot_val(iomap->prot) & _PAGE_CACHE_MASK) |
+ (pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK));
+
+   err = apply_to_page_range(r.mm, addr, size, remap_io, );
+   if (unlikely(err)) {
+   zap_vma_ptes(vma, addr, (r.pfn - r.start_pfn) << PAGE_SHIFT);
+   return err;
+   }
+
+   return 0;
+}
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 3/3] drm/i915/selftests: Add selftest for memory region PF handling

2019-12-22 Thread Abdiel Janulgue
Instead of testing individually our new fault handlers, iterate over all
memory regions and test all from one interface.

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
---
 .../drm/i915/gem/selftests/i915_gem_mman.c| 233 --
 1 file changed, 160 insertions(+), 73 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
index 591435c5f368..8c32888e31ed 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
@@ -9,6 +9,8 @@
 #include "gt/intel_engine_pm.h"
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_pm.h"
+#include "gem/i915_gem_lmem.h"
+#include "gem/i915_gem_region.h"
 #include "huge_gem_object.h"
 #include "i915_selftest.h"
 #include "selftests/i915_random.h"
@@ -725,44 +727,93 @@ static int igt_mmap_offset_exhaustion(void *arg)
goto out;
 }
 
+typedef int (*obj_set_fn_t)(struct drm_i915_gem_object *obj, bool init);
+
+static int gtt_obj_set(struct drm_i915_gem_object *obj, bool init)
+{
+   u32 __iomem *map;
+   struct i915_vma *vma;
+   int err = 0;
+
+   i915_gem_object_lock(obj);
+   err = i915_gem_object_set_to_gtt_domain(obj, true);
+   i915_gem_object_unlock(obj);
+   if (err)
+   return err;
+
+   vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE);
+   if (IS_ERR(vma))
+   return PTR_ERR(vma);
+
+   intel_gt_pm_get(vma->vm->gt);
+   map = i915_vma_pin_iomap(vma);
+   i915_vma_unpin(vma);
+   if (IS_ERR(map)) {
+   err = PTR_ERR(map);
+   goto out;
+   }
+
+   if (init) {
+   memset_io(map, POISON_INUSE, PAGE_SIZE);
+   } else {
+   if (memchr_inv(map, POISON_FREE, PAGE_SIZE)) {
+   pr_err("Write via mmap did not land in backing 
store\n");
+   err = -EINVAL;
+   }
+   }
+   i915_vma_unpin_iomap(vma);
+
+out:
+   intel_gt_pm_put(vma->vm->gt);
+   return err;
+}
+
+static int cpu_obj_set(struct drm_i915_gem_object *obj, bool init)
+{
+   int err = 0;
+   void *vaddr = i915_gem_object_pin_map(obj, i915_gem_object_is_lmem(obj) 
?
+   I915_MAP_WC : I915_MAP_WB);
+   if (IS_ERR(vaddr))
+   return PTR_ERR(vaddr);
+
+   if (init) {
+   memset(vaddr, POISON_INUSE, PAGE_SIZE);
+   i915_gem_object_flush_map(obj);
+   } else {
+   if (memchr_inv(vaddr, POISON_FREE, PAGE_SIZE)) {
+   pr_err("Write via mmap did not land in backing 
store\n");
+   err = -EINVAL;
+   }
+   }
+   i915_gem_object_unpin_map(obj);
+
+   return err;
+}
+
 #define expand32(x) (((x) << 0) | ((x) << 8) | ((x) << 16) | ((x) << 24))
-static int igt_mmap(void *arg, enum i915_mmap_type type)
+static int igt_mmap(struct drm_i915_private *i915, struct drm_i915_gem_object 
*obj,
+   enum i915_mmap_type type, obj_set_fn_t obj_set_fn)
 {
-   struct drm_i915_private *i915 = arg;
-   struct drm_i915_gem_object *obj;
struct i915_mmap_offset *mmo;
struct vm_area_struct *area;
unsigned long addr;
-   void *vaddr;
-   int err = 0, i;
+   int err = 0, out_err = 0, i;
 
-   if (!i915_ggtt_has_aperture(>ggtt))
+   if (!i915_ggtt_has_aperture(>ggtt) &&
+   type == I915_MMAP_TYPE_GTT)
return 0;
 
-   obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
-   if (IS_ERR(obj))
-   return PTR_ERR(obj);
-
-   vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
-   if (IS_ERR(vaddr)) {
-   err = PTR_ERR(vaddr);
-   goto out;
-   }
-   memset(vaddr, POISON_INUSE, PAGE_SIZE);
-   i915_gem_object_flush_map(obj);
-   i915_gem_object_unpin_map(obj);
+   err = obj_set_fn(obj, true);
+   if (err)
+   return err;
 
mmo = mmap_offset_attach(obj, type, NULL);
-   if (IS_ERR(mmo)) {
-   err = PTR_ERR(mmo);
-   goto out;
-   }
+   if (IS_ERR(mmo))
+   return PTR_ERR(mmo);
 
addr = igt_mmap_node(i915, >vma_node, 0, PROT_WRITE, MAP_SHARED);
-   if (IS_ERR_VALUE(addr)) {
-   err = addr;
-   goto out;
-   }
+   if (IS_ERR_VALUE(addr))
+   return addr;
 
pr_debug("igt_mmap() @ %lx\n", addr);
 
@@ -808,31 +859,50 @@ static int igt_mmap(void *arg, enum i915_mmap_type type)
 
 out_unmap:
vm_munmap(addr, PAGE_SIZE);
+   out_err = obj_set_fn(obj, false);
+   if (out_err)
+   err = out_err;
 
-   vaddr = i915

[Intel-gfx] [PATCH 2/3] drm/i915: Add lmem fault handler

2019-12-22 Thread Abdiel Janulgue
Fault handler to handle missing pages for lmem objects.

v6: Use new remap_io_sg interface for noncontiguous fault handling

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_lmem.c |  1 +
 drivers/gpu/drm/i915/gem/i915_gem_lmem.h |  1 +
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 56 ++--
 3 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c 
b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
index 520cc9cac471..ea5278ca9d99 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
@@ -6,6 +6,7 @@
 #include "intel_memory_region.h"
 #include "gem/i915_gem_region.h"
 #include "gem/i915_gem_lmem.h"
+#include "gem/i915_gem_mman.h"
 #include "i915_drv.h"
 
 const struct drm_i915_gem_object_ops i915_gem_lmem_obj_ops = {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h 
b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
index 7c176b8b7d2f..54b709ed3a02 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
@@ -7,6 +7,7 @@
 #define __I915_GEM_LMEM_H
 
 #include 
+#include 
 
 struct drm_i915_private;
 struct drm_i915_gem_object;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 879fff8adc48..6d6c6ab84b6d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -11,6 +11,7 @@
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_requests.h"
 
+#include "i915_gem_lmem.h"
 #include "i915_drv.h"
 #include "i915_gem_gtt.h"
 #include "i915_gem_ioctls.h"
@@ -216,6 +217,7 @@ static vm_fault_t i915_error_to_vmf_fault(int err)
 
case -ENOSPC: /* shmemfs allocation failure */
case -ENOMEM: /* our allocation failure */
+   case -ENXIO:
return VM_FAULT_OOM;
 
case 0:
@@ -274,6 +276,32 @@ static vm_fault_t vm_fault_cpu(struct vm_fault *vmf)
return ret;
 }
 
+static vm_fault_t vm_fault_iomem(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   struct intel_memory_region *mem = obj->mm.region;
+   unsigned long size = area->vm_end - area->vm_start;
+   bool write = area->vm_flags & VM_WRITE;
+   int ret, offs;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write)
+   return VM_FAULT_SIGBUS;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return i915_error_to_vmf_fault(ret);
+
+   ret = remap_io_sg(area, area->vm_start, mem->io_start - 
mem->region.start,
+ i915_gem_object_get_sg(obj, 0, ),
+ size, >iomap);
+   i915_gem_object_unpin_pages(obj);
+
+   return i915_error_to_vmf_fault(ret);
+}
+
 static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
 {
 #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
@@ -560,7 +588,8 @@ __assign_mmap_offset(struct drm_file *file,
}
 
if (mmap_type != I915_MMAP_TYPE_GTT &&
-   !i915_gem_object_has_struct_page(obj)) {
+   !i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_STRUCT_PAGE |
+ I915_GEM_OBJECT_HAS_IOMEM)) {
err = -ENODEV;
goto out;
}
@@ -694,6 +723,25 @@ static const struct vm_operations_struct vm_ops_cpu = {
.close = vm_close,
 };
 
+static const struct vm_operations_struct vm_ops_iomem = {
+   .fault = vm_fault_iomem,
+   .open = vm_open,
+   .close = vm_close,
+};
+
+static const struct vm_operations_struct *
+get_vm_cpu_ops(struct drm_i915_gem_object *obj)
+{
+   if (i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_STRUCT_PAGE))
+   return _ops_cpu;
+
+   if (i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_IOMEM))
+   return _ops_iomem;
+
+   GEM_BUG_ON("unknown object type");
+   return NULL;
+}
+
 /*
  * This overcomes the limitation in drm_gem_mmap's assignment of a
  * drm_gem_object as the vma->vm_private_data. Since we need to
@@ -762,18 +810,18 @@ int i915_gem_mmap(struct file *filp, struct 
vm_area_struct *vma)
case I915_MMAP_TYPE_WC:
vma->vm_page_prot =
pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
-   vma->vm_ops = _ops_cpu;
+   vma->vm_ops = get_vm_cpu_ops(to_intel_bo(obj));
break;
 
case I915_MMAP_TYPE_WB:
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
-   vma->vm_ops = _ops

[Intel-gfx] [PATCH 3/3] drm/i915/selftests: Add selftest for memory region PF handling

2019-12-19 Thread Abdiel Janulgue
Instead of testing individually our new fault handlers, iterate over all
memory regions and test all from one interface.

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
---
 .../drm/i915/gem/selftests/i915_gem_mman.c| 233 --
 1 file changed, 160 insertions(+), 73 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
index 591435c5f368..8c32888e31ed 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
@@ -9,6 +9,8 @@
 #include "gt/intel_engine_pm.h"
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_pm.h"
+#include "gem/i915_gem_lmem.h"
+#include "gem/i915_gem_region.h"
 #include "huge_gem_object.h"
 #include "i915_selftest.h"
 #include "selftests/i915_random.h"
@@ -725,44 +727,93 @@ static int igt_mmap_offset_exhaustion(void *arg)
goto out;
 }
 
+typedef int (*obj_set_fn_t)(struct drm_i915_gem_object *obj, bool init);
+
+static int gtt_obj_set(struct drm_i915_gem_object *obj, bool init)
+{
+   u32 __iomem *map;
+   struct i915_vma *vma;
+   int err = 0;
+
+   i915_gem_object_lock(obj);
+   err = i915_gem_object_set_to_gtt_domain(obj, true);
+   i915_gem_object_unlock(obj);
+   if (err)
+   return err;
+
+   vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE);
+   if (IS_ERR(vma))
+   return PTR_ERR(vma);
+
+   intel_gt_pm_get(vma->vm->gt);
+   map = i915_vma_pin_iomap(vma);
+   i915_vma_unpin(vma);
+   if (IS_ERR(map)) {
+   err = PTR_ERR(map);
+   goto out;
+   }
+
+   if (init) {
+   memset_io(map, POISON_INUSE, PAGE_SIZE);
+   } else {
+   if (memchr_inv(map, POISON_FREE, PAGE_SIZE)) {
+   pr_err("Write via mmap did not land in backing 
store\n");
+   err = -EINVAL;
+   }
+   }
+   i915_vma_unpin_iomap(vma);
+
+out:
+   intel_gt_pm_put(vma->vm->gt);
+   return err;
+}
+
+static int cpu_obj_set(struct drm_i915_gem_object *obj, bool init)
+{
+   int err = 0;
+   void *vaddr = i915_gem_object_pin_map(obj, i915_gem_object_is_lmem(obj) 
?
+   I915_MAP_WC : I915_MAP_WB);
+   if (IS_ERR(vaddr))
+   return PTR_ERR(vaddr);
+
+   if (init) {
+   memset(vaddr, POISON_INUSE, PAGE_SIZE);
+   i915_gem_object_flush_map(obj);
+   } else {
+   if (memchr_inv(vaddr, POISON_FREE, PAGE_SIZE)) {
+   pr_err("Write via mmap did not land in backing 
store\n");
+   err = -EINVAL;
+   }
+   }
+   i915_gem_object_unpin_map(obj);
+
+   return err;
+}
+
 #define expand32(x) (((x) << 0) | ((x) << 8) | ((x) << 16) | ((x) << 24))
-static int igt_mmap(void *arg, enum i915_mmap_type type)
+static int igt_mmap(struct drm_i915_private *i915, struct drm_i915_gem_object 
*obj,
+   enum i915_mmap_type type, obj_set_fn_t obj_set_fn)
 {
-   struct drm_i915_private *i915 = arg;
-   struct drm_i915_gem_object *obj;
struct i915_mmap_offset *mmo;
struct vm_area_struct *area;
unsigned long addr;
-   void *vaddr;
-   int err = 0, i;
+   int err = 0, out_err = 0, i;
 
-   if (!i915_ggtt_has_aperture(>ggtt))
+   if (!i915_ggtt_has_aperture(>ggtt) &&
+   type == I915_MMAP_TYPE_GTT)
return 0;
 
-   obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
-   if (IS_ERR(obj))
-   return PTR_ERR(obj);
-
-   vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
-   if (IS_ERR(vaddr)) {
-   err = PTR_ERR(vaddr);
-   goto out;
-   }
-   memset(vaddr, POISON_INUSE, PAGE_SIZE);
-   i915_gem_object_flush_map(obj);
-   i915_gem_object_unpin_map(obj);
+   err = obj_set_fn(obj, true);
+   if (err)
+   return err;
 
mmo = mmap_offset_attach(obj, type, NULL);
-   if (IS_ERR(mmo)) {
-   err = PTR_ERR(mmo);
-   goto out;
-   }
+   if (IS_ERR(mmo))
+   return PTR_ERR(mmo);
 
addr = igt_mmap_node(i915, >vma_node, 0, PROT_WRITE, MAP_SHARED);
-   if (IS_ERR_VALUE(addr)) {
-   err = addr;
-   goto out;
-   }
+   if (IS_ERR_VALUE(addr))
+   return addr;
 
pr_debug("igt_mmap() @ %lx\n", addr);
 
@@ -808,31 +859,50 @@ static int igt_mmap(void *arg, enum i915_mmap_type type)
 
 out_unmap:
vm_munmap(addr, PAGE_SIZE);
+   out_err = obj_set_fn(obj, false);
+   if (out_err)
+   err = out_err;
 
-   vaddr = i915

[Intel-gfx] [PATCH 1/3] drm/i915: allow prefaulting discontiguous objects in remap_io_mapping()

2019-12-19 Thread Abdiel Janulgue
Provide a way to set the PTE of the physical address of kernel memory in
addition to just incrementing the pfn for a page range.

Signed-off-by: Abdiel Janulgue 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c |  1 +
 drivers/gpu/drm/i915/i915_drv.h  |  4 +++-
 drivers/gpu/drm/i915/i915_mm.c   | 17 ++---
 3 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 879fff8adc48..aa5d6623d86c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -360,6 +360,7 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
   area->vm_start + (vma->ggtt_view.partial.offset 
<< PAGE_SHIFT),
   (ggtt->gmadr.start + vma->node.start) >> 
PAGE_SHIFT,
   min_t(u64, vma->size, area->vm_end - 
area->vm_start),
+  NULL,
   >iomap);
if (ret)
goto err_fence;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0781b6326b8c..5ee0fe4d492b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2015,9 +2015,11 @@ int i915_reg_read_ioctl(struct drm_device *dev, void 
*data,
intel_de_wait_for_register((dev_priv_), (reg_), (mask_), 0, (timeout_))
 
 /* i915_mm.c */
+typedef unsigned long (*io_pfn_t)(struct drm_i915_gem_object *obj,
+ unsigned long n);
 int remap_io_mapping(struct vm_area_struct *vma,
 unsigned long addr, unsigned long pfn, unsigned long size,
-struct io_mapping *iomap);
+io_pfn_t fn, struct io_mapping *iomap);
 
 static inline int intel_hws_csb_write_index(struct drm_i915_private *i915)
 {
diff --git a/drivers/gpu/drm/i915/i915_mm.c b/drivers/gpu/drm/i915/i915_mm.c
index 318562ce64c0..86a73444bed4 100644
--- a/drivers/gpu/drm/i915/i915_mm.c
+++ b/drivers/gpu/drm/i915/i915_mm.c
@@ -32,7 +32,11 @@
 struct remap_pfn {
struct mm_struct *mm;
unsigned long pfn;
+   unsigned long start_pfn;
pgprot_t prot;
+
+   io_pfn_t fn;
+   struct drm_i915_gem_object *obj;
 };
 
 static int remap_pfn(pte_t *pte, unsigned long addr, void *data)
@@ -41,7 +45,10 @@ static int remap_pfn(pte_t *pte, unsigned long addr, void 
*data)
 
/* Special PTE are not associated with any struct page */
set_pte_at(r->mm, addr, pte, pte_mkspecial(pfn_pte(r->pfn, r->prot)));
-   r->pfn++;
+   if (r->fn)
+   r->pfn = r->fn(r->obj, r->start_pfn++);
+   else
+   r->pfn++;
 
return 0;
 }
@@ -52,15 +59,17 @@ static int remap_pfn(pte_t *pte, unsigned long addr, void 
*data)
  * @addr: target user address to start at
  * @pfn: physical address of kernel memory
  * @size: size of map area
+ * @fn: if provided, the function translates each increment of @pfn to io pfn
  * @iomap: the source io_mapping
  *
  *  Note: this is only safe if the mm semaphore is held when called.
  */
 int remap_io_mapping(struct vm_area_struct *vma,
 unsigned long addr, unsigned long pfn, unsigned long size,
-struct io_mapping *iomap)
+io_pfn_t fn, struct io_mapping *iomap)
 {
-   struct remap_pfn r;
+   struct remap_pfn r = { 0 };
+   struct i915_mmap_offset *priv = vma->vm_private_data;
int err;
 
 #define EXPECTED_FLAGS (VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP)
@@ -69,6 +78,8 @@ int remap_io_mapping(struct vm_area_struct *vma,
/* We rely on prevalidation of the io-mapping to skip track_pfn(). */
r.mm = vma->vm_mm;
r.pfn = pfn;
+   r.fn = fn;
+   r.obj = priv->obj;
r.prot = __pgprot((pgprot_val(iomap->prot) & _PAGE_CACHE_MASK) |
  (pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK));
 
-- 
2.17.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/3] drm/i915: Add lmem fault handler

2019-12-19 Thread Abdiel Janulgue
Fault handler to handle missing pages for lmem objects.

v5: Use new remap_io_mapping interface for noncontiguous fault handling

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_lmem.c | 13 ++
 drivers/gpu/drm/i915/gem/i915_gem_lmem.h |  4 ++
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 56 ++--
 3 files changed, 69 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c 
b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
index 520cc9cac471..e8326d8b66f7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
@@ -6,6 +6,7 @@
 #include "intel_memory_region.h"
 #include "gem/i915_gem_region.h"
 #include "gem/i915_gem_lmem.h"
+#include "gem/i915_gem_mman.h"
 #include "i915_drv.h"
 
 const struct drm_i915_gem_object_ops i915_gem_lmem_obj_ops = {
@@ -56,6 +57,18 @@ i915_gem_object_lmem_io_map(struct drm_i915_gem_object *obj,
return io_mapping_map_wc(>mm.region->iomap, offset, size);
 }
 
+unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
+ unsigned long n)
+{
+   struct intel_memory_region *mem = obj->mm.region;
+   resource_size_t offset;
+
+   offset = i915_gem_object_get_dma_address(obj, n);
+   offset -= mem->region.start;
+
+   return (mem->io_start + offset) >> PAGE_SHIFT;
+}
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj)
 {
return obj->ops == _gem_lmem_obj_ops;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h 
b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
index 7c176b8b7d2f..4d5fca1a3e0e 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
@@ -7,6 +7,7 @@
 #define __I915_GEM_LMEM_H
 
 #include 
+#include 
 
 struct drm_i915_private;
 struct drm_i915_gem_object;
@@ -22,6 +23,9 @@ void __iomem *
 i915_gem_object_lmem_io_map_page_atomic(struct drm_i915_gem_object *obj,
unsigned long n);
 
+unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
+ unsigned long n);
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj);
 
 struct drm_i915_gem_object *
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index aa5d6623d86c..3ba10f17361b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -11,6 +11,7 @@
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_requests.h"
 
+#include "i915_gem_lmem.h"
 #include "i915_drv.h"
 #include "i915_gem_gtt.h"
 #include "i915_gem_ioctls.h"
@@ -216,6 +217,7 @@ static vm_fault_t i915_error_to_vmf_fault(int err)
 
case -ENOSPC: /* shmemfs allocation failure */
case -ENOMEM: /* our allocation failure */
+   case -ENXIO:
return VM_FAULT_OOM;
 
case 0:
@@ -274,6 +276,32 @@ static vm_fault_t vm_fault_cpu(struct vm_fault *vmf)
return ret;
 }
 
+vm_fault_t vm_fault_iomem(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   struct intel_memory_region *mem = obj->mm.region;
+   unsigned long size = area->vm_end - area->vm_start;
+   bool write = area->vm_flags & VM_WRITE;
+   int ret;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write)
+   return VM_FAULT_SIGBUS;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return i915_error_to_vmf_fault(ret);
+
+   ret = remap_io_mapping(area, area->vm_start,
+  i915_gem_object_lmem_io_pfn(obj, 0), size,
+  i915_gem_object_lmem_io_pfn, >iomap);
+   i915_gem_object_unpin_pages(obj);
+
+   return i915_error_to_vmf_fault(ret);
+}
+
 static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
 {
 #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
@@ -561,7 +589,8 @@ __assign_mmap_offset(struct drm_file *file,
}
 
if (mmap_type != I915_MMAP_TYPE_GTT &&
-   !i915_gem_object_has_struct_page(obj)) {
+   !i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_STRUCT_PAGE |
+ I915_GEM_OBJECT_HAS_IOMEM)) {
err = -ENODEV;
goto out;
}
@@ -695,6 +724,25 @@ static const struct vm_operations_struct vm_ops_cpu = {
.close = vm_close,
 };
 
+static const struct vm_operations_struct vm_ops_iomem = {
+   .fault = vm_fault_iomem,
+  

Re: [Intel-gfx] ✗ Fi.CI.BAT: failure for series starting with [1/2] drm/i915: Add lmem fault handler

2019-12-17 Thread Abdiel Janulgue



On 17/12/2019 15.00, Patchwork wrote:
> == Series Details ==
> 
> Series: series starting with [1/2] drm/i915: Add lmem fault handler
> URL   : https://patchwork.freedesktop.org/series/71051/
> State : failure
> 
> == Summary ==
> 
> CI Bug Log - changes from CI_DRM_7580 -> Patchwork_15810
> 
> 
> Summary
> ---
> 
>   **FAILURE**
> 
>   Serious unknown changes coming with Patchwork_15810 absolutely need to be
>   verified manually.
>   
>   If you think the reported changes have nothing to do with the changes
>   introduced in Patchwork_15810, please notify your bug team to allow them
>   to document this new failure mode, which will reduce false positives in CI.
> 
>   External URL: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/index.html
> 
> Possible new issues
> ---
> 
>   Here are the unknown changes that may have been introduced in 
> Patchwork_15810:
> 
> ### IGT changes ###
> 
>  Possible regressions 
> 
>   * igt@i915_selftest@live_mman:
> - fi-ilk-650: [PASS][1] -> [INCOMPLETE][2]
>[1]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7580/fi-ilk-650/igt@i915_selftest@live_mman.html
>[2]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-ilk-650/igt@i915_selftest@live_mman.html
> - fi-bsw-n3050:   NOTRUN -> [INCOMPLETE][3]
>[3]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-bsw-n3050/igt@i915_selftest@live_mman.html
> - fi-ivb-3770:[PASS][4] -> [DMESG-FAIL][5]
>[4]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7580/fi-ivb-3770/igt@i915_selftest@live_mman.html
>[5]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-ivb-3770/igt@i915_selftest@live_mman.html
> - fi-hsw-4770r:   [PASS][6] -> [DMESG-FAIL][7]
>[6]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7580/fi-hsw-4770r/igt@i915_selftest@live_mman.html
>[7]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-hsw-4770r/igt@i915_selftest@live_mman.html
> - fi-bsw-kefka:   [PASS][8] -> [INCOMPLETE][9]
>[8]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7580/fi-bsw-kefka/igt@i915_selftest@live_mman.html
>[9]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-bsw-kefka/igt@i915_selftest@live_mman.html
> - fi-blb-e6850:   [PASS][10] -> [INCOMPLETE][11]
>[10]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7580/fi-blb-e6850/igt@i915_selftest@live_mman.html
>[11]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-blb-e6850/igt@i915_selftest@live_mman.html
> - fi-bwr-2160:[PASS][12] -> [INCOMPLETE][13]
>[12]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7580/fi-bwr-2160/igt@i915_selftest@live_mman.html
>[13]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-bwr-2160/igt@i915_selftest@live_mman.html
> - fi-kbl-8809g:   [PASS][14] -> [DMESG-FAIL][15]
>[14]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7580/fi-kbl-8809g/igt@i915_selftest@live_mman.html
>[15]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-kbl-8809g/igt@i915_selftest@live_mman.html
> - fi-bsw-nick:[PASS][16] -> [INCOMPLETE][17]
>[16]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7580/fi-bsw-nick/igt@i915_selftest@live_mman.html
>[17]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-bsw-nick/igt@i915_selftest@live_mman.html
> 

hmm, doesn't look too good with the memory regions.

>   * igt@runner@aborted:
> - fi-ilk-650: NOTRUN -> [FAIL][18]
>[18]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-ilk-650/igt@run...@aborted.html
> - fi-pnv-d510:NOTRUN -> [FAIL][19]
>[19]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-pnv-d510/igt@run...@aborted.html
> - fi-bxt-dsi: NOTRUN -> [FAIL][20]
>[20]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-bxt-dsi/igt@run...@aborted.html
> - fi-bsw-n3050:   NOTRUN -> [FAIL][21]
>[21]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-bsw-n3050/igt@run...@aborted.html
> - fi-blb-e6850:   NOTRUN -> [FAIL][22]
>[22]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-blb-e6850/igt@run...@aborted.html
> - fi-bsw-kefka:   NOTRUN -> [FAIL][23]
>[23]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-bsw-kefka/igt@run...@aborted.html
> - fi-bsw-nick:NOTRUN -> [FAIL][24]
>[24]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-bsw-nick/igt@run...@aborted.html
> - fi-elk-e7500:   NOTRUN -> [FAIL][25]
>[25]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15810/fi-elk-e7500/igt@run...@aborted.html
> 
>   
> Known issues
> 
> 
>   Here are the changes found in Patchwork_15810 that come from known issues:
> 
> ### IGT changes ###
> 
> 

Re: [Intel-gfx] [PATCH 1/2] drm/i915: Add lmem fault handler

2019-12-17 Thread Abdiel Janulgue



On 17/12/2019 14.14, Chris Wilson wrote:
> Quoting Abdiel Janulgue (2019-12-17 11:57:49)
>> Fault handler to handle missing pages for lmem objects.
>>
>> v4: Restore non-contigous fault handling in addition to remap_io_mapping
>>
>> Signed-off-by: Abdiel Janulgue 
>> Signed-off-by: Matthew Auld 
>> Cc: Chris Wilson 
>> Cc: Joonas Lahtinen 
>> ---
>>  drivers/gpu/drm/i915/gem/i915_gem_lmem.c | 13 +
>>  drivers/gpu/drm/i915/gem/i915_gem_lmem.h |  4 ++
>>  drivers/gpu/drm/i915/gem/i915_gem_mman.c | 71 ++--
>>  3 files changed, 84 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c 
>> b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
>> index 520cc9cac471..e8326d8b66f7 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
>> @@ -6,6 +6,7 @@
>>  #include "intel_memory_region.h"
>>  #include "gem/i915_gem_region.h"
>>  #include "gem/i915_gem_lmem.h"
>> +#include "gem/i915_gem_mman.h"
>>  #include "i915_drv.h"
>>  
>>  const struct drm_i915_gem_object_ops i915_gem_lmem_obj_ops = {
>> @@ -56,6 +57,18 @@ i915_gem_object_lmem_io_map(struct drm_i915_gem_object 
>> *obj,
>> return io_mapping_map_wc(>mm.region->iomap, offset, size);
>>  }
>>  
>> +unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
>> + unsigned long n)
>> +{
>> +   struct intel_memory_region *mem = obj->mm.region;
>> +   resource_size_t offset;
>> +
>> +   offset = i915_gem_object_get_dma_address(obj, n);
>> +   offset -= mem->region.start;
>> +
>> +   return (mem->io_start + offset) >> PAGE_SHIFT;
>> +}
>> +
>>  bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj)
>>  {
>> return obj->ops == _gem_lmem_obj_ops;
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h 
>> b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
>> index 7c176b8b7d2f..4d5fca1a3e0e 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
>> @@ -7,6 +7,7 @@
>>  #define __I915_GEM_LMEM_H
>>  
>>  #include 
>> +#include 
>>  
>>  struct drm_i915_private;
>>  struct drm_i915_gem_object;
>> @@ -22,6 +23,9 @@ void __iomem *
>>  i915_gem_object_lmem_io_map_page_atomic(struct drm_i915_gem_object *obj,
>> unsigned long n);
>>  
>> +unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
>> + unsigned long n);
>> +
>>  bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj);
>>  
>>  struct drm_i915_gem_object *
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
>> b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
>> index 879fff8adc48..f5f7af745d1d 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
>> @@ -11,6 +11,7 @@
>>  #include "gt/intel_gt.h"
>>  #include "gt/intel_gt_requests.h"
>>  
>> +#include "i915_gem_lmem.h"
>>  #include "i915_drv.h"
>>  #include "i915_gem_gtt.h"
>>  #include "i915_gem_ioctls.h"
>> @@ -216,6 +217,7 @@ static vm_fault_t i915_error_to_vmf_fault(int err)
>>  
>> case -ENOSPC: /* shmemfs allocation failure */
>> case -ENOMEM: /* our allocation failure */
>> +   case -ENXIO:
>> return VM_FAULT_OOM;
>>  
>> case 0:
>> @@ -274,6 +276,47 @@ static vm_fault_t vm_fault_cpu(struct vm_fault *vmf)
>> return ret;
>>  }
>>  
>> +vm_fault_t vm_fault_iomem(struct vm_fault *vmf)
>> +{
>> +   struct vm_area_struct *area = vmf->vma;
>> +   struct i915_mmap_offset *priv = area->vm_private_data;
>> +   struct drm_i915_gem_object *obj = priv->obj;
>> +   struct intel_memory_region *mem = obj->mm.region;
>> +   unsigned long i, size = area->vm_end - area->vm_start;
>> +   bool write = area->vm_flags & VM_WRITE;
>> +   int ret;
>> +
>> +   /* Sanity check that we allow writing into this object */
>> +   if (i915_gem_object_is_readonly(obj) && write)
>> +   return VM_FAULT_SIGBUS;
>> +
>> +   ret = i915_gem_object_pin_pages(obj);
>> +   if 

[Intel-gfx] [PATCH 1/2] drm/i915: Add lmem fault handler

2019-12-17 Thread Abdiel Janulgue
Fault handler to handle missing pages for lmem objects.

v4: Restore non-contigous fault handling in addition to remap_io_mapping

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_lmem.c | 13 +
 drivers/gpu/drm/i915/gem/i915_gem_lmem.h |  4 ++
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 71 ++--
 3 files changed, 84 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c 
b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
index 520cc9cac471..e8326d8b66f7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
@@ -6,6 +6,7 @@
 #include "intel_memory_region.h"
 #include "gem/i915_gem_region.h"
 #include "gem/i915_gem_lmem.h"
+#include "gem/i915_gem_mman.h"
 #include "i915_drv.h"
 
 const struct drm_i915_gem_object_ops i915_gem_lmem_obj_ops = {
@@ -56,6 +57,18 @@ i915_gem_object_lmem_io_map(struct drm_i915_gem_object *obj,
return io_mapping_map_wc(>mm.region->iomap, offset, size);
 }
 
+unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
+ unsigned long n)
+{
+   struct intel_memory_region *mem = obj->mm.region;
+   resource_size_t offset;
+
+   offset = i915_gem_object_get_dma_address(obj, n);
+   offset -= mem->region.start;
+
+   return (mem->io_start + offset) >> PAGE_SHIFT;
+}
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj)
 {
return obj->ops == _gem_lmem_obj_ops;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h 
b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
index 7c176b8b7d2f..4d5fca1a3e0e 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
@@ -7,6 +7,7 @@
 #define __I915_GEM_LMEM_H
 
 #include 
+#include 
 
 struct drm_i915_private;
 struct drm_i915_gem_object;
@@ -22,6 +23,9 @@ void __iomem *
 i915_gem_object_lmem_io_map_page_atomic(struct drm_i915_gem_object *obj,
unsigned long n);
 
+unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
+ unsigned long n);
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj);
 
 struct drm_i915_gem_object *
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 879fff8adc48..f5f7af745d1d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -11,6 +11,7 @@
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_requests.h"
 
+#include "i915_gem_lmem.h"
 #include "i915_drv.h"
 #include "i915_gem_gtt.h"
 #include "i915_gem_ioctls.h"
@@ -216,6 +217,7 @@ static vm_fault_t i915_error_to_vmf_fault(int err)
 
case -ENOSPC: /* shmemfs allocation failure */
case -ENOMEM: /* our allocation failure */
+   case -ENXIO:
return VM_FAULT_OOM;
 
case 0:
@@ -274,6 +276,47 @@ static vm_fault_t vm_fault_cpu(struct vm_fault *vmf)
return ret;
 }
 
+vm_fault_t vm_fault_iomem(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   struct intel_memory_region *mem = obj->mm.region;
+   unsigned long i, size = area->vm_end - area->vm_start;
+   bool write = area->vm_flags & VM_WRITE;
+   int ret;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write)
+   return VM_FAULT_SIGBUS;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return i915_error_to_vmf_fault(ret);
+
+   if (obj->flags & I915_BO_ALLOC_CONTIGUOUS) {
+   ret = remap_io_mapping(area, area->vm_start,
+  i915_gem_object_lmem_io_pfn(obj, 0), 
size,
+  >iomap);
+   i915_gem_object_unpin_pages(obj);
+   return i915_error_to_vmf_fault(ret);
+   } else {
+   vm_fault_t vmf_ret = VM_FAULT_SIGBUS;
+   if (GEM_WARN_ON(size < PAGE_SIZE))
+   return vmf_ret;
+
+   for (i = 0; i < size >> PAGE_SHIFT; i++) {
+   vmf_ret = vmf_insert_pfn(area,
+(unsigned long)area->vm_start 
+ i * PAGE_SIZE,
+
i915_gem_object_lmem_io_pfn(obj, i));
+   if (vmf_ret != VM_FAULT_NOPAGE)
+   break;
+   }
+   i915_gem_object_unpin_pages(obj);
+   re

[Intel-gfx] [PATCH 2/2] drm/i915/selftests: Add selftest for memory region PF handling

2019-12-17 Thread Abdiel Janulgue
Instead of testing individually our new fault handlers, iterate over all
memory regions and test all from one interface.

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
---
 .../drm/i915/gem/selftests/i915_gem_mman.c| 226 --
 1 file changed, 153 insertions(+), 73 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
index 591435c5f368..e98ec15e7c51 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
@@ -9,6 +9,8 @@
 #include "gt/intel_engine_pm.h"
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_pm.h"
+#include "gem/i915_gem_lmem.h"
+#include "gem/i915_gem_region.h"
 #include "huge_gem_object.h"
 #include "i915_selftest.h"
 #include "selftests/i915_random.h"
@@ -725,44 +727,94 @@ static int igt_mmap_offset_exhaustion(void *arg)
goto out;
 }
 
+typedef int (*obj_set_fn_t)(struct drm_i915_gem_object *obj, bool init);
+
+static int gtt_obj_set(struct drm_i915_gem_object *obj, bool init)
+{
+   u32 __iomem *map;
+   struct i915_vma *vma;
+   int err = 0;
+
+   i915_gem_object_lock(obj);
+   err = i915_gem_object_set_to_gtt_domain(obj, true);
+   i915_gem_object_unlock(obj);
+   if (err)
+   return err;
+
+   vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE);
+   if (IS_ERR(vma))
+   return PTR_ERR(vma);
+
+   intel_gt_pm_get(vma->vm->gt);
+   map = i915_vma_pin_iomap(vma);
+   i915_vma_unpin(vma);
+   if (IS_ERR(map)) {
+   err = PTR_ERR(map);
+   goto out;
+   }
+
+   if (init) {
+   memset_io(map, POISON_INUSE, PAGE_SIZE);
+   i915_gem_object_flush_map(obj);
+   } else {
+   if (memchr_inv(map, POISON_FREE, PAGE_SIZE)) {
+   pr_err("Write via mmap did not land in backing 
store\n");
+   err = -EINVAL;
+   }
+   }
+   i915_vma_unpin_iomap(vma);
+
+out:
+   intel_gt_pm_put(vma->vm->gt);
+   return err;
+}
+
+static int cpu_obj_set(struct drm_i915_gem_object *obj, bool init)
+{
+   int err = 0;
+   void *vaddr = i915_gem_object_pin_map(obj, i915_gem_object_is_lmem(obj) 
?
+   I915_MAP_WC : I915_MAP_WB);
+   if (IS_ERR(vaddr))
+   return PTR_ERR(vaddr);
+
+   if (init) {
+   memset(vaddr, POISON_INUSE, PAGE_SIZE);
+   i915_gem_object_flush_map(obj);
+   } else {
+   if (memchr_inv(vaddr, POISON_FREE, PAGE_SIZE)) {
+   pr_err("Write via mmap did not land in backing 
store\n");
+   err = -EINVAL;
+   }
+   }
+   i915_gem_object_unpin_map(obj);
+
+   return err;
+}
+
 #define expand32(x) (((x) << 0) | ((x) << 8) | ((x) << 16) | ((x) << 24))
-static int igt_mmap(void *arg, enum i915_mmap_type type)
+static int igt_mmap(struct drm_i915_private *i915, struct drm_i915_gem_object 
*obj,
+   enum i915_mmap_type type, obj_set_fn_t obj_set_fn)
 {
-   struct drm_i915_private *i915 = arg;
-   struct drm_i915_gem_object *obj;
struct i915_mmap_offset *mmo;
struct vm_area_struct *area;
unsigned long addr;
-   void *vaddr;
-   int err = 0, i;
+   int err = 0, out_err = 0, i;
 
-   if (!i915_ggtt_has_aperture(>ggtt))
+   if (!i915_ggtt_has_aperture(>ggtt) &&
+   type == I915_MMAP_TYPE_GTT)
return 0;
 
-   obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
-   if (IS_ERR(obj))
-   return PTR_ERR(obj);
-
-   vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
-   if (IS_ERR(vaddr)) {
-   err = PTR_ERR(vaddr);
-   goto out;
-   }
-   memset(vaddr, POISON_INUSE, PAGE_SIZE);
-   i915_gem_object_flush_map(obj);
-   i915_gem_object_unpin_map(obj);
+   err = obj_set_fn(obj, true);
+   if (err)
+   return err;
 
mmo = mmap_offset_attach(obj, type, NULL);
-   if (IS_ERR(mmo)) {
-   err = PTR_ERR(mmo);
-   goto out;
-   }
+   if (IS_ERR(mmo))
+   return PTR_ERR(mmo);
 
addr = igt_mmap_node(i915, >vma_node, 0, PROT_WRITE, MAP_SHARED);
-   if (IS_ERR_VALUE(addr)) {
-   err = addr;
-   goto out;
-   }
+   if (IS_ERR_VALUE(addr))
+   return addr;
 
pr_debug("igt_mmap() @ %lx\n", addr);
 
@@ -808,31 +860,46 @@ static int igt_mmap(void *arg, enum i915_mmap_type type)
 
 out_unmap:
vm_munmap(addr, PAGE_SIZE);
+   out_err = obj_set_fn(obj, false);
+   if (out_err)

Re: [Intel-gfx] [PATCH] drm/i915: Add lmem fault handler

2019-12-12 Thread Abdiel Janulgue



On 12/12/2019 17.19, Chris Wilson wrote:
> Quoting Matthew Auld (2019-12-12 15:11:02)
>> On Thu, 12 Dec 2019 at 14:20, Chris Wilson  wrote:
>>>
>>> Quoting Abdiel Janulgue (2019-12-12 11:34:38)
>>>> Fault handler to handle missing pages for lmem objects.
>>>>
>>>> v3: Add get_vm_cpu_ops, iterate over all memory regions in the
>>>> lmem selftest, use remap_io_mapping.
>>>>
>>>> Signed-off-by: Abdiel Janulgue 
>>>> Signed-off-by: Matthew Auld 
>>>> Cc: Chris Wilson 
>>>> Cc: Joonas Lahtinen 
>>>> ---
>>>>  drivers/gpu/drm/i915/gem/i915_gem_lmem.c  |  40 +
>>>>  drivers/gpu/drm/i915/gem/i915_gem_lmem.h  |   6 +
>>>>  drivers/gpu/drm/i915/gem/i915_gem_mman.c  |  32 +++-
>>>>  drivers/gpu/drm/i915/gem/i915_gem_mman.h  |   1 +
>>>>  .../drm/i915/gem/selftests/i915_gem_mman.c| 137 +++---
>>>>  5 files changed, 188 insertions(+), 28 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c 
>>>> b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
>>>> index 0e2bf6b7e143..bbe625935005 100644
>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
>>>> @@ -6,8 +6,36 @@
>>>>  #include "intel_memory_region.h"
>>>>  #include "gem/i915_gem_region.h"
>>>>  #include "gem/i915_gem_lmem.h"
>>>> +#include "gem/i915_gem_mman.h"
>>>>  #include "i915_drv.h"
>>>>
>>>> +vm_fault_t vm_fault_iomem(struct vm_fault *vmf)
>>>> +{
>>>> +   struct vm_area_struct *area = vmf->vma;
>>>> +   struct i915_mmap_offset *priv = area->vm_private_data;
>>>> +   struct drm_i915_gem_object *obj = priv->obj;
>>>> +   struct intel_memory_region *mem = obj->mm.region;
>>>> +   unsigned long size = area->vm_end - area->vm_start;
>>>> +   bool write = area->vm_flags & VM_WRITE;
>>>> +   int ret;
>>>> +
>>>> +   /* Sanity check that we allow writing into this object */
>>>> +   if (i915_gem_object_is_readonly(obj) && write)
>>>> +   return VM_FAULT_SIGBUS;
>>>> +
>>>> +   ret = i915_gem_object_pin_pages(obj);
>>>> +   if (ret)
>>>> +   return i915_error_to_vmf_fault(ret);
>>>> +
>>>> +   ret = remap_io_mapping(area, area->vm_start,
>>>> +  i915_gem_object_lmem_io_pfn(obj, 0), size,
>>>> +  >iomap);
>>>
>>> So this implementation only works with contiguous objects, right?
>>
>> Hmm can't we go back to what we had before, so support !contiguous also?
> 
> The fun part is that you can do both :) Do a discontiguous
> remap_io_mapping() The queue part is that remap_io_mapping() avoids the
> O(N^2), and should give us O(N) instead.

So just to be clear,

if (obj->flags & I915_BO_ALLOC_CONTIGUOUS) {
remap_io_mapping(...)
} else {
for(...)
vmf_insert_pfn()
}

??

- Abdiel
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915: Add lmem fault handler

2019-12-12 Thread Abdiel Janulgue
Fault handler to handle missing pages for lmem objects.

v3: Add get_vm_cpu_ops, iterate over all memory regions in the
lmem selftest, use remap_io_mapping.

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_lmem.c  |  40 +
 drivers/gpu/drm/i915/gem/i915_gem_lmem.h  |   6 +
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  |  32 +++-
 drivers/gpu/drm/i915/gem/i915_gem_mman.h  |   1 +
 .../drm/i915/gem/selftests/i915_gem_mman.c| 137 +++---
 5 files changed, 188 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c 
b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
index 0e2bf6b7e143..bbe625935005 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
@@ -6,8 +6,36 @@
 #include "intel_memory_region.h"
 #include "gem/i915_gem_region.h"
 #include "gem/i915_gem_lmem.h"
+#include "gem/i915_gem_mman.h"
 #include "i915_drv.h"
 
+vm_fault_t vm_fault_iomem(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   struct intel_memory_region *mem = obj->mm.region;
+   unsigned long size = area->vm_end - area->vm_start;
+   bool write = area->vm_flags & VM_WRITE;
+   int ret;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write)
+   return VM_FAULT_SIGBUS;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return i915_error_to_vmf_fault(ret);
+
+   ret = remap_io_mapping(area, area->vm_start,
+  i915_gem_object_lmem_io_pfn(obj, 0), size,
+  >iomap);
+
+   i915_gem_object_unpin_pages(obj);
+
+   return i915_error_to_vmf_fault(ret);
+}
+
 const struct drm_i915_gem_object_ops i915_gem_lmem_obj_ops = {
.flags = I915_GEM_OBJECT_HAS_IOMEM,
 
@@ -56,6 +84,18 @@ i915_gem_object_lmem_io_map(struct drm_i915_gem_object *obj,
return io_mapping_map_wc(>mm.region->iomap, offset, size);
 }
 
+unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
+ unsigned long n)
+{
+   struct intel_memory_region *mem = obj->mm.region;
+   resource_size_t offset;
+
+   offset = i915_gem_object_get_dma_address(obj, n);
+   offset -= mem->region.start;
+
+   return (mem->io_start + offset) >> PAGE_SHIFT;
+}
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj)
 {
return obj->ops == _gem_lmem_obj_ops;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h 
b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
index 7c176b8b7d2f..36a412ace3cf 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
@@ -7,6 +7,7 @@
 #define __I915_GEM_LMEM_H
 
 #include 
+#include 
 
 struct drm_i915_private;
 struct drm_i915_gem_object;
@@ -22,8 +23,13 @@ void __iomem *
 i915_gem_object_lmem_io_map_page_atomic(struct drm_i915_gem_object *obj,
unsigned long n);
 
+unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
+ unsigned long n);
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj);
 
+vm_fault_t vm_fault_iomem(struct vm_fault *vmf);
+
 struct drm_i915_gem_object *
 i915_gem_object_create_lmem(struct drm_i915_private *i915,
resource_size_t size,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 879fff8adc48..958ca2033379 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -11,6 +11,7 @@
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_requests.h"
 
+#include "i915_gem_lmem.h"
 #include "i915_drv.h"
 #include "i915_gem_gtt.h"
 #include "i915_gem_ioctls.h"
@@ -203,7 +204,7 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
return view;
 }
 
-static vm_fault_t i915_error_to_vmf_fault(int err)
+vm_fault_t i915_error_to_vmf_fault(int err)
 {
switch (err) {
default:
@@ -216,6 +217,7 @@ static vm_fault_t i915_error_to_vmf_fault(int err)
 
case -ENOSPC: /* shmemfs allocation failure */
case -ENOMEM: /* our allocation failure */
+   case -ENXIO:
return VM_FAULT_OOM;
 
case 0:
@@ -560,7 +562,8 @@ __assign_mmap_offset(struct drm_file *file,
}
 
if (mmap_type != I915_MMAP_TYPE_GTT &&
-   !i915_gem_object_has_struct_page(obj)) {
+   !i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_S

[Intel-gfx] [PATCH] drm/i915: Add lmem fault handler

2019-12-10 Thread Abdiel Janulgue
Fault handler to handle missing pages for lmem objects.

v2: Handle ENXIO in fault error, account for offset in region start
for fake lmem (Matt).
Add selftest (Chris).

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_lmem.c  |  44 
 drivers/gpu/drm/i915/gem/i915_gem_lmem.h  |   6 +
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  |  16 ++-
 drivers/gpu/drm/i915/gem/i915_gem_mman.h  |   1 +
 .../drm/i915/gem/selftests/i915_gem_mman.c| 105 ++
 5 files changed, 147 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c 
b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
index 0e2bf6b7e143..7e6d8d1546e3 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
@@ -6,8 +6,40 @@
 #include "intel_memory_region.h"
 #include "gem/i915_gem_region.h"
 #include "gem/i915_gem_lmem.h"
+#include "gem/i915_gem_mman.h"
 #include "i915_drv.h"
 
+vm_fault_t vm_fault_lmem(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   unsigned long size = area->vm_end - area->vm_start;
+   bool write = area->vm_flags & VM_WRITE;
+   vm_fault_t vmf_ret;
+   int i, ret;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write)
+   return VM_FAULT_SIGBUS;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return i915_error_to_vmf_fault(ret);
+
+   for (i = 0; i < size >> PAGE_SHIFT; i++) {
+   vmf_ret = vmf_insert_pfn(area,
+(unsigned long)area->vm_start + i * 
PAGE_SIZE,
+i915_gem_object_lmem_io_pfn(obj, i));
+   if (vmf_ret != VM_FAULT_NOPAGE)
+   break;
+   }
+
+   i915_gem_object_unpin_pages(obj);
+
+   return vmf_ret;
+}
+
 const struct drm_i915_gem_object_ops i915_gem_lmem_obj_ops = {
.flags = I915_GEM_OBJECT_HAS_IOMEM,
 
@@ -56,6 +88,18 @@ i915_gem_object_lmem_io_map(struct drm_i915_gem_object *obj,
return io_mapping_map_wc(>mm.region->iomap, offset, size);
 }
 
+unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
+ unsigned long n)
+{
+   struct intel_memory_region *mem = obj->mm.region;
+   resource_size_t offset;
+
+   offset = i915_gem_object_get_dma_address(obj, n);
+   offset -= mem->region.start;
+
+   return (mem->io_start + offset) >> PAGE_SHIFT;
+}
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj)
 {
return obj->ops == _gem_lmem_obj_ops;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h 
b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
index 7c176b8b7d2f..917ebef1529f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
@@ -7,6 +7,7 @@
 #define __I915_GEM_LMEM_H
 
 #include 
+#include 
 
 struct drm_i915_private;
 struct drm_i915_gem_object;
@@ -22,8 +23,13 @@ void __iomem *
 i915_gem_object_lmem_io_map_page_atomic(struct drm_i915_gem_object *obj,
unsigned long n);
 
+unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
+ unsigned long n);
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj);
 
+vm_fault_t vm_fault_lmem(struct vm_fault *vmf);
+
 struct drm_i915_gem_object *
 i915_gem_object_create_lmem(struct drm_i915_private *i915,
resource_size_t size,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 879fff8adc48..c67c07905df5 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -11,6 +11,7 @@
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_requests.h"
 
+#include "i915_gem_lmem.h"
 #include "i915_drv.h"
 #include "i915_gem_gtt.h"
 #include "i915_gem_ioctls.h"
@@ -203,7 +204,7 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
return view;
 }
 
-static vm_fault_t i915_error_to_vmf_fault(int err)
+vm_fault_t i915_error_to_vmf_fault(int err)
 {
switch (err) {
default:
@@ -216,6 +217,7 @@ static vm_fault_t i915_error_to_vmf_fault(int err)
 
case -ENOSPC: /* shmemfs allocation failure */
case -ENOMEM: /* our allocation failure */
+   case -ENXIO:
return VM_FAULT_OOM;
 
case 0:
@@ -560,7 +562,8 @@ __assign_mmap_offset(struct drm_file *file,
}
 
if (mmap_

[Intel-gfx] [PATCH] drm/i915: Add lmem fault handler

2019-12-05 Thread Abdiel Janulgue
Fault handler to handle missing pages for lmem objects.

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_lmem.c | 43 
 drivers/gpu/drm/i915/gem/i915_gem_lmem.h |  6 
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 15 +++--
 drivers/gpu/drm/i915/gem/i915_gem_mman.h |  1 +
 4 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c 
b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
index 0e2bf6b7e143..78ac8d160cd7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
@@ -6,8 +6,40 @@
 #include "intel_memory_region.h"
 #include "gem/i915_gem_region.h"
 #include "gem/i915_gem_lmem.h"
+#include "gem/i915_gem_mman.h"
 #include "i915_drv.h"
 
+vm_fault_t vm_fault_lmem(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   unsigned long size = area->vm_end - area->vm_start;
+   bool write = area->vm_flags & VM_WRITE;
+   vm_fault_t vmf_ret;
+   int i, ret;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write)
+   return VM_FAULT_SIGBUS;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return i915_error_to_vmf_fault(ret);
+
+   for (i = 0; i < size >> PAGE_SHIFT; i++) {
+   vmf_ret = vmf_insert_pfn(area,
+(unsigned long)area->vm_start + i * 
PAGE_SIZE,
+i915_gem_object_lmem_io_pfn(obj, i));
+   if (vmf_ret != VM_FAULT_NOPAGE)
+   break;
+   }
+
+   i915_gem_object_unpin_pages(obj);
+
+   return vmf_ret;
+}
+
 const struct drm_i915_gem_object_ops i915_gem_lmem_obj_ops = {
.flags = I915_GEM_OBJECT_HAS_IOMEM,
 
@@ -56,6 +88,17 @@ i915_gem_object_lmem_io_map(struct drm_i915_gem_object *obj,
return io_mapping_map_wc(>mm.region->iomap, offset, size);
 }
 
+unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
+ unsigned long n)
+{
+   struct intel_memory_region *mem = obj->mm.region;
+   resource_size_t offset;
+
+   offset = i915_gem_object_get_dma_address(obj, n);
+
+   return (mem->io_start + offset) >> PAGE_SHIFT;
+}
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj)
 {
return obj->ops == _gem_lmem_obj_ops;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h 
b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
index 7c176b8b7d2f..917ebef1529f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
@@ -7,6 +7,7 @@
 #define __I915_GEM_LMEM_H
 
 #include 
+#include 
 
 struct drm_i915_private;
 struct drm_i915_gem_object;
@@ -22,8 +23,13 @@ void __iomem *
 i915_gem_object_lmem_io_map_page_atomic(struct drm_i915_gem_object *obj,
unsigned long n);
 
+unsigned long i915_gem_object_lmem_io_pfn(struct drm_i915_gem_object *obj,
+ unsigned long n);
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj);
 
+vm_fault_t vm_fault_lmem(struct vm_fault *vmf);
+
 struct drm_i915_gem_object *
 i915_gem_object_create_lmem(struct drm_i915_private *i915,
resource_size_t size,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 3a3f30bc8ac7..5f6451ede53d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -11,6 +11,7 @@
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_requests.h"
 
+#include "i915_gem_lmem.h"
 #include "i915_drv.h"
 #include "i915_gem_gtt.h"
 #include "i915_gem_ioctls.h"
@@ -203,7 +204,7 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
return view;
 }
 
-static vm_fault_t i915_error_to_vmf_fault(int err)
+vm_fault_t i915_error_to_vmf_fault(int err)
 {
switch (err) {
default:
@@ -560,7 +561,8 @@ __assign_mmap_offset(struct drm_file *file,
}
 
if (mmap_type != I915_MMAP_TYPE_GTT &&
-   !i915_gem_object_has_struct_page(obj)) {
+   !i915_gem_object_has_struct_page(obj) &&
+   !i915_gem_object_is_lmem(obj)) {
err = -ENODEV;
goto out;
}
@@ -685,6 +687,12 @@ static const struct vm_operations_struct vm_ops_cpu = {
.close = vm_close,
 };
 
+static const struct vm_operations_struct vm_ops_lmem = {
+   .fault = vm_fault_lmem,
+   .open = vm_ope

Re: [Intel-gfx] [PATCH 2/4] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET

2019-11-19 Thread Abdiel Janulgue

On 19/11/2019 13.37, Abdiel Janulgue wrote:

> +struct drm_i915_gem_mmap_offset {
> + /** Handle for the object being mapped. */
> + __u32 handle;
> + __u32 pad;
> + /**
> +  * Fake offset to use for subsequent mmap call
> +  *
> +  * This is a fixed-size type for 32/64 compatibility.
> +  */
> + __u64 offset;
> +
> + /**
> +  * Flags for extended behaviour.
> +  *
> +  * It is mandatory that either one of the MMAP_OFFSET flags
> +  * should be passed here.
> +  */
> + __u64 flags;
> +#define I915_MMAP_OFFSET_GTT 0
> +#define I915_MMAP_OFFSET_WC  1
> +#define I915_MMAP_OFFSET_WB  2
> +#define I915_MMAP_OFFSET_UC  3
> +
> + __u64 extensions;
> +};

The simple memset IGT portion of this, coming up soon.

-Abdiel
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 1/4] drm/i915: Allow i915 to manage the vma offset nodes instead of drm core

2019-11-19 Thread Abdiel Janulgue
Have i915 replace the core drm_gem_mmap implementation to overcome its
limitation in having only a single mmap offset node per gem object.
This change allows us to have multiple mmap offsets per object and
enables a mmapping instance to use unique fault-handlers per user vma.

This allows i915 to store extra data within vma->vm_private_data and
assign the pagefault ops for each mmap instance allowing objects to use
multiple fault handlers depending on its backing storage.

v2:
 - Fix race condition exposed by gem_mmap_gtt@close-race. Simplify
   lifetime management of the mmap offset objects be ensuring it is
   owned by the parent gem object instead of refcounting.
 - Track mmo used by fencing to avoid locking when revoking mmaps
   during GPU reset.
 - Rebase.
v3:
 - Simplify mmo tracking
v4:
 - use vma->mmo in __i915_gem_object_release_mmap_gtt
v5:
 - Revoke CPU mmaps on i915_gem_object_unbind() since unlike GTT
   mmaps, they don't have bound i915_vma objects. Rebase.
v6: Minor tweaks, header re-org (Chris)
v7:
- Call drm_vma_node_revoke for the mmo with corresponding file when
  releasing the gem handle instead of in the mmo's teardown.
- Add flag I915_BO_READONLY instead of obj->readonly.

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/gem/i915_gem_domain.c|   3 +-
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 241 +++---
 drivers/gpu/drm/i915/gem/i915_gem_mman.h  |  28 ++
 drivers/gpu/drm/i915/gem/i915_gem_object.c|  18 ++
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   7 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  19 ++
 drivers/gpu/drm/i915/gem/i915_gem_pages.c |   3 +
 drivers/gpu/drm/i915/gem/i915_gem_tiling.c|   1 +
 .../drm/i915/gem/selftests/i915_gem_mman.c|  20 +-
 drivers/gpu/drm/i915/gt/intel_reset.c |   7 +-
 drivers/gpu/drm/i915/i915_drv.c   |  11 +-
 drivers/gpu/drm/i915/i915_drv.h   |   3 -
 drivers/gpu/drm/i915/i915_gem.c   |   3 +-
 drivers/gpu/drm/i915/i915_getparam.c  |   1 +
 drivers/gpu/drm/i915/i915_vma.c   |   3 +-
 drivers/gpu/drm/i915/i915_vma.h   |   3 +
 16 files changed, 313 insertions(+), 58 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_mman.h

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c 
b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
index e2af63af67ad..fd1c6f12b77a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
@@ -13,6 +13,7 @@
 #include "i915_gem_object.h"
 #include "i915_vma.h"
 #include "i915_gem_lmem.h"
+#include "i915_gem_mman.h"
 
 static void __i915_gem_object_flush_for_display(struct drm_i915_gem_object 
*obj)
 {
@@ -255,7 +256,7 @@ int i915_gem_object_set_cache_level(struct 
drm_i915_gem_object *obj,
}
 
if (obj->userfault_count)
-   __i915_gem_object_release_mmap(obj);
+   __i915_gem_object_release_mmap_gtt(obj);
 
/*
 * As we no longer need a fence for GTT access,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index d60973603cc1..36fffb671601 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -14,6 +14,7 @@
 #include "i915_gem_gtt.h"
 #include "i915_gem_ioctls.h"
 #include "i915_gem_object.h"
+#include "i915_gem_mman.h"
 #include "i915_trace.h"
 #include "i915_vma.h"
 
@@ -219,7 +220,8 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 {
 #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
struct vm_area_struct *area = vmf->vma;
-   struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *i915 = to_i915(dev);
struct intel_runtime_pm *rpm = >runtime_pm;
@@ -312,6 +314,9 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
list_add(>userfault_link, >ggtt.userfault_list);
mutex_unlock(>ggtt.vm.mutex);
 
+   /* Track the mmo associated with the fenced vma */
+   vma->mmo = priv;
+
if (IS_ACTIVE(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND))
intel_wakeref_auto(>ggtt.userfault_wakeref,
   
msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));
@@ -358,28 +363,19 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
}
 }
 
-void __i915_gem_object_release_mmap(struct drm_i915_gem_object *obj)
+void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *

[Intel-gfx] [PATCH 3/4] drm/i915: cpu-map based dumb buffers

2019-11-19 Thread Abdiel Janulgue
Prefer CPU WC mmaps via our new mmap offset plumbing otherwise fall-
back to GTT mmaps when hw doesn't support PAT

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
Acked-by: Chris Wilson 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 18 ++
 drivers/gpu/drm/i915/gem/i915_gem_mman.h |  2 ++
 drivers/gpu/drm/i915/i915_drv.c  |  1 +
 3 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index bb05c53c03c8..3913634ab717 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -540,6 +540,24 @@ __assign_gem_object_mmap_data(struct drm_file *file,
return ret;
 }
 
+int
+i915_gem_mmap_dumb(struct drm_file *file,
+ struct drm_device *dev,
+ u32 handle,
+ u64 *offset)
+{
+   enum i915_mmap_type mmap_type;
+
+   if (boot_cpu_has(X86_FEATURE_PAT))
+   mmap_type = I915_MMAP_TYPE_WC;
+   else if (!i915_ggtt_has_aperture(_i915(dev)->ggtt))
+   return -ENODEV;
+   else
+   mmap_type = I915_MMAP_TYPE_GTT;
+
+   return __assign_gem_object_mmap_data(file, handle, mmap_type, offset);
+}
+
 /**
  * i915_gem_mmap_offset_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.h 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.h
index 4d3b493e853a..6e70b91dabc4 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.h
@@ -24,6 +24,8 @@ void i915_mmap_offset_destroy(struct i915_mmap_offset *mmo, 
struct mutex *mutex)
 void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj);
 void i915_gem_object_release_mmap(struct drm_i915_gem_object *obj);
 void i915_gem_object_release_mmap_offset(struct drm_i915_gem_object *obj);
+int i915_gem_mmap_dumb(struct drm_file *file_priv, struct drm_device *dev,
+ u32 handle, u64 *offset);
 int i915_gem_mmap_gtt_version(void);
 
 #endif
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index ac6d4470ce75..f7db0bbbe302 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2767,6 +2767,7 @@ static struct drm_driver driver = {
.get_scanout_position = i915_get_crtc_scanoutpos,
 
.dumb_create = i915_gem_dumb_create,
+   .dumb_map_offset = i915_gem_mmap_dumb,
.ioctls = i915_ioctls,
.num_ioctls = ARRAY_SIZE(i915_ioctls),
.fops = _driver_fops,
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 2/4] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET

2019-11-19 Thread Abdiel Janulgue
This is really just an alias of mmap_gtt. The 'mmap offset' nomenclature
comes from the value returned by this ioctl which is the offset into the
device fd which userpace uses with mmap(2).

mmap_gtt was our initial mmap_offset implementation, this extends
our CPU mmap support to allow additional fault handlers that depends on
the object's backing pages.

Note that we multiplex mmap_gtt and mmap_offset through the same ioctl,
and use the zero extending behaviour of drm to differentiate between
them, when we inspect the flags.

v2:
- Drop the alias, just rename the struct (Chris)
- Don't bail out on no PAT when doing WB mmaps
- Prepare uAPI for further extensions
v3:
- drop MMAP_OFFSET_FLAGS
v4:
- Tweaks, header re-org

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_ioctls.h|  4 +-
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 45 ---
 drivers/gpu/drm/i915/gem/i915_gem_mman.h  |  1 +
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 ++
 drivers/gpu/drm/i915/i915_drv.c   |  2 +-
 drivers/gpu/drm/i915/i915_drv.h   |  1 -
 include/uapi/drm/i915_drm.h   | 27 +++
 7 files changed, 72 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h 
b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
index ddc7f2a52b3e..87d8b27f426d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
@@ -28,8 +28,8 @@ int i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file);
 int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
-int i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
-   struct drm_file *file);
+int i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
+  struct drm_file *file);
 int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
 struct drm_file *file);
 int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 36fffb671601..bb05c53c03c8 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -145,6 +145,9 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  * 3 - Remove implicit set-domain(GTT) and synchronisation on initial
  * pagefault; swapin remains transparent.
  *
+ * 4 - Support multiple fault handlers per object depending on object's
+ * backing storage (a.k.a. MMAP_OFFSET).
+ *
  * Restrictions:
  *
  *  * snoopable objects cannot be accessed via the GTT. It can cause machine
@@ -172,7 +175,7 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  */
 int i915_gem_mmap_gtt_version(void)
 {
-   return 3;
+   return 4;
 }
 
 static inline struct i915_ggtt_view
@@ -538,7 +541,7 @@ __assign_gem_object_mmap_data(struct drm_file *file,
 }
 
 /**
- * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
+ * i915_gem_mmap_offset_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
  * @data: GTT mapping ioctl data
  * @file: GEM object info
@@ -553,13 +556,41 @@ __assign_gem_object_mmap_data(struct drm_file *file,
  * userspace.
  */
 int
-i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
-   struct drm_file *file)
+i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
+  struct drm_file *file)
 {
-   struct drm_i915_gem_mmap_gtt *args = data;
+   struct drm_i915_private *i915 = to_i915(dev);
+   struct drm_i915_gem_mmap_offset *args = data;
+   enum i915_mmap_type type;
+
+   switch (args->flags) {
+   case I915_MMAP_OFFSET_GTT:
+   if (!i915_ggtt_has_aperture(>ggtt))
+   return -ENODEV;
+   type = I915_MMAP_TYPE_GTT;
+   break;
+
+   case I915_MMAP_OFFSET_WC:
+   if (!boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+   type = I915_MMAP_TYPE_WC;
+   break;
+
+   case I915_MMAP_OFFSET_WB:
+   type = I915_MMAP_TYPE_WB;
+   break;
+
+   case I915_MMAP_OFFSET_UC:
+   if (!boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+   type = I915_MMAP_TYPE_UC;
+   break;
+
+   default:
+   return -EINVAL;
+   }
 
-   return __assign_gem_object_mmap_data(file, args->handle,
-I915_MMAP_TYPE_GTT,
+   return __assign_gem_object_mmap_data(file, args->handle, type,
 >offset);
 }
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.h 
b/drivers/g

[Intel-gfx] [PATCH 4/4] drm/i915: Add cpu fault handler for mmap_offset

2019-11-19 Thread Abdiel Janulgue
Fault handler to handle missing pages for shmem-backed objects.

v2: bail out of inserting PTEs when failing to insert the
fault address
v3: has struct page check
v4: Add self-test for validating CPU fault handler to ensure PTEs
are revoked when an object is unbound.
v5: Add comment where PTEs are revoked (Chris)

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
Reviewed-by: Chris Wilson 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 129 ++
 .../drm/i915/gem/selftests/i915_gem_mman.c|  48 ++-
 2 files changed, 145 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 3913634ab717..b892f645ca2d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include 
 
 #include "gt/intel_gt.h"
@@ -201,6 +202,71 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
return view;
 }
 
+static vm_fault_t i915_error_to_vmf_fault(int err)
+{
+   switch (err) {
+   default:
+   WARN_ONCE(err, "unhandled error in %s: %i\n", __func__, err);
+   /* fallthrough */
+   case -EIO: /* shmemfs failure from swap device */
+   case -EFAULT: /* purged object */
+   case -ENODEV: /* bad object, how did you get here! */
+   return VM_FAULT_SIGBUS;
+
+   case -ENOSPC: /* shmemfs allocation failure */
+   case -ENOMEM: /* our allocation failure */
+   return VM_FAULT_OOM;
+
+   case 0:
+   case -EAGAIN:
+   case -ERESTARTSYS:
+   case -EINTR:
+   case -EBUSY:
+   /*
+* EBUSY is ok: this just means that another thread
+* already did the job.
+*/
+   return VM_FAULT_NOPAGE;
+   }
+}
+
+static vm_fault_t i915_gem_fault_cpu(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   vm_fault_t vmf_ret;
+   unsigned long i, size = area->vm_end - area->vm_start;
+   bool write = area->vm_flags & VM_WRITE;
+   int ret;
+
+   if (!i915_gem_object_has_struct_page(obj))
+   return VM_FAULT_SIGBUS;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write)
+   return VM_FAULT_SIGBUS;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return i915_error_to_vmf_fault(ret);
+
+   /* PTEs are revoked in obj->ops->put_pages() */
+   for (i = 0; i < size >> PAGE_SHIFT; i++) {
+   struct page *page = i915_gem_object_get_page(obj, i);
+
+   vmf_ret = vmf_insert_pfn(area,
+(unsigned long)area->vm_start + i * 
PAGE_SIZE,
+page_to_pfn(page));
+   if (vmf_ret != VM_FAULT_NOPAGE)
+   break;
+   }
+
+   i915_gem_object_unpin_pages(obj);
+
+   return vmf_ret;
+}
+
 /**
  * i915_gem_fault - fault a page into the GTT
  * @vmf: fault info
@@ -340,30 +406,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
intel_runtime_pm_put(rpm, wakeref);
i915_gem_object_unpin_pages(obj);
 err:
-   switch (ret) {
-   default:
-   WARN_ONCE(ret, "unhandled error in %s: %i\n", __func__, ret);
-   /* fallthrough */
-   case -EIO: /* shmemfs failure from swap device */
-   case -EFAULT: /* purged object */
-   case -ENODEV: /* bad object, how did you get here! */
-   return VM_FAULT_SIGBUS;
-
-   case -ENOSPC: /* shmemfs allocation failure */
-   case -ENOMEM: /* our allocation failure */
-   return VM_FAULT_OOM;
-
-   case 0:
-   case -EAGAIN:
-   case -ERESTARTSYS:
-   case -EINTR:
-   case -EBUSY:
-   /*
-* EBUSY is ok: this just means that another thread
-* already did the job.
-*/
-   return VM_FAULT_NOPAGE;
-   }
+   return i915_error_to_vmf_fault(ret);
 }
 
 void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
@@ -647,6 +690,33 @@ static const struct vm_operations_struct 
i915_gem_gtt_vm_ops = {
.close = i915_gem_vm_close,
 };
 
+static const struct vm_operations_struct i915_gem_cpu_vm_ops = {
+   .fault = i915_gem_fault_cpu,
+   .open = i915_gem_vm_open,
+   .close = i915_gem_vm_close,
+};
+
+static void set_vmdata_mmap_offset(struct i915_mmap_offset *mmo, struct 
vm_area_struct *vma)
+{
+   switch (mmo->mmap_type) {
+   case I915_MMAP_TYPE_WC:
+   vma->vm_page_prot =
+   pgpro

[Intel-gfx] [PATCH 4/4] drm/i915: Add cpu fault handler for mmap_offset

2019-11-15 Thread Abdiel Janulgue
Fault handler to handle missing pages for shmem-backed objects.

v2: bail out of inserting PTEs when failing to insert the
fault address
v3: has struct page check
v4: Add self-test for validating CPU fault handler to ensure PTEs
are revoked when an object is unbound.

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 128 ++
 .../drm/i915/gem/selftests/i915_gem_mman.c|  47 +--
 2 files changed, 141 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index c1756e4f46b9..2f7ed2e6dfa8 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include 
 
 #include "gt/intel_gt.h"
@@ -201,6 +202,70 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
return view;
 }
 
+static vm_fault_t i915_error_to_vmf_fault(int err)
+{
+   switch (err) {
+   default:
+   WARN_ONCE(err, "unhandled error in %s: %i\n", __func__, err);
+   /* fallthrough */
+   case -EIO: /* shmemfs failure from swap device */
+   case -EFAULT: /* purged object */
+   case -ENODEV: /* bad object, how did you get here! */
+   return VM_FAULT_SIGBUS;
+
+   case -ENOSPC: /* shmemfs allocation failure */
+   case -ENOMEM: /* our allocation failure */
+   return VM_FAULT_OOM;
+
+   case 0:
+   case -EAGAIN:
+   case -ERESTARTSYS:
+   case -EINTR:
+   case -EBUSY:
+   /*
+* EBUSY is ok: this just means that another thread
+* already did the job.
+*/
+   return VM_FAULT_NOPAGE;
+   }
+}
+
+static vm_fault_t i915_gem_fault_cpu(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   vm_fault_t vmf_ret;
+   unsigned long i, size = area->vm_end - area->vm_start;
+   bool write = area->vm_flags & VM_WRITE;
+   int ret;
+
+   if (!i915_gem_object_has_struct_page(obj))
+   return VM_FAULT_SIGBUS;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write)
+   return VM_FAULT_SIGBUS;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return i915_error_to_vmf_fault(ret);
+
+   for (i = 0; i < size >> PAGE_SHIFT; i++) {
+   struct page *page = i915_gem_object_get_page(obj, i);
+
+   vmf_ret = vmf_insert_pfn(area,
+(unsigned long)area->vm_start + i * 
PAGE_SIZE,
+page_to_pfn(page));
+   if (vmf_ret != VM_FAULT_NOPAGE)
+   break;
+   }
+
+   i915_gem_object_unpin_pages(obj);
+
+   return vmf_ret;
+}
+
 /**
  * i915_gem_fault - fault a page into the GTT
  * @vmf: fault info
@@ -340,30 +405,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
intel_runtime_pm_put(rpm, wakeref);
i915_gem_object_unpin_pages(obj);
 err:
-   switch (ret) {
-   default:
-   WARN_ONCE(ret, "unhandled error in %s: %i\n", __func__, ret);
-   /* fallthrough */
-   case -EIO: /* shmemfs failure from swap device */
-   case -EFAULT: /* purged object */
-   case -ENODEV: /* bad object, how did you get here! */
-   return VM_FAULT_SIGBUS;
-
-   case -ENOSPC: /* shmemfs allocation failure */
-   case -ENOMEM: /* our allocation failure */
-   return VM_FAULT_OOM;
-
-   case 0:
-   case -EAGAIN:
-   case -ERESTARTSYS:
-   case -EINTR:
-   case -EBUSY:
-   /*
-* EBUSY is ok: this just means that another thread
-* already did the job.
-*/
-   return VM_FAULT_NOPAGE;
-   }
+   return i915_error_to_vmf_fault(ret);
 }
 
 void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
@@ -650,6 +692,33 @@ static const struct vm_operations_struct 
i915_gem_gtt_vm_ops = {
.close = i915_gem_vm_close,
 };
 
+static const struct vm_operations_struct i915_gem_cpu_vm_ops = {
+   .fault = i915_gem_fault_cpu,
+   .open = i915_gem_vm_open,
+   .close = i915_gem_vm_close,
+};
+
+static void set_vmdata_mmap_offset(struct i915_mmap_offset *mmo, struct 
vm_area_struct *vma)
+{
+   switch (mmo->mmap_type) {
+   case I915_MMAP_TYPE_WC:
+   vma->vm_page_prot =
+   pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+   break;
+   case I915_MMAP_TYPE_WB:
+   vma->

[Intel-gfx] [PATCH 3/4] drm/i915: cpu-map based dumb buffers

2019-11-15 Thread Abdiel Janulgue
Prefer CPU WC mmaps via our new mmap offset plumbing otherwise fall-
back to GTT mmaps when hw doesn't support PAT

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 18 ++
 drivers/gpu/drm/i915/gem/i915_gem_mman.h |  2 ++
 drivers/gpu/drm/i915/i915_drv.c  |  1 +
 3 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index d2ed8a463672..c1756e4f46b9 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -540,6 +540,24 @@ __assign_gem_object_mmap_data(struct drm_file *file,
return ret;
 }
 
+int
+i915_gem_mmap_dumb(struct drm_file *file,
+ struct drm_device *dev,
+ u32 handle,
+ u64 *offset)
+{
+   enum i915_mmap_type mmap_type;
+
+   if (boot_cpu_has(X86_FEATURE_PAT))
+   mmap_type = I915_MMAP_TYPE_WC;
+   else if (!i915_ggtt_has_aperture(_i915(dev)->ggtt))
+   return -ENODEV;
+   else
+   mmap_type = I915_MMAP_TYPE_GTT;
+
+   return __assign_gem_object_mmap_data(file, handle, mmap_type, offset);
+}
+
 /**
  * i915_gem_mmap_offset_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.h 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.h
index 4d3b493e853a..6e70b91dabc4 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.h
@@ -24,6 +24,8 @@ void i915_mmap_offset_destroy(struct i915_mmap_offset *mmo, 
struct mutex *mutex)
 void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj);
 void i915_gem_object_release_mmap(struct drm_i915_gem_object *obj);
 void i915_gem_object_release_mmap_offset(struct drm_i915_gem_object *obj);
+int i915_gem_mmap_dumb(struct drm_file *file_priv, struct drm_device *dev,
+ u32 handle, u64 *offset);
 int i915_gem_mmap_gtt_version(void);
 
 #endif
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index ac6d4470ce75..f7db0bbbe302 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2767,6 +2767,7 @@ static struct drm_driver driver = {
.get_scanout_position = i915_get_crtc_scanoutpos,
 
.dumb_create = i915_gem_dumb_create,
+   .dumb_map_offset = i915_gem_mmap_dumb,
.ioctls = i915_ioctls,
.num_ioctls = ARRAY_SIZE(i915_ioctls),
.fops = _driver_fops,
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 2/4] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET

2019-11-15 Thread Abdiel Janulgue
This is really just an alias of mmap_gtt. The 'mmap offset' nomenclature
comes from the value returned by this ioctl which is the offset into the
device fd which userpace uses with mmap(2).

mmap_gtt was our initial mmap_offset implementation, this extends
our CPU mmap support to allow additional fault handlers that depends on
the object's backing pages.

Note that we multiplex mmap_gtt and mmap_offset through the same ioctl,
and use the zero extending behaviour of drm to differentiate between
them, when we inspect the flags.

v2:
- Drop the alias, just rename the struct (Chris)
- Don't bail out on no PAT when doing WB mmaps
- Prepare uAPI for further extensions
v3:
- drop MMAP_OFFSET_FLAGS
v4:
- Tweaks, header re-org

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_ioctls.h|  4 +-
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 42 ---
 drivers/gpu/drm/i915/gem/i915_gem_mman.h  |  1 +
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 ++
 drivers/gpu/drm/i915/i915_drv.c   |  3 +-
 drivers/gpu/drm/i915/i915_drv.h   |  1 -
 include/uapi/drm/i915_drm.h   | 27 
 7 files changed, 72 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h 
b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
index ddc7f2a52b3e..87d8b27f426d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
@@ -28,8 +28,8 @@ int i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file);
 int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
-int i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
-   struct drm_file *file);
+int i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
+  struct drm_file *file);
 int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
 struct drm_file *file);
 int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index e602dfb44532..d2ed8a463672 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -145,6 +145,9 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  * 3 - Remove implicit set-domain(GTT) and synchronisation on initial
  * pagefault; swapin remains transparent.
  *
+ * 4 - Support multiple fault handlers per object depending on object's
+ * backing storage (a.k.a. MMAP_OFFSET).
+ *
  * Restrictions:
  *
  *  * snoopable objects cannot be accessed via the GTT. It can cause machine
@@ -172,7 +175,7 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  */
 int i915_gem_mmap_gtt_version(void)
 {
-   return 3;
+   return 4;
 }
 
 static inline struct i915_ggtt_view
@@ -538,7 +541,7 @@ __assign_gem_object_mmap_data(struct drm_file *file,
 }
 
 /**
- * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
+ * i915_gem_mmap_offset_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
  * @data: GTT mapping ioctl data
  * @file: GEM object info
@@ -553,10 +556,39 @@ __assign_gem_object_mmap_data(struct drm_file *file,
  * userspace.
  */
 int
-i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
-   struct drm_file *file)
+i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
+  struct drm_file *file)
 {
-   struct drm_i915_gem_mmap_gtt *args = data;
+   struct drm_i915_private *i915 = to_i915(dev);
+   struct drm_i915_gem_mmap_offset *args = data;
+   enum i915_mmap_type type;
+
+   switch (args->flags) {
+   case I915_MMAP_OFFSET_GTT:
+   if (!i915_ggtt_has_aperture(>ggtt))
+   return -ENODEV;
+   type = I915_MMAP_TYPE_GTT;
+   break;
+
+   case I915_MMAP_OFFSET_WC:
+   if (!boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+   type = I915_MMAP_TYPE_WC;
+   break;
+
+   case I915_MMAP_OFFSET_WB:
+   type = I915_MMAP_TYPE_WB;
+   break;
+
+   case I915_MMAP_OFFSET_UC:
+   if (!boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+   type = I915_MMAP_TYPE_UC;
+   break;
+
+   default:
+   return -EINVAL;
+   }
 
return __assign_gem_object_mmap_data(file, args->handle,
 I915_MMAP_TYPE_GTT,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.h 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.h
index 25a3c4d6cd65..4d3b493e853a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.h
+++ b/drivers/gpu

[Intel-gfx] [PATCH 1/4] drm/i915: Allow i915 to manage the vma offset nodes instead of drm core

2019-11-15 Thread Abdiel Janulgue
Have i915 replace the core drm_gem_mmap implementation to overcome its
limitation in having only a single mmap offset node per gem object.
This change allows us to have multiple mmap offsets per object and
enables a mmapping instance to use unique fault-handlers per user vma.

This allows i915 to store extra data within vma->vm_private_data and
assign the pagefault ops for each mmap instance allowing objects to use
multiple fault handlers depending on its backing storage.

v2:
 - Fix race condition exposed by gem_mmap_gtt@close-race. Simplify
   lifetime management of the mmap offset objects be ensuring it is
   owned by the parent gem object instead of refcounting.
 - Track mmo used by fencing to Avoid locking when revoking mmaps
   during GPU reset.
 - Rebase.
v3:
 - Simplify mmo tracking
v4:
 - use vma->mmo in __i915_gem_object_release_mmap_gtt
v5:
 - Revoke CPU mmaps on i915_gem_object_unbind() since unlike GTT
   mmaps, they don't have bound i915_vmas objects. Rebase.
v6: Minor tweaks, header re-org (Chris)

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/gem/i915_gem_domain.c|   3 +-
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 243 +++---
 drivers/gpu/drm/i915/gem/i915_gem_mman.h  |  28 ++
 drivers/gpu/drm/i915/gem/i915_gem_object.c|  14 +
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   7 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  19 ++
 drivers/gpu/drm/i915/gem/i915_gem_pages.c |   3 +
 drivers/gpu/drm/i915/gem/i915_gem_tiling.c|   1 +
 .../drm/i915/gem/selftests/i915_gem_mman.c|  21 +-
 drivers/gpu/drm/i915/gt/intel_reset.c |   7 +-
 drivers/gpu/drm/i915/i915_drv.c   |  10 +-
 drivers/gpu/drm/i915/i915_drv.h   |   3 -
 drivers/gpu/drm/i915/i915_gem.c   |   3 +-
 drivers/gpu/drm/i915/i915_getparam.c  |   1 +
 drivers/gpu/drm/i915/i915_vma.c   |   3 +-
 drivers/gpu/drm/i915/i915_vma.h   |   3 +
 16 files changed, 313 insertions(+), 56 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_mman.h

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c 
b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
index e2af63af67ad..fd1c6f12b77a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
@@ -13,6 +13,7 @@
 #include "i915_gem_object.h"
 #include "i915_vma.h"
 #include "i915_gem_lmem.h"
+#include "i915_gem_mman.h"
 
 static void __i915_gem_object_flush_for_display(struct drm_i915_gem_object 
*obj)
 {
@@ -255,7 +256,7 @@ int i915_gem_object_set_cache_level(struct 
drm_i915_gem_object *obj,
}
 
if (obj->userfault_count)
-   __i915_gem_object_release_mmap(obj);
+   __i915_gem_object_release_mmap_gtt(obj);
 
/*
 * As we no longer need a fence for GTT access,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index d60973603cc1..e602dfb44532 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -14,6 +14,7 @@
 #include "i915_gem_gtt.h"
 #include "i915_gem_ioctls.h"
 #include "i915_gem_object.h"
+#include "i915_gem_mman.h"
 #include "i915_trace.h"
 #include "i915_vma.h"
 
@@ -219,7 +220,8 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 {
 #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
struct vm_area_struct *area = vmf->vma;
-   struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *i915 = to_i915(dev);
struct intel_runtime_pm *rpm = >runtime_pm;
@@ -312,6 +314,9 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
list_add(>userfault_link, >ggtt.userfault_list);
mutex_unlock(>ggtt.vm.mutex);
 
+   /* Track the mmo associated with the fenced vma */
+   vma->mmo = priv;
+
if (IS_ACTIVE(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND))
intel_wakeref_auto(>ggtt.userfault_wakeref,
   
msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));
@@ -358,28 +363,19 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
}
 }
 
-void __i915_gem_object_release_mmap(struct drm_i915_gem_object *obj)
+void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
 {
struct i915_vma *vma;
 
GEM_BUG_ON(!obj->userfault_count);
 
-   obj->userfault_count = 0;
-   list_del(>userfault_link);
-   drm_vma_node_unmap(>bas

[Intel-gfx] [PATCH 4/4] drm/i915: Add cpu fault handler for mmap_offset

2019-11-14 Thread Abdiel Janulgue
Fault handler to handle missing pages for shmem-backed objects.

v2: bail out of inserting PTEs when failing to insert the
fault address
v3: has struct page check
v4: Add self-test for validating CPU fault handler to ensure PTEs
are revoked when an object is unbound.

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 128 ++
 .../drm/i915/gem/selftests/i915_gem_mman.c|  47 +--
 2 files changed, 141 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index d625f0f5d395..62ebc24b219f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include 
 
 #include "gt/intel_gt.h"
@@ -200,6 +201,70 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
return view;
 }
 
+static vm_fault_t i915_error_to_vmf_fault(int err)
+{
+   switch (err) {
+   default:
+   WARN_ONCE(err, "unhandled error in %s: %i\n", __func__, err);
+   /* fallthrough */
+   case -EIO: /* shmemfs failure from swap device */
+   case -EFAULT: /* purged object */
+   case -ENODEV: /* bad object, how did you get here! */
+   return VM_FAULT_SIGBUS;
+
+   case -ENOSPC: /* shmemfs allocation failure */
+   case -ENOMEM: /* our allocation failure */
+   return VM_FAULT_OOM;
+
+   case 0:
+   case -EAGAIN:
+   case -ERESTARTSYS:
+   case -EINTR:
+   case -EBUSY:
+   /*
+* EBUSY is ok: this just means that another thread
+* already did the job.
+*/
+   return VM_FAULT_NOPAGE;
+   }
+}
+
+static vm_fault_t i915_gem_fault_cpu(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   vm_fault_t vmf_ret;
+   unsigned long i, size = area->vm_end - area->vm_start;
+   bool write = area->vm_flags & VM_WRITE;
+   int ret;
+
+   if (!i915_gem_object_has_struct_page(obj))
+   return VM_FAULT_SIGBUS;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write)
+   return VM_FAULT_SIGBUS;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return i915_error_to_vmf_fault(ret);
+
+   for (i = 0; i < size >> PAGE_SHIFT; i++) {
+   struct page *page = i915_gem_object_get_page(obj, i);
+
+   vmf_ret = vmf_insert_pfn(area,
+(unsigned long)area->vm_start + i * 
PAGE_SIZE,
+page_to_pfn(page));
+   if (vmf_ret != VM_FAULT_NOPAGE)
+   break;
+   }
+
+   i915_gem_object_unpin_pages(obj);
+
+   return vmf_ret;
+}
+
 /**
  * i915_gem_fault - fault a page into the GTT
  * @vmf: fault info
@@ -339,30 +404,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
intel_runtime_pm_put(rpm, wakeref);
i915_gem_object_unpin_pages(obj);
 err:
-   switch (ret) {
-   default:
-   WARN_ONCE(ret, "unhandled error in %s: %i\n", __func__, ret);
-   /* fallthrough */
-   case -EIO: /* shmemfs failure from swap device */
-   case -EFAULT: /* purged object */
-   case -ENODEV: /* bad object, how did you get here! */
-   return VM_FAULT_SIGBUS;
-
-   case -ENOSPC: /* shmemfs allocation failure */
-   case -ENOMEM: /* our allocation failure */
-   return VM_FAULT_OOM;
-
-   case 0:
-   case -EAGAIN:
-   case -ERESTARTSYS:
-   case -EINTR:
-   case -EBUSY:
-   /*
-* EBUSY is ok: this just means that another thread
-* already did the job.
-*/
-   return VM_FAULT_NOPAGE;
-   }
+   return i915_error_to_vmf_fault(ret);
 }
 
 void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
@@ -651,6 +693,33 @@ static const struct vm_operations_struct 
i915_gem_gtt_vm_ops = {
.close = i915_gem_vm_close,
 };
 
+static const struct vm_operations_struct i915_gem_cpu_vm_ops = {
+   .fault = i915_gem_fault_cpu,
+   .open = i915_gem_vm_open,
+   .close = i915_gem_vm_close,
+};
+
+static void set_vmdata_mmap_offset(struct i915_mmap_offset *mmo, struct 
vm_area_struct *vma)
+{
+   switch (mmo->mmap_type) {
+   case I915_MMAP_TYPE_WC:
+   vma->vm_page_prot =
+   pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+   break;
+   case I915_MMAP_TYPE_WB:
+   vma->

[Intel-gfx] [PATCH 3/4] drm/i915: cpu-map based dumb buffers

2019-11-14 Thread Abdiel Janulgue
Prefer CPU WC mmaps via our new mmap offset plumbing otherwise fall-
back to GTT mmaps when hw doesn't support PAT

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 13 +
 drivers/gpu/drm/i915/i915_drv.c  |  1 +
 drivers/gpu/drm/i915/i915_drv.h  |  2 ++
 3 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 5c173c29b3d2..d625f0f5d395 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -567,6 +567,19 @@ static int gem_mmap_offset(struct drm_device *dev, void 
*data,
 >offset);
 }
 
+int
+i915_gem_mmap_dumb(struct drm_file *file,
+ struct drm_device *dev,
+ u32 handle,
+ u64 *offset)
+{
+   enum i915_mmap_type mmap_type = boot_cpu_has(X86_FEATURE_PAT) ?
+   I915_MMAP_TYPE_WC : I915_MMAP_TYPE_GTT;
+
+   return __assign_gem_object_mmap_data(file, handle, mmap_type,
+offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 5fe071640893..021460c78ae7 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2766,6 +2766,7 @@ static struct drm_driver driver = {
.get_scanout_position = i915_get_crtc_scanoutpos,
 
.dumb_create = i915_gem_dumb_create,
+   .dumb_map_offset = i915_gem_mmap_dumb,
.ioctls = i915_ioctls,
.num_ioctls = ARRAY_SIZE(i915_ioctls),
.fops = _driver_fops,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 968c53bfb57b..4633bfe61e14 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1861,6 +1861,8 @@ i915_mutex_lock_interruptible(struct drm_device *dev)
 int i915_gem_dumb_create(struct drm_file *file_priv,
 struct drm_device *dev,
 struct drm_mode_create_dumb *args);
+int i915_gem_mmap_dumb(struct drm_file *file_priv, struct drm_device *dev,
+ u32 handle, u64 *offset);
 int i915_gem_mmap_gtt_version(void);
 
 int __must_check i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno);
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 1/4] drm/i915: Allow i915 to manage the vma offset nodes instead of drm core

2019-11-14 Thread Abdiel Janulgue
Have i915 replace the core drm_gem_mmap implementation to overcome its
limitation in having only a single mmap offset node per gem object.
This change allows us to have multiple mmap offsets per object and
enables a mmapping instance to use unique fault-handlers per user vma.

This allows i915 to store extra data within vma->vm_private_data and
assign the pagefault ops for each mmap instance allowing objects to use
multiple fault handlers depending on its backing storage.

v2:
 - Fix race condition exposed by gem_mmap_gtt@close-race. Simplify
   lifetime management of the mmap offset objects be ensuring it is
   owned by the parent gem object instead of refcounting.
 - Track mmo used by fencing to Avoid locking when revoking mmaps
   during GPU reset.
 - Rebase.
v3:
 - Simplify mmo tracking
v4:
 - use vma->mmo in __i915_gem_object_release_mmap_gtt
v5:
 - Revoke CPU mmaps on i915_gem_object_unbind() since unlike GTT
   mmaps, they don't have bound i915_vmas objects. Rebase.

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/gem/i915_gem_domain.c|   2 +-
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 235 +++---
 drivers/gpu/drm/i915/gem/i915_gem_object.c|  13 +
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   8 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  19 ++
 .../drm/i915/gem/selftests/i915_gem_mman.c|  12 +-
 drivers/gpu/drm/i915/gt/intel_reset.c |   7 +-
 drivers/gpu/drm/i915/i915_drv.c   |  10 +-
 drivers/gpu/drm/i915/i915_drv.h   |   3 +-
 drivers/gpu/drm/i915/i915_gem.c   |   5 +-
 drivers/gpu/drm/i915/i915_vma.c   |  15 +-
 drivers/gpu/drm/i915/i915_vma.h   |   3 +
 12 files changed, 278 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c 
b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
index e2af63af67ad..d6c56272e785 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
@@ -255,7 +255,7 @@ int i915_gem_object_set_cache_level(struct 
drm_i915_gem_object *obj,
}
 
if (obj->userfault_count)
-   __i915_gem_object_release_mmap(obj);
+   __i915_gem_object_release_mmap_gtt(obj);
 
/*
 * As we no longer need a fence for GTT access,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index d60973603cc1..e2df6379c7a7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -219,7 +219,8 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 {
 #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
struct vm_area_struct *area = vmf->vma;
-   struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *i915 = to_i915(dev);
struct intel_runtime_pm *rpm = >runtime_pm;
@@ -312,6 +313,9 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
list_add(>userfault_link, >ggtt.userfault_list);
mutex_unlock(>ggtt.vm.mutex);
 
+   /* Track the mmo associated with the fenced vma */
+   vma->mmo = priv;
+
if (IS_ACTIVE(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND))
intel_wakeref_auto(>ggtt.userfault_wakeref,
   
msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));
@@ -358,7 +362,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
}
 }
 
-void __i915_gem_object_release_mmap(struct drm_i915_gem_object *obj)
+void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
 {
struct i915_vma *vma;
 
@@ -366,20 +370,16 @@ void __i915_gem_object_release_mmap(struct 
drm_i915_gem_object *obj)
 
obj->userfault_count = 0;
list_del(>userfault_link);
-   drm_vma_node_unmap(>base.vma_node,
-  obj->base.dev->anon_inode->i_mapping);
 
-   for_each_ggtt_vma(vma, obj)
+   for_each_ggtt_vma(vma, obj) {
+   if (vma->mmo)
+   drm_vma_node_unmap(>mmo->vma_node,
+  
obj->base.dev->anon_inode->i_mapping);
i915_vma_unset_userfault(vma);
+   }
 }
 
 /**
- * i915_gem_object_release_mmap - remove physical page mappings
- * @obj: obj in question
- *
- * Preserve the reservation of the mmapping with the DRM core code, but
- * relinquish ownership of the pages back to the system.
- *
  * It is vital that we remove the page mapping if we have mapped a tiled
  * object through the GTT and then lose the fen

[Intel-gfx] [PATCH 2/4] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET

2019-11-14 Thread Abdiel Janulgue
This is really just an alias of mmap_gtt. The 'mmap offset' nomenclature
comes from the value returned by this ioctl which is the offset into the
device fd which userpace uses with mmap(2).

mmap_gtt was our initial mmap_offset implementation, this extends
our CPU mmap support to allow additional fault handlers that depends on
the object's backing pages.

Note that we multiplex mmap_gtt and mmap_offset through the same ioctl,
and use the zero extending behaviour of drm to differentiate between
them, when we inspect the flags.

v2:
- Drop the alias, just rename the struct (Chris)
- Don't bail out on no PAT when doing WB mmaps
- Prepare uAPI for further extensions
v3:
- drop MMAP_OFFSET_FLAGS

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 44 ++-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 ++
 include/uapi/drm/i915_drm.h   | 27 +++-
 3 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index e2df6379c7a7..5c173c29b3d2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -144,6 +144,9 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  * 3 - Remove implicit set-domain(GTT) and synchronisation on initial
  * pagefault; swapin remains transparent.
  *
+ * 4 - Support multiple fault handlers per object depending on object's
+ * backing storage (a.k.a. MMAP_OFFSET).
+ *
  * Restrictions:
  *
  *  * snoopable objects cannot be accessed via the GTT. It can cause machine
@@ -171,7 +174,7 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  */
 int i915_gem_mmap_gtt_version(void)
 {
-   return 3;
+   return 4;
 }
 
 static inline struct i915_ggtt_view
@@ -535,6 +538,35 @@ __assign_gem_object_mmap_data(struct drm_file *file,
return ret;
 }
 
+static int gem_mmap_offset(struct drm_device *dev, void *data,
+  struct drm_file *file)
+{
+   struct drm_i915_gem_mmap_offset *args = data;
+   enum i915_mmap_type type;
+
+   switch (args->flags) {
+   case I915_MMAP_OFFSET_WC:
+   if (!boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+   type = I915_MMAP_TYPE_WC;
+   break;
+   case I915_MMAP_OFFSET_WB:
+   type = I915_MMAP_TYPE_WB;
+   break;
+   case I915_MMAP_OFFSET_UC:
+   if (!boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+   type = I915_MMAP_TYPE_UC;
+   break;
+   default:
+   return -EINVAL;
+
+   };
+
+   return __assign_gem_object_mmap_data(file, args->handle, type,
+>offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
@@ -554,7 +586,15 @@ int
 i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
 {
-   struct drm_i915_gem_mmap_gtt *args = data;
+   struct drm_i915_gem_mmap_offset *args = data;
+   struct drm_i915_private *i915 = to_i915(dev);
+
+   if (args->flags)
+   return gem_mmap_offset(dev, data, file);
+
+   if (!i915_ggtt_has_aperture(>ggtt))
+   /* No aperture, cannot mmap via legacy GTT */
+   return -ENODEV;
 
return __assign_gem_object_mmap_data(file, args->handle,
 I915_MMAP_TYPE_GTT,
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 632d6b804cfb..07237fbfdaac 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -65,6 +65,9 @@ struct drm_i915_gem_object_ops {
 
 enum i915_mmap_type {
I915_MMAP_TYPE_GTT = 0,
+   I915_MMAP_TYPE_WC,
+   I915_MMAP_TYPE_WB,
+   I915_MMAP_TYPE_UC,
 };
 
 struct i915_mmap_offset {
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 5400d7e057f1..e9a80b94 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -394,7 +394,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_GEM_PREAD   DRM_IOW (DRM_COMMAND_BASE + 
DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
 #define DRM_IOCTL_I915_GEM_PWRITE  DRM_IOW (DRM_COMMAND_BASE + 
DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
 #define DRM_IOCTL_I915_GEM_MMAPDRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
-#define DRM_IOCTL_I915_GEM_MMAP_GTTDRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_gtt)
+#define DRM_IOCTL_I915_GEM_MMAP_GTTDRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP_GTT, struct drm_i9

Re: [Intel-gfx] [PATCH] drm/i915/selftests: Wrap vm_mmap() around GEM objects

2019-11-07 Thread Abdiel Janulgue


On 06/11/2019 10.26, Chris Wilson wrote:
> Provide a utility function to create a vma corresponding to an mmap() of
> our device. And use it to exercise the equivalent of userspace
> performing a GTT mmap of our objects.
> 
> Signed-off-by: Chris Wilson 
> Cc: Abdiel Janulgue 

Reviewed-by: Abdiel Janulgue 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH] drm/i915/gem: Early rejection of no-aperture map_ggtt

2019-11-05 Thread Abdiel Janulgue


On 05/11/2019 16.53, Chris Wilson wrote:
> If the device does not have an aperture through which we can indirectly
> access and detile the buffers, simply reject the ioctl. Later we can
> extend the ioctl to support different modes, but as an extension the
> user must opt in and explicitly control the mmap type (viz
> MMAP_OFFSET_IOCTL).

Reviewed-by: Abdiel Janulgue 

> 
> Signed-off-by: Chris Wilson 
> Cc: Abdiel Janulgue 
> Cc: Matthew Auld 
> Cc: Joonas Lahtinen 
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_mman.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> index e3002849844b..d60973603cc1 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> @@ -450,6 +450,9 @@ i915_gem_mmap_gtt(struct drm_file *file,
>   struct drm_i915_gem_object *obj;
>   int ret;
>  
> + if (!i915_ggtt_has_aperture(_i915(dev)->ggtt))
> + return -ENODEV;
> +
>   obj = i915_gem_object_lookup(file, handle);
>   if (!obj)
>   return -ENOENT;
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 4/5] drm/i915: cpu-map based dumb buffers

2019-10-23 Thread Abdiel Janulgue
Prefer CPU WC mmaps via our new mmap offset plumbing otherwise fall-
back to GTT mmaps when hw doesn't support PAT

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 13 +
 drivers/gpu/drm/i915/i915_drv.c  |  1 +
 drivers/gpu/drm/i915/i915_drv.h  |  2 ++
 3 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 69779eca6309..209273b836ad 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -566,6 +566,19 @@ static int gem_mmap_offset(struct drm_device *dev, void 
*data,
 >offset);
 }
 
+int
+i915_gem_mmap_dumb(struct drm_file *file,
+ struct drm_device *dev,
+ u32 handle,
+ u64 *offset)
+{
+   enum i915_mmap_type mmap_type = boot_cpu_has(X86_FEATURE_PAT) ?
+   I915_MMAP_TYPE_WC : I915_MMAP_TYPE_GTT;
+
+   return __assign_gem_object_mmap_data(file, handle, mmap_type,
+offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 7dba9b2ea00b..031f59c9e5c9 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2750,6 +2750,7 @@ static struct drm_driver driver = {
.get_scanout_position = i915_get_crtc_scanoutpos,
 
.dumb_create = i915_gem_dumb_create,
+   .dumb_map_offset = i915_gem_mmap_dumb,
.ioctls = i915_ioctls,
.num_ioctls = ARRAY_SIZE(i915_ioctls),
.fops = _driver_fops,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ed0fc1d6dfab..fa26f0575efe 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1932,6 +1932,8 @@ i915_mutex_lock_interruptible(struct drm_device *dev)
 int i915_gem_dumb_create(struct drm_file *file_priv,
 struct drm_device *dev,
 struct drm_mode_create_dumb *args);
+int i915_gem_mmap_dumb(struct drm_file *file_priv, struct drm_device *dev,
+ u32 handle, u64 *offset);
 int i915_gem_mmap_gtt_version(void);
 
 int __must_check i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno);
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 5/5] drm/i915: Add cpu fault handler for mmap_offset

2019-10-23 Thread Abdiel Janulgue
Fault handler to handle missing pages for shmem-backed objects.

v2: bail out of inserting PTEs when failing to insert the
fault address
v3: has struct page check

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 128 ++-
 1 file changed, 103 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 209273b836ad..2c38f5cf367b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include 
 
 #include "gt/intel_gt.h"
@@ -200,6 +201,70 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
return view;
 }
 
+static vm_fault_t i915_error_to_vmf_fault(int err)
+{
+   switch (err) {
+   default:
+   WARN_ONCE(err, "unhandled error in %s: %i\n", __func__, err);
+   /* fallthrough */
+   case -EIO: /* shmemfs failure from swap device */
+   case -EFAULT: /* purged object */
+   case -ENODEV: /* bad object, how did you get here! */
+   return VM_FAULT_SIGBUS;
+
+   case -ENOSPC: /* shmemfs allocation failure */
+   case -ENOMEM: /* our allocation failure */
+   return VM_FAULT_OOM;
+
+   case 0:
+   case -EAGAIN:
+   case -ERESTARTSYS:
+   case -EINTR:
+   case -EBUSY:
+   /*
+* EBUSY is ok: this just means that another thread
+* already did the job.
+*/
+   return VM_FAULT_NOPAGE;
+   }
+}
+
+static vm_fault_t i915_gem_fault_cpu(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   vm_fault_t vmf_ret;
+   unsigned long i, size = area->vm_end - area->vm_start;
+   bool write = area->vm_flags & VM_WRITE;
+   int ret;
+
+   if (!i915_gem_object_has_struct_page(obj))
+   return VM_FAULT_SIGBUS;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write)
+   return VM_FAULT_SIGBUS;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return i915_error_to_vmf_fault(ret);
+
+   for (i = 0; i < size >> PAGE_SHIFT; i++) {
+   struct page *page = i915_gem_object_get_page(obj, i);
+
+   vmf_ret = vmf_insert_pfn(area,
+(unsigned long)area->vm_start + i * 
PAGE_SIZE,
+page_to_pfn(page));
+   if (vmf_ret != VM_FAULT_NOPAGE)
+   break;
+   }
+
+   i915_gem_object_unpin_pages(obj);
+
+   return vmf_ret;
+}
+
 /**
  * i915_gem_fault - fault a page into the GTT
  * @vmf: fault info
@@ -339,30 +404,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
intel_runtime_pm_put(rpm, wakeref);
i915_gem_object_unpin_pages(obj);
 err:
-   switch (ret) {
-   default:
-   WARN_ONCE(ret, "unhandled error in %s: %i\n", __func__, ret);
-   /* fallthrough */
-   case -EIO: /* shmemfs failure from swap device */
-   case -EFAULT: /* purged object */
-   case -ENODEV: /* bad object, how did you get here! */
-   return VM_FAULT_SIGBUS;
-
-   case -ENOSPC: /* shmemfs allocation failure */
-   case -ENOMEM: /* our allocation failure */
-   return VM_FAULT_OOM;
-
-   case 0:
-   case -EAGAIN:
-   case -ERESTARTSYS:
-   case -EINTR:
-   case -EBUSY:
-   /*
-* EBUSY is ok: this just means that another thread
-* already did the job.
-*/
-   return VM_FAULT_NOPAGE;
-   }
+   return i915_error_to_vmf_fault(ret);
 }
 
 void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
@@ -650,6 +692,33 @@ static const struct vm_operations_struct 
i915_gem_gtt_vm_ops = {
.close = i915_gem_vm_close,
 };
 
+static const struct vm_operations_struct i915_gem_cpu_vm_ops = {
+   .fault = i915_gem_fault_cpu,
+   .open = i915_gem_vm_open,
+   .close = i915_gem_vm_close,
+};
+
+static void set_vmdata_mmap_offset(struct i915_mmap_offset *mmo, struct 
vm_area_struct *vma)
+{
+   switch (mmo->mmap_type) {
+   case I915_MMAP_TYPE_WC:
+   vma->vm_page_prot =
+   pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+   break;
+   case I915_MMAP_TYPE_WB:
+   vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+   break;
+   case I915_MMAP_TYPE_UC:
+   vma->vm_page_prot =
+  

[Intel-gfx] [PATCH 1/5] drm/i915: Allow i915 to manage the vma offset nodes instead of drm core

2019-10-23 Thread Abdiel Janulgue
Have i915 replace the core drm_gem_mmap implementation to overcome its
limitation in having only a single mmap offset node per gem object.
This change allows us to have multiple mmap offsets per object and
enables a mmapping instance to use unique fault-handlers per user vma.

This allows i915 to store extra data within vma->vm_private_data and
assign the pagefault ops for each mmap instance allowing objects to use
multiple fault handlers depending on its backing storage.

v2:
 - Fix race condition exposed by gem_mmap_gtt@close-race. Simplify
   lifetime management of the mmap offset objects be ensuring it is
   owned by the parent gem object instead of refcounting.
 - Track mmo used by fencing to Avoid locking when revoking mmaps
   during GPU reset.
 - Rebase.
v3:
- Simplify mmo tracking
v4:
- use vma->mmo in __i915_gem_object_release_mmap_gtt

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/gem/i915_gem_domain.c|   2 +-
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 229 --
 drivers/gpu/drm/i915/gem/i915_gem_object.c|  13 +
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   9 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  19 ++
 .../drm/i915/gem/selftests/i915_gem_mman.c|  12 +-
 drivers/gpu/drm/i915/gt/intel_reset.c |   7 +-
 drivers/gpu/drm/i915/i915_drv.c   |  10 +-
 drivers/gpu/drm/i915/i915_drv.h   |   3 +-
 drivers/gpu/drm/i915/i915_gem.c   |   2 +-
 drivers/gpu/drm/i915/i915_vma.c   |  15 +-
 drivers/gpu/drm/i915/i915_vma.h   |   3 +
 12 files changed, 274 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c 
b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
index 9937b4c341f1..40792d2017a7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
@@ -254,7 +254,7 @@ int i915_gem_object_set_cache_level(struct 
drm_i915_gem_object *obj,
}
 
if (obj->userfault_count)
-   __i915_gem_object_release_mmap(obj);
+   __i915_gem_object_release_mmap_gtt(obj);
 
/*
 * As we no longer need a fence for GTT access,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index fd4122d8c0a9..3491bb06606b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -219,7 +219,8 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 {
 #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
struct vm_area_struct *area = vmf->vma;
-   struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *i915 = to_i915(dev);
struct intel_runtime_pm *rpm = >runtime_pm;
@@ -312,6 +313,9 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
list_add(>userfault_link, >ggtt.userfault_list);
mutex_unlock(>ggtt.vm.mutex);
 
+   /* Track the mmo associated with the fenced vma */
+   vma->mmo = priv;
+
if (CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)
intel_wakeref_auto(>ggtt.userfault_wakeref,
   
msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));
@@ -358,7 +362,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
}
 }
 
-void __i915_gem_object_release_mmap(struct drm_i915_gem_object *obj)
+void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
 {
struct i915_vma *vma;
 
@@ -366,20 +370,16 @@ void __i915_gem_object_release_mmap(struct 
drm_i915_gem_object *obj)
 
obj->userfault_count = 0;
list_del(>userfault_link);
-   drm_vma_node_unmap(>base.vma_node,
-  obj->base.dev->anon_inode->i_mapping);
 
-   for_each_ggtt_vma(vma, obj)
+   for_each_ggtt_vma(vma, obj) {
+   if (vma->mmo)
+   drm_vma_node_unmap(>mmo->vma_node,
+  
obj->base.dev->anon_inode->i_mapping);
i915_vma_unset_userfault(vma);
+   }
 }
 
 /**
- * i915_gem_object_release_mmap - remove physical page mappings
- * @obj: obj in question
- *
- * Preserve the reservation of the mmapping with the DRM core code, but
- * relinquish ownership of the pages back to the system.
- *
  * It is vital that we remove the page mapping if we have mapped a tiled
  * object through the GTT and then lose the fence register due to
  * resource pressure. Similarly if the object has been moved out of the
@@ -387,7 +387,7 @@ void __i915_gem_object_relea

[Intel-gfx] [PATCH 2/5] drm/i915: define i915_ggtt_has_aperture

2019-10-23 Thread Abdiel Janulgue
From: Daniele Ceraolo Spurio 

The following patches in the series will use it to avoid certain
operations when the mappable aperture is not available in HW.

Signed-off-by: Daniele Ceraolo Spurio 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_gem_gtt.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index f074f1de66e8..2809aa41 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -575,6 +575,11 @@ void i915_ggtt_disable_guc(struct i915_ggtt *ggtt);
 int i915_init_ggtt(struct drm_i915_private *dev_priv);
 void i915_ggtt_driver_release(struct drm_i915_private *dev_priv);
 
+static inline bool i915_ggtt_has_aperture(struct i915_ggtt *ggtt)
+{
+   return ggtt->mappable_end > 0;
+}
+
 int i915_ppgtt_init_hw(struct intel_gt *gt);
 
 struct i915_ppgtt *i915_ppgtt_create(struct drm_i915_private *dev_priv);
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 3/5] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET

2019-10-23 Thread Abdiel Janulgue
This is really just an alias of mmap_gtt. The 'mmap offset' nomenclature
comes from the value returned by this ioctl which is the offset into the
device fd which userpace uses with mmap(2).

mmap_gtt was our initial mmap_offset implementation, this extends
our CPU mmap support to allow additional fault handlers that depends on
the object's backing pages.

Note that we multiplex mmap_gtt and mmap_offset through the same ioctl,
and use the zero extending behaviour of drm to differentiate between
them, when we inspect the flags.

v2:
- Drop the alias, just rename the struct (Chris)
- Don't bail out on no PAT when doing WB mmaps
- Prepare uAPI for further extensions
v3:
- drop MMAP_OFFSET_FLAGS

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 44 ++-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 ++
 include/uapi/drm/i915_drm.h   | 27 +++-
 3 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 3491bb06606b..69779eca6309 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -144,6 +144,9 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  * 3 - Remove implicit set-domain(GTT) and synchronisation on initial
  * pagefault; swapin remains transparent.
  *
+ * 4 - Support multiple fault handlers per object depending on object's
+ * backing storage (a.k.a. MMAP_OFFSET).
+ *
  * Restrictions:
  *
  *  * snoopable objects cannot be accessed via the GTT. It can cause machine
@@ -171,7 +174,7 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  */
 int i915_gem_mmap_gtt_version(void)
 {
-   return 3;
+   return 4;
 }
 
 static inline struct i915_ggtt_view
@@ -534,6 +537,35 @@ __assign_gem_object_mmap_data(struct drm_file *file,
return ret;
 }
 
+static int gem_mmap_offset(struct drm_device *dev, void *data,
+  struct drm_file *file)
+{
+   struct drm_i915_gem_mmap_offset *args = data;
+   enum i915_mmap_type type;
+
+   switch (args->flags) {
+   case I915_MMAP_OFFSET_WC:
+   if (!boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+   type = I915_MMAP_TYPE_WC;
+   break;
+   case I915_MMAP_OFFSET_WB:
+   type = I915_MMAP_TYPE_WB;
+   break;
+   case I915_MMAP_OFFSET_UC:
+   if (!boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+   type = I915_MMAP_TYPE_UC;
+   break;
+   default:
+   return -EINVAL;
+
+   };
+
+   return __assign_gem_object_mmap_data(file, args->handle, type,
+>offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
@@ -553,7 +585,15 @@ int
 i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
 {
-   struct drm_i915_gem_mmap_gtt *args = data;
+   struct drm_i915_gem_mmap_offset *args = data;
+   struct drm_i915_private *i915 = to_i915(dev);
+
+   if (args->flags)
+   return gem_mmap_offset(dev, data, file);
+
+   if (!i915_ggtt_has_aperture(>ggtt))
+   /* No aperture, cannot mmap via legacy GTT */
+   return -ENODEV;
 
return __assign_gem_object_mmap_data(file, args->handle,
 I915_MMAP_TYPE_GTT,
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 c5c305bd9927..c643d45f5c0d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -64,6 +64,9 @@ struct drm_i915_gem_object_ops {
 
 enum i915_mmap_type {
I915_MMAP_TYPE_GTT = 0,
+   I915_MMAP_TYPE_WC,
+   I915_MMAP_TYPE_WB,
+   I915_MMAP_TYPE_UC,
 };
 
 struct i915_mmap_offset {
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 63d40cba97e0..190659923dea 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -394,7 +394,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_GEM_PREAD   DRM_IOW (DRM_COMMAND_BASE + 
DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
 #define DRM_IOCTL_I915_GEM_PWRITE  DRM_IOW (DRM_COMMAND_BASE + 
DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
 #define DRM_IOCTL_I915_GEM_MMAPDRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
-#define DRM_IOCTL_I915_GEM_MMAP_GTTDRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_gtt)
+#define DRM_IOCTL_I915_GEM_MMAP_GTTDRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP_GTT, struct drm_i9

Re: [Intel-gfx] [PATCH 3/5] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET

2019-10-23 Thread Abdiel Janulgue

>  i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
>   struct drm_file *file)
>  {
> - struct drm_i915_gem_mmap_gtt *args = data;
> + struct drm_i915_gem_mmap_offset *args = data;
> + struct drm_i915_private *i915 = to_i915(dev);
> +
> + if (args->flags)
> + return gem_mmap_offset(dev, data, file);
> +
> + if (!HAS_MAPPABLE_APERTURE(i915))

Disregard this series. This should've been i915_ggtt_has_aperture()
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 3/5] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET

2019-10-23 Thread Abdiel Janulgue
This is really just an alias of mmap_gtt. The 'mmap offset' nomenclature
comes from the value returned by this ioctl which is the offset into the
device fd which userpace uses with mmap(2).

mmap_gtt was our initial mmap_offset implementation, this extends
our CPU mmap support to allow additional fault handlers that depends on
the object's backing pages.

Note that we multiplex mmap_gtt and mmap_offset through the same ioctl,
and use the zero extending behaviour of drm to differentiate between
them, when we inspect the flags.

v2:
- Drop the alias, just rename the struct (Chris)
- Don't bail out on no PAT when doing WB mmaps
- Prepare uAPI for further extensions
v3:
- drop MMAP_OFFSET_FLAGS

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 44 ++-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 ++
 include/uapi/drm/i915_drm.h   | 27 +++-
 3 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 3491bb06606b..a3eb194fd3b4 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -144,6 +144,9 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  * 3 - Remove implicit set-domain(GTT) and synchronisation on initial
  * pagefault; swapin remains transparent.
  *
+ * 4 - Support multiple fault handlers per object depending on object's
+ * backing storage (a.k.a. MMAP_OFFSET).
+ *
  * Restrictions:
  *
  *  * snoopable objects cannot be accessed via the GTT. It can cause machine
@@ -171,7 +174,7 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  */
 int i915_gem_mmap_gtt_version(void)
 {
-   return 3;
+   return 4;
 }
 
 static inline struct i915_ggtt_view
@@ -534,6 +537,35 @@ __assign_gem_object_mmap_data(struct drm_file *file,
return ret;
 }
 
+static int gem_mmap_offset(struct drm_device *dev, void *data,
+  struct drm_file *file)
+{
+   struct drm_i915_gem_mmap_offset *args = data;
+   enum i915_mmap_type type;
+
+   switch (args->flags) {
+   case I915_MMAP_OFFSET_WC:
+   if (!boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+   type = I915_MMAP_TYPE_WC;
+   break;
+   case I915_MMAP_OFFSET_WB:
+   type = I915_MMAP_TYPE_WB;
+   break;
+   case I915_MMAP_OFFSET_UC:
+   if (!boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+   type = I915_MMAP_TYPE_UC;
+   break;
+   default:
+   return -EINVAL;
+
+   };
+
+   return __assign_gem_object_mmap_data(file, args->handle, type,
+>offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
@@ -553,7 +585,15 @@ int
 i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
 {
-   struct drm_i915_gem_mmap_gtt *args = data;
+   struct drm_i915_gem_mmap_offset *args = data;
+   struct drm_i915_private *i915 = to_i915(dev);
+
+   if (args->flags)
+   return gem_mmap_offset(dev, data, file);
+
+   if (!HAS_MAPPABLE_APERTURE(i915))
+   /* No aperture, cannot mmap via legacy GTT */
+   return -ENODEV;
 
return __assign_gem_object_mmap_data(file, args->handle,
 I915_MMAP_TYPE_GTT,
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 c5c305bd9927..c643d45f5c0d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -64,6 +64,9 @@ struct drm_i915_gem_object_ops {
 
 enum i915_mmap_type {
I915_MMAP_TYPE_GTT = 0,
+   I915_MMAP_TYPE_WC,
+   I915_MMAP_TYPE_WB,
+   I915_MMAP_TYPE_UC,
 };
 
 struct i915_mmap_offset {
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 63d40cba97e0..190659923dea 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -394,7 +394,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_GEM_PREAD   DRM_IOW (DRM_COMMAND_BASE + 
DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
 #define DRM_IOCTL_I915_GEM_PWRITE  DRM_IOW (DRM_COMMAND_BASE + 
DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
 #define DRM_IOCTL_I915_GEM_MMAPDRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
-#define DRM_IOCTL_I915_GEM_MMAP_GTTDRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_gtt)
+#define DRM_IOCTL_I915_GEM_MMAP_GTTDRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP_GTT, struct drm_i915_

[Intel-gfx] [PATCH 4/5] drm/i915: cpu-map based dumb buffers

2019-10-23 Thread Abdiel Janulgue
Prefer CPU WC mmaps via our new mmap offset plumbing otherwise fall-
back to GTT mmaps when hw doesn't support PAT

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 13 +
 drivers/gpu/drm/i915/i915_drv.c  |  1 +
 drivers/gpu/drm/i915/i915_drv.h  |  2 ++
 3 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index a3eb194fd3b4..db810af1cc13 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -566,6 +566,19 @@ static int gem_mmap_offset(struct drm_device *dev, void 
*data,
 >offset);
 }
 
+int
+i915_gem_mmap_dumb(struct drm_file *file,
+ struct drm_device *dev,
+ u32 handle,
+ u64 *offset)
+{
+   enum i915_mmap_type mmap_type = boot_cpu_has(X86_FEATURE_PAT) ?
+   I915_MMAP_TYPE_WC : I915_MMAP_TYPE_GTT;
+
+   return __assign_gem_object_mmap_data(file, handle, mmap_type,
+offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 7dba9b2ea00b..031f59c9e5c9 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2750,6 +2750,7 @@ static struct drm_driver driver = {
.get_scanout_position = i915_get_crtc_scanoutpos,
 
.dumb_create = i915_gem_dumb_create,
+   .dumb_map_offset = i915_gem_mmap_dumb,
.ioctls = i915_ioctls,
.num_ioctls = ARRAY_SIZE(i915_ioctls),
.fops = _driver_fops,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ed0fc1d6dfab..fa26f0575efe 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1932,6 +1932,8 @@ i915_mutex_lock_interruptible(struct drm_device *dev)
 int i915_gem_dumb_create(struct drm_file *file_priv,
 struct drm_device *dev,
 struct drm_mode_create_dumb *args);
+int i915_gem_mmap_dumb(struct drm_file *file_priv, struct drm_device *dev,
+ u32 handle, u64 *offset);
 int i915_gem_mmap_gtt_version(void);
 
 int __must_check i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno);
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 2/5] drm/i915: define i915_ggtt_has_aperture

2019-10-23 Thread Abdiel Janulgue
From: Daniele Ceraolo Spurio 

The following patches in the series will use it to avoid certain
operations when the mappable aperture is not available in HW.

Signed-off-by: Daniele Ceraolo Spurio 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_gem_gtt.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index f074f1de66e8..2809aa41 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -575,6 +575,11 @@ void i915_ggtt_disable_guc(struct i915_ggtt *ggtt);
 int i915_init_ggtt(struct drm_i915_private *dev_priv);
 void i915_ggtt_driver_release(struct drm_i915_private *dev_priv);
 
+static inline bool i915_ggtt_has_aperture(struct i915_ggtt *ggtt)
+{
+   return ggtt->mappable_end > 0;
+}
+
 int i915_ppgtt_init_hw(struct intel_gt *gt);
 
 struct i915_ppgtt *i915_ppgtt_create(struct drm_i915_private *dev_priv);
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 1/5] drm/i915: Allow i915 to manage the vma offset nodes instead of drm core

2019-10-23 Thread Abdiel Janulgue
Have i915 replace the core drm_gem_mmap implementation to overcome its
limitation in having only a single mmap offset node per gem object.
This change allows us to have multiple mmap offsets per object and
enables a mmapping instance to use unique fault-handlers per user vma.

This allows i915 to store extra data within vma->vm_private_data and
assign the pagefault ops for each mmap instance allowing objects to use
multiple fault handlers depending on its backing storage.

v2:
 - Fix race condition exposed by gem_mmap_gtt@close-race. Simplify
   lifetime management of the mmap offset objects be ensuring it is
   owned by the parent gem object instead of refcounting.
 - Track mmo used by fencing to avoid locking when revoking mmaps
   during GPU reset.
 - Rebase.
v3:
- Simplify mmo tracking
v4:
- use vma->mmo in __i915_gem_object_release_mmap_gtt

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/gem/i915_gem_domain.c|   2 +-
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 229 --
 drivers/gpu/drm/i915/gem/i915_gem_object.c|  13 +
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   9 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  19 ++
 .../drm/i915/gem/selftests/i915_gem_mman.c|  12 +-
 drivers/gpu/drm/i915/gt/intel_reset.c |   7 +-
 drivers/gpu/drm/i915/i915_drv.c   |  10 +-
 drivers/gpu/drm/i915/i915_drv.h   |   3 +-
 drivers/gpu/drm/i915/i915_gem.c   |   2 +-
 drivers/gpu/drm/i915/i915_vma.c   |  15 +-
 drivers/gpu/drm/i915/i915_vma.h   |   3 +
 12 files changed, 274 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c 
b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
index 9937b4c341f1..40792d2017a7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
@@ -254,7 +254,7 @@ int i915_gem_object_set_cache_level(struct 
drm_i915_gem_object *obj,
}
 
if (obj->userfault_count)
-   __i915_gem_object_release_mmap(obj);
+   __i915_gem_object_release_mmap_gtt(obj);
 
/*
 * As we no longer need a fence for GTT access,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index fd4122d8c0a9..3491bb06606b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -219,7 +219,8 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 {
 #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
struct vm_area_struct *area = vmf->vma;
-   struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *i915 = to_i915(dev);
struct intel_runtime_pm *rpm = >runtime_pm;
@@ -312,6 +313,9 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
list_add(>userfault_link, >ggtt.userfault_list);
mutex_unlock(>ggtt.vm.mutex);
 
+   /* Track the mmo associated with the fenced vma */
+   vma->mmo = priv;
+
if (CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)
intel_wakeref_auto(>ggtt.userfault_wakeref,
   
msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));
@@ -358,7 +362,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
}
 }
 
-void __i915_gem_object_release_mmap(struct drm_i915_gem_object *obj)
+void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
 {
struct i915_vma *vma;
 
@@ -366,20 +370,16 @@ void __i915_gem_object_release_mmap(struct 
drm_i915_gem_object *obj)
 
obj->userfault_count = 0;
list_del(>userfault_link);
-   drm_vma_node_unmap(>base.vma_node,
-  obj->base.dev->anon_inode->i_mapping);
 
-   for_each_ggtt_vma(vma, obj)
+   for_each_ggtt_vma(vma, obj) {
+   if (vma->mmo)
+   drm_vma_node_unmap(>mmo->vma_node,
+  
obj->base.dev->anon_inode->i_mapping);
i915_vma_unset_userfault(vma);
+   }
 }
 
 /**
- * i915_gem_object_release_mmap - remove physical page mappings
- * @obj: obj in question
- *
- * Preserve the reservation of the mmapping with the DRM core code, but
- * relinquish ownership of the pages back to the system.
- *
  * It is vital that we remove the page mapping if we have mapped a tiled
  * object through the GTT and then lose the fence register due to
  * resource pressure. Similarly if the object has been moved out of the
@@ -387,7 +387,7 @@ void __i915_gem_object_relea

[Intel-gfx] [PATCH 5/5] drm/i915: Add cpu fault handler for mmap_offset

2019-10-23 Thread Abdiel Janulgue
Fault handler to handle missing pages for shmem-backed objects.

v2: bail out of inserting PTEs when failing to insert the
fault address
v3: has struct page check

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 128 ++-
 1 file changed, 103 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index db810af1cc13..1a4198971d0c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include 
 
 #include "gt/intel_gt.h"
@@ -200,6 +201,70 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
return view;
 }
 
+static vm_fault_t i915_error_to_vmf_fault(int err)
+{
+   switch (err) {
+   default:
+   WARN_ONCE(err, "unhandled error in %s: %i\n", __func__, err);
+   /* fallthrough */
+   case -EIO: /* shmemfs failure from swap device */
+   case -EFAULT: /* purged object */
+   case -ENODEV: /* bad object, how did you get here! */
+   return VM_FAULT_SIGBUS;
+
+   case -ENOSPC: /* shmemfs allocation failure */
+   case -ENOMEM: /* our allocation failure */
+   return VM_FAULT_OOM;
+
+   case 0:
+   case -EAGAIN:
+   case -ERESTARTSYS:
+   case -EINTR:
+   case -EBUSY:
+   /*
+* EBUSY is ok: this just means that another thread
+* already did the job.
+*/
+   return VM_FAULT_NOPAGE;
+   }
+}
+
+static vm_fault_t i915_gem_fault_cpu(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   vm_fault_t vmf_ret;
+   unsigned long i, size = area->vm_end - area->vm_start;
+   bool write = area->vm_flags & VM_WRITE;
+   int ret;
+
+   if (!i915_gem_object_has_struct_page(obj))
+   return VM_FAULT_SIGBUS;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write)
+   return VM_FAULT_SIGBUS;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return i915_error_to_vmf_fault(ret);
+
+   for (i = 0; i < size >> PAGE_SHIFT; i++) {
+   struct page *page = i915_gem_object_get_page(obj, i);
+
+   vmf_ret = vmf_insert_pfn(area,
+(unsigned long)area->vm_start + i * 
PAGE_SIZE,
+page_to_pfn(page));
+   if (vmf_ret != VM_FAULT_NOPAGE)
+   break;
+   }
+
+   i915_gem_object_unpin_pages(obj);
+
+   return vmf_ret;
+}
+
 /**
  * i915_gem_fault - fault a page into the GTT
  * @vmf: fault info
@@ -339,30 +404,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
intel_runtime_pm_put(rpm, wakeref);
i915_gem_object_unpin_pages(obj);
 err:
-   switch (ret) {
-   default:
-   WARN_ONCE(ret, "unhandled error in %s: %i\n", __func__, ret);
-   /* fallthrough */
-   case -EIO: /* shmemfs failure from swap device */
-   case -EFAULT: /* purged object */
-   case -ENODEV: /* bad object, how did you get here! */
-   return VM_FAULT_SIGBUS;
-
-   case -ENOSPC: /* shmemfs allocation failure */
-   case -ENOMEM: /* our allocation failure */
-   return VM_FAULT_OOM;
-
-   case 0:
-   case -EAGAIN:
-   case -ERESTARTSYS:
-   case -EINTR:
-   case -EBUSY:
-   /*
-* EBUSY is ok: this just means that another thread
-* already did the job.
-*/
-   return VM_FAULT_NOPAGE;
-   }
+   return i915_error_to_vmf_fault(ret);
 }
 
 void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
@@ -650,6 +692,33 @@ static const struct vm_operations_struct 
i915_gem_gtt_vm_ops = {
.close = i915_gem_vm_close,
 };
 
+static const struct vm_operations_struct i915_gem_cpu_vm_ops = {
+   .fault = i915_gem_fault_cpu,
+   .open = i915_gem_vm_open,
+   .close = i915_gem_vm_close,
+};
+
+static void set_vmdata_mmap_offset(struct i915_mmap_offset *mmo, struct 
vm_area_struct *vma)
+{
+   switch (mmo->mmap_type) {
+   case I915_MMAP_TYPE_WC:
+   vma->vm_page_prot =
+   pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+   break;
+   case I915_MMAP_TYPE_WB:
+   vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+   break;
+   case I915_MMAP_TYPE_UC:
+   vma->vm_page_prot =
+  

Re: [Intel-gfx] [PATCH 4/5] drm/i915: cpu-map based dumb buffers

2019-10-22 Thread Abdiel Janulgue


On 21/10/2019 16.35, Chris Wilson wrote:
> Quoting Abdiel Janulgue (2019-10-21 11:48:10)
>> +int
>> +i915_gem_mmap_dumb(struct drm_file *file,
>> + struct drm_device *dev,
>> + u32 handle,
>> + u64 *offset)
>> +{
>> +   return __assign_gem_object_mmap_data(file, handle, I915_MMAP_TYPE_WC,
> 
> It still needs to do boot_cpu_has(PAT),

So we probably need a special use-case for GTT mmaps in those kind of
hw, no?


 but it looks like
> kms_frontbuffer is not doing enough dirtyfb for its dumb buffer usage.
> Bad IGT (it's either a bug in the test for not adhering to the uabi
> for dumb buffers, or we have some tracking bug intel_frontbuffer).
> -Chris
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 2/5] drm/i915: define HAS_MAPPABLE_APERTURE

2019-10-21 Thread Abdiel Janulgue
From: Daniele Ceraolo Spurio 

The following patches in the series will use it to avoid certain
operations when aperture is not available in HW.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_drv.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ed0fc1d6dfab..a407ca62888b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1732,6 +1732,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define OVERLAY_NEEDS_PHYSICAL(dev_priv) \
(INTEL_INFO(dev_priv)->display.overlay_needs_physical)
 
+#define HAS_MAPPABLE_APERTURE(dev_priv) (dev_priv->ggtt.mappable_end > 0)
+
 /* Early gen2 have a totally busted CS tlb and require pinned batches. */
 #define HAS_BROKEN_CS_TLB(dev_priv)(IS_I830(dev_priv) || 
IS_I845G(dev_priv))
 
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 5/5] drm/i915: Add cpu fault handler for mmap_offset

2019-10-21 Thread Abdiel Janulgue
Fault handler to handle missing pages for shmem-backed objects.

v2: bail out of inserting PTEs when failing to insert the
fault address
v3: has struct page check

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 128 ++-
 1 file changed, 103 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 8e2919832483..300b1b8b5a8a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include 
 
 #include "gt/intel_gt.h"
@@ -200,6 +201,70 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
return view;
 }
 
+static vm_fault_t i915_error_to_vmf_fault(int err)
+{
+   switch (err) {
+   default:
+   WARN_ONCE(err, "unhandled error in %s: %i\n", __func__, err);
+   /* fallthrough */
+   case -EIO: /* shmemfs failure from swap device */
+   case -EFAULT: /* purged object */
+   case -ENODEV: /* bad object, how did you get here! */
+   return VM_FAULT_SIGBUS;
+
+   case -ENOSPC: /* shmemfs allocation failure */
+   case -ENOMEM: /* our allocation failure */
+   return VM_FAULT_OOM;
+
+   case 0:
+   case -EAGAIN:
+   case -ERESTARTSYS:
+   case -EINTR:
+   case -EBUSY:
+   /*
+* EBUSY is ok: this just means that another thread
+* already did the job.
+*/
+   return VM_FAULT_NOPAGE;
+   }
+}
+
+static vm_fault_t i915_gem_fault_cpu(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   vm_fault_t vmf_ret;
+   unsigned long i, size = area->vm_end - area->vm_start;
+   bool write = area->vm_flags & VM_WRITE;
+   int ret;
+
+   if (!i915_gem_object_has_struct_page(obj))
+   return VM_FAULT_SIGBUS;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write)
+   return VM_FAULT_SIGBUS;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return i915_error_to_vmf_fault(ret);
+
+   for (i = 0; i < size >> PAGE_SHIFT; i++) {
+   struct page *page = i915_gem_object_get_page(obj, i);
+
+   vmf_ret = vmf_insert_pfn(area,
+(unsigned long)area->vm_start + i * 
PAGE_SIZE,
+page_to_pfn(page));
+   if (vmf_ret != VM_FAULT_NOPAGE)
+   break;
+   }
+
+   i915_gem_object_unpin_pages(obj);
+
+   return vmf_ret;
+}
+
 /**
  * i915_gem_fault - fault a page into the GTT
  * @vmf: fault info
@@ -339,30 +404,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
intel_runtime_pm_put(rpm, wakeref);
i915_gem_object_unpin_pages(obj);
 err:
-   switch (ret) {
-   default:
-   WARN_ONCE(ret, "unhandled error in %s: %i\n", __func__, ret);
-   /* fallthrough */
-   case -EIO: /* shmemfs failure from swap device */
-   case -EFAULT: /* purged object */
-   case -ENODEV: /* bad object, how did you get here! */
-   return VM_FAULT_SIGBUS;
-
-   case -ENOSPC: /* shmemfs allocation failure */
-   case -ENOMEM: /* our allocation failure */
-   return VM_FAULT_OOM;
-
-   case 0:
-   case -EAGAIN:
-   case -ERESTARTSYS:
-   case -EINTR:
-   case -EBUSY:
-   /*
-* EBUSY is ok: this just means that another thread
-* already did the job.
-*/
-   return VM_FAULT_NOPAGE;
-   }
+   return i915_error_to_vmf_fault(ret);
 }
 
 void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
@@ -647,6 +689,33 @@ static const struct vm_operations_struct 
i915_gem_gtt_vm_ops = {
.close = i915_gem_vm_close,
 };
 
+static const struct vm_operations_struct i915_gem_cpu_vm_ops = {
+   .fault = i915_gem_fault_cpu,
+   .open = i915_gem_vm_open,
+   .close = i915_gem_vm_close,
+};
+
+static void set_vmdata_mmap_offset(struct i915_mmap_offset *mmo, struct 
vm_area_struct *vma)
+{
+   switch (mmo->mmap_type) {
+   case I915_MMAP_TYPE_WC:
+   vma->vm_page_prot =
+   pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+   break;
+   case I915_MMAP_TYPE_WB:
+   vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+   break;
+   case I915_MMAP_TYPE_UC:
+   vma->vm_page_prot =
+  

[Intel-gfx] [PATCH 4/5] drm/i915: cpu-map based dumb buffers

2019-10-21 Thread Abdiel Janulgue
No reason for sticking to GTT mmaps now we have CPU WC mmaps via
our new mmap offset plumbing.

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 10 ++
 drivers/gpu/drm/i915/i915_drv.c  |  1 +
 drivers/gpu/drm/i915/i915_drv.h  |  2 ++
 3 files changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index a3eb194fd3b4..8e2919832483 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -566,6 +566,16 @@ static int gem_mmap_offset(struct drm_device *dev, void 
*data,
 >offset);
 }
 
+int
+i915_gem_mmap_dumb(struct drm_file *file,
+ struct drm_device *dev,
+ u32 handle,
+ u64 *offset)
+{
+   return __assign_gem_object_mmap_data(file, handle, I915_MMAP_TYPE_WC,
+offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index ead2e6ca7907..2157bc961e1f 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2752,6 +2752,7 @@ static struct drm_driver driver = {
.get_scanout_position = i915_get_crtc_scanoutpos,
 
.dumb_create = i915_gem_dumb_create,
+   .dumb_map_offset = i915_gem_mmap_dumb,
.ioctls = i915_ioctls,
.num_ioctls = ARRAY_SIZE(i915_ioctls),
.fops = _driver_fops,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a407ca62888b..800674d167a5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1934,6 +1934,8 @@ i915_mutex_lock_interruptible(struct drm_device *dev)
 int i915_gem_dumb_create(struct drm_file *file_priv,
 struct drm_device *dev,
 struct drm_mode_create_dumb *args);
+int i915_gem_mmap_dumb(struct drm_file *file_priv, struct drm_device *dev,
+ u32 handle, u64 *offset);
 int i915_gem_mmap_gtt_version(void);
 
 int __must_check i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno);
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 3/5] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET

2019-10-21 Thread Abdiel Janulgue
This is really just an alias of mmap_gtt. The 'mmap offset' nomenclature
comes from the value returned by this ioctl which is the offset into the
device fd which userpace uses with mmap(2).

mmap_gtt was our initial mmap_offset implementation, this extends
our CPU mmap support to allow additional fault handlers that depends on
the object's backing pages.

Note that we multiplex mmap_gtt and mmap_offset through the same ioctl,
and use the zero extending behaviour of drm to differentiate between
them, when we inspect the flags.

v2:
- Drop the alias, just rename the struct (Chris)
- Don't bail out on no PAT when doing WB mmaps
- Prepare uAPI for further extensions
v3:
- drop MMAP_OFFSET_FLAGS

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 44 ++-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 ++
 include/uapi/drm/i915_drm.h   | 27 +++-
 3 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 3491bb06606b..a3eb194fd3b4 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -144,6 +144,9 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  * 3 - Remove implicit set-domain(GTT) and synchronisation on initial
  * pagefault; swapin remains transparent.
  *
+ * 4 - Support multiple fault handlers per object depending on object's
+ * backing storage (a.k.a. MMAP_OFFSET).
+ *
  * Restrictions:
  *
  *  * snoopable objects cannot be accessed via the GTT. It can cause machine
@@ -171,7 +174,7 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  */
 int i915_gem_mmap_gtt_version(void)
 {
-   return 3;
+   return 4;
 }
 
 static inline struct i915_ggtt_view
@@ -534,6 +537,35 @@ __assign_gem_object_mmap_data(struct drm_file *file,
return ret;
 }
 
+static int gem_mmap_offset(struct drm_device *dev, void *data,
+  struct drm_file *file)
+{
+   struct drm_i915_gem_mmap_offset *args = data;
+   enum i915_mmap_type type;
+
+   switch (args->flags) {
+   case I915_MMAP_OFFSET_WC:
+   if (!boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+   type = I915_MMAP_TYPE_WC;
+   break;
+   case I915_MMAP_OFFSET_WB:
+   type = I915_MMAP_TYPE_WB;
+   break;
+   case I915_MMAP_OFFSET_UC:
+   if (!boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+   type = I915_MMAP_TYPE_UC;
+   break;
+   default:
+   return -EINVAL;
+
+   };
+
+   return __assign_gem_object_mmap_data(file, args->handle, type,
+>offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
@@ -553,7 +585,15 @@ int
 i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
 {
-   struct drm_i915_gem_mmap_gtt *args = data;
+   struct drm_i915_gem_mmap_offset *args = data;
+   struct drm_i915_private *i915 = to_i915(dev);
+
+   if (args->flags)
+   return gem_mmap_offset(dev, data, file);
+
+   if (!HAS_MAPPABLE_APERTURE(i915))
+   /* No aperture, cannot mmap via legacy GTT */
+   return -ENODEV;
 
return __assign_gem_object_mmap_data(file, args->handle,
 I915_MMAP_TYPE_GTT,
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 c5c305bd9927..c643d45f5c0d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -64,6 +64,9 @@ struct drm_i915_gem_object_ops {
 
 enum i915_mmap_type {
I915_MMAP_TYPE_GTT = 0,
+   I915_MMAP_TYPE_WC,
+   I915_MMAP_TYPE_WB,
+   I915_MMAP_TYPE_UC,
 };
 
 struct i915_mmap_offset {
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 63d40cba97e0..190659923dea 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -394,7 +394,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_GEM_PREAD   DRM_IOW (DRM_COMMAND_BASE + 
DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
 #define DRM_IOCTL_I915_GEM_PWRITE  DRM_IOW (DRM_COMMAND_BASE + 
DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
 #define DRM_IOCTL_I915_GEM_MMAPDRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
-#define DRM_IOCTL_I915_GEM_MMAP_GTTDRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_gtt)
+#define DRM_IOCTL_I915_GEM_MMAP_GTTDRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP_GTT, struct drm_i915_

[Intel-gfx] [PATCH 1/5] drm/i915: Allow i915 to manage the vma offset nodes instead of drm core

2019-10-21 Thread Abdiel Janulgue
Have i915 replace the core drm_gem_mmap implementation to overcome its
limitation in having only a single mmap offset node per gem object.
This change allows us to have multiple mmap offsets per object and
enables a mmapping instance to use unique fault-handlers per user vma.

This allows i915 to store extra data within vma->vm_private_data and
assign the pagefault ops for each mmap instance allowing objects to use
multiple fault handlers depending on its backing storage.

v2:
 - Fix race condition exposed by gem_mmap_gtt@close-race. Simplify
   lifetime management of the mmap offset objects be ensuring it is
   owned by the parent gem object instead of refcounting.
 - Track mmo used by fencing to Avoid locking when revoking mmaps
   during GPU reset.
 - Rebase.
v3:
- Simplify mmo tracking
v4:
- use vma->mmo in __i915_gem_object_release_mmap_gtt

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/gem/i915_gem_domain.c|   2 +-
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 229 --
 drivers/gpu/drm/i915/gem/i915_gem_object.c|  13 +
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   9 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  19 ++
 .../drm/i915/gem/selftests/i915_gem_mman.c|  12 +-
 drivers/gpu/drm/i915/gt/intel_reset.c |   7 +-
 drivers/gpu/drm/i915/i915_drv.c   |  10 +-
 drivers/gpu/drm/i915/i915_drv.h   |   3 +-
 drivers/gpu/drm/i915/i915_gem.c   |   2 +-
 drivers/gpu/drm/i915/i915_vma.c   |  15 +-
 drivers/gpu/drm/i915/i915_vma.h   |   4 +
 12 files changed, 275 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c 
b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
index 9937b4c341f1..40792d2017a7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
@@ -254,7 +254,7 @@ int i915_gem_object_set_cache_level(struct 
drm_i915_gem_object *obj,
}
 
if (obj->userfault_count)
-   __i915_gem_object_release_mmap(obj);
+   __i915_gem_object_release_mmap_gtt(obj);
 
/*
 * As we no longer need a fence for GTT access,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index fd4122d8c0a9..3491bb06606b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -219,7 +219,8 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 {
 #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
struct vm_area_struct *area = vmf->vma;
-   struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *i915 = to_i915(dev);
struct intel_runtime_pm *rpm = >runtime_pm;
@@ -312,6 +313,9 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
list_add(>userfault_link, >ggtt.userfault_list);
mutex_unlock(>ggtt.vm.mutex);
 
+   /* Track the mmo associated with the fenced vma */
+   vma->mmo = priv;
+
if (CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)
intel_wakeref_auto(>ggtt.userfault_wakeref,
   
msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));
@@ -358,7 +362,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
}
 }
 
-void __i915_gem_object_release_mmap(struct drm_i915_gem_object *obj)
+void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
 {
struct i915_vma *vma;
 
@@ -366,20 +370,16 @@ void __i915_gem_object_release_mmap(struct 
drm_i915_gem_object *obj)
 
obj->userfault_count = 0;
list_del(>userfault_link);
-   drm_vma_node_unmap(>base.vma_node,
-  obj->base.dev->anon_inode->i_mapping);
 
-   for_each_ggtt_vma(vma, obj)
+   for_each_ggtt_vma(vma, obj) {
+   if (vma->mmo)
+   drm_vma_node_unmap(>mmo->vma_node,
+  
obj->base.dev->anon_inode->i_mapping);
i915_vma_unset_userfault(vma);
+   }
 }
 
 /**
- * i915_gem_object_release_mmap - remove physical page mappings
- * @obj: obj in question
- *
- * Preserve the reservation of the mmapping with the DRM core code, but
- * relinquish ownership of the pages back to the system.
- *
  * It is vital that we remove the page mapping if we have mapped a tiled
  * object through the GTT and then lose the fence register due to
  * resource pressure. Similarly if the object has been moved out of the
@@ -387,7 +387,7 @@ void __i915_gem_object_relea

Re: [Intel-gfx] [PATCH v3 4/5] drm/i915: cpu-map based dumb buffers

2019-10-15 Thread Abdiel Janulgue


On 15/10/2019 14.15, Chris Wilson wrote:
> Quoting Abdiel Janulgue (2019-10-15 09:37:23)
>> +int
>> +i915_gem_mmap_dumb(struct drm_file *file,
>> + struct drm_device *dev,
>> + u32 handle,
>> + u64 *offset)
>> +{
>> +   struct drm_i915_private *i915 = to_i915(dev);
>> +   enum i915_mmap_type mmap_type = HAS_MAPPABLE_APERTURE(i915) ?
>> +   I915_MMAP_TYPE_GTT : I915_MMAP_TYPE_WC;
> 
> Is there any reason to prefer GTT at all?
> -Chris

I'm not aware of any. :/ Yeah this could be all CPU mmaps

> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH v3 3/5] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET

2019-10-15 Thread Abdiel Janulgue
This is really just an alias of mmap_gtt. The 'mmap offset' nomenclature
comes the value returned by this ioctl which is the offset into the
device fd which userpace uses with mmap(2).

mmap_gtt was our initial mmap_offset implementation, this extends
our CPU mmap support to allow additional fault handlers that depends on
the object's backing pages.

Note that we multiplex mmap_gtt and mmap_offset through the same ioctl,
and use the zero extending behaviour of drm to differentiate between
them, when we inspect the flags.

v2:
- Drop the alias, just rename the struct (Chris)
- Don't bail out on no PAT when doing WB mmaps
- Prepare uAPI for further extensions

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 36 +--
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 ++
 include/uapi/drm/i915_drm.h   | 30 +++-
 3 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 4fb46cbf1bcc..763f3bd78e65 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -144,6 +144,9 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  * 3 - Remove implicit set-domain(GTT) and synchronisation on initial
  * pagefault; swapin remains transparent.
  *
+ * 4 - Support multiple fault handlers per object depending on object's
+ * backing storage (a.k.a. MMAP_OFFSET).
+ *
  * Restrictions:
  *
  *  * snoopable objects cannot be accessed via the GTT. It can cause machine
@@ -171,7 +174,7 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  */
 int i915_gem_mmap_gtt_version(void)
 {
-   return 3;
+   return 4;
 }
 
 static inline struct i915_ggtt_view
@@ -539,6 +542,27 @@ __assign_gem_object_mmap_data(struct drm_file *file,
return ret;
 }
 
+static int gem_mmap_offset(struct drm_device *dev, void *data,
+  struct drm_file *file)
+{
+   struct drm_i915_gem_mmap_offset *args = data;
+   enum i915_mmap_type type;
+
+   if ((args->flags & (I915_MMAP_OFFSET_WC | I915_MMAP_OFFSET_UC)) &&
+   !boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+
+   if (args->flags & I915_MMAP_OFFSET_WC)
+   type = I915_MMAP_TYPE_WC;
+   else if (args->flags & I915_MMAP_OFFSET_WB)
+   type = I915_MMAP_TYPE_WB;
+   else if (args->flags & I915_MMAP_OFFSET_UC)
+   type = I915_MMAP_TYPE_UC;
+
+   return __assign_gem_object_mmap_data(file, args->handle, type,
+>offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
@@ -558,7 +582,15 @@ int
 i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
 {
-   struct drm_i915_gem_mmap_gtt *args = data;
+   struct drm_i915_gem_mmap_offset *args = data;
+   struct drm_i915_private *i915 = to_i915(dev);
+
+   if (args->flags & I915_MMAP_OFFSET_FLAGS)
+   return gem_mmap_offset(dev, data, file);
+
+   if (!HAS_MAPPABLE_APERTURE(i915))
+   /* No aperture, cannot mmap via legacy GTT */
+   return -ENODEV;
 
return __assign_gem_object_mmap_data(file, args->handle,
 I915_MMAP_TYPE_GTT,
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 c5c305bd9927..c643d45f5c0d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -64,6 +64,9 @@ struct drm_i915_gem_object_ops {
 
 enum i915_mmap_type {
I915_MMAP_TYPE_GTT = 0,
+   I915_MMAP_TYPE_WC,
+   I915_MMAP_TYPE_WB,
+   I915_MMAP_TYPE_UC,
 };
 
 struct i915_mmap_offset {
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 63d40cba97e0..09e777133c81 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -394,7 +394,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_GEM_PREAD   DRM_IOW (DRM_COMMAND_BASE + 
DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
 #define DRM_IOCTL_I915_GEM_PWRITE  DRM_IOW (DRM_COMMAND_BASE + 
DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
 #define DRM_IOCTL_I915_GEM_MMAPDRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
-#define DRM_IOCTL_I915_GEM_MMAP_GTTDRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_gtt)
+#define DRM_IOCTL_I915_GEM_MMAP_GTTDRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_offset)
 #define DRM_IOCTL_I915_GEM_SET_DOMAIN  DRM_IOW (DRM_COMMAND_BASE + 
DRM_I915_GEM_

[Intel-gfx] [PATCH v3 5/5] drm/i915: Add cpu fault handler for mmap_offset

2019-10-15 Thread Abdiel Janulgue
Fault handler to handle missing pages for shmem-backed objects.

v2: bail out of inserting PTEs when failing to insert the
fault address

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 125 ++-
 1 file changed, 100 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 5ee97c64c6d6..92327fa27ec8 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include 
 
 #include "gt/intel_gt.h"
@@ -200,6 +201,67 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
return view;
 }
 
+static vm_fault_t i915_error_to_vmf_fault(int err)
+{
+   switch (err) {
+   default:
+   WARN_ONCE(err, "unhandled error in %s: %i\n", __func__, err);
+   /* fallthrough */
+   case -EIO: /* shmemfs failure from swap device */
+   case -EFAULT: /* purged object */
+   case -ENODEV: /* bad object, how did you get here! */
+   return VM_FAULT_SIGBUS;
+
+   case -ENOSPC: /* shmemfs allocation failure */
+   case -ENOMEM: /* our allocation failure */
+   return VM_FAULT_OOM;
+
+   case 0:
+   case -EAGAIN:
+   case -ERESTARTSYS:
+   case -EINTR:
+   case -EBUSY:
+   /*
+* EBUSY is ok: this just means that another thread
+* already did the job.
+*/
+   return VM_FAULT_NOPAGE;
+   }
+}
+
+static vm_fault_t i915_gem_fault_cpu(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   vm_fault_t vmf_ret;
+   unsigned long i, size = area->vm_end - area->vm_start;
+   bool write = area->vm_flags & VM_WRITE;
+   int ret;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write)
+   return VM_FAULT_SIGBUS;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return i915_error_to_vmf_fault(ret);
+
+   for (i = 0; i < size >> PAGE_SHIFT; i++) {
+   struct page *page = i915_gem_object_get_page(obj, i);
+
+   vmf_ret = vmf_insert_pfn(area,
+(unsigned long)area->vm_start + i * 
PAGE_SIZE,
+page_to_pfn(page));
+   if (vmf_ret != VM_FAULT_NOPAGE)
+   break;
+   }
+
+   i915_gem_object_unpin_pages(obj);
+
+   return vmf_ret;
+}
+
 /**
  * i915_gem_fault - fault a page into the GTT
  * @vmf: fault info
@@ -339,30 +401,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
intel_runtime_pm_put(rpm, wakeref);
i915_gem_object_unpin_pages(obj);
 err:
-   switch (ret) {
-   default:
-   WARN_ONCE(ret, "unhandled error in %s: %i\n", __func__, ret);
-   /* fallthrough */
-   case -EIO: /* shmemfs failure from swap device */
-   case -EFAULT: /* purged object */
-   case -ENODEV: /* bad object, how did you get here! */
-   return VM_FAULT_SIGBUS;
-
-   case -ENOSPC: /* shmemfs allocation failure */
-   case -ENOMEM: /* our allocation failure */
-   return VM_FAULT_OOM;
-
-   case 0:
-   case -EAGAIN:
-   case -ERESTARTSYS:
-   case -EINTR:
-   case -EBUSY:
-   /*
-* EBUSY is ok: this just means that another thread
-* already did the job.
-*/
-   return VM_FAULT_NOPAGE;
-   }
+   return i915_error_to_vmf_fault(ret);
 }
 
 void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
@@ -647,6 +686,33 @@ static const struct vm_operations_struct 
i915_gem_gtt_vm_ops = {
.close = i915_gem_vm_close,
 };
 
+static const struct vm_operations_struct i915_gem_cpu_vm_ops = {
+   .fault = i915_gem_fault_cpu,
+   .open = i915_gem_vm_open,
+   .close = i915_gem_vm_close,
+};
+
+static void set_vmdata_mmap_offset(struct i915_mmap_offset *mmo, struct 
vm_area_struct *vma)
+{
+   switch (mmo->mmap_type) {
+   case I915_MMAP_TYPE_WC:
+   vma->vm_page_prot =
+   pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+   break;
+   case I915_MMAP_TYPE_WB:
+   vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+   break;
+   case I915_MMAP_TYPE_UC:
+   vma->vm_page_prot =
+   pgprot_noncached(vm_get_page_prot(vma->vm_flags));
+   break;
+   default:
+   bre

[Intel-gfx] [PATCH v3 4/5] drm/i915: cpu-map based dumb buffers

2019-10-15 Thread Abdiel Janulgue
If there is no aperture we can't use map_gtt to map dumb buffers, so we
need a cpu-map based path to do it. We prefer map_gtt on platforms that
do have aperture.

Signed-off-by: Abdiel Janulgue 
Cc: Daniele Ceraolo Spurio 
Cc: Tvrtko Ursulin 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 13 +
 drivers/gpu/drm/i915/i915_drv.c  |  1 +
 drivers/gpu/drm/i915/i915_drv.h  |  2 ++
 3 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 763f3bd78e65..5ee97c64c6d6 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -563,6 +563,19 @@ static int gem_mmap_offset(struct drm_device *dev, void 
*data,
 >offset);
 }
 
+int
+i915_gem_mmap_dumb(struct drm_file *file,
+ struct drm_device *dev,
+ u32 handle,
+ u64 *offset)
+{
+   struct drm_i915_private *i915 = to_i915(dev);
+   enum i915_mmap_type mmap_type = HAS_MAPPABLE_APERTURE(i915) ?
+   I915_MMAP_TYPE_GTT : I915_MMAP_TYPE_WC;
+
+   return __assign_gem_object_mmap_data(file, handle, mmap_type, offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index dcf22981fdf2..39af8b5310d2 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2750,6 +2750,7 @@ static struct drm_driver driver = {
.get_scanout_position = i915_get_crtc_scanoutpos,
 
.dumb_create = i915_gem_dumb_create,
+   .dumb_map_offset = i915_gem_mmap_dumb,
.ioctls = i915_ioctls,
.num_ioctls = ARRAY_SIZE(i915_ioctls),
.fops = _driver_fops,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b8e495a73d14..55c6a26093f0 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1933,6 +1933,8 @@ i915_mutex_lock_interruptible(struct drm_device *dev)
 int i915_gem_dumb_create(struct drm_file *file_priv,
 struct drm_device *dev,
 struct drm_mode_create_dumb *args);
+int i915_gem_mmap_dumb(struct drm_file *file_priv, struct drm_device *dev,
+ u32 handle, u64 *offset);
 int i915_gem_mmap_gtt_version(void);
 
 int __must_check i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno);
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH v3 2/5] drm/i915: define HAS_MAPPABLE_APERTURE

2019-10-15 Thread Abdiel Janulgue
From: Daniele Ceraolo Spurio 

The following patches in the series will use it to avoid certain
operations when aperture is not available in HW.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_drv.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 2b06c957e627..b8e495a73d14 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1735,6 +1735,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define OVERLAY_NEEDS_PHYSICAL(dev_priv) \
(INTEL_INFO(dev_priv)->display.overlay_needs_physical)
 
+#define HAS_MAPPABLE_APERTURE(dev_priv) (dev_priv->ggtt.mappable_end > 0)
+
 /* Early gen2 have a totally busted CS tlb and require pinned batches. */
 #define HAS_BROKEN_CS_TLB(dev_priv)(IS_I830(dev_priv) || 
IS_I845G(dev_priv))
 
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH v3 1/5] drm/i915: Allow i915 to manage the vma offset nodes instead of drm core

2019-10-15 Thread Abdiel Janulgue
Have i915 replace the core drm_gem_mmap implementation to overcome its
limitation in having only a single mmap offset node per gem object.
This change allows us to have multiple mmap offsets per object and
enables a mmapping instance to use unique fault-handlers per user vma.

This allows i915 to store extra data within vma->vm_private_data and
assign the pagefault ops for each mmap instance allowing objects to use
multiple fault handlers depending on its backing storage.

v2:
 - Fix race condition exposed by gem_mmap_gtt@close-race. Simplify
   lifetime management of the mmap offset objects be ensuring it is
   owned by the parent gem object instead of refcounting.
 - Track mmo used by fencing to Avoid locking when revoking mmaps
   during GPU reset.
 - Rebase.
v3:
- Simplify mmo tracking

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/gem/i915_gem_domain.c|   2 +-
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 232 --
 drivers/gpu/drm/i915/gem/i915_gem_object.c|  13 +
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   9 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  19 ++
 .../drm/i915/gem/selftests/i915_gem_mman.c|  12 +-
 drivers/gpu/drm/i915/gt/intel_reset.c |   7 +-
 drivers/gpu/drm/i915/i915_drv.c   |  10 +-
 drivers/gpu/drm/i915/i915_drv.h   |   3 +-
 drivers/gpu/drm/i915/i915_gem.c   |   2 +-
 drivers/gpu/drm/i915/i915_vma.c   |  15 +-
 drivers/gpu/drm/i915/i915_vma.h   |   4 +
 12 files changed, 279 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c 
b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
index 9937b4c341f1..40792d2017a7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
@@ -254,7 +254,7 @@ int i915_gem_object_set_cache_level(struct 
drm_i915_gem_object *obj,
}
 
if (obj->userfault_count)
-   __i915_gem_object_release_mmap(obj);
+   __i915_gem_object_release_mmap_gtt(obj);
 
/*
 * As we no longer need a fence for GTT access,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index fd4122d8c0a9..4fb46cbf1bcc 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -219,7 +219,8 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 {
 #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
struct vm_area_struct *area = vmf->vma;
-   struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *i915 = to_i915(dev);
struct intel_runtime_pm *rpm = >runtime_pm;
@@ -312,6 +313,9 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
list_add(>userfault_link, >ggtt.userfault_list);
mutex_unlock(>ggtt.vm.mutex);
 
+   /* Track the mmo associated with the fenced vma */
+   vma->mmo = priv;
+
if (CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)
intel_wakeref_auto(>ggtt.userfault_wakeref,
   
msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));
@@ -358,28 +362,29 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
}
 }
 
-void __i915_gem_object_release_mmap(struct drm_i915_gem_object *obj)
+void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
 {
struct i915_vma *vma;
+   struct i915_mmap_offset *mmo;
 
GEM_BUG_ON(!obj->userfault_count);
 
obj->userfault_count = 0;
list_del(>userfault_link);
-   drm_vma_node_unmap(>base.vma_node,
-  obj->base.dev->anon_inode->i_mapping);
+
+   mutex_lock(>mmo_lock);
+   list_for_each_entry(mmo, >mmap_offsets, offset) {
+   if (mmo->mmap_type == I915_MMAP_TYPE_GTT)
+   drm_vma_node_unmap(>vma_node,
+  
obj->base.dev->anon_inode->i_mapping);
+   }
+   mutex_unlock(>mmo_lock);
 
for_each_ggtt_vma(vma, obj)
i915_vma_unset_userfault(vma);
 }
 
 /**
- * i915_gem_object_release_mmap - remove physical page mappings
- * @obj: obj in question
- *
- * Preserve the reservation of the mmapping with the DRM core code, but
- * relinquish ownership of the pages back to the system.
- *
  * It is vital that we remove the page mapping if we have mapped a tiled
  * object through the GTT and then lose the fence register due to
  * resource pressure. Similarly if the object has been moved out of th

[Intel-gfx] [PATCH v2 1/5] drm/i915: Allow i915 to manage the vma offset nodes instead of drm core

2019-10-07 Thread Abdiel Janulgue
Have i915 replace the core drm_gem_mmap implementation to overcome its
limitation in having only a single mmap offset node per gem object.
This change allows us to have multiple mmap offsets per object and
enables a mmapping instance to use unique fault-handlers per user vma.

This allows i915 to store extra data within vma->vm_private_data and
assign the pagefault ops for each mmap instance allowing objects to use
multiple fault handlers depending on its backing storage.

v2:
 - Fix race condition exposed by gem_mmap_gtt@close-race. Simplify
   lifetime management of the mmap offset objects be ensuring it is
   owned by the parent gem object instead of refcounting.
 - Track mmo used by fencing to Avoid locking when revoking mmaps
   during GPU reset.
 - Rebase

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/gem/i915_gem_domain.c|   2 +-
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 245 --
 drivers/gpu/drm/i915/gem/i915_gem_object.c|  13 +
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   9 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  23 ++
 .../drm/i915/gem/selftests/i915_gem_mman.c|  12 +-
 drivers/gpu/drm/i915/gt/intel_reset.c |   7 +-
 drivers/gpu/drm/i915/i915_drv.c   |  10 +-
 drivers/gpu/drm/i915/i915_drv.h   |   3 +-
 drivers/gpu/drm/i915/i915_gem.c   |   2 +-
 drivers/gpu/drm/i915/i915_vma.c   |  24 +-
 drivers/gpu/drm/i915/i915_vma.h   |   4 +
 12 files changed, 305 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c 
b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
index 9937b4c341f1..40792d2017a7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
@@ -254,7 +254,7 @@ int i915_gem_object_set_cache_level(struct 
drm_i915_gem_object *obj,
}
 
if (obj->userfault_count)
-   __i915_gem_object_release_mmap(obj);
+   __i915_gem_object_release_mmap_gtt(obj);
 
/*
 * As we no longer need a fence for GTT access,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index fd4122d8c0a9..af4377a80502 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -219,7 +219,8 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 {
 #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
struct vm_area_struct *area = vmf->vma;
-   struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *i915 = to_i915(dev);
struct intel_runtime_pm *rpm = >runtime_pm;
@@ -312,6 +313,12 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
list_add(>userfault_link, >ggtt.userfault_list);
mutex_unlock(>ggtt.vm.mutex);
 
+   /* Track the mmo associated with the fenced vma */
+   mutex_lock(>vma_lock);
+   vma->mmo = priv;
+   list_move(>mmo_link, >vma_list);
+   mutex_unlock(>vma_lock);
+
if (CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)
intel_wakeref_auto(>ggtt.userfault_wakeref,
   
msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));
@@ -358,28 +365,29 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
}
 }
 
-void __i915_gem_object_release_mmap(struct drm_i915_gem_object *obj)
+void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
 {
struct i915_vma *vma;
+   struct i915_mmap_offset *mmo;
 
GEM_BUG_ON(!obj->userfault_count);
 
obj->userfault_count = 0;
list_del(>userfault_link);
-   drm_vma_node_unmap(>base.vma_node,
-  obj->base.dev->anon_inode->i_mapping);
+
+   mutex_lock(>mmo_lock);
+   list_for_each_entry(mmo, >mmap_offsets, offset) {
+   if (mmo->mmap_type == I915_MMAP_TYPE_GTT)
+   drm_vma_node_unmap(>vma_node,
+  
obj->base.dev->anon_inode->i_mapping);
+   }
+   mutex_unlock(>mmo_lock);
 
for_each_ggtt_vma(vma, obj)
i915_vma_unset_userfault(vma);
 }
 
 /**
- * i915_gem_object_release_mmap - remove physical page mappings
- * @obj: obj in question
- *
- * Preserve the reservation of the mmapping with the DRM core code, but
- * relinquish ownership of the pages back to the system.
- *
  * It is vital that we remove the page mapping if we have mapped a tiled
  * object through the GTT and then lose the fence reg

[Intel-gfx] [PATCH v2 4/5] drm/i915: cpu-map based dumb buffers

2019-10-07 Thread Abdiel Janulgue
If there is no aperture we can't use map_gtt to map dumb buffers, so we
need a cpu-map based path to do it. We prefer map_gtt on platforms that
do have aperture.

Signed-off-by: Abdiel Janulgue 
Cc: Daniele Ceraolo Spurio 
Cc: Tvrtko Ursulin 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 13 +
 drivers/gpu/drm/i915/i915_drv.c  |  1 +
 drivers/gpu/drm/i915/i915_drv.h  |  2 ++
 3 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index ae1e687408da..a9604d0db606 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -569,6 +569,19 @@ static int gem_mmap_offset(struct drm_device *dev, void 
*data,
 >offset);
 }
 
+int
+i915_gem_mmap_dumb(struct drm_file *file,
+ struct drm_device *dev,
+ u32 handle,
+ u64 *offset)
+{
+   struct drm_i915_private *i915 = dev->dev_private;
+   enum i915_mmap_type mmap_type = HAS_MAPPABLE_APERTURE(i915) ?
+   I915_MMAP_TYPE_GTT : I915_MMAP_TYPE_OFFSET_WC;
+
+   return __assign_gem_object_mmap_data(file, handle, mmap_type, offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 9182da57182b..0fbbe03befb0 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2748,6 +2748,7 @@ static struct drm_driver driver = {
.get_scanout_position = i915_get_crtc_scanoutpos,
 
.dumb_create = i915_gem_dumb_create,
+   .dumb_map_offset = i915_gem_mmap_dumb,
.ioctls = i915_ioctls,
.num_ioctls = ARRAY_SIZE(i915_ioctls),
.fops = _driver_fops,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 659319f03f18..47487beaf0e3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2278,6 +2278,8 @@ i915_mutex_lock_interruptible(struct drm_device *dev)
 int i915_gem_dumb_create(struct drm_file *file_priv,
 struct drm_device *dev,
 struct drm_mode_create_dumb *args);
+int i915_gem_mmap_dumb(struct drm_file *file_priv, struct drm_device *dev,
+ u32 handle, u64 *offset);
 int i915_gem_mmap_gtt_version(void);
 
 int __must_check i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno);
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH v2 3/5] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET

2019-10-07 Thread Abdiel Janulgue
This is really just an alias of mmap_gtt. Add a new CPU mmap
implementation that allows multiple fault handlers that depends on
the object's backing pages.

Note that we multiplex mmap_gtt and mmap_offset through the same ioctl,
and use the zero extending behaviour of drm to differentiate between
them, when we inspect the flags.

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 36 +--
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 ++
 drivers/gpu/drm/i915/i915_drv.c   |  2 +-
 include/uapi/drm/i915_drm.h   | 28 +++
 4 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index af4377a80502..ae1e687408da 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -144,6 +144,9 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  * 3 - Remove implicit set-domain(GTT) and synchronisation on initial
  * pagefault; swapin remains transparent.
  *
+ * 4 - Support multiple fault handlers per object depending on object's
+ * backing storage (a.k.a. MMAP_OFFSET).
+ *
  * Restrictions:
  *
  *  * snoopable objects cannot be accessed via the GTT. It can cause machine
@@ -171,7 +174,7 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  */
 int i915_gem_mmap_gtt_version(void)
 {
-   return 3;
+   return 4;
 }
 
 static inline struct i915_ggtt_view
@@ -545,6 +548,27 @@ __assign_gem_object_mmap_data(struct drm_file *file,
return ret;
 }
 
+static int gem_mmap_offset(struct drm_device *dev, void *data,
+  struct drm_file *file)
+{
+   struct drm_i915_gem_mmap_offset *args = data;
+   enum i915_mmap_type type;
+
+   if ((args->flags & (I915_MMAP_OFFSET_WC | I915_MMAP_OFFSET_WB)) &&
+   !boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+
+   if (args->flags & I915_MMAP_OFFSET_WC)
+   type = I915_MMAP_TYPE_OFFSET_WC;
+   else if (args->flags & I915_MMAP_OFFSET_WB)
+   type = I915_MMAP_TYPE_OFFSET_WB;
+   else if (args->flags & I915_MMAP_OFFSET_UC)
+   type = I915_MMAP_TYPE_OFFSET_UC;
+
+   return __assign_gem_object_mmap_data(file, args->handle, type,
+>offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
@@ -564,7 +588,15 @@ int
 i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
 {
-   struct drm_i915_gem_mmap_gtt *args = data;
+   struct drm_i915_gem_mmap_offset *args = data;
+   struct drm_i915_private *i915 = to_i915(dev);
+
+   if (args->flags & I915_MMAP_OFFSET_FLAGS)
+   return gem_mmap_offset(dev, data, file);
+
+   if (!HAS_MAPPABLE_APERTURE(i915))
+   /* No aperture, cannot mmap via legacy GTT */
+   return -ENODEV;
 
return __assign_gem_object_mmap_data(file, args->handle,
 I915_MMAP_TYPE_GTT,
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 74544eca5e2c..18e891f4e9d3 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -64,6 +64,9 @@ struct drm_i915_gem_object_ops {
 
 enum i915_mmap_type {
I915_MMAP_TYPE_GTT = 0,
+   I915_MMAP_TYPE_OFFSET_WC,
+   I915_MMAP_TYPE_OFFSET_WB,
+   I915_MMAP_TYPE_OFFSET_UC,
 };
 
 struct i915_mmap_offset {
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index cc70aba6ac26..9182da57182b 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2696,7 +2696,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW),
-   DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, 
DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_OFFSET, i915_gem_mmap_gtt_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling_ioctl, 
DRM_RENDER_ALLOW),
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 30c542144016..bc85656ab7fd 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -359,6

[Intel-gfx] [PATCH v2 2/5] drm/i915: define HAS_MAPPABLE_APERTURE

2019-10-07 Thread Abdiel Janulgue
From: Daniele Ceraolo Spurio 

The following patches in the series will use it to avoid certain
operations when aperture is not available in HW.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_drv.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index fa6dd301a738..659319f03f18 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2080,6 +2080,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define OVERLAY_NEEDS_PHYSICAL(dev_priv) \
(INTEL_INFO(dev_priv)->display.overlay_needs_physical)
 
+#define HAS_MAPPABLE_APERTURE(dev_priv) (dev_priv->ggtt.mappable_end > 0)
+
 /* Early gen2 have a totally busted CS tlb and require pinned batches. */
 #define HAS_BROKEN_CS_TLB(dev_priv)(IS_I830(dev_priv) || 
IS_I845G(dev_priv))
 
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH v2 5/5] drm/i915: Add cpu fault handler for mmap_offset

2019-10-07 Thread Abdiel Janulgue
Fault handler to handle missing pages for shmem-backed objects.

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 125 ++-
 1 file changed, 100 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index a9604d0db606..02afdae812ba 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include 
 
 #include "gt/intel_gt.h"
@@ -200,6 +201,67 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
return view;
 }
 
+static vm_fault_t i915_error_to_vmf_fault(int err)
+{
+   switch (err) {
+   default:
+   WARN_ONCE(err, "unhandled error in %s: %i\n", __func__, err);
+   /* fallthrough */
+   case -EIO: /* shmemfs failure from swap device */
+   case -EFAULT: /* purged object */
+   case -ENODEV: /* bad object, how did you get here! */
+   return VM_FAULT_SIGBUS;
+
+   case -ENOSPC: /* shmemfs allocation failure */
+   case -ENOMEM: /* our allocation failure */
+   return VM_FAULT_OOM;
+
+   case 0:
+   case -EAGAIN:
+   case -ERESTARTSYS:
+   case -EINTR:
+   case -EBUSY:
+   /*
+* EBUSY is ok: this just means that another thread
+* already did the job.
+*/
+   return VM_FAULT_NOPAGE;
+   }
+}
+
+static vm_fault_t i915_gem_fault_cpu(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   vm_fault_t vmf_ret;
+   unsigned long size = area->vm_end - area->vm_start;
+   bool write = area->vm_flags & VM_WRITE;
+   int i, ret;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write)
+   return VM_FAULT_SIGBUS;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return i915_error_to_vmf_fault(ret);
+
+   for (i = 0; i < size >> PAGE_SHIFT; i++) {
+   struct page *page = i915_gem_object_get_page(obj, i);
+
+   vmf_ret = vmf_insert_pfn(area,
+(unsigned long)area->vm_start + i * 
PAGE_SIZE,
+page_to_pfn(page));
+   if (vmf_ret & VM_FAULT_ERROR)
+   break;
+   }
+
+   i915_gem_object_unpin_pages(obj);
+
+   return vmf_ret;
+}
+
 /**
  * i915_gem_fault - fault a page into the GTT
  * @vmf: fault info
@@ -342,30 +404,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
intel_runtime_pm_put(rpm, wakeref);
i915_gem_object_unpin_pages(obj);
 err:
-   switch (ret) {
-   default:
-   WARN_ONCE(ret, "unhandled error in %s: %i\n", __func__, ret);
-   /* fallthrough */
-   case -EIO: /* shmemfs failure from swap device */
-   case -EFAULT: /* purged object */
-   case -ENODEV: /* bad object, how did you get here! */
-   return VM_FAULT_SIGBUS;
-
-   case -ENOSPC: /* shmemfs allocation failure */
-   case -ENOMEM: /* our allocation failure */
-   return VM_FAULT_OOM;
-
-   case 0:
-   case -EAGAIN:
-   case -ERESTARTSYS:
-   case -EINTR:
-   case -EBUSY:
-   /*
-* EBUSY is ok: this just means that another thread
-* already did the job.
-*/
-   return VM_FAULT_NOPAGE;
-   }
+   return i915_error_to_vmf_fault(ret);
 }
 
 void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
@@ -660,6 +699,33 @@ static const struct vm_operations_struct 
i915_gem_gtt_vm_ops = {
.close = i915_gem_vm_close,
 };
 
+static const struct vm_operations_struct i915_gem_cpu_vm_ops = {
+   .fault = i915_gem_fault_cpu,
+   .open = i915_gem_vm_open,
+   .close = i915_gem_vm_close,
+};
+
+static void set_vmdata_mmap_offset(struct i915_mmap_offset *mmo, struct 
vm_area_struct *vma)
+{
+   switch (mmo->mmap_type) {
+   case I915_MMAP_TYPE_OFFSET_WC:
+   vma->vm_page_prot =
+   pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+   break;
+   case I915_MMAP_TYPE_OFFSET_WB:
+   vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+   break;
+   case I915_MMAP_TYPE_OFFSET_UC:
+   vma->vm_page_prot =
+   pgprot_noncached(vm_get_page_prot(vma->vm_flags));
+   break;
+   default:
+   break;
+   }
+
+   vma->vm_ops = _gem_cpu_vm_ops;
+}

[Intel-gfx] [PATCH v2 4/5] drm/i915: cpu-map based dumb buffers

2019-10-07 Thread Abdiel Janulgue
If there is no aperture we can't use map_gtt to map dumb buffers, so we
need a cpu-map based path to do it. We prefer map_gtt on platforms that
do have aperture.

Signed-off-by: Abdiel Janulgue 
Cc: Daniele Ceraolo Spurio 
Cc: Tvrtko Ursulin 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 13 +
 drivers/gpu/drm/i915/i915_drv.c  |  1 +
 drivers/gpu/drm/i915/i915_drv.h  |  2 ++
 3 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index ae1e687408da..a9604d0db606 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -569,6 +569,19 @@ static int gem_mmap_offset(struct drm_device *dev, void 
*data,
 >offset);
 }
 
+int
+i915_gem_mmap_dumb(struct drm_file *file,
+ struct drm_device *dev,
+ u32 handle,
+ u64 *offset)
+{
+   struct drm_i915_private *i915 = dev->dev_private;
+   enum i915_mmap_type mmap_type = HAS_MAPPABLE_APERTURE(i915) ?
+   I915_MMAP_TYPE_GTT : I915_MMAP_TYPE_OFFSET_WC;
+
+   return __assign_gem_object_mmap_data(file, handle, mmap_type, offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 9182da57182b..0fbbe03befb0 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2748,6 +2748,7 @@ static struct drm_driver driver = {
.get_scanout_position = i915_get_crtc_scanoutpos,
 
.dumb_create = i915_gem_dumb_create,
+   .dumb_map_offset = i915_gem_mmap_dumb,
.ioctls = i915_ioctls,
.num_ioctls = ARRAY_SIZE(i915_ioctls),
.fops = _driver_fops,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 659319f03f18..47487beaf0e3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2278,6 +2278,8 @@ i915_mutex_lock_interruptible(struct drm_device *dev)
 int i915_gem_dumb_create(struct drm_file *file_priv,
 struct drm_device *dev,
 struct drm_mode_create_dumb *args);
+int i915_gem_mmap_dumb(struct drm_file *file_priv, struct drm_device *dev,
+ u32 handle, u64 *offset);
 int i915_gem_mmap_gtt_version(void);
 
 int __must_check i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno);
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH v2 2/5] drm/i915: define HAS_MAPPABLE_APERTURE

2019-10-07 Thread Abdiel Janulgue
From: Daniele Ceraolo Spurio 

The following patches in the series will use it to avoid certain
operations when aperture is not available in HW.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_drv.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index fa6dd301a738..659319f03f18 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2080,6 +2080,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define OVERLAY_NEEDS_PHYSICAL(dev_priv) \
(INTEL_INFO(dev_priv)->display.overlay_needs_physical)
 
+#define HAS_MAPPABLE_APERTURE(dev_priv) (dev_priv->ggtt.mappable_end > 0)
+
 /* Early gen2 have a totally busted CS tlb and require pinned batches. */
 #define HAS_BROKEN_CS_TLB(dev_priv)(IS_I830(dev_priv) || 
IS_I845G(dev_priv))
 
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH v2 1/5] drm/i915: Allow i915 to manage the vma offset nodes instead of drm core

2019-10-07 Thread Abdiel Janulgue
Have i915 replace the core drm_gem_mmap implementation to overcome its
limitation in having only a single mmap offset node per gem object.
This change allows us to have multiple mmap offsets per object and
enables a mmapping instance to use unique fault-handlers per user vma.

This allows i915 to store extra data within vma->vm_private_data and
assign the pagefault ops for each mmap instance allowing objects to use
multiple fault handlers depending on its backing storage.

v2:
 - Fix race condition exposed by gem_mmap_gtt@close-race. Simplify
   lifetime management of the mmap offset objects be ensuring it is
   owned by the parent gem object instead of refcounting.
 - Track mmo used by fencing to Avoid locking when revoking mmaps
   during GPU reset.
 - Rebase

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/gem/i915_gem_domain.c|   2 +-
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 245 --
 drivers/gpu/drm/i915/gem/i915_gem_object.c|  13 +
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   9 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  23 ++
 .../drm/i915/gem/selftests/i915_gem_mman.c|  12 +-
 drivers/gpu/drm/i915/gt/intel_reset.c |   7 +-
 drivers/gpu/drm/i915/i915_drv.c   |  10 +-
 drivers/gpu/drm/i915/i915_drv.h   |   3 +-
 drivers/gpu/drm/i915/i915_gem.c   |   2 +-
 drivers/gpu/drm/i915/i915_vma.c   |  24 +-
 drivers/gpu/drm/i915/i915_vma.h   |   4 +
 12 files changed, 305 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c 
b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
index 9937b4c341f1..40792d2017a7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
@@ -254,7 +254,7 @@ int i915_gem_object_set_cache_level(struct 
drm_i915_gem_object *obj,
}
 
if (obj->userfault_count)
-   __i915_gem_object_release_mmap(obj);
+   __i915_gem_object_release_mmap_gtt(obj);
 
/*
 * As we no longer need a fence for GTT access,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index fd4122d8c0a9..af4377a80502 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -219,7 +219,8 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 {
 #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
struct vm_area_struct *area = vmf->vma;
-   struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *i915 = to_i915(dev);
struct intel_runtime_pm *rpm = >runtime_pm;
@@ -312,6 +313,12 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
list_add(>userfault_link, >ggtt.userfault_list);
mutex_unlock(>ggtt.vm.mutex);
 
+   /* Track the mmo associated with the fenced vma */
+   mutex_lock(>vma_lock);
+   vma->mmo = priv;
+   list_move(>mmo_link, >vma_list);
+   mutex_unlock(>vma_lock);
+
if (CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)
intel_wakeref_auto(>ggtt.userfault_wakeref,
   
msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));
@@ -358,28 +365,29 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
}
 }
 
-void __i915_gem_object_release_mmap(struct drm_i915_gem_object *obj)
+void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
 {
struct i915_vma *vma;
+   struct i915_mmap_offset *mmo;
 
GEM_BUG_ON(!obj->userfault_count);
 
obj->userfault_count = 0;
list_del(>userfault_link);
-   drm_vma_node_unmap(>base.vma_node,
-  obj->base.dev->anon_inode->i_mapping);
+
+   mutex_lock(>mmo_lock);
+   list_for_each_entry(mmo, >mmap_offsets, offset) {
+   if (mmo->mmap_type == I915_MMAP_TYPE_GTT)
+   drm_vma_node_unmap(>vma_node,
+  
obj->base.dev->anon_inode->i_mapping);
+   }
+   mutex_unlock(>mmo_lock);
 
for_each_ggtt_vma(vma, obj)
i915_vma_unset_userfault(vma);
 }
 
 /**
- * i915_gem_object_release_mmap - remove physical page mappings
- * @obj: obj in question
- *
- * Preserve the reservation of the mmapping with the DRM core code, but
- * relinquish ownership of the pages back to the system.
- *
  * It is vital that we remove the page mapping if we have mapped a tiled
  * object through the GTT and then lose the fence reg

[Intel-gfx] [PATCH v2 5/5] drm/i915: Add cpu fault handler for mmap_offset

2019-10-07 Thread Abdiel Janulgue
Fault handler to handle missing pages for shmem-backed objects.

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 125 ++-
 1 file changed, 100 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index a9604d0db606..02afdae812ba 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include 
 
 #include "gt/intel_gt.h"
@@ -200,6 +201,67 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
return view;
 }
 
+static vm_fault_t i915_error_to_vmf_fault(int err)
+{
+   switch (err) {
+   default:
+   WARN_ONCE(err, "unhandled error in %s: %i\n", __func__, err);
+   /* fallthrough */
+   case -EIO: /* shmemfs failure from swap device */
+   case -EFAULT: /* purged object */
+   case -ENODEV: /* bad object, how did you get here! */
+   return VM_FAULT_SIGBUS;
+
+   case -ENOSPC: /* shmemfs allocation failure */
+   case -ENOMEM: /* our allocation failure */
+   return VM_FAULT_OOM;
+
+   case 0:
+   case -EAGAIN:
+   case -ERESTARTSYS:
+   case -EINTR:
+   case -EBUSY:
+   /*
+* EBUSY is ok: this just means that another thread
+* already did the job.
+*/
+   return VM_FAULT_NOPAGE;
+   }
+}
+
+static vm_fault_t i915_gem_fault_cpu(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   vm_fault_t vmf_ret;
+   unsigned long size = area->vm_end - area->vm_start;
+   bool write = area->vm_flags & VM_WRITE;
+   int i, ret;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write)
+   return VM_FAULT_SIGBUS;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return i915_error_to_vmf_fault(ret);
+
+   for (i = 0; i < size >> PAGE_SHIFT; i++) {
+   struct page *page = i915_gem_object_get_page(obj, i);
+
+   vmf_ret = vmf_insert_pfn(area,
+(unsigned long)area->vm_start + i * 
PAGE_SIZE,
+page_to_pfn(page));
+   if (vmf_ret & VM_FAULT_ERROR)
+   break;
+   }
+
+   i915_gem_object_unpin_pages(obj);
+
+   return vmf_ret;
+}
+
 /**
  * i915_gem_fault - fault a page into the GTT
  * @vmf: fault info
@@ -342,30 +404,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
intel_runtime_pm_put(rpm, wakeref);
i915_gem_object_unpin_pages(obj);
 err:
-   switch (ret) {
-   default:
-   WARN_ONCE(ret, "unhandled error in %s: %i\n", __func__, ret);
-   /* fallthrough */
-   case -EIO: /* shmemfs failure from swap device */
-   case -EFAULT: /* purged object */
-   case -ENODEV: /* bad object, how did you get here! */
-   return VM_FAULT_SIGBUS;
-
-   case -ENOSPC: /* shmemfs allocation failure */
-   case -ENOMEM: /* our allocation failure */
-   return VM_FAULT_OOM;
-
-   case 0:
-   case -EAGAIN:
-   case -ERESTARTSYS:
-   case -EINTR:
-   case -EBUSY:
-   /*
-* EBUSY is ok: this just means that another thread
-* already did the job.
-*/
-   return VM_FAULT_NOPAGE;
-   }
+   return i915_error_to_vmf_fault(ret);
 }
 
 void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
@@ -660,6 +699,33 @@ static const struct vm_operations_struct 
i915_gem_gtt_vm_ops = {
.close = i915_gem_vm_close,
 };
 
+static const struct vm_operations_struct i915_gem_cpu_vm_ops = {
+   .fault = i915_gem_fault_cpu,
+   .open = i915_gem_vm_open,
+   .close = i915_gem_vm_close,
+};
+
+static void set_vmdata_mmap_offset(struct i915_mmap_offset *mmo, struct 
vm_area_struct *vma)
+{
+   switch (mmo->mmap_type) {
+   case I915_MMAP_TYPE_OFFSET_WC:
+   vma->vm_page_prot =
+   pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+   break;
+   case I915_MMAP_TYPE_OFFSET_WB:
+   vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+   break;
+   case I915_MMAP_TYPE_OFFSET_UC:
+   vma->vm_page_prot =
+   pgprot_noncached(vm_get_page_prot(vma->vm_flags));
+   break;
+   default:
+   break;
+   }
+
+   vma->vm_ops = _gem_cpu_vm_ops;
+}

[Intel-gfx] [PATCH v2 3/5] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET

2019-10-07 Thread Abdiel Janulgue
This is really just an alias of mmap_gtt. Add a new CPU mmap
implementation that allows multiple fault handlers that depends on
the object's backing pages.

Note that we multiplex mmap_gtt and mmap_offset through the same ioctl,
and use the zero extending behaviour of drm to differentiate between
them, when we inspect the flags.

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 36 +--
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 ++
 drivers/gpu/drm/i915/i915_drv.c   |  2 +-
 include/uapi/drm/i915_drm.h   | 28 +++
 4 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index af4377a80502..ae1e687408da 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -144,6 +144,9 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  * 3 - Remove implicit set-domain(GTT) and synchronisation on initial
  * pagefault; swapin remains transparent.
  *
+ * 4 - Support multiple fault handlers per object depending on object's
+ * backing storage (a.k.a. MMAP_OFFSET).
+ *
  * Restrictions:
  *
  *  * snoopable objects cannot be accessed via the GTT. It can cause machine
@@ -171,7 +174,7 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  */
 int i915_gem_mmap_gtt_version(void)
 {
-   return 3;
+   return 4;
 }
 
 static inline struct i915_ggtt_view
@@ -545,6 +548,27 @@ __assign_gem_object_mmap_data(struct drm_file *file,
return ret;
 }
 
+static int gem_mmap_offset(struct drm_device *dev, void *data,
+  struct drm_file *file)
+{
+   struct drm_i915_gem_mmap_offset *args = data;
+   enum i915_mmap_type type;
+
+   if ((args->flags & (I915_MMAP_OFFSET_WC | I915_MMAP_OFFSET_WB)) &&
+   !boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+
+   if (args->flags & I915_MMAP_OFFSET_WC)
+   type = I915_MMAP_TYPE_OFFSET_WC;
+   else if (args->flags & I915_MMAP_OFFSET_WB)
+   type = I915_MMAP_TYPE_OFFSET_WB;
+   else if (args->flags & I915_MMAP_OFFSET_UC)
+   type = I915_MMAP_TYPE_OFFSET_UC;
+
+   return __assign_gem_object_mmap_data(file, args->handle, type,
+>offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
@@ -564,7 +588,15 @@ int
 i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
 {
-   struct drm_i915_gem_mmap_gtt *args = data;
+   struct drm_i915_gem_mmap_offset *args = data;
+   struct drm_i915_private *i915 = to_i915(dev);
+
+   if (args->flags & I915_MMAP_OFFSET_FLAGS)
+   return gem_mmap_offset(dev, data, file);
+
+   if (!HAS_MAPPABLE_APERTURE(i915))
+   /* No aperture, cannot mmap via legacy GTT */
+   return -ENODEV;
 
return __assign_gem_object_mmap_data(file, args->handle,
 I915_MMAP_TYPE_GTT,
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 74544eca5e2c..18e891f4e9d3 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -64,6 +64,9 @@ struct drm_i915_gem_object_ops {
 
 enum i915_mmap_type {
I915_MMAP_TYPE_GTT = 0,
+   I915_MMAP_TYPE_OFFSET_WC,
+   I915_MMAP_TYPE_OFFSET_WB,
+   I915_MMAP_TYPE_OFFSET_UC,
 };
 
 struct i915_mmap_offset {
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index cc70aba6ac26..9182da57182b 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2696,7 +2696,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW),
-   DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, 
DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_OFFSET, i915_gem_mmap_gtt_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling_ioctl, 
DRM_RENDER_ALLOW),
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 30c542144016..bc85656ab7fd 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -359,6

Re: [Intel-gfx] [PATCH 04/21] drm/i915: Refresh the errno to vmf_fault translations

2019-09-03 Thread Abdiel Janulgue

On 02/09/2019 7.02, Chris Wilson wrote:
> It's been a long time since we accidentally reported -EIO upon wedging,
> it can now only be generated by failure to swap in a page.
> 

Reviewed-by: Abdiel Janulgue 

> Signed-off-by: Chris Wilson 
> Cc: Abdiel Janulgue 
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_mman.c | 39 +---
>  1 file changed, 15 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> index 261c9bd83f51..82db2b783123 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> @@ -287,6 +287,9 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
>   view.type = I915_GGTT_VIEW_PARTIAL;
>   vma = i915_gem_object_ggtt_pin(obj, , 0, 0, flags);
>   }
> +
> + /* The entire mappable GGTT is pinned? Unexpected! */
> + GEM_BUG_ON(vma == ERR_PTR(-ENOSPC));
>   }
>   if (IS_ERR(vma)) {
>   ret = PTR_ERR(vma);
> @@ -333,23 +336,19 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
>   i915_gem_object_unpin_pages(obj);
>  err:
>   switch (ret) {
> - case -EIO:
> - /*
> -  * We eat errors when the gpu is terminally wedged to avoid
> -  * userspace unduly crashing (gl has no provisions for mmaps to
> -  * fail). But any other -EIO isn't ours (e.g. swap in failure)
> -  * and so needs to be reported.
> -  */
> - if (!intel_gt_is_wedged(ggtt->vm.gt))
> - return VM_FAULT_SIGBUS;
> - /* else, fall through */
> - case -EAGAIN:
> - /*
> -  * EAGAIN means the gpu is hung and we'll wait for the error
> -  * handler to reset everything when re-faulting in
> -  * i915_mutex_lock_interruptible.
> -  */
> + default:
> + WARN_ONCE(ret, "unhandled error in %s: %i\n", __func__, ret);
> + /* fallthrough */
> + case -EIO: /* shmemfs failure from swap device */
> + case -EFAULT: /* purged object */
> + return VM_FAULT_SIGBUS;
> +
> + case -ENOSPC: /* shmemfs allocation failure */
> + case -ENOMEM: /* our allocation failure */
> + return VM_FAULT_OOM;
> +
>   case 0:
> + case -EAGAIN:
>   case -ERESTARTSYS:
>   case -EINTR:
>   case -EBUSY:
> @@ -358,14 +357,6 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
>* already did the job.
>*/
>   return VM_FAULT_NOPAGE;
> - case -ENOMEM:
> - return VM_FAULT_OOM;
> - case -ENOSPC:
> - case -EFAULT:
> - return VM_FAULT_SIGBUS;
> - default:
> - WARN_ONCE(ret, "unhandled error in %s: %i\n", __func__, ret);
> - return VM_FAULT_SIGBUS;
>   }
>  }
>  
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH i-g-t] i915/gem_mmap_gtt: Race mmap offset generation against closure

2019-08-29 Thread Abdiel Janulgue
Yup, this is a valid issue.

Reviewed-by: Abdiel Janulgue 

On 26/08/2019 18.20, Chris Wilson wrote:
> Signed-off-by: Chris Wilson 
> Cc: Abdiel Janulgue 
> ---
>  tests/i915/gem_mmap_gtt.c | 98 +++
>  1 file changed, 98 insertions(+)
> 
> diff --git a/tests/i915/gem_mmap_gtt.c b/tests/i915/gem_mmap_gtt.c
> index 8eff91850..81068f7d1 100644
> --- a/tests/i915/gem_mmap_gtt.c
> +++ b/tests/i915/gem_mmap_gtt.c
> @@ -26,6 +26,7 @@
>   */
>  
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -360,6 +361,99 @@ test_isolation(int i915)
>   igt_assert(ptr == MAP_FAILED);
>  }
>  
> +static void
> +test_close_race(int i915)
> +{
> + const int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
> + uint32_t *handles;
> +
> + handles = mmap64(0, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
> + igt_assert(handles != MAP_FAILED);
> +
> + igt_fork(child, ncpus) {
> + do {
> + struct drm_i915_gem_mmap_gtt mmap_arg = {};
> + int i = 1 + random() % ncpus;
> + uint32_t old;
> +
> + mmap_arg.handle = gem_create(i915, 4096);
> + old = atomic_exchange([i], mmap_arg.handle);
> + ioctl(i915, DRM_IOCTL_GEM_CLOSE, );
> +
> + if (ioctl(i915,
> +   DRM_IOCTL_I915_GEM_MMAP_GTT,
> +   _arg) != -1) {
> + void *ptr;
> +
> + ptr = mmap64(0, 4096,
> +  PROT_READ, MAP_SHARED, i915,
> +  mmap_arg.offset);
> + if (ptr != MAP_FAILED)
> + munmap(ptr, 4096);
> + }
> + } while (!READ_ONCE(handles[0]));
> + }
> +
> + sleep(20);
> + handles[0] = 1;
> + igt_waitchildren();
> +
> + for (int i = 1; i <= ncpus; i++)
> + ioctl(i915, DRM_IOCTL_GEM_CLOSE, handles[i]);
> + munmap(handles, 4096);
> +}
> +
> +static void
> +test_flink_race(int i915)
> +{
> + const int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
> + uint32_t *handles;
> +
> + handles = mmap64(0, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
> + igt_assert(handles != MAP_FAILED);
> +
> + igt_fork(child, ncpus) {
> + int fd = gem_reopen_driver(i915);
> +
> + do {
> + struct drm_i915_gem_mmap_gtt mmap_arg = {};
> + uint32_t old;
> + int i = 1 + random() % ncpus;
> +
> + old = atomic_exchange([i],
> +   gem_create(i915, 4096));
> + if (!old)
> + continue;
> +
> + mmap_arg.handle =
> + gem_open(fd, gem_flink(i915, old));
> + ioctl(i915, DRM_IOCTL_GEM_CLOSE, );
> +
> + if (ioctl(fd,
> +   DRM_IOCTL_I915_GEM_MMAP_GTT,
> +   _arg) != -1) {
> + void *ptr;
> +
> + ptr = mmap64(0, 4096,
> +  PROT_READ, MAP_SHARED, fd,
> +  mmap_arg.offset);
> + if (ptr != MAP_FAILED)
> + munmap(ptr, 4096);
> + }
> +
> + ioctl(fd, DRM_IOCTL_GEM_CLOSE, _arg.handle);
> + } while (!READ_ONCE(handles[0]));
> + }
> +
> + sleep(20);
> + handles[0] = 1;
> + igt_waitchildren();
> +
> + for (int i = 1; i <= ncpus; i++)
> + ioctl(i915, DRM_IOCTL_GEM_CLOSE, handles[i]);
> + munmap(handles, 4096);
> +}
> +
>  static void
>  test_write_gtt(int fd)
>  {
> @@ -985,6 +1079,10 @@ igt_main
>   test_wc(fd);
>   igt_subtest("isolation")
>   test_isolation(fd);
> + igt_subtest("close-race")
> + test_close_race(fd);
> + igt_subtest("flink-race")
> + test_flink_race(fd);
>   igt_subtest("pf-nonblock")
>   test_pf_nonblock(fd);
>  
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH 5/5] drm/i915: cpu-map based dumb buffers

2019-08-27 Thread Abdiel Janulgue


On 26/08/2019 15.48, Chris Wilson wrote:
> Quoting Abdiel Janulgue (2019-08-26 13:21:02)
>> +int
>> +i915_gem_mmap_dumb(struct drm_file *file,
>> + struct drm_device *dev,
>> + u32 handle,
>> + u64 *offset)
>> +{
>> +   struct drm_i915_private *i915 = dev->dev_private;
>> +   enum i915_mmap_type mmap_type = HAS_MAPPABLE_APERTURE(i915) ?
>> +   I915_MMAP_TYPE_GTT : I915_MMAP_TYPE_OFFSET_WC;
> 
> Is there any reason for using GTT if we support WC? The buffer is meant
> to be linear.
> -Chris
>

Actually there seems no reason at all. Yeah dumb BO mmaps should
probably be done via mmap_offset CPU WC mmaps.

-Abdiel
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 5/5] drm/i915: cpu-map based dumb buffers

2019-08-26 Thread Abdiel Janulgue
If there is no aperture we can't use map_gtt to map dumb buffers, so we
need a cpu-map based path to do it. We prefer map_gtt on platforms that
do have aperture.

Signed-off-by: Abdiel Janulgue 
Cc: Daniele Ceraolo Spurio 
Cc: Tvrtko Ursulin 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 13 +
 drivers/gpu/drm/i915/i915_drv.c  |  2 +-
 drivers/gpu/drm/i915/i915_drv.h  |  2 +-
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index d0a653a9a4cc..ff35b0517e59 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -615,6 +615,19 @@ static int gem_mmap_offset(struct drm_device *dev, void 
*data,
 >offset);
 }
 
+int
+i915_gem_mmap_dumb(struct drm_file *file,
+ struct drm_device *dev,
+ u32 handle,
+ u64 *offset)
+{
+   struct drm_i915_private *i915 = dev->dev_private;
+   enum i915_mmap_type mmap_type = HAS_MAPPABLE_APERTURE(i915) ?
+   I915_MMAP_TYPE_GTT : I915_MMAP_TYPE_OFFSET_WC;
+
+   return __assign_gem_object_mmap_data(file, handle, mmap_type, offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 68ed4499fa52..40ccadc9ef29 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2826,7 +2826,7 @@ static struct drm_driver driver = {
.get_scanout_position = i915_get_crtc_scanoutpos,
 
.dumb_create = i915_gem_dumb_create,
-   .dumb_map_offset = i915_gem_mmap_gtt,
+   .dumb_map_offset = i915_gem_mmap_dumb,
.ioctls = i915_ioctls,
.num_ioctls = ARRAY_SIZE(i915_ioctls),
.fops = _driver_fops,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4e1d2e0fcc86..d3514184efef 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2300,7 +2300,7 @@ i915_mutex_lock_interruptible(struct drm_device *dev)
 int i915_gem_dumb_create(struct drm_file *file_priv,
 struct drm_device *dev,
 struct drm_mode_create_dumb *args);
-int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev,
+int i915_gem_mmap_dumb(struct drm_file *file_priv, struct drm_device *dev,
  u32 handle, u64 *offset);
 int i915_gem_mmap_gtt_version(void);
 
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 2/5] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET

2019-08-26 Thread Abdiel Janulgue
This is really just an alias of mmap_gtt. Add a new CPU mmap
implementation that allows multiple fault handlers that depends on
the object's backing pages.

Note that we multiplex mmap_gtt and mmap_offset through the same ioctl,
and use the zero extending behaviour of drm to differentiate between
them, when we inspect the flags.

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 34 ++-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 ++
 drivers/gpu/drm/i915/i915_drv.c   |  2 +-
 include/uapi/drm/i915_drm.h   | 28 +++
 4 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index fb7e39f115d7..87690aa64814 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -143,6 +143,9 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  * 3 - Remove implicit set-domain(GTT) and synchronisation on initial
  * pagefault; swapin remains transparent.
  *
+ * 4 - Support multiple fault handlers per object depending on object's
+ * backing storage (a.k.a. MMAP_OFFSET).
+ *
  * Restrictions:
  *
  *  * snoopable objects cannot be accessed via the GTT. It can cause machine
@@ -170,7 +173,7 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
  */
 int i915_gem_mmap_gtt_version(void)
 {
-   return 3;
+   return 4;
 }
 
 static inline struct i915_ggtt_view
@@ -524,6 +527,27 @@ __assign_gem_object_mmap_data(struct drm_file *file,
return ret;
 }
 
+static int gem_mmap_offset(struct drm_device *dev, void *data,
+  struct drm_file *file)
+{
+   struct drm_i915_gem_mmap_offset *args = data;
+   enum i915_mmap_type type;
+
+   if ((args->flags & (I915_MMAP_OFFSET_WC | I915_MMAP_OFFSET_WB)) &&
+   !boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+
+   if (args->flags & I915_MMAP_OFFSET_WC)
+   type = I915_MMAP_TYPE_OFFSET_WC;
+   else if (args->flags & I915_MMAP_OFFSET_WB)
+   type = I915_MMAP_TYPE_OFFSET_WB;
+   else if (args->flags & I915_MMAP_OFFSET_UC)
+   type = I915_MMAP_TYPE_OFFSET_UC;
+
+   return __assign_gem_object_mmap_data(file, args->handle, type,
+>offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
@@ -544,6 +568,14 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
 {
struct drm_i915_gem_mmap_offset *args = data;
+   struct drm_i915_private *i915 = to_i915(dev);
+
+   if (args->flags & I915_MMAP_OFFSET_FLAGS)
+   return gem_mmap_offset(dev, data, file);
+
+   if (!HAS_MAPPABLE_APERTURE(i915))
+   /* No aperture, cannot mmap via legacy GTT */
+   return -ENODEV;
 
return __assign_gem_object_mmap_data(file, args->handle,
 I915_MMAP_TYPE_GTT,
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 d74ddb479318..cf7712aea2d9 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -62,6 +62,9 @@ struct drm_i915_gem_object_ops {
 
 enum i915_mmap_type {
I915_MMAP_TYPE_GTT = 0,
+   I915_MMAP_TYPE_OFFSET_WC,
+   I915_MMAP_TYPE_OFFSET_WB,
+   I915_MMAP_TYPE_OFFSET_UC,
 };
 
 struct i915_mmap_offset {
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index bdd597200984..68ed4499fa52 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2774,7 +2774,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW),
-   DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, 
DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_OFFSET, i915_gem_mmap_gtt_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling_ioctl, 
DRM_RENDER_ALLOW),
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 469dc512cca3..75fc9277e9ab 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -359,6 +359,7 @@ typedef struct _drm_i915_sarea {
 

[Intel-gfx] [PATCH 3/5] drm/i915: Add cpu fault handler for mmap_offset

2019-08-26 Thread Abdiel Janulgue
Fault handler to handle missing pages for shmem-backed objects. Handle also
logic needed to refault pages depending on fault handler usage.

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_domain.c |   2 +-
 drivers/gpu/drm/i915/gem/i915_gem_mman.c   | 189 -
 drivers/gpu/drm/i915/gem/i915_gem_object.h |   2 +-
 drivers/gpu/drm/i915/i915_gem.c|   2 +-
 4 files changed, 149 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c 
b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
index 9c58e8fac1d9..517e73c3aa31 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
@@ -254,7 +254,7 @@ int i915_gem_object_set_cache_level(struct 
drm_i915_gem_object *obj,
}
 
if (obj->userfault_count)
-   __i915_gem_object_release_mmap(obj);
+   __i915_gem_object_release_mmap_gtt(obj);
 
/*
 * As we no longer need a fence for GTT access,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 87690aa64814..d0a653a9a4cc 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include 
 
 #include "gt/intel_gt.h"
@@ -199,6 +200,45 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
return view;
 }
 
+static vm_fault_t i915_error_to_vmf_fault(int err, struct intel_gt *gt)
+{
+   switch (err) {
+   case -EIO:
+   /*
+* We eat errors when the gpu is terminally wedged to avoid
+* userspace unduly crashing (gl has no provisions for mmaps to
+* fail). But any other -EIO isn't ours (e.g. swap in failure)
+* and so needs to be reported.
+*/
+   if (!intel_gt_is_wedged(gt))
+   return VM_FAULT_SIGBUS;
+   /* else, fall through */
+   case -EAGAIN:
+   /*
+* EAGAIN means the gpu is hung and we'll wait for the error
+* handler to reset everything when re-faulting in
+* i915_mutex_lock_interruptible.
+*/
+   case 0:
+   case -ERESTARTSYS:
+   case -EINTR:
+   case -EBUSY:
+   /*
+* EBUSY is ok: this just means that another thread
+* already did the job.
+*/
+   return VM_FAULT_NOPAGE;
+   case -ENOMEM:
+   return VM_FAULT_OOM;
+   case -ENOSPC:
+   case -EFAULT:
+   return VM_FAULT_SIGBUS;
+   default:
+   WARN_ONCE(err, "unhandled error in %s: %i\n", __func__, err);
+   return VM_FAULT_SIGBUS;
+   }
+}
+
 /**
  * i915_gem_fault - fault a page into the GTT
  * @vmf: fault info
@@ -336,44 +376,48 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
intel_runtime_pm_put(rpm, wakeref);
i915_gem_object_unpin_pages(obj);
 err:
-   switch (ret) {
-   case -EIO:
-   /*
-* We eat errors when the gpu is terminally wedged to avoid
-* userspace unduly crashing (gl has no provisions for mmaps to
-* fail). But any other -EIO isn't ours (e.g. swap in failure)
-* and so needs to be reported.
-*/
-   if (!intel_gt_is_wedged(ggtt->vm.gt))
-   return VM_FAULT_SIGBUS;
-   /* else, fall through */
-   case -EAGAIN:
-   /*
-* EAGAIN means the gpu is hung and we'll wait for the error
-* handler to reset everything when re-faulting in
-* i915_mutex_lock_interruptible.
-*/
-   case 0:
-   case -ERESTARTSYS:
-   case -EINTR:
-   case -EBUSY:
-   /*
-* EBUSY is ok: this just means that another thread
-* already did the job.
-*/
-   return VM_FAULT_NOPAGE;
-   case -ENOMEM:
-   return VM_FAULT_OOM;
-   case -ENOSPC:
-   case -EFAULT:
-   return VM_FAULT_SIGBUS;
-   default:
-   WARN_ONCE(ret, "unhandled error in %s: %i\n", __func__, ret);
+   return i915_error_to_vmf_fault(ret, ggtt->vm.gt);
+}
+
+static vm_fault_t i915_gem_fault_cpu(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   struct drm_device *dev = obj->base.dev;
+   struct drm_i915_private *dev_priv = to_i915(dev);
+   vm_fault_t vmf_ret;
+   unsigned long size = area-

[Intel-gfx] [PATCH 4/5] drm/i915: define HAS_MAPPABLE_APERTURE

2019-08-26 Thread Abdiel Janulgue
From: Daniele Ceraolo Spurio 

The following patches in the series will use it to avoid certain
operations when aperture is not available in HW.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_drv.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index bf2927e88e14..4e1d2e0fcc86 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2110,6 +2110,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define OVERLAY_NEEDS_PHYSICAL(dev_priv) \
(INTEL_INFO(dev_priv)->display.overlay_needs_physical)
 
+#define HAS_MAPPABLE_APERTURE(dev_priv) (dev_priv->ggtt.mappable_end > 0)
+
 /* Early gen2 have a totally busted CS tlb and require pinned batches. */
 #define HAS_BROKEN_CS_TLB(dev_priv)(IS_I830(dev_priv) || 
IS_I845G(dev_priv))
 
-- 
2.23.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 1/5] drm/i915: Allow i915 to manage the vma offset nodes instead of drm core

2019-08-26 Thread Abdiel Janulgue
Have i915 replace the core drm_gem_mmap implementation to overcome its
limitation in having only a single mmap offset node per gem object.
The change allows us to have multiple mmap offsets per object. This
enables a mmapping instance to use unique fault-handlers per user vma.

This enables us to store extra data within vma->vm_private_data and assign
the pagefault ops for each mmap instance allowing objects to use multiple
fault handlers depending on its backing storage.

Signed-off-by: Abdiel Janulgue 
Cc: Joonas Lahtinen 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 193 --
 drivers/gpu/drm/i915/gem/i915_gem_object.c|  19 ++
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   7 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  18 ++
 .../drm/i915/gem/selftests/i915_gem_mman.c|  12 +-
 drivers/gpu/drm/i915/gt/intel_reset.c |  11 +-
 drivers/gpu/drm/i915/i915_drv.c   |   9 +-
 drivers/gpu/drm/i915/i915_drv.h   |   1 +
 drivers/gpu/drm/i915/i915_vma.c   |  20 +-
 9 files changed, 254 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 595539a09e38..fb7e39f115d7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -218,7 +218,8 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 {
 #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
struct vm_area_struct *area = vmf->vma;
-   struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *i915 = to_i915(dev);
struct intel_runtime_pm *rpm = >runtime_pm;
@@ -372,13 +373,20 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 void __i915_gem_object_release_mmap(struct drm_i915_gem_object *obj)
 {
struct i915_vma *vma;
+   struct i915_mmap_offset *mmo;
 
GEM_BUG_ON(!obj->userfault_count);
 
obj->userfault_count = 0;
list_del(>userfault_link);
-   drm_vma_node_unmap(>base.vma_node,
-  obj->base.dev->anon_inode->i_mapping);
+
+   mutex_lock(>mmo_lock);
+   list_for_each_entry(mmo, >mmap_offsets, offset) {
+   if (mmo->mmap_type == I915_MMAP_TYPE_GTT)
+   drm_vma_node_unmap(>vma_node,
+  
obj->base.dev->anon_inode->i_mapping);
+   }
+   mutex_unlock(>mmo_lock);
 
for_each_ggtt_vma(vma, obj)
i915_vma_unset_userfault(vma);
@@ -433,14 +441,33 @@ void i915_gem_object_release_mmap(struct 
drm_i915_gem_object *obj)
intel_runtime_pm_put(>runtime_pm, wakeref);
 }
 
-static int create_mmap_offset(struct drm_i915_gem_object *obj)
+static void init_mmap_offset(struct drm_i915_gem_object *obj,
+struct i915_mmap_offset *mmo)
+{
+   mutex_lock(>mmo_lock);
+   kref_init(>ref);
+   list_add(>offset, >mmap_offsets);
+   mutex_unlock(>mmo_lock);
+
+   mmo->obj = obj;
+}
+
+static int create_mmap_offset(struct drm_i915_gem_object *obj,
+ struct i915_mmap_offset *mmo)
 {
struct drm_i915_private *i915 = to_i915(obj->base.dev);
+   struct drm_device *dev = obj->base.dev;
int err;
 
-   err = drm_gem_create_mmap_offset(>base);
-   if (likely(!err))
+   drm_vma_node_reset(>vma_node);
+   if (mmo->file)
+   drm_vma_node_allow(>vma_node, mmo->file);
+   err = drm_vma_offset_add(dev->vma_offset_manager, >vma_node,
+obj->base.size / PAGE_SIZE);
+   if (likely(!err)) {
+   init_mmap_offset(obj, mmo);
return 0;
+   }
 
/* Attempt to reap some mmap space from dead objects */
do {
@@ -451,32 +478,48 @@ static int create_mmap_offset(struct drm_i915_gem_object 
*obj)
break;
 
i915_gem_drain_freed_objects(i915);
-   err = drm_gem_create_mmap_offset(>base);
-   if (!err)
+   err = drm_vma_offset_add(dev->vma_offset_manager, 
>vma_node,
+obj->base.size / PAGE_SIZE);
+   if (!err) {
+   init_mmap_offset(obj, mmo);
break;
+   }
 
} while (flush_delayed_work(>gem.retire_work));
 
return err;
 }
 
-int
-i915_gem_mmap_gtt(struct drm_file *file,
- struct drm_device *dev,
- u32 handle,
- u64 *offset)
+static int
+__assign_gem_object_mmap_data(struct drm_file *file,
+

Re: [Intel-gfx] [PATCH i-g-t] i915/gem_mmap_gtt: Test mmap_offset lifetime

2019-08-13 Thread Abdiel Janulgue


On 10/08/2019 15.38, Chris Wilson wrote:
> Closing the object on another file should not affect the local
> mmap_offset.
> 

Thanks for this! It helped squeezed the bug out of mmap_offset.

Reviewed-by: Abdiel Janulgue 


> Signed-off-by: Chris Wilson 
> Cc: Abdiel Janulgue 
> ---
>  tests/i915/gem_mmap_gtt.c | 40 +++
>  1 file changed, 40 insertions(+)
> 
> diff --git a/tests/i915/gem_mmap_gtt.c b/tests/i915/gem_mmap_gtt.c
> index 6f3a9c36e..8eff91850 100644
> --- a/tests/i915/gem_mmap_gtt.c
> +++ b/tests/i915/gem_mmap_gtt.c
> @@ -322,6 +322,44 @@ test_pf_nonblock(int i915)
>   igt_spin_free(i915, spin);
>  }
>  
> +static void
> +test_isolation(int i915)
> +{
> + struct drm_i915_gem_mmap_gtt mmap_arg;
> + int A = gem_reopen_driver(i915);
> + int B = gem_reopen_driver(i915);
> + uint64_t offset_a, offset_b;
> + uint32_t a, b;
> + void *ptr;
> +
> + a = gem_create(A, 4096);
> + b = gem_open(B, gem_flink(A, a));
> +
> + mmap_arg.handle = a;
> + do_ioctl(A, DRM_IOCTL_I915_GEM_MMAP_GTT, _arg);
> + offset_a = mmap_arg.offset;
> +
> + mmap_arg.handle = b;
> + do_ioctl(B, DRM_IOCTL_I915_GEM_MMAP_GTT, _arg);
> + offset_b = mmap_arg.offset;
> +
> + igt_info("A: {fd:%d, handle:%d, offset:%"PRIx64"}\n",
> +  A, a, offset_a);
> + igt_info("B: {fd:%d, handle:%d, offset:%"PRIx64"}\n",
> +  B, b, offset_b);
> +
> + close(B);
> +
> + ptr = mmap64(0, 4096, PROT_READ, MAP_SHARED, A, offset_a);
> + igt_assert(ptr != MAP_FAILED);
> + munmap(ptr, 4096);
> +
> + close(A);
> +
> + ptr = mmap64(0, 4096, PROT_READ, MAP_SHARED, A, offset_a);
> + igt_assert(ptr == MAP_FAILED);
> +}
> +
>  static void
>  test_write_gtt(int fd)
>  {
> @@ -945,6 +983,8 @@ igt_main
>   test_write_cpu_read_gtt(fd);
>   igt_subtest("basic-wc")
>   test_wc(fd);
> + igt_subtest("isolation")
> + test_isolation(fd);
>   igt_subtest("pf-nonblock")
>   test_pf_nonblock(fd);
>  
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH] drm/i915: Drop expectations of VM_IO from our GGTT mmappings

2019-08-07 Thread Abdiel Janulgue

On 07/08/2019 12.41, Chris Wilson wrote:
> We don't really want to use VM_IO for our GGTT mmaps (it implies that
> the mmap contains memory mapped registers, which we do not expose) yet I
> overzealously added it to an assert just because that's how we always
> had setup the vma.

Reviewed-by: Abdiel Janulgue 

> 
> Signed-off-by: Chris Wilson 
> Cc: Joonas Lahtinen 
> Cc: Abdiel Janulgue 
> ---
>  drivers/gpu/drm/i915/i915_mm.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_mm.c b/drivers/gpu/drm/i915/i915_mm.c
> index c23bb29e6d3e..318562ce64c0 100644
> --- a/drivers/gpu/drm/i915/i915_mm.c
> +++ b/drivers/gpu/drm/i915/i915_mm.c
> @@ -63,9 +63,8 @@ int remap_io_mapping(struct vm_area_struct *vma,
>   struct remap_pfn r;
>   int err;
>  
> - GEM_BUG_ON((vma->vm_flags &
> - (VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP)) !=
> -(VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP));
> +#define EXPECTED_FLAGS (VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP)
> + GEM_BUG_ON((vma->vm_flags & EXPECTED_FLAGS) != EXPECTED_FLAGS);
>  
>   /* We rely on prevalidation of the io-mapping to skip track_pfn(). */
>   r.mm = vma->vm_mm;
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH] drm/i915/gtt: Fix rounding for 36b

2019-07-22 Thread Abdiel Janulgue


On 19/07/2019 16.07, Chris Wilson wrote:
> The top-level page directory for 36b is a single entry, not multiple
> like 32b. Fix up the rounding on the calculation of the size of the top
> level so that we populate the 4th level correctly for 36b.
> 

Reviewed-by: Abdiel Janulgue 

> Reported-by: Jose Souza 
> Signed-off-by: Chris Wilson 
> Fixes: 1eda701eace2 ("drm/i915/gtt: Recursive cleanup for gen8")
> Cc: Abdiel Janulgue 
> Cc: Jose Souza 
> ---
>  drivers/gpu/drm/i915/i915_gem_gtt.c | 17 ++---
>  1 file changed, 10 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
> b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 220aba5a94d2..7dd08ff6c0eb 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -905,6 +905,12 @@ static inline unsigned int gen8_pt_count(u64 start, u64 
> end)
>   return end - start;
>  }
>  
> +static inline unsigned int gen8_pd_top_count(const struct i915_address_space 
> *vm)
> +{
> + unsigned int shift = __gen8_pte_shift(vm->top);
> + return (vm->total + (1ull << shift) - 1) >> shift;
> +}
> +
>  static void __gen8_ppgtt_cleanup(struct i915_address_space *vm,
>struct i915_page_directory *pd,
>int count, int lvl)
> @@ -930,9 +936,7 @@ static void gen8_ppgtt_cleanup(struct i915_address_space 
> *vm)
>   if (intel_vgpu_active(vm->i915))
>   gen8_ppgtt_notify_vgt(ppgtt, false);
>  
> - __gen8_ppgtt_cleanup(vm, ppgtt->pd,
> -  vm->total >> __gen8_pte_shift(vm->top),
> -  vm->top);
> + __gen8_ppgtt_cleanup(vm, ppgtt->pd, gen8_pd_top_count(vm), vm->top);
>   free_scratch(vm);
>  }
>  
> @@ -1391,7 +1395,7 @@ static int gen8_preallocate_top_level_pdp(struct 
> i915_ppgtt *ppgtt)
>   unsigned int idx;
>  
>   GEM_BUG_ON(vm->top != 2);
> - GEM_BUG_ON((vm->total >> __gen8_pte_shift(2)) != GEN8_3LVL_PDPES);
> + GEM_BUG_ON(gen8_pd_top_count(vm) != GEN8_3LVL_PDPES);
>  
>   for (idx = 0; idx < GEN8_3LVL_PDPES; idx++) {
>   struct i915_page_directory *pde;
> @@ -1428,7 +1432,7 @@ static void ppgtt_init(struct i915_ppgtt *ppgtt, struct 
> intel_gt *gt)
>  static struct i915_page_directory *
>  gen8_alloc_top_pd(struct i915_address_space *vm)
>  {
> - const unsigned int count = vm->total >> __gen8_pte_shift(vm->top);
> + const unsigned int count = gen8_pd_top_count(vm);
>   struct i915_page_directory *pd;
>  
>   GEM_BUG_ON(count > ARRAY_SIZE(pd->entry));
> @@ -1514,8 +1518,7 @@ static struct i915_ppgtt *gen8_ppgtt_create(struct 
> drm_i915_private *i915)
>  
>  err_free_pd:
>   __gen8_ppgtt_cleanup(>vm, ppgtt->pd,
> -  ppgtt->vm.total >> __gen8_pte_shift(ppgtt->vm.top),
> -  ppgtt->vm.top);
> +  gen8_pd_top_count(>vm), ppgtt->vm.top);
>  err_free_scratch:
>   free_scratch(>vm);
>  err_free:
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH 4/4] drm/i915/gtt: Tidy up ppgtt insertion for gen8

2019-07-16 Thread Abdiel Janulgue


On 12/07/2019 14.27, Chris Wilson wrote:
> Apply the new radix shift helpers to extract the multi-level indices
> cleanly when inserting pte into the gtt tree.
> 
Reviewed-by: Abdiel Janulgue 

> Signed-off-by: Chris Wilson 
> ---
>  drivers/gpu/drm/i915/i915_gem_gtt.c | 115 +++-
>  drivers/gpu/drm/i915/i915_gem_gtt.h |  90 ++
>  2 files changed, 48 insertions(+), 157 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
> b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 72e0f9799a46..de78dc8c425c 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -1131,47 +1131,28 @@ static inline struct sgt_dma {
>   return (struct sgt_dma) { sg, addr, addr + sg->length };
>  }
>  
> -struct gen8_insert_pte {
> - u16 pml4e;
> - u16 pdpe;
> - u16 pde;
> - u16 pte;
> -};
> -
> -static __always_inline struct gen8_insert_pte gen8_insert_pte(u64 start)
> -{
> - return (struct gen8_insert_pte) {
> -  gen8_pml4e_index(start),
> -  gen8_pdpe_index(start),
> -  gen8_pde_index(start),
> -  gen8_pte_index(start),
> - };
> -}
> -
> -static __always_inline bool
> +static __always_inline u64
>  gen8_ppgtt_insert_pte_entries(struct i915_ppgtt *ppgtt,
> struct i915_page_directory *pdp,
> struct sgt_dma *iter,
> -   struct gen8_insert_pte *idx,
> +   u64 idx,
> enum i915_cache_level cache_level,
> u32 flags)
>  {
>   struct i915_page_directory *pd;
>   const gen8_pte_t pte_encode = gen8_pte_encode(0, cache_level, flags);
>   gen8_pte_t *vaddr;
> - bool ret;
>  
> - GEM_BUG_ON(idx->pdpe >= i915_pdpes_per_pdp(>vm));
> - pd = i915_pd_entry(pdp, idx->pdpe);
> - vaddr = kmap_atomic_px(i915_pt_entry(pd, idx->pde));
> + pd = i915_pd_entry(pdp, gen8_pd_index(idx, 2));
> + vaddr = kmap_atomic_px(i915_pt_entry(pd, gen8_pd_index(idx, 1)));
>   do {
> - vaddr[idx->pte] = pte_encode | iter->dma;
> + vaddr[gen8_pd_index(idx, 0)] = pte_encode | iter->dma;
>  
>   iter->dma += I915_GTT_PAGE_SIZE;
>   if (iter->dma >= iter->max) {
>   iter->sg = __sg_next(iter->sg);
>   if (!iter->sg) {
> - ret = false;
> + idx = 0;
>   break;
>   }
>  
> @@ -1179,30 +1160,22 @@ gen8_ppgtt_insert_pte_entries(struct i915_ppgtt 
> *ppgtt,
>   iter->max = iter->dma + iter->sg->length;
>   }
>  
> - if (++idx->pte == GEN8_PTES) {
> - idx->pte = 0;
> -
> - if (++idx->pde == I915_PDES) {
> - idx->pde = 0;
> -
> + if (gen8_pd_index(++idx, 0) == 0) {
> + if (gen8_pd_index(idx, 1) == 0) {
>   /* Limited by sg length for 3lvl */
> - if (++idx->pdpe == GEN8_PML4ES_PER_PML4) {
> - idx->pdpe = 0;
> - ret = true;
> + if (gen8_pd_index(idx, 2) == 0)
>   break;
> - }
>  
> - GEM_BUG_ON(idx->pdpe >= 
> i915_pdpes_per_pdp(>vm));
> - pd = pdp->entry[idx->pdpe];
> + pd = pdp->entry[gen8_pd_index(idx, 2)];
>   }
>  
>   kunmap_atomic(vaddr);
> - vaddr = kmap_atomic_px(i915_pt_entry(pd, idx->pde));
> + vaddr = kmap_atomic_px(i915_pt_entry(pd, 
> gen8_pd_index(idx, 1)));
>   }
>   } while (1);
>   kunmap_atomic(vaddr);
>  
> - return ret;
> + return idx;
>  }
>  
>  static void gen8_ppgtt_insert_3lvl(struct i915_address_space *vm,
> @@ -1212,9 +1185,9 @@ static void gen8_ppgtt_insert_3lvl(struct 
> i915_address_space *vm,
>  {
>   struct i915_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
>   struct sgt_dma iter = sgt_dma(vma);
> - struct gen8_insert_pte idx = gen8_insert_pte(vma->node.start);
>  
> - gen8_ppgtt_insert_pte_entries(ppgtt, ppgtt->pd, , ,
> + gen8_ppgtt_insert_pte_entries(ppgtt, ppgtt->pd,

Re: [Intel-gfx] [PATCH 3/4] drm/i915/gtt: Recursive ppgtt alloc for gen8

2019-07-16 Thread Abdiel Janulgue


On 12/07/2019 14.27, Chris Wilson wrote:
> Refactor the separate allocation routines into a single recursive
> function.
> 

Reviewed-by: Abdiel Janulgue 

> Signed-off-by: Chris Wilson 
> ---
>  drivers/gpu/drm/i915/i915_gem_gtt.c | 272 ++--
>  1 file changed, 97 insertions(+), 175 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
> b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 7b2f3188d435..72e0f9799a46 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -1007,199 +1007,119 @@ static void gen8_ppgtt_clear(struct 
> i915_address_space *vm,
>  start, start + length, vm->top);
>  }
>  
> -static void gen8_ppgtt_clear_pd(struct i915_address_space *vm,
> - struct i915_page_directory *pd,
> - u64 start, u64 length)
> -{
> - GEM_BUG_ON(!IS_ALIGNED(start, BIT_ULL(GEN8_PTE_SHIFT)));
> - GEM_BUG_ON(!IS_ALIGNED(length, BIT_ULL(GEN8_PTE_SHIFT)));
> -
> - start >>= GEN8_PTE_SHIFT;
> - length >>= GEN8_PTE_SHIFT;
> -
> - __gen8_ppgtt_clear(vm, pd, start, start + length, 1);
> -}
> -
> -static void gen8_ppgtt_clear_pdp(struct i915_address_space *vm,
> -  struct i915_page_directory * const pdp,
> -  u64 start, u64 length)
> -{
> - GEM_BUG_ON(!IS_ALIGNED(start, BIT_ULL(GEN8_PTE_SHIFT)));
> - GEM_BUG_ON(!IS_ALIGNED(length, BIT_ULL(GEN8_PTE_SHIFT)));
> -
> - start >>= GEN8_PTE_SHIFT;
> - length >>= GEN8_PTE_SHIFT;
> -
> - __gen8_ppgtt_clear(vm, pdp, start, start + length, 2);
> -}
> -
> -static int gen8_ppgtt_alloc_pd(struct i915_address_space *vm,
> -struct i915_page_directory *pd,
> -u64 start, u64 length)
> +static int __gen8_ppgtt_alloc(struct i915_address_space * const vm,
> +   struct i915_page_directory * const pd,
> +   u64 * const start, u64 end, int lvl)
>  {
> - struct i915_page_table *pt, *alloc = NULL;
> - u64 from = start;
> - unsigned int pde;
> + const struct i915_page_scratch * const scratch = >scratch[lvl];
> + struct i915_page_table *alloc = NULL;
> + unsigned int idx, len;
>   int ret = 0;
>  
> + len = gen8_pd_range(*start, end, lvl--, );
> + DBG("%s(%p):{lvl:%d, start:%llx, end:%llx, idx:%d, len:%d, used:%d}\n",
> + __func__, vm, lvl + 1, *start, end,
> + idx, len, atomic_read(px_used(pd)));
> + GEM_BUG_ON(!len || (idx + len - 1) >> gen8_pd_shift(1));
> +
>   spin_lock(>lock);
> - gen8_for_each_pde(pt, pd, start, length, pde) {
> - const int count = gen8_pte_count(start, length);
> + GEM_BUG_ON(!atomic_read(px_used(pd))); /* Must be pinned! */
> + do {
> + struct i915_page_table *pt = pd->entry[idx];
>  
>   if (!pt) {
>   spin_unlock(>lock);
>  
> - pt = fetch_and_zero();
> - if (!pt)
> - pt = alloc_pt(vm);
> - if (IS_ERR(pt)) {
> - ret = PTR_ERR(pt);
> - goto unwind;
> - }
> + DBG("%s(%p):{ lvl:%d, idx:%d } allocating new tree\n",
> + __func__, vm, lvl + 1, idx);
>  
> - if (count < GEN8_PTES || intel_vgpu_active(vm->i915))
> - fill_px(pt, vm->scratch[0].encode);
> + pt = fetch_and_zero();
> + if (lvl) {
> + if (!pt) {
> + pt = _pd(vm)->pt;
> + if (IS_ERR(pt)) {
> + ret = PTR_ERR(pt);
> + goto out;
> + }
> + }
>  
> - spin_lock(>lock);
> - if (!pd->entry[pde]) {
> - set_pd_entry(pd, pde, pt);
> + fill_px(pt, vm->scratch[lvl].encode);
>   } else {
> - alloc = pt;
> - pt = pd->entry[pde];
> - }
> - }
> -
> - atomic_add(count, >used);
> - }
> - spin_unlock(>lock);
> - goto out;
> -
> -unwind:
> - gen8_ppgtt_clear_pd(vm

Re: [Intel-gfx] [PATCH 3/4] drm/i915/gtt: Recursive ppgtt alloc for gen8

2019-07-16 Thread Abdiel Janulgue


On 12/07/2019 14.27, Chris Wilson wrote:
> Refactor the separate allocation routines into a single recursive
> function.
> 
Reviewed-by: Abdiel Janulgue 

> Signed-off-by: Chris Wilson 
> ---
>  drivers/gpu/drm/i915/i915_gem_gtt.c | 272 ++--
>  1 file changed, 97 insertions(+), 175 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
> b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 7b2f3188d435..72e0f9799a46 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -1007,199 +1007,119 @@ static void gen8_ppgtt_clear(struct 
> i915_address_space *vm,
>  start, start + length, vm->top);
>  }
>  
> -static void gen8_ppgtt_clear_pd(struct i915_address_space *vm,
> - struct i915_page_directory *pd,
> - u64 start, u64 length)
> -{
> - GEM_BUG_ON(!IS_ALIGNED(start, BIT_ULL(GEN8_PTE_SHIFT)));
> - GEM_BUG_ON(!IS_ALIGNED(length, BIT_ULL(GEN8_PTE_SHIFT)));
> -
> - start >>= GEN8_PTE_SHIFT;
> - length >>= GEN8_PTE_SHIFT;
> -
> - __gen8_ppgtt_clear(vm, pd, start, start + length, 1);
> -}
> -
> -static void gen8_ppgtt_clear_pdp(struct i915_address_space *vm,
> -  struct i915_page_directory * const pdp,
> -  u64 start, u64 length)
> -{
> - GEM_BUG_ON(!IS_ALIGNED(start, BIT_ULL(GEN8_PTE_SHIFT)));
> - GEM_BUG_ON(!IS_ALIGNED(length, BIT_ULL(GEN8_PTE_SHIFT)));
> -
> - start >>= GEN8_PTE_SHIFT;
> - length >>= GEN8_PTE_SHIFT;
> -
> - __gen8_ppgtt_clear(vm, pdp, start, start + length, 2);
> -}
> -
> -static int gen8_ppgtt_alloc_pd(struct i915_address_space *vm,
> -struct i915_page_directory *pd,
> -u64 start, u64 length)
> +static int __gen8_ppgtt_alloc(struct i915_address_space * const vm,
> +   struct i915_page_directory * const pd,
> +   u64 * const start, u64 end, int lvl)
>  {
> - struct i915_page_table *pt, *alloc = NULL;
> - u64 from = start;
> - unsigned int pde;
> + const struct i915_page_scratch * const scratch = >scratch[lvl];
> + struct i915_page_table *alloc = NULL;
> + unsigned int idx, len;
>   int ret = 0;
>  
> + len = gen8_pd_range(*start, end, lvl--, );
> + DBG("%s(%p):{lvl:%d, start:%llx, end:%llx, idx:%d, len:%d, used:%d}\n",
> + __func__, vm, lvl + 1, *start, end,
> + idx, len, atomic_read(px_used(pd)));
> + GEM_BUG_ON(!len || (idx + len - 1) >> gen8_pd_shift(1));
> +
>   spin_lock(>lock);
> - gen8_for_each_pde(pt, pd, start, length, pde) {
> - const int count = gen8_pte_count(start, length);
> + GEM_BUG_ON(!atomic_read(px_used(pd))); /* Must be pinned! */
> + do {
> + struct i915_page_table *pt = pd->entry[idx];
>  
>   if (!pt) {
>   spin_unlock(>lock);
>  
> - pt = fetch_and_zero();
> - if (!pt)
> - pt = alloc_pt(vm);
> - if (IS_ERR(pt)) {
> - ret = PTR_ERR(pt);
> - goto unwind;
> - }
> + DBG("%s(%p):{ lvl:%d, idx:%d } allocating new tree\n",
> + __func__, vm, lvl + 1, idx);
>  
> - if (count < GEN8_PTES || intel_vgpu_active(vm->i915))
> - fill_px(pt, vm->scratch[0].encode);
> + pt = fetch_and_zero();
> + if (lvl) {
> + if (!pt) {
> + pt = _pd(vm)->pt;
> + if (IS_ERR(pt)) {
> + ret = PTR_ERR(pt);
> + goto out;
> + }
> + }
>  
> - spin_lock(>lock);
> - if (!pd->entry[pde]) {
> - set_pd_entry(pd, pde, pt);
> + fill_px(pt, vm->scratch[lvl].encode);
>   } else {
> - alloc = pt;
> - pt = pd->entry[pde];
> - }
> - }
> -
> - atomic_add(count, >used);
> - }
> - spin_unlock(>lock);
> - goto out;
> -
> -unwind:
> - gen8_ppgtt_clear_pd(vm

Re: [Intel-gfx] [PATCH 2/4] drm/i915/gtt: Recursive ppgtt clear for gen8

2019-07-12 Thread Abdiel Janulgue


On 12/07/2019 14.27, Chris Wilson wrote:
> With an explicit level, we can refactor the separate clear functions
> as a simple recursive function. The additional knowledge of the level
> allows us to spot when we can free an entire subtree at once.
> 
> Signed-off-by: Chris Wilson 
> ---

Reviewed-by: Abdiel Janulgue 

>  drivers/gpu/drm/i915/Kconfig.debug  |  15 +++
>  drivers/gpu/drm/i915/i915_gem_gtt.c | 154 
>  2 files changed, 105 insertions(+), 64 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/Kconfig.debug 
> b/drivers/gpu/drm/i915/Kconfig.debug
> index 8d922bb4d953..ed8c787058a5 100644
> --- a/drivers/gpu/drm/i915/Kconfig.debug
> +++ b/drivers/gpu/drm/i915/Kconfig.debug
> @@ -94,6 +94,21 @@ config DRM_I915_TRACE_GEM
>  
> If in doubt, say "N".
>  
> +config DRM_I915_TRACE_GTT
> + bool "Insert extra ftrace output from the GTT internals"
> + depends on DRM_I915_DEBUG_GEM
> + select TRACING
> + default n
> + help
> +   Enable additional and verbose debugging output that will spam
> +   ordinary tests, but may be vital for post-mortem debugging when
> +   used with /proc/sys/kernel/ftrace_dump_on_oops
> +
> +   Recommended for driver developers only.
> +
> +   If in doubt, say "N".
> +
> +
>  config DRM_I915_SW_FENCE_DEBUG_OBJECTS
>  bool "Enable additional driver debugging for fence objects"
>  depends on DRM_I915
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
> b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 305c65c08a6a..7b2f3188d435 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -46,6 +46,12 @@
>  
>  #define I915_GFP_ALLOW_FAIL (GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN)
>  
> +#if IS_ENABLED(CONFIG_DRM_I915_TRACE_GTT)
> +#define DBG(...) trace_printk(__VA_ARGS__)
> +#else
> +#define DBG(...)
> +#endif
> +
>  /**
>   * DOC: Global GTT views
>   *
> @@ -796,6 +802,9 @@ release_pd_entry(struct i915_page_directory * const pd,
>  {
>   bool free = false;
>  
> + if (atomic_add_unless(>used, -1, 1))
> + return false;
> +
>   spin_lock(>lock);
>   if (atomic_dec_and_test(>used)) {
>   clear_pd_entry(pd, idx, scratch);
> @@ -927,86 +936,101 @@ static void gen8_ppgtt_cleanup(struct 
> i915_address_space *vm)
>   free_scratch(vm);
>  }
>  
> -/* Removes entries from a single page table, releasing it if it's empty.
> - * Caller can use the return value to update higher-level entries.
> - */
> -static void gen8_ppgtt_clear_pt(const struct i915_address_space *vm,
> - struct i915_page_table *pt,
> - u64 start, u64 length)
> +static u64 __gen8_ppgtt_clear(struct i915_address_space * const vm,
> +   struct i915_page_directory * const pd,
> +   u64 start, const u64 end, int lvl)
>  {
> - const unsigned int num_entries = gen8_pte_count(start, length);
> - gen8_pte_t *vaddr;
> + const struct i915_page_scratch * const scratch = >scratch[lvl];
> + unsigned int idx, len;
>  
> - vaddr = kmap_atomic_px(pt);
> - memset64(vaddr + gen8_pte_index(start),
> -  vm->scratch[0].encode,
> -  num_entries);
> - kunmap_atomic(vaddr);
> + len = gen8_pd_range(start, end, lvl--, );
> + DBG("%s(%p):{ lvl:%d, start:%llx, end:%llx, idx:%d, len:%d, used:%d}\n",
> + __func__, vm, lvl + 1, start, end,
> + idx, len, atomic_read(px_used(pd)));
> + GEM_BUG_ON(!len || len >= atomic_read(px_used(pd)));
>  
> - GEM_BUG_ON(num_entries > atomic_read(>used));
> + do {
> + struct i915_page_table *pt = pd->entry[idx];
> +
> + if (atomic_fetch_inc(>used) >> gen8_pd_shift(1) &&
> + gen8_pd_contains(start, end, lvl)) {
> + DBG("%s(%p):{ lvl:%d, idx:%d, start:%llx, end:%llx } 
> removing pd\n",
> + __func__, vm, lvl + 1, idx, start, end);
> + clear_pd_entry(pd, idx, scratch);
> + __gen8_ppgtt_cleanup(vm, as_pd(pt), I915_PDES, lvl);
> + start += (u64)I915_PDES << gen8_pd_shift(lvl);
> + continue;
> + }
>  
> - atomic_sub(num_entries, >used);
> -}
> + if (lvl) {
> + start = __gen8_ppgtt_clear(vm, as_pd(pt),
> +start, end, lvl);
> + } else {
>

Re: [Intel-gfx] [PATCH 1/4] drm/i915/gtt: Recursive cleanup for gen8

2019-07-12 Thread Abdiel Janulgue


On 12/07/2019 14.27, Chris Wilson wrote:
> With an explicit level, we can refactor the separate cleanup functions
> as a simple recursive function. We take the opportunity to pass down the
> size of each level so that we can deal with the different sizes of
> top-level and avoid over allocating for 32/36-bit vm.
> 
> Signed-off-by: Chris Wilson 
> ---

Reviewed-by: Abdiel Janulgue 

Regards,
Abdiel


>  drivers/gpu/drm/i915/i915_gem_gtt.c | 93 ++---
>  drivers/gpu/drm/i915/i915_gem_gtt.h |  2 +-
>  2 files changed, 33 insertions(+), 62 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
> b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 753090a7729e..305c65c08a6a 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -713,11 +713,11 @@ static struct i915_page_table *alloc_pt(struct 
> i915_address_space *vm)
>   return pt;
>  }
>  
> -static struct i915_page_directory *__alloc_pd(void)
> +static struct i915_page_directory *__alloc_pd(size_t sz)
>  {
>   struct i915_page_directory *pd;
>  
> - pd = kzalloc(sizeof(*pd), I915_GFP_ALLOW_FAIL);
> + pd = kzalloc(sz, I915_GFP_ALLOW_FAIL);
>   if (unlikely(!pd))
>   return NULL;
>  
> @@ -729,7 +729,7 @@ static struct i915_page_directory *alloc_pd(struct 
> i915_address_space *vm)
>  {
>   struct i915_page_directory *pd;
>  
> - pd = __alloc_pd();
> + pd = __alloc_pd(sizeof(*pd));
>   if (unlikely(!pd))
>   return ERR_PTR(-ENOMEM);
>  
> @@ -766,7 +766,7 @@ __set_pd_entry(struct i915_page_directory * const pd,
>  struct i915_page_dma * const to,
>  u64 (*encode)(const dma_addr_t, const enum i915_cache_level))
>  {
> - GEM_BUG_ON(atomic_read(px_used(pd)) > 512);
> + GEM_BUG_ON(atomic_read(px_used(pd)) > ARRAY_SIZE(pd->entry));
>  
>   atomic_inc(px_used(pd));
>   pd->entry[idx] = to;
> @@ -896,64 +896,34 @@ static inline unsigned int gen8_pt_count(u64 start, u64 
> end)
>   return end - start;
>  }
>  
> -static void gen8_free_page_tables(struct i915_address_space *vm,
> -   struct i915_page_directory *pd)
> +static void __gen8_ppgtt_cleanup(struct i915_address_space *vm,
> +  struct i915_page_directory *pd,
> +  int count, int lvl)
>  {
> - int i;
> -
> - for (i = 0; i < I915_PDES; i++) {
> - if (pd->entry[i])
> - free_pd(vm, pd->entry[i]);
> - }
> -}
> -
> -static void gen8_ppgtt_cleanup_3lvl(struct i915_address_space *vm,
> - struct i915_page_directory *pdp)
> -{
> - const unsigned int pdpes = i915_pdpes_per_pdp(vm);
> - int i;
> -
> - for (i = 0; i < pdpes; i++) {
> - if (!pdp->entry[i])
> - continue;
> -
> - gen8_free_page_tables(vm, pdp->entry[i]);
> - free_pd(vm, pdp->entry[i]);
> - }
> -
> - free_px(vm, pdp);
> -}
> -
> -static void gen8_ppgtt_cleanup_4lvl(struct i915_ppgtt *ppgtt)
> -{
> - struct i915_page_directory * const pml4 = ppgtt->pd;
> - int i;
> -
> - for (i = 0; i < GEN8_PML4ES_PER_PML4; i++) {
> - struct i915_page_directory *pdp = i915_pdp_entry(pml4, i);
> + if (lvl) {
> + void **pde = pd->entry;
>  
> - if (!pdp)
> - continue;
> + do {
> + if (!*pde)
> + continue;
>  
> - gen8_ppgtt_cleanup_3lvl(>vm, pdp);
> + __gen8_ppgtt_cleanup(vm, *pde, I915_PDES, lvl - 1);
> + } while (pde++, --count);
>   }
>  
> - free_px(>vm, pml4);
> + free_px(vm, pd);
>  }
>  
>  static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
>  {
> - struct drm_i915_private *i915 = vm->i915;
>   struct i915_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
>  
> - if (intel_vgpu_active(i915))
> + if (intel_vgpu_active(vm->i915))
>   gen8_ppgtt_notify_vgt(ppgtt, false);
>  
> - if (i915_vm_is_4lvl(vm))
> - gen8_ppgtt_cleanup_4lvl(ppgtt);
> - else
> - gen8_ppgtt_cleanup_3lvl(>vm, ppgtt->pd);
> -
> + __gen8_ppgtt_cleanup(vm, ppgtt->pd,
> +  vm->total >> __gen8_pte_shift(vm->top),
> +  vm->top);
>   free_scratch(vm);
>  }
>  
> @@ -1505,24 +1475,18 @@ static int gen8_preallocate_top_level_pdp(stru

Re: [Intel-gfx] [PATCH] drm/i915: Split out GTT fault handler to make it generic

2019-06-04 Thread Abdiel Janulgue


On 06/04/2019 02:00 PM, Chris Wilson wrote:

>> +
>> +   /* Access to snoopable pages through the GTT is incoherent. */
>> +   if (obj->cache_level != I915_CACHE_NONE && !HAS_LLC(dev_priv)) {
> 
> And that is very, very specific to one path.
> 
Oops, yep that should be gtt-fault specific


> From the sampling here, this is not generic preamble.
> -Chris
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH] drm/i915: Split out GTT fault handler to make it generic

2019-06-04 Thread Abdiel Janulgue
Allow reuse of the fault-handling code in preparation for having
multiple fault handlers depending on the mmaping type and backing
storage.

Cc: Matthew Auld 
Cc: Chris Wilson 
Cc: Joonas Lahtinen 

Signed-off-by: Abdiel Janulgue 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 208 ++-
 1 file changed, 132 insertions(+), 76 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index c7b9b34de01b..ed20fab66d2f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -197,6 +197,133 @@ compute_partial_view(const struct drm_i915_gem_object 
*obj,
return view;
 }
 
+struct gem_object_fault {
+   struct drm_i915_gem_object *obj;
+   pgoff_t page_offset;
+   intel_wakeref_t wakeref;
+   int srcu;
+   bool pin_vma;
+   vm_fault_t error_ret;
+};
+
+static vm_fault_t __vm_fault_from_error(struct drm_i915_private *i915,
+   int fault_ret)
+{
+   switch (fault_ret) {
+   case -EIO:
+   /*
+* We eat errors when the gpu is terminally wedged to avoid
+* userspace unduly crashing (gl has no provisions for mmaps to
+* fail). But any other -EIO isn't ours (e.g. swap in failure)
+* and so needs to be reported.
+*/
+   if (!i915_terminally_wedged(i915))
+   return VM_FAULT_SIGBUS;
+   /* else: fall through */
+   case -EAGAIN:
+   /*
+* EAGAIN means the gpu is hung and we'll wait for the error
+* handler to reset everything when re-faulting in
+* i915_mutex_lock_interruptible.
+*/
+   case 0:
+   case -ERESTARTSYS:
+   case -EINTR:
+   case -EBUSY:
+   /*
+* EBUSY is ok: this just means that another thread
+* already did the job.
+*/
+   return VM_FAULT_NOPAGE;
+   case -ENOMEM:
+   return VM_FAULT_OOM;
+   case -ENOSPC:
+   case -EFAULT:
+   return VM_FAULT_SIGBUS;
+   default:
+   WARN_ONCE(fault_ret, "unhandled error in %s: %i\n", __func__,
+ fault_ret);
+   return VM_FAULT_SIGBUS;
+   }
+}
+
+static int __prepare_object_fault(struct vm_fault *vmf,
+ bool pin_vma,
+ struct gem_object_fault *f)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
+   struct drm_device *dev = obj->base.dev;
+   struct drm_i915_private *dev_priv = to_i915(dev);
+   bool write = area->vm_flags & VM_WRITE;
+   int ret;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write) {
+   f->error_ret = VM_FAULT_SIGBUS;
+   return -EACCES;
+   }
+
+   f->obj = obj;
+   /* We don't use vmf->pgoff since that has the fake offset */
+   f->page_offset = (vmf->address - area->vm_start) >> PAGE_SHIFT;
+
+   trace_i915_gem_object_fault(obj, f->page_offset, true, write);
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   goto err;
+
+   f->wakeref = intel_runtime_pm_get(dev_priv);
+
+   f->srcu = i915_reset_trylock(dev_priv);
+   if (f->srcu < 0) {
+   ret = f->srcu;
+   goto err_rpm;
+   }
+
+   f->pin_vma = pin_vma;
+   if (f->pin_vma) {
+   ret = i915_mutex_lock_interruptible(dev);
+   if (ret)
+   goto err_reset;
+   }
+
+   /* Access to snoopable pages through the GTT is incoherent. */
+   if (obj->cache_level != I915_CACHE_NONE && !HAS_LLC(dev_priv)) {
+   ret = -EFAULT;
+   goto err_unlock;
+   }
+
+   return 0;
+
+err_unlock:
+   if (f->pin_vma)
+   mutex_unlock(>struct_mutex);
+err_reset:
+   i915_reset_unlock(dev_priv, f->srcu);
+err_rpm:
+   intel_runtime_pm_put(dev_priv, f->wakeref);
+   i915_gem_object_unpin_pages(obj);
+err:
+   f->error_ret = __vm_fault_from_error(dev_priv, ret);
+   return ret;
+}
+
+static vm_fault_t __object_fault_fini(int fault_ret, struct gem_object_fault 
*f)
+{
+   struct drm_device *dev = f->obj->base.dev;
+   struct drm_i915_private *dev_priv = to_i915(dev);
+
+   if (f->pin_vma)
+   mutex_unlock(>struct_mutex);
+   i915_reset_unlock(dev_priv, f->srcu);
+   intel_runtime_pm_put(dev_priv, f->wakeref);
+   i915_gem_object_unpin_pages(f->obj);
+
+   return __vm_fault_from_error(dev_priv, fault_ret);
+}

[Intel-gfx] [PATCH v3] drm/i915/query: Split out query item checks

2019-02-11 Thread Abdiel Janulgue
This simplifies adding new query item objects.

v2: Use query_hdr (Tvrtko, Chris).
int instead of u32 in return (Tvrtko)
v3: More naming fixes (Tvrtko)

Signed-off-by: Abdiel Janulgue 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/i915_query.c | 39 ---
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_query.c 
b/drivers/gpu/drm/i915/i915_query.c
index cbcb957b7141..782183b78f49 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -10,12 +10,34 @@
 #include "i915_query.h"
 #include 
 
+static int copy_query_item(void *query_hdr, size_t query_sz,
+  u32 total_length,
+  struct drm_i915_query_item *query_item)
+{
+   if (query_item->length == 0)
+   return total_length;
+
+   if (query_item->length < total_length)
+   return -EINVAL;
+
+   if (copy_from_user(query_hdr, u64_to_user_ptr(query_item->data_ptr),
+  query_sz))
+   return -EFAULT;
+
+   if (!access_ok(u64_to_user_ptr(query_item->data_ptr),
+  total_length))
+   return -EFAULT;
+
+   return 0;
+}
+
 static int query_topology_info(struct drm_i915_private *dev_priv,
   struct drm_i915_query_item *query_item)
 {
const struct sseu_dev_info *sseu = _INFO(dev_priv)->sseu;
struct drm_i915_query_topology_info topo;
u32 slice_length, subslice_length, eu_length, total_length;
+   int ret;
 
if (query_item->flags != 0)
return -EINVAL;
@@ -33,23 +55,14 @@ static int query_topology_info(struct drm_i915_private 
*dev_priv,
 
total_length = sizeof(topo) + slice_length + subslice_length + 
eu_length;
 
-   if (query_item->length == 0)
-   return total_length;
-
-   if (query_item->length < total_length)
-   return -EINVAL;
-
-   if (copy_from_user(, u64_to_user_ptr(query_item->data_ptr),
-  sizeof(topo)))
-   return -EFAULT;
+   ret = copy_query_item(, sizeof(topo), total_length,
+ query_item);
+   if (ret != 0)
+   return ret;
 
if (topo.flags != 0)
return -EINVAL;
 
-   if (!access_ok(u64_to_user_ptr(query_item->data_ptr),
-  total_length))
-   return -EFAULT;
-
memset(, 0, sizeof(topo));
topo.max_slices = sseu->max_slices;
topo.max_subslices = sseu->max_subslices;
-- 
2.19.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2] drm/i915/query: Split out query item checks

2019-01-16 Thread Abdiel Janulgue
This simplifies adding new query item objects.

v2: Use query_hdr (Tvrtko, Chris).
int instead of u32 in return (Tvrtko)

Signed-off-by: Abdiel Janulgue 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/i915_query.c | 39 ---
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_query.c 
b/drivers/gpu/drm/i915/i915_query.c
index cbcb957b7141..b2449cffda51 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -10,12 +10,34 @@
 #include "i915_query.h"
 #include 
 
+static int init_query_item_check(void *query_hdr, size_t data_sz,
+u32 total_length,
+struct drm_i915_query_item *query_item)
+{
+   if (query_item->length == 0)
+   return total_length;
+
+   if (query_item->length < total_length)
+   return -EINVAL;
+
+   if (copy_from_user(query_hdr, u64_to_user_ptr(query_item->data_ptr),
+  data_sz))
+   return -EFAULT;
+
+   if (!access_ok(u64_to_user_ptr(query_item->data_ptr),
+  total_length))
+   return -EFAULT;
+
+   return 0;
+}
+
 static int query_topology_info(struct drm_i915_private *dev_priv,
   struct drm_i915_query_item *query_item)
 {
const struct sseu_dev_info *sseu = _INFO(dev_priv)->sseu;
struct drm_i915_query_topology_info topo;
u32 slice_length, subslice_length, eu_length, total_length;
+   int ret;
 
if (query_item->flags != 0)
return -EINVAL;
@@ -33,23 +55,14 @@ static int query_topology_info(struct drm_i915_private 
*dev_priv,
 
total_length = sizeof(topo) + slice_length + subslice_length + 
eu_length;
 
-   if (query_item->length == 0)
-   return total_length;
-
-   if (query_item->length < total_length)
-   return -EINVAL;
-
-   if (copy_from_user(, u64_to_user_ptr(query_item->data_ptr),
-  sizeof(topo)))
-   return -EFAULT;
+   ret = init_query_item_check(, sizeof(topo), total_length,
+   query_item);
+   if (ret != 0)
+   return ret;
 
if (topo.flags != 0)
return -EINVAL;
 
-   if (!access_ok(u64_to_user_ptr(query_item->data_ptr),
-  total_length))
-   return -EFAULT;
-
memset(, 0, sizeof(topo));
topo.max_slices = sseu->max_slices;
topo.max_subslices = sseu->max_subslices;
-- 
2.19.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915/query: Split out query item checks

2019-01-09 Thread Abdiel Janulgue
This simplifies adding new query item objects.

Signed-off-by: Abdiel Janulgue 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/i915_query.c | 40 ---
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_query.c 
b/drivers/gpu/drm/i915/i915_query.c
index cbcb957b7141..b4f26605f617 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -10,12 +10,33 @@
 #include "i915_query.h"
 #include 
 
+static int init_query_item_check(void* data_ptr, size_t data_sz,
+u32 total_length,
+struct drm_i915_query_item *query_item)
+{
+   if (query_item->length == 0)
+   return total_length;
+
+   if (query_item->length < total_length)
+   return -EINVAL;
+
+   if (copy_from_user(data_ptr, u64_to_user_ptr(query_item->data_ptr),
+  data_sz))
+   return -EFAULT;
+
+   if (!access_ok(u64_to_user_ptr(query_item->data_ptr),
+  total_length))
+   return -EFAULT;
+
+   return 0;
+}
+
 static int query_topology_info(struct drm_i915_private *dev_priv,
   struct drm_i915_query_item *query_item)
 {
const struct sseu_dev_info *sseu = _INFO(dev_priv)->sseu;
struct drm_i915_query_topology_info topo;
-   u32 slice_length, subslice_length, eu_length, total_length;
+   u32 ret, slice_length, subslice_length, eu_length, total_length;
 
if (query_item->flags != 0)
return -EINVAL;
@@ -33,23 +54,14 @@ static int query_topology_info(struct drm_i915_private 
*dev_priv,
 
total_length = sizeof(topo) + slice_length + subslice_length + 
eu_length;
 
-   if (query_item->length == 0)
-   return total_length;
-
-   if (query_item->length < total_length)
-   return -EINVAL;
-
-   if (copy_from_user(, u64_to_user_ptr(query_item->data_ptr),
-  sizeof(topo)))
-   return -EFAULT;
+   ret = init_query_item_check(, sizeof(topo), total_length,
+   query_item);
+   if (ret != 0)
+   return ret;
 
if (topo.flags != 0)
return -EINVAL;
 
-   if (!access_ok(u64_to_user_ptr(query_item->data_ptr),
-  total_length))
-   return -EFAULT;
-
memset(, 0, sizeof(topo));
topo.max_slices = sseu->max_slices;
topo.max_subslices = sseu->max_subslices;
-- 
2.19.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 1/2] drm/i915/selftests: Extend partial vma coverage to check parallel creation

2018-04-09 Thread Abdiel Janulgue
From: Chris Wilson 

One important use of partial vma is to provide mappable access to the
object while it is being used elsewhere (pinned entirely into the
unmappable portion of the Global GTT, i.e. for use as a display scanout).

Signed-off-by: Chris Wilson 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/selftests/i915_vma.c | 59 +++
 1 file changed, 52 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c 
b/drivers/gpu/drm/i915/selftests/i915_vma.c
index eb89e30..ea48bac 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -606,11 +606,17 @@ static int igt_vma_partial(void *arg)
struct drm_i915_private *i915 = arg;
struct i915_address_space *vm = >ggtt.base;
const unsigned int npages = 1021; /* prime! */
-   struct drm_i915_gem_object *obj;
+   struct drm_i915_gem_object *obj = NULL;
const struct phase {
const char *name;
+   unsigned int flags;
+#define CREATE BIT(0)
+#define WHOLE  BIT(1)
} phases[] = {
-   { "create" },
+   { "create", CREATE },
+   { "lookup" },
+   { "whole", WHOLE },
+   { "recreate", CREATE | WHOLE },
{ "lookup" },
{ },
}, *p;
@@ -618,17 +624,44 @@ static int igt_vma_partial(void *arg)
struct i915_vma *vma;
int err = -ENOMEM;
 
-   /* Create lots of different VMA for the object and check that
+   /*
+* Create lots of different VMA for the object and check that
 * we are returned the same VMA when we later request the same range.
 */
 
-   obj = i915_gem_object_create_internal(i915, npages*PAGE_SIZE);
-   if (IS_ERR(obj))
-   goto out;
-
for (p = phases; p->name; p++) { /* exercise both create/lookup */
unsigned int count, nvma;
 
+   if (p->flags & CREATE) {
+   if (obj)
+   i915_gem_object_put(obj);
+
+   obj = i915_gem_object_create_internal(i915,
+ npages*PAGE_SIZE);
+   if (IS_ERR(obj))
+   goto out;
+   }
+
+   if (p->flags & WHOLE) {
+   /*
+* Make sure we can create mappable partial vma
+* while the whole object is in use elsewhere.
+*/
+   vma = i915_vma_instance(obj, vm, NULL);
+   if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
+   goto out_object;
+   }
+
+   err = i915_vma_unbind(vma);
+   if (err)
+   goto out_object;
+
+   err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH);
+   if (err)
+   goto out_object;
+   }
+
nvma = 0;
for_each_prime_number_from(sz, 1, npages) {
for_each_prime_number_from(offset, 0, npages - sz) {
@@ -707,12 +740,24 @@ static int igt_vma_partial(void *arg)
err = -EINVAL;
goto out_object;
}
+
+   if (p->flags & WHOLE) {
+   vma = i915_vma_instance(obj, vm, NULL);
+   if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
+   goto out_object;
+   }
+
+   i915_vma_unpin(vma);
+   }
}
 
 out_object:
i915_gem_object_put(obj);
 out:
return err;
+#undef CREATE
+#undef WHOLE
 }
 
 int i915_vma_mock_selftests(void)
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/2] drm/i915/selftests: Compare mappable vma against instance in unmappable region

2018-04-09 Thread Abdiel Janulgue
Add an additional comparison to check the entire vma created in the mappable
region of the global GTT against the one in the unmappable range.

Further test with an assert_partial as well to ensure the VMA corresponds
to the original object's backing store.

Signed-off-by: Abdiel Janulgue <abdiel.janul...@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/selftests/i915_vma.c | 44 ++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c 
b/drivers/gpu/drm/i915/selftests/i915_vma.c
index ea48bac..10cf4df 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -554,6 +554,30 @@ static bool assert_partial(struct drm_i915_gem_object *obj,
return true;
 }
 
+static bool assert_vma_compare(struct i915_vma *vma1, struct i915_vma *vma2)
+{
+   struct sgt_iter sgt;
+   dma_addr_t dma;
+   unsigned long offset = 0;
+
+   for_each_sgt_dma(dma, sgt, vma1->pages) {
+   dma_addr_t src;
+
+   src = sg_dma_address(vma2->pages->sgl) +
+   (offset << PAGE_SHIFT);
+
+   if (src != dma) {
+   pr_err("VMA comparison failed. DMA mismatch for partial 
"
+  "page offset %lu\n", offset);
+   return false;
+   }
+
+   offset++;
+   }
+
+   return true;
+}
+
 static bool assert_pin(struct i915_vma *vma,
   struct i915_ggtt_view *view,
   u64 size,
@@ -621,7 +645,7 @@ static int igt_vma_partial(void *arg)
{ },
}, *p;
unsigned int sz, offset;
-   struct i915_vma *vma;
+   struct i915_vma *vma, *vma_unmapped = NULL;
int err = -ENOMEM;
 
/*
@@ -660,6 +684,8 @@ static int igt_vma_partial(void *arg)
err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH);
if (err)
goto out_object;
+
+   vma_unmapped = vma;
}
 
nvma = 0;
@@ -748,6 +774,22 @@ static int igt_vma_partial(void *arg)
goto out_object;
}
 
+   if (!assert_partial(obj, vma, 0, npages)) {
+   pr_err("(%s) Inconsistent partial pages for 
(offset=%d, size=%d)\n",
+  p->name, offset, sz);
+   err = -EINVAL;
+   goto out_object;
+   }
+
+   if (vma_unmapped) {
+   if (!assert_vma_compare(vma, vma_unmapped)) {
+   pr_err("(%s) Inconsistent vma from 
unmapped region\n",
+  p->name);
+   err = -EINVAL;
+   goto out_object;
+   }
+   }
+
i915_vma_unpin(vma);
}
}
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v2 1/1] i915: additional GEM documentation

2018-03-27 Thread Abdiel Janulgue


On 03/02/2018 04:09 PM, kevin.rogo...@intel.com wrote:
> From: Kevin Rogovin <kevin.rogo...@intel.com>
> 
> This patch provides additional overview documentation to the
> i915 kernel driver GEM. In addition, it presents already written
> documentation to i915.rst as well.
> 
> Signed-off-by: Kevin Rogovin <kevin.rogo...@intel.com>

Makes sense. From a GEM newcomer's POV like me, the document does help
in lowering barrier of entry to understanding GEM structures and
entry-points. A detailed description of how the GuC submission mechanism
works could be another good addition, but that could be done in a
subsequent series.

Reviewed-by: Abdiel Janulgue <abdiel.janul...@linux.intel.com>

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [igt-dev] [PATCH igt 1/5] lib/dummyload: Avoid assertions in lowlevel spin constructor

2018-02-28 Thread Abdiel Janulgue


On 02/28/2018 05:51 PM, Chris Wilson wrote:
> __igt_spin_batch_new() may be used inside a background helper which is
> competing against the GPU being reset. As such, we cannot even assert
> that the spin->handle is busy immediately after submission as it may
> have already been reset by another client writing to i915_wedged.
> 
> Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

Reviewed-by: Abdiel Janulgue <abdiel.janul...@linux.intel.com>

> ---
>  lib/igt_dummyload.c | 17 ++---
>  tests/pm_rps.c  |  4 +++-
>  2 files changed, 17 insertions(+), 4 deletions(-)
> 
> diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c
> index ddd43451..4b20f23d 100644
> --- a/lib/igt_dummyload.c
> +++ b/lib/igt_dummyload.c
> @@ -25,6 +25,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  
> @@ -207,7 +208,6 @@ ___igt_spin_batch_new(int fd, uint32_t ctx, unsigned 
> engine, uint32_t dep,
>  
>   spin->out_fence = emit_recursive_batch(spin, fd, ctx, engine, dep,
>  out_fence);
> - igt_assert(gem_bo_busy(fd, spin->handle));
>  
>   pthread_mutex_lock(_lock);
>   igt_list_add(>link, _list);
> @@ -240,9 +240,14 @@ __igt_spin_batch_new(int fd, uint32_t ctx, unsigned 
> engine, uint32_t dep)
>  igt_spin_t *
>  igt_spin_batch_new(int fd, uint32_t ctx, unsigned engine, uint32_t dep)
>  {
> + igt_spin_t *spin;
> +
>   igt_require_gem(fd);
>  
> - return __igt_spin_batch_new(fd, ctx, engine, dep);
> + spin = __igt_spin_batch_new(fd, ctx, engine, dep);
> + igt_assert(gem_bo_busy(fd, spin->handle));
> +
> + return spin;
>  }
>  
>  igt_spin_t *
> @@ -269,10 +274,16 @@ __igt_spin_batch_new_fence(int fd, uint32_t ctx, 
> unsigned engine)
>  igt_spin_t *
>  igt_spin_batch_new_fence(int fd, uint32_t ctx, unsigned engine)
>  {
> + igt_spin_t *spin;
> +
>   igt_require_gem(fd);
>   igt_require(gem_has_exec_fence(fd));
>  
> - return __igt_spin_batch_new_fence(fd, ctx, engine);
> + spin = __igt_spin_batch_new_fence(fd, ctx, engine);
> + igt_assert(gem_bo_busy(fd, spin->handle));
> + igt_assert(poll(&(struct pollfd){spin->out_fence, POLLIN}, 1, 0) == 0);
> +
> + return spin;
>  }
>  
>  static void notify(union sigval arg)
> diff --git a/tests/pm_rps.c b/tests/pm_rps.c
> index f71976ed..006d084b 100644
> --- a/tests/pm_rps.c
> +++ b/tests/pm_rps.c
> @@ -221,6 +221,8 @@ static void load_helper_run(enum load load)
>   return;
>   }
>  
> + igt_require_gem(drm_fd);
> +
>   lh.exit = false;
>   lh.load = load;
>  
> @@ -233,7 +235,7 @@ static void load_helper_run(enum load load)
>  
>   igt_debug("Applying %s load...\n", lh.load ? "high" : "low");
>  
> - spin[0] = igt_spin_batch_new(drm_fd, 0, 0, 0);
> + spin[0] = __igt_spin_batch_new(drm_fd, 0, 0, 0);
>   if (lh.load == HIGH)
>   spin[1] = __igt_spin_batch_new(drm_fd, 0, 0, 0);
>   while (!lh.exit) {
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2] drm/i915: Ignore TMDS clock limit for DP++ when EDID override is set

2017-12-15 Thread Abdiel Janulgue
4K modes testing by using dummy EDID data has never been working
properly on boxes with DP++ (dual-mode) adaptors. The reason for
this is that those modes got pruned during hdmi mode validation.
intel_hdmi_mode_valid returns CLOCK_HIGH because the pixel clock
reported by the 4k mode is higher than dual port TMDS clock limit.

However 4k injection does work properly on machines that don't have
DP++ adapters because the mode is never validated against the DP++
TMDS clock limit.

v2: Don't detect the DP++ limits when we're testing using overridden
EDIDs. Make sure to check for the override condition after
respecting the value of drm_dp_dual_mode_detect (Jani Nikula).

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101649
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Jani Nikula <jani.nik...@intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Signed-off-by: Abdiel Janulgue <abdiel.janul...@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_hdmi.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index bced7b9..9834690 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1567,7 +1567,10 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector 
*connector, bool has_edid)
 * there's nothing connected to the port.
 */
if (type == DRM_DP_DUAL_MODE_UNKNOWN) {
-   if (has_edid &&
+   /* An overridden EDID imply that we want this port for testing.
+* Make sure not to set limits for that port.
+*/
+   if (has_edid && !connector->override_edid &&
intel_bios_is_port_dp_dual_mode(dev_priv, port)) {
DRM_DEBUG_KMS("Assuming DP dual mode adaptor presence 
based on VBT\n");
type = DRM_DP_DUAL_MODE_TYPE1_DVI;
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915: Ignore TMDS clock limit for DP++ when EDID override is set

2017-12-14 Thread Abdiel Janulgue
4K modes testing by using dummy EDID data has never been working
properly on boxes with DP++ (dual-mode) adaptors. The reason for
this is that  those modes got pruned during hdmi mode validation.
intel_hdmi_mode_valid returns CLOCK_HIGH  because the pixel clock
reported by the 4k mode is higher than dual port TMDS clock limit.

However 4k injection does work properly on machines that don't have
DP++ adapters because the mode is never validated against the DP++
TMDS clock limit.

Ignore the limits when we're testing using overriden EDIDs.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101649
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Jani Nikula <jani.nik...@intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Signed-off-by: Abdiel Janulgue <abdiel.janul...@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_hdmi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index bced7b9..d133353 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1576,7 +1576,7 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector 
*connector, bool has_edid)
}
}
 
-   if (type == DRM_DP_DUAL_MODE_NONE)
+   if (type == DRM_DP_DUAL_MODE_NONE || connector->override_edid)
return;
 
hdmi->dp_dual_mode.type = type;
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH i-g-t v2 1/3] tests/gem_hangcheck_forcewake: Drop gem_hangcheck_forcewake.c

2017-11-29 Thread Abdiel Janulgue
gem_hangcheck_forcewake has been superseded by drv_hangman, and a lot of
other very extensive hangchecking that is not run by CI (Chris).

v2: Split into multiple patches (Antonio Argenziano)

Signed-off-by: Abdiel Janulgue <abdiel.janul...@linux.intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
---
 tests/Makefile.sources  |   1 -
 tests/gem_hangcheck_forcewake.c | 123 
 tests/meson.build   |   1 -
 3 files changed, 125 deletions(-)
 delete mode 100644 tests/gem_hangcheck_forcewake.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 34ca71a..84d80a3 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -99,7 +99,6 @@ TESTS_progs = \
gem_gtt_cpu_tlb \
gem_gtt_hog \
gem_gtt_speed \
-   gem_hangcheck_forcewake \
gem_largeobject \
gem_linear_blits \
gem_lut_handle \
diff --git a/tests/gem_hangcheck_forcewake.c b/tests/gem_hangcheck_forcewake.c
deleted file mode 100644
index a3e7554..000
--- a/tests/gem_hangcheck_forcewake.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright © 2011 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 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- *Daniel Vetter <daniel.vet...@ffwll.ch>
- *
- */
-
-#include "igt.h"
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "drm.h"
-#include "intel_bufmgr.h"
-
-IGT_TEST_DESCRIPTION("Provoke the hangcheck timer on an otherwise idle"
-" system.");
-
-/*
- * Testcase: Provoke the hangcheck timer on an otherwise idle system
- *
- * This tries to hit forcewake locking bugs when the hangcheck runs. Somehow we
- * often luck out and the hangcheck runs while someone else is already holding
- * the dev->struct_mutex.
- *
- * It's imperative that nothing else runs while this test runs, i.e. kill your 
X
- * session, please.
- */
-
-static drm_intel_bufmgr *bufmgr;
-struct intel_batchbuffer *batch;
-
-uint32_t blob[2048*2048];
-
-#define MAX_BLT_SIZE 128
-igt_simple_main
-{
-   drm_intel_bo *bo = NULL;
-   uint32_t tiling_mode = I915_TILING_X;
-   unsigned long pitch, act_size;
-   int fd, i, devid;
-
-   igt_skip_on_simulation();
-
-   memset(blob, 'A', sizeof(blob));
-
-   fd = drm_open_driver(DRIVER_INTEL);
-   igt_require_gem(fd);
-
-   bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
-   drm_intel_bufmgr_gem_enable_reuse(bufmgr);
-   devid = intel_get_drm_devid(fd);
-   batch = intel_batchbuffer_alloc(bufmgr, devid);
-
-   act_size = 2048;
-   igt_info("filling ring\n");
-   drm_intel_bo_unreference(bo);
-   bo = drm_intel_bo_alloc_tiled(bufmgr, "tiled bo", act_size, act_size,
- 4, _mode, , 0);
-
-   drm_intel_bo_subdata(bo, 0, act_size*act_size*4, blob);
-
-   if (IS_965(devid))
-   pitch /= 4;
-
-   for (i = 0; i < 1; i++) {
-   BLIT_COPY_BATCH_START(XY_SRC_COPY_BLT_SRC_TILED |
- XY_SRC_COPY_BLT_DST_TILED);
-   OUT_BATCH((3 << 24) | /* 32 bits */
- (0xcc << 16) | /* copy ROP */
- pitch);
-   OUT_BATCH(0 << 16 | 1024);
-   OUT_BATCH((2048) << 16 | (2048));
-   OUT_RELOC_FENCED(bo, I915_GEM_DOMAIN_RENDER, 
I915_GEM_DOMAIN_RENDER, 0);
-   OUT_BATCH(0 << 16 | 0);
-   OUT_BATCH(pitch);
-   OUT_RELOC_FENCED(bo, I915_GEM_DOMAIN_RENDER, 0, 0);
-   ADVANCE_BATCH();
-
-   if (batch->gen >= 6) {
-   BEGIN_BATCH(3, 0);
-

[Intel-gfx] [PATCH i-g-t v2 2/3] tests/gem_pin: Drop gem_pin.c

2017-11-29 Thread Abdiel Janulgue
gem_pin ABI is going away (Chris).

Signed-off-by: Abdiel Janulgue <abdiel.janul...@linux.intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
---
 tests/Makefile.sources |   1 -
 tests/gem_pin.c| 248 -
 tests/meson.build  |   1 -
 3 files changed, 250 deletions(-)
 delete mode 100644 tests/gem_pin.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 84d80a3..4f936e7 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -111,7 +111,6 @@ TESTS_progs = \
gem_mocs_settings \
gem_partial_pwrite_pread \
gem_persistent_relocs \
-   gem_pin \
gem_pipe_control_store_loop \
gem_ppgtt \
gem_pread \
diff --git a/tests/gem_pin.c b/tests/gem_pin.c
deleted file mode 100644
index 9ea3b1e..000
--- a/tests/gem_pin.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright © 20013 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 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- *Chris Wilson <ch...@chris-wilson.co.uk>
- *
- */
-
-/* Exercises pinning of small bo */
-
-#include "igt.h"
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-
-
-IGT_TEST_DESCRIPTION("Exercises pinning of small buffer objects.");
-
-#define COPY_BLT_CMD(2<<29|0x53<<22|0x6)
-#define BLT_WRITE_ALPHA (1<<21)
-#define BLT_WRITE_RGB   (1<<20)
-
-static void exec(int fd, uint32_t handle, uint32_t offset)
-{
-   struct drm_i915_gem_execbuffer2 execbuf;
-   struct drm_i915_gem_exec_object2 gem_exec[1];
-   struct drm_i915_gem_relocation_entry gem_reloc[1];
-
-   gem_reloc[0].offset = 1024;
-   gem_reloc[0].delta = 0;
-   gem_reloc[0].target_handle = handle;
-   gem_reloc[0].read_domains = I915_GEM_DOMAIN_RENDER;
-   gem_reloc[0].write_domain = 0;
-   gem_reloc[0].presumed_offset = 0;
-
-   gem_exec[0].handle = handle;
-   gem_exec[0].relocation_count = 1;
-   gem_exec[0].relocs_ptr = to_user_pointer(gem_reloc);
-   gem_exec[0].alignment = 0;
-   gem_exec[0].offset = 0;
-   gem_exec[0].flags = 0;
-   gem_exec[0].rsvd1 = 0;
-   gem_exec[0].rsvd2 = 0;
-
-   execbuf.buffers_ptr = to_user_pointer(gem_exec);
-   execbuf.buffer_count = 1;
-   execbuf.batch_start_offset = 0;
-   execbuf.batch_len = 8;
-   execbuf.cliprects_ptr = 0;
-   execbuf.num_cliprects = 0;
-   execbuf.DR1 = 0;
-   execbuf.DR4 = 0;
-   execbuf.flags = 0;
-   i915_execbuffer2_set_context_id(execbuf, 0);
-   execbuf.rsvd2 = 0;
-
-   do_ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, );
-   igt_assert(gem_exec[0].offset == offset);
-}
-
-static int gem_linear_blt(int fd,
- uint32_t *batch,
- uint32_t src,
- uint32_t dst,
- uint32_t length,
- struct drm_i915_gem_relocation_entry *reloc)
-{
-   uint32_t *b = batch;
-
-   *b++ = COPY_BLT_CMD | BLT_WRITE_ALPHA | BLT_WRITE_RGB;
-   *b++ = 0x66 << 16 | 1 << 25 | 1 << 24 | (4*1024);
-   *b++ = 0;
-   *b++ = (length / (4*1024)) << 16 | 1024;
-   *b++ = 0;
-   reloc->offset = (b-batch-1) * sizeof(uint32_t);
-   reloc->delta = 0;
-   reloc->target_handle = dst;
-   reloc->read_domains = I915_GEM_DOMAIN_RENDER;
-   reloc->write_domain = I915_GEM_DOMAIN_RENDER;
-   reloc->presumed_offset = 0;
-   reloc++;
-   if (intel_gen(intel_get_drm_devid(fd)) >= 8)
-   *b++ = 0; /* FIXME */
-
-   *b++ = 0;
-   *b++ = 4*1024;
-   *b++ = 0;
-   reloc->offset = (b-batch-1) * sizeof(uint32_t);
-   reloc->delta = 0;
-   reloc->target

[Intel-gfx] [PATCH i-g-t v2 3/3] tests/gem_seqno_wrap: Drop gem_seqno_wrap.c

2017-11-29 Thread Abdiel Janulgue
gem_seqno_wrap is defunct as the debug API withered away. The
handling of wraparound under many different workloads is tested by
gem_exec_whisper (Chris).

Signed-off-by: Abdiel Janulgue <abdiel.janul...@linux.intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
---
 tests/Makefile.sources |   1 -
 tests/gem_seqno_wrap.c | 483 -
 tests/meson.build  |   1 -
 3 files changed, 485 deletions(-)
 delete mode 100644 tests/gem_seqno_wrap.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 4f936e7..e4e06d0 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -132,7 +132,6 @@ TESTS_progs = \
gem_ring_sync_copy \
gem_ring_sync_loop \
gem_ringfill \
-   gem_seqno_wrap \
gem_set_tiling_vs_blt \
gem_set_tiling_vs_gtt \
gem_set_tiling_vs_pwrite \
diff --git a/tests/gem_seqno_wrap.c b/tests/gem_seqno_wrap.c
deleted file mode 100644
index c8cad5f..000
--- a/tests/gem_seqno_wrap.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (c) 2012 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 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- *Mika Kuoppala <mika.kuopp...@intel.com>
- *
- */
-
-/*
- * This test runs blitcopy -> rendercopy with multiple buffers over wrap
- * boundary.
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "igt.h"
-#include "igt_sysfs.h"
-#include "intel_bufmgr.h"
-
-IGT_TEST_DESCRIPTION("Runs blitcopy -> rendercopy with multiple buffers over"
-" wrap boundary.");
-
-static int drm_fd;
-static int debugfs;
-static int devid;
-static int card_index = 0;
-static uint32_t last_seqno = 0;
-
-static struct intel_batchbuffer *batch_blt;
-static struct intel_batchbuffer *batch_3d;
-
-struct option_struct {
-   int rounds;
-   int background;
-   int timeout;
-   int dontwrap;
-   int prewrap_space;
-   int random;
-   int buffers;
-};
-
-static struct option_struct options;
-
-static void init_buffer(drm_intel_bufmgr *bufmgr,
-   struct igt_buf *buf,
-   drm_intel_bo *bo,
-   int width, int height)
-{
-   /* buf->bo = drm_intel_bo_alloc(bufmgr, "", size, 4096); */
-   buf->bo = bo;
-   buf->size = width * height * 4;
-   igt_assert(buf->bo);
-   buf->tiling = I915_TILING_NONE;
-   buf->num_tiles = width * height * 4;
-   buf->stride = width * 4;
-}
-
-static void
-set_bo(drm_intel_bo *bo, uint32_t val, int width, int height)
-{
-   int size = width * height;
-   uint32_t *vaddr;
-
-   drm_intel_gem_bo_start_gtt_access(bo, true);
-   vaddr = bo->virtual;
-   while (size--)
-   *vaddr++ = val;
-}
-
-static void
-cmp_bo(drm_intel_bo *bo, uint32_t val, int width, int height)
-{
-   int size = width * height;
-   uint32_t *vaddr;
-
-   drm_intel_gem_bo_start_gtt_access(bo, false);
-   vaddr = bo->virtual;
-   while (size--) {
-   igt_assert_f(*vaddr++ == val,
-"%d: 0x%x differs from assumed 0x%x\n"
-"seqno_before_test 0x%x, "
-" approximated seqno on test fail 0x%x\n",
-width * height - size, *vaddr-1, val,
-last_seqno, last_seqno + val * 2);
-   }
-}
-
-static drm_intel_bo *
-create_bo(drm_intel_bufmgr *bufmgr, uint32_t val, int width, int height)
-{
-   drm_intel_bo *bo;
-
-   bo = drm_intel_bo_alloc(bufmgr, "bo", width * height * 4, 0);
-   igt_assert(bo);
-
-   /* gtt map doesn't have a write paramet

[Intel-gfx] [PATCH] i-g-t/tests: Drop gem_seqno_wrap, gem_pin, gem_hangcheck_forcewake

2017-10-10 Thread Abdiel Janulgue
This improves the GEM tests section of I-G-T to make it more
suitable for CI testing

Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Abdiel Janulgue <abdiel.janul...@linux.intel.com>
---
 tests/Makefile.sources  |   3 -
 tests/gem_hangcheck_forcewake.c | 123 --
 tests/gem_pin.c | 248 -
 tests/gem_seqno_wrap.c  | 483 
 tests/meson.build   |   3 -
 5 files changed, 860 deletions(-)
 delete mode 100644 tests/gem_hangcheck_forcewake.c
 delete mode 100644 tests/gem_pin.c
 delete mode 100644 tests/gem_seqno_wrap.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index bb6652e..7f52298 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -99,7 +99,6 @@ TESTS_progs = \
gem_gtt_cpu_tlb \
gem_gtt_hog \
gem_gtt_speed \
-   gem_hangcheck_forcewake \
gem_largeobject \
gem_linear_blits \
gem_lut_handle \
@@ -112,7 +111,6 @@ TESTS_progs = \
gem_mocs_settings \
gem_partial_pwrite_pread \
gem_persistent_relocs \
-   gem_pin \
gem_pipe_control_store_loop \
gem_ppgtt \
gem_pread \
@@ -134,7 +132,6 @@ TESTS_progs = \
gem_ring_sync_copy \
gem_ring_sync_loop \
gem_ringfill \
-   gem_seqno_wrap \
gem_set_tiling_vs_blt \
gem_set_tiling_vs_gtt \
gem_set_tiling_vs_pwrite \
diff --git a/tests/gem_hangcheck_forcewake.c b/tests/gem_hangcheck_forcewake.c
deleted file mode 100644
index a3e7554..000
--- a/tests/gem_hangcheck_forcewake.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright © 2011 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 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- *Daniel Vetter <daniel.vet...@ffwll.ch>
- *
- */
-
-#include "igt.h"
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "drm.h"
-#include "intel_bufmgr.h"
-
-IGT_TEST_DESCRIPTION("Provoke the hangcheck timer on an otherwise idle"
-" system.");
-
-/*
- * Testcase: Provoke the hangcheck timer on an otherwise idle system
- *
- * This tries to hit forcewake locking bugs when the hangcheck runs. Somehow we
- * often luck out and the hangcheck runs while someone else is already holding
- * the dev->struct_mutex.
- *
- * It's imperative that nothing else runs while this test runs, i.e. kill your 
X
- * session, please.
- */
-
-static drm_intel_bufmgr *bufmgr;
-struct intel_batchbuffer *batch;
-
-uint32_t blob[2048*2048];
-
-#define MAX_BLT_SIZE 128
-igt_simple_main
-{
-   drm_intel_bo *bo = NULL;
-   uint32_t tiling_mode = I915_TILING_X;
-   unsigned long pitch, act_size;
-   int fd, i, devid;
-
-   igt_skip_on_simulation();
-
-   memset(blob, 'A', sizeof(blob));
-
-   fd = drm_open_driver(DRIVER_INTEL);
-   igt_require_gem(fd);
-
-   bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
-   drm_intel_bufmgr_gem_enable_reuse(bufmgr);
-   devid = intel_get_drm_devid(fd);
-   batch = intel_batchbuffer_alloc(bufmgr, devid);
-
-   act_size = 2048;
-   igt_info("filling ring\n");
-   drm_intel_bo_unreference(bo);
-   bo = drm_intel_bo_alloc_tiled(bufmgr, "tiled bo", act_size, act_size,
- 4, _mode, , 0);
-
-   drm_intel_bo_subdata(bo, 0, act_size*act_size*4, blob);
-
-   if (IS_965(devid))
-   pitch /= 4;
-
-   for (i = 0; i < 1; i++) {
-   BLIT_COPY_BATCH_START(XY_SRC_COPY_BLT_SRC_TILED |
- XY_SRC_COPY_BLT_DST_TILED);
-   OUT_BATCH((3 << 24) | /* 32 bits */
- (0xcc << 16) | /* copy ROP 

Re: [Intel-gfx] [PATCH i-g-t 2/2] igt_core: Rework igt_system()

2017-09-25 Thread Abdiel Janulgue


On 09/21/2017 03:52 PM, Petri Latvala wrote:
> Instead of redirecting output to pipes and forking, redirect after
> forking to avoid having to carefully unredirect before logging
> anything.
> 
> igt@tools_test@sysfs_l3_parity had a racy condition where it prints
> the output of intel_l3_parity prepended by [cmd], but that ended up
> being printed again prepended by [cmd] because output was redirected,
> causing outputs to appear multiple times. This patch fixes that.
> 
> CC: Abdiel Janulgue <abdiel.janul...@linux.intel.com>
> Signed-off-by: Petri Latvala <petri.latv...@intel.com>

Thanks for fixing this. Series is
Reviewed-by: Abdiel Janulgue <abdiel.janul...@linux.intel.com>

> ---
>  lib/igt_core.c | 115 
> -
>  1 file changed, 40 insertions(+), 75 deletions(-)
> 
> diff --git a/lib/igt_core.c b/lib/igt_core.c
> index 9f4ee68b..47b4682d 100644
> --- a/lib/igt_core.c
> +++ b/lib/igt_core.c
> @@ -2237,58 +2237,23 @@ FILE *__igt_fopen_data(const char* igt_srcdir, const 
> char* igt_datadir,
>   return fp;
>  }
>  
> -struct output_pipe {
> - int output_fd;
> - int save_fd;
> - int read_fd;
> - int write_fd;
> - bool redirected;
> - enum igt_log_level log_level;
> -};
> -
> -static bool redirect_output(struct output_pipe *p, int output_fd,
> - enum igt_log_level level)
> +static void log_output(int *fd, enum igt_log_level level)
>  {
> - int fds[2];
> -
> - if (pipe(fds) == -1)
> - goto err;
> -
> - /* save output */
> - if ((p->save_fd = dup(output_fd)) == -1)
> - goto err;
> -
> - /* Redirect output to our buffer */
> - if (dup2(fds[1], output_fd) == -1)
> - goto err;
> -
> - p->output_fd = output_fd;
> - p->read_fd = fds[0];
> - p->write_fd = fds[1];
> - p->redirected = true;
> - p->log_level = level;
> -
> - return true;
> -err:
> - close(fds[0]);
> - close(fds[1]);
> - close(p->save_fd);
> + ssize_t len;
> + char buf[PIPE_BUF];
>  
> - return false;
> -}
> + if (*fd < 0)
> + return;
>  
> -static void unredirect_output(struct output_pipe *p)
> -{
> - if (!p->redirected)
> + memset(buf, 0, sizeof(buf));
> + len = read(*fd, buf, sizeof(buf));
> + if (len <= 0) {
> + close(*fd);
> + *fd = -1;
>   return;
> + }
>  
> - /* read_fd is closed separately. We still need to read its
> -  * buffered contents after un-redirecting the stream.
> -  */
> - close(p->write_fd);
> - dup2(p->save_fd, p->output_fd);
> - close(p->save_fd);
> - p->redirected = false;
> + igt_log(IGT_LOG_DOMAIN, level, "[cmd] %s", buf);
>  }
>  
>  /**
> @@ -2304,48 +2269,48 @@ static void unredirect_output(struct output_pipe *p)
>   */
>  int igt_system(const char *command)
>  {
> -#define OUT 0
> -#define ERR 1
> - struct output_pipe op[2];
> - int i, status;
> + int outpipe[2] = { -1, -1 };
> + int errpipe[2] = { -1, -1 };
> + int status;
>   struct igt_helper_process process = {};
> - char buf[PIPE_BUF];
>  
> - if (!redirect_output([OUT], STDOUT_FILENO, IGT_LOG_INFO))
> + if (pipe(outpipe) < 0)
>   goto err;
> - if (!redirect_output([ERR], STDERR_FILENO, IGT_LOG_WARN))
> + if (pipe(errpipe) < 0)
>   goto err;
>  
>   igt_fork_helper() {
> - igt_assert(execl("/bin/sh", "sh", "-c", command,
> -  (char *) NULL) != -1);
> + close(outpipe[0]);
> + close(errpipe[0]);
> +
> + if (dup2(outpipe[1], STDOUT_FILENO) < 0)
> + goto child_err;
> + if (dup2(errpipe[1], STDERR_FILENO) < 0)
> + goto child_err;
> +
> + execl("/bin/sh", "sh", "-c", command,
> +   (char *) NULL);
> +
> + child_err:
> + exit(EXIT_FAILURE);
>   }
>  
> - for (i = 0; i < ARRAY_SIZE(op); i++) {
> - struct output_pipe *current = [i];
> + close(outpipe[1]);
> + close(errpipe[1]);
>  
> - /* Unredirect so igt_log() works */
> - unredirect_output(current);
> - memset(buf, 0, sizeof(buf));
> - while (read(current->read_fd, buf, sizeof(buf)) > 0) {
> - 

Re: [Intel-gfx] [PATCH i-g-t] tools_test: Clean up and fix sysfs_l3_parity

2017-09-20 Thread Abdiel Janulgue


On 09/19/2017 02:33 PM, Petri Latvala wrote:
> Multiple misunderstandings of the expectations of the test and some
> missed parts of the shell-to-c conversion caused a couple of issues to
> remain.
> 
> First, we need to actually disable a subbank before we check that a
> subbank is disabled (invoke the tool with -d).
> 
> Second, the original pipe to wc -l was to check that the tool prints
> only one line, not that it prints "at least" a line. Modify the last
> check to verify that an "is disabled" text is _not_ printed.
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101650
> CC: Abdiel Janulgue <abdiel.janul...@linux.intel.com>
> Signed-off-by: Petri Latvala <petri.latv...@intel.com>

Reviewed-by: Abdiel Janulgue <abdiel.janul...@linux.intel.com>


> ---
>  tests/tools_test.c | 83 
> ++
>  1 file changed, 46 insertions(+), 37 deletions(-)
> 
> diff --git a/tests/tools_test.c b/tests/tools_test.c
> index 132bb88b..ed32bb29 100644
> --- a/tests/tools_test.c
> +++ b/tests/tools_test.c
> @@ -28,26 +28,31 @@
>  #include 
>  
>  struct line_check {
> - bool found;
> + int found;
>   const char *substr;
>  };
>  
>  /**
>   * Our igt_log_buffer_inspect handler. Checks the output of the
> - * intel_l3_parity tool and returns line_check::found to true if
> - * a specific substring is found.
> + * intel_l3_parity tool and increments line_check::found if a specific
> + * substring is found.
>   */
> -static bool check_cmd_return_value(const char *line, void *data)
> +static bool check_cmd_output(const char *line, void *data)
>  {
>   struct line_check *check = data;
>  
> - if (!strstr(line, check->substr)) {
> - check->found = false;
> - return false;
> + if (strstr(line, check->substr)) {
> + check->found++;
>   }
>  
> - check->found = true;
> - return true;
> + return false;
> +}
> +
> +static void assert_cmd_success(int exec_return)
> +{
> + igt_skip_on_f(exec_return == IGT_EXIT_SKIP,
> +   "intel_l3_parity not supported\n");
> + igt_assert_eq(exec_return, IGT_EXIT_SUCCESS);
>  }
>  
>  igt_main
> @@ -56,46 +61,50 @@ igt_main
>  
>   igt_subtest("sysfs_l3_parity") {
>   int exec_return;
> + struct line_check line;
>  
> + /* Sanity check that l3 parity tool is usable: Enable
> +  * row,bank,subbank 0,0,0.
> +  */
>   igt_system_cmd(exec_return,
>  "../tools/intel_l3_parity -r 0 -b 0 "
>  "-s 0 -e");
> - igt_skip_on_f(exec_return == IGT_EXIT_SKIP,
> -   "intel_l3_parity not supported\n");
> - igt_assert_eq(exec_return, IGT_EXIT_SUCCESS);
> + assert_cmd_success(exec_return);
>  
> + /* Disable row,bank,subbank 0,0,0. */
> + igt_system_cmd(exec_return, "../tools/intel_l3_parity -r 0 -b 0 
> "
> +"-s 0 -d");
> + assert_cmd_success(exec_return);
> +
> + /* Check that disabling was successful */
>   igt_system_cmd(exec_return, "../tools/intel_l3_parity -l");
> - if (exec_return == IGT_EXIT_SUCCESS) {
> - struct line_check line;
> - line.substr = "Row 0, Bank 0, Subbank 0 is disabled";
> - igt_log_buffer_inspect(check_cmd_return_value,
> -);
> - igt_assert_eq(line.found, true);
> - }
> + assert_cmd_success(exec_return);
> + line.substr = "Row 0, Bank 0, Subbank 0 is disabled";
> + line.found = 0;
> + igt_log_buffer_inspect(check_cmd_output,
> +);
> + igt_assert_eq(line.found, 1);
>  
> + /* Re-enable row,bank,subbank 0,0,0 */
>   igt_system_cmd(exec_return,
>  "../tools/intel_l3_parity -r 0 -b 0 "
>  "-s 0 -e");
> - igt_skip_on_f(exec_return == IGT_EXIT_SKIP,
> -   "intel_l3_parity not supported\n");
> - igt_assert_eq(exec_return, IGT_EXIT_SUCCESS);
> + assert_cmd_success(exec_return);
>  
> - /* Check that we can clear remaps:
> -

Re: [Intel-gfx] [PATCH i-g-t] tests/tools_test: Make sure l3_parity is supported

2017-09-13 Thread Abdiel Janulgue


On 09/13/2017 01:10 PM, Petri Latvala wrote:
> On Wed, Sep 13, 2017 at 12:24:18PM +0300, Abdiel Janulgue wrote:
>> v3: Don't pipe the output of intel_l3_parity, parse it's output
>> directly. (Petri)
>>
>> v2: Check support before executing test.
>> Skip test only if intel_l3_parity tool tells us to skip. (Petri)
>>
>> bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101650
>> Cc: Petri Latvala <petri.latv...@intel.com>
>> Signed-off-by: Abdiel Janulgue <abdiel.janul...@linux.intel.com>
>> ---
>>  tests/tools_test.c | 64 
>> ++
>>  1 file changed, 36 insertions(+), 28 deletions(-)
>>
>> diff --git a/tests/tools_test.c b/tests/tools_test.c
>> index 1baf60b..572d5f4 100644
>> --- a/tests/tools_test.c
>> +++ b/tests/tools_test.c
>> @@ -27,23 +27,26 @@
>>  #include 
>>  #include 
>>  
>> +struct line_check {
>> +bool found;
>> +const char *substr;
>> +};
>> +
>>  /**
>> - * Parse the r-value of a [cmd] string.
>> + * Our igt_log_buffer_inspect handler. Checks the output of the
>> + * intel_l3_parity tool and returns true if a specific substring
>> + * is found.
> 
> 
> The return value is for the log_buffer_inspect interface, isn't it?
> This rather sets line_check::found to true.
> 
> 
>>   */
>> -static bool check_cmd_return_value(const char *s, void *data)
>> +static bool check_cmd_return_value(const char *line, void *data)
>>  {
>> -int *val = data;
>> -char *cmd, *found;
>> -const char *delim = "[cmd]";
>> -const int delim_len = strlen(delim);
>> +struct line_check *check = data;
>>  
>> -if (!(cmd = strstr(s, delim)))
>> +if (!strstr(line, check->substr)) {
>> +check->found = false;
>>  return false;
>> +}
>>  
>> -found = cmd + delim_len + 1;
>> -igt_assert(delim_len + strlen(found) < strlen(cmd));
>> -
>> -*val = atoi(found);
>> +check->found = true;
>>  return true;
>>  }
>>  
>> @@ -57,37 +60,42 @@ igt_main
>>  igt_system_cmd(exec_return,
>> "../tools/intel_l3_parity -r 0 -b 0 "
>> "-s 0 -e");
>> -igt_assert(exec_return == IGT_EXIT_SUCCESS);
>> +igt_skip_on_f(exec_return == IGT_EXIT_SKIP,
>> +  "intel_l3_parity not supported\n");
>> +igt_assert_eq(exec_return, IGT_EXIT_SUCCESS);
>>  
>> -igt_system_cmd(exec_return,
>> -   "../tools/intel_l3_parity -l | "
>> -   "grep -c 'Row 0, Bank 0, Subbank 0 "
>> -   "is disabled'");
>> +igt_system_cmd(exec_return, "../tools/intel_l3_parity -l");
>>  if (exec_return == IGT_EXIT_SUCCESS) {
>> -int val = -1;
>> +struct line_check line;
>> +line.substr = "Row 0, Bank 0, Subbank 0 is disabled";
>>  igt_log_buffer_inspect(check_cmd_return_value,
>> -   );
>> -igt_assert(val == 1);
>> -} else {
>> -igt_fail(IGT_EXIT_FAILURE);
>> +   );
>> +igt_assert_eq(line.found, true);
>>  }
>>  
>>  igt_system_cmd(exec_return,
>> "../tools/intel_l3_parity -r 0 -b 0 "
>> "-s 0 -e");
>> -igt_assert(exec_return == IGT_EXIT_SUCCESS);
>> +igt_skip_on_f(exec_return == IGT_EXIT_SKIP,
>> +  "intel_l3_parity not supported\n");
>> +igt_assert_eq(exec_return, IGT_EXIT_SUCCESS);
>>  
>> -/* Check that we can clear remaps */
>> +/* Check that we can clear remaps:
>> + * In the original shell script, the output of intel_l3_parity 
>> -l
>> + * was piped thru wc -l to check if the tool would at least
>> + * return a line. Just watch for one of the expected output
>> + * string as an alternative.
> 
> 
> This is an excellent change.
> 
> 
>> + * ("is disabled" unique only to intel_l3_parity.c:dumpit())
>> + */
>>  igt_system_cmd(exec_return,
>> "../tools/intel_l3_parity -l | "
>> "wc -l");
> 
> ...but you still left the piping to wc -l here. :P
> 

Oops. Fix coming, thanks for the review!
> 
> 
> 
> With those fixed, this is
> 
> Reviewed-by: Petri Latvala <petri.latv...@intel.com>
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH i-g-t] tests/tools_test: Make sure l3_parity is supported

2017-09-13 Thread Abdiel Janulgue
v3: Don't pipe the output of intel_l3_parity, parse it's output
directly. (Petri)

v2: Check support before executing test.
Skip test only if intel_l3_parity tool tells us to skip. (Petri)

bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101650
Cc: Petri Latvala <petri.latv...@intel.com>
Signed-off-by: Abdiel Janulgue <abdiel.janul...@linux.intel.com>
---
 tests/tools_test.c | 64 ++
 1 file changed, 36 insertions(+), 28 deletions(-)

diff --git a/tests/tools_test.c b/tests/tools_test.c
index 1baf60b..572d5f4 100644
--- a/tests/tools_test.c
+++ b/tests/tools_test.c
@@ -27,23 +27,26 @@
 #include 
 #include 
 
+struct line_check {
+   bool found;
+   const char *substr;
+};
+
 /**
- * Parse the r-value of a [cmd] string.
+ * Our igt_log_buffer_inspect handler. Checks the output of the
+ * intel_l3_parity tool and returns true if a specific substring
+ * is found.
  */
-static bool check_cmd_return_value(const char *s, void *data)
+static bool check_cmd_return_value(const char *line, void *data)
 {
-   int *val = data;
-   char *cmd, *found;
-   const char *delim = "[cmd]";
-   const int delim_len = strlen(delim);
+   struct line_check *check = data;
 
-   if (!(cmd = strstr(s, delim)))
+   if (!strstr(line, check->substr)) {
+   check->found = false;
return false;
+   }
 
-   found = cmd + delim_len + 1;
-   igt_assert(delim_len + strlen(found) < strlen(cmd));
-
-   *val = atoi(found);
+   check->found = true;
return true;
 }
 
@@ -57,37 +60,42 @@ igt_main
igt_system_cmd(exec_return,
   "../tools/intel_l3_parity -r 0 -b 0 "
   "-s 0 -e");
-   igt_assert(exec_return == IGT_EXIT_SUCCESS);
+   igt_skip_on_f(exec_return == IGT_EXIT_SKIP,
+ "intel_l3_parity not supported\n");
+   igt_assert_eq(exec_return, IGT_EXIT_SUCCESS);
 
-   igt_system_cmd(exec_return,
-  "../tools/intel_l3_parity -l | "
-  "grep -c 'Row 0, Bank 0, Subbank 0 "
-  "is disabled'");
+   igt_system_cmd(exec_return, "../tools/intel_l3_parity -l");
if (exec_return == IGT_EXIT_SUCCESS) {
-   int val = -1;
+   struct line_check line;
+   line.substr = "Row 0, Bank 0, Subbank 0 is disabled";
igt_log_buffer_inspect(check_cmd_return_value,
-  );
-   igt_assert(val == 1);
-   } else {
-   igt_fail(IGT_EXIT_FAILURE);
+  );
+   igt_assert_eq(line.found, true);
}
 
igt_system_cmd(exec_return,
   "../tools/intel_l3_parity -r 0 -b 0 "
   "-s 0 -e");
-   igt_assert(exec_return == IGT_EXIT_SUCCESS);
+   igt_skip_on_f(exec_return == IGT_EXIT_SKIP,
+ "intel_l3_parity not supported\n");
+   igt_assert_eq(exec_return, IGT_EXIT_SUCCESS);
 
-   /* Check that we can clear remaps */
+   /* Check that we can clear remaps:
+* In the original shell script, the output of intel_l3_parity 
-l
+* was piped thru wc -l to check if the tool would at least
+* return a line. Just watch for one of the expected output
+* string as an alternative.
+* ("is disabled" unique only to intel_l3_parity.c:dumpit())
+*/
igt_system_cmd(exec_return,
   "../tools/intel_l3_parity -l | "
   "wc -l");
if (exec_return == IGT_EXIT_SUCCESS) {
-   int val = -1;
+   struct line_check line;
+   line.substr = "is disabled";
igt_log_buffer_inspect(check_cmd_return_value,
-  );
-   igt_assert(val == 1);
-   } else {
-   igt_fail(IGT_EXIT_FAILURE);
+  );
+   igt_assert_eq(line.found, true);
}
}
 
-- 
2.9.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


  1   2   3   >