dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] drm/lima: add heap buffer support
@ 2020-01-16 13:11 Qiang Yu
  2020-01-16 13:11 ` [PATCH 1/5] drm/lima: update register info Qiang Yu
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Qiang Yu @ 2020-01-16 13:11 UTC (permalink / raw)
  To: dri-devel
  Cc: lima, David Airlie, Vasily Khoruzhick, Andreas Baierl, Qiang Yu,
	Erico Nunes

Support heap buffer allocation which can grow the back memory
size when GP has an out of memory interrupt so that user don't
need to allocate a very large buffer at the beginning.

Qiang Yu (5):
  drm/lima: update register info
  drm/lima: add lima_vm_map_bo
  drm/lima: support heap buffer creation
  drm/lima: recover task by enlarging heap buffer
  drm/lima: increase driver version to 1.1

 drivers/gpu/drm/lima/lima_drv.c   |  16 +++-
 drivers/gpu/drm/lima/lima_drv.h   |   1 +
 drivers/gpu/drm/lima/lima_gem.c   | 130 ++++++++++++++++++++++++++++--
 drivers/gpu/drm/lima/lima_gem.h   |   4 +
 drivers/gpu/drm/lima/lima_gp.c    |  51 +++++++++++-
 drivers/gpu/drm/lima/lima_mmu.c   |   5 ++
 drivers/gpu/drm/lima/lima_mmu.h   |   1 +
 drivers/gpu/drm/lima/lima_regs.h  |   1 +
 drivers/gpu/drm/lima/lima_sched.c |  35 ++++++--
 drivers/gpu/drm/lima/lima_sched.h |   6 ++
 drivers/gpu/drm/lima/lima_vm.c    |  44 +++++++++-
 drivers/gpu/drm/lima/lima_vm.h    |   1 +
 include/uapi/drm/lima_drm.h       |   9 ++-
 13 files changed, 284 insertions(+), 20 deletions(-)

-- 
2.17.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/5] drm/lima: update register info
  2020-01-16 13:11 [PATCH 0/5] drm/lima: add heap buffer support Qiang Yu
@ 2020-01-16 13:11 ` Qiang Yu
  2020-01-16 13:11 ` [PATCH 2/5] drm/lima: add lima_vm_map_bo Qiang Yu
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Qiang Yu @ 2020-01-16 13:11 UTC (permalink / raw)
  To: dri-devel
  Cc: lima, David Airlie, Vasily Khoruzhick, Andreas Baierl, Qiang Yu,
	Erico Nunes

From Mali r10p0 kernel driver source code.

Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
 drivers/gpu/drm/lima/lima_regs.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/lima/lima_regs.h b/drivers/gpu/drm/lima/lima_regs.h
index ace8ecefbe90..0124c90e0153 100644
--- a/drivers/gpu/drm/lima/lima_regs.h
+++ b/drivers/gpu/drm/lima/lima_regs.h
@@ -239,6 +239,7 @@
 #define   LIMA_MMU_STATUS_REPLAY_BUFFER_EMPTY BIT(4)
 #define   LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE BIT(5)
 #define   LIMA_MMU_STATUS_BUS_ID(x)           ((x >> 6) & 0x1F)
+#define   LIMA_MMU_STATUS_STALL_NOT_ACTIVE    BIT(31)
 #define LIMA_MMU_COMMAND                      0x0008
 #define   LIMA_MMU_COMMAND_ENABLE_PAGING      0x00
 #define   LIMA_MMU_COMMAND_DISABLE_PAGING     0x01
-- 
2.17.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/5] drm/lima: add lima_vm_map_bo
  2020-01-16 13:11 [PATCH 0/5] drm/lima: add heap buffer support Qiang Yu
  2020-01-16 13:11 ` [PATCH 1/5] drm/lima: update register info Qiang Yu
@ 2020-01-16 13:11 ` Qiang Yu
  2020-01-16 13:11 ` [PATCH 3/5] drm/lima: support heap buffer creation Qiang Yu
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Qiang Yu @ 2020-01-16 13:11 UTC (permalink / raw)
  To: dri-devel
  Cc: lima, David Airlie, Vasily Khoruzhick, Andreas Baierl, Qiang Yu,
	Erico Nunes

For dynamically mapping added backup memory of lima_bo to vm.
This is a preparation for adding heap buffer support.

Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
 drivers/gpu/drm/lima/lima_vm.c | 40 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/lima/lima_vm.h |  1 +
 2 files changed, 41 insertions(+)

diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c
index 840e2350d872..d46f2a69ab42 100644
--- a/drivers/gpu/drm/lima/lima_vm.c
+++ b/drivers/gpu/drm/lima/lima_vm.c
@@ -277,3 +277,43 @@ void lima_vm_print(struct lima_vm *vm)
 		}
 	}
 }
+
+int lima_vm_map_bo(struct lima_vm *vm, struct lima_bo *bo, int pageoff)
+{
+	struct lima_bo_va *bo_va;
+	struct sg_dma_page_iter sg_iter;
+	int offset = 0, err;
+	u32 base;
+
+	mutex_lock(&bo->lock);
+
+	bo_va = lima_vm_bo_find(vm, bo);
+	if (!bo_va) {
+		err = -ENOENT;
+		goto err_out0;
+	}
+
+	mutex_lock(&vm->lock);
+
+	base = bo_va->node.start + (pageoff << PAGE_SHIFT);
+	for_each_sg_dma_page(bo->base.sgt->sgl, &sg_iter, bo->base.sgt->nents, pageoff) {
+		err = lima_vm_map_page(vm, sg_page_iter_dma_address(&sg_iter), base + offset);
+		if (err)
+			goto err_out1;
+
+		offset += PAGE_SIZE;
+	}
+
+	mutex_unlock(&vm->lock);
+
+	mutex_unlock(&bo->lock);
+	return 0;
+
+err_out1:
+	if (offset)
+		lima_vm_unmap_range(vm, base, base + offset - 1);
+	mutex_unlock(&vm->lock);
+err_out0:
+	mutex_unlock(&bo->lock);
+	return err;
+}
diff --git a/drivers/gpu/drm/lima/lima_vm.h b/drivers/gpu/drm/lima/lima_vm.h
index e0bdedcf14dd..22aeec77d84d 100644
--- a/drivers/gpu/drm/lima/lima_vm.h
+++ b/drivers/gpu/drm/lima/lima_vm.h
@@ -58,5 +58,6 @@ static inline void lima_vm_put(struct lima_vm *vm)
 }
 
 void lima_vm_print(struct lima_vm *vm);
+int lima_vm_map_bo(struct lima_vm *vm, struct lima_bo *bo, int pageoff);
 
 #endif
-- 
2.17.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/5] drm/lima: support heap buffer creation
  2020-01-16 13:11 [PATCH 0/5] drm/lima: add heap buffer support Qiang Yu
  2020-01-16 13:11 ` [PATCH 1/5] drm/lima: update register info Qiang Yu
  2020-01-16 13:11 ` [PATCH 2/5] drm/lima: add lima_vm_map_bo Qiang Yu
@ 2020-01-16 13:11 ` Qiang Yu
  2020-01-16 13:11 ` [PATCH 4/5] drm/lima: recover task by enlarging heap buffer Qiang Yu
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Qiang Yu @ 2020-01-16 13:11 UTC (permalink / raw)
  To: dri-devel
  Cc: lima, David Airlie, Vasily Khoruzhick, Andreas Baierl, Qiang Yu,
	Erico Nunes

heap buffer is used as output of GP and input of PP for
Mali Utgard GPU. Size of heap buffer depends on the task
so is a runtime variable.

Previously we just create a large enough buffer as heap
buffer. Now we add a heap buffer type to be able to
increase the backup memory dynamically when GP fail due
to lack of heap memory.

Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
 drivers/gpu/drm/lima/lima_drv.c |   6 +-
 drivers/gpu/drm/lima/lima_drv.h |   1 +
 drivers/gpu/drm/lima/lima_gem.c | 130 ++++++++++++++++++++++++++++++--
 drivers/gpu/drm/lima/lima_gem.h |   4 +
 drivers/gpu/drm/lima/lima_vm.c  |   4 +-
 include/uapi/drm/lima_drm.h     |   9 ++-
 6 files changed, 143 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c
index 124efe4fa97b..18f88aaef1a2 100644
--- a/drivers/gpu/drm/lima/lima_drv.c
+++ b/drivers/gpu/drm/lima/lima_drv.c
@@ -15,10 +15,14 @@
 #include "lima_vm.h"
 
 int lima_sched_timeout_ms;
+uint lima_heap_init_nr_pages = 8;
 
 MODULE_PARM_DESC(sched_timeout_ms, "task run timeout in ms");
 module_param_named(sched_timeout_ms, lima_sched_timeout_ms, int, 0444);
 
+MODULE_PARM_DESC(heap_init_nr_pages, "heap buffer init number of pages");
+module_param_named(heap_init_nr_pages, lima_heap_init_nr_pages, uint, 0444);
+
 static int lima_ioctl_get_param(struct drm_device *dev, void *data, struct drm_file *file)
 {
 	struct drm_lima_get_param *args = data;
@@ -68,7 +72,7 @@ static int lima_ioctl_gem_create(struct drm_device *dev, void *data, struct drm_
 	if (args->pad)
 		return -EINVAL;
 
-	if (args->flags)
+	if (args->flags & ~(LIMA_BO_FLAG_HEAP))
 		return -EINVAL;
 
 	if (args->size == 0)
diff --git a/drivers/gpu/drm/lima/lima_drv.h b/drivers/gpu/drm/lima/lima_drv.h
index 69c7344715c9..f492ecc6a5d9 100644
--- a/drivers/gpu/drm/lima/lima_drv.h
+++ b/drivers/gpu/drm/lima/lima_drv.h
@@ -9,6 +9,7 @@
 #include "lima_ctx.h"
 
 extern int lima_sched_timeout_ms;
+extern uint lima_heap_init_nr_pages;
 
 struct lima_vm;
 struct lima_bo;
diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
index d0059d8c97d8..24e1a086d5fe 100644
--- a/drivers/gpu/drm/lima/lima_gem.c
+++ b/drivers/gpu/drm/lima/lima_gem.c
@@ -4,6 +4,8 @@
 #include <linux/mm.h>
 #include <linux/sync_file.h>
 #include <linux/pagemap.h>
+#include <linux/shmem_fs.h>
+#include <linux/dma-mapping.h>
 
 #include <drm/drm_file.h>
 #include <drm/drm_syncobj.h>
@@ -15,6 +17,80 @@
 #include "lima_gem.h"
 #include "lima_vm.h"
 
+int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
+{
+	struct page **pages;
+	struct address_space *mapping = bo->base.base.filp->f_mapping;
+	struct device *dev = bo->base.base.dev->dev;
+	size_t old_size = bo->heap_size;
+	size_t new_size = bo->heap_size ? bo->heap_size * 2 :
+		(lima_heap_init_nr_pages << PAGE_SHIFT);
+	struct sg_table sgt;
+	int i, ret;
+
+	if (bo->heap_size >= bo->base.base.size)
+		return -ENOSPC;
+
+	new_size = min(new_size, bo->base.base.size);
+
+	mutex_lock(&bo->base.pages_lock);
+
+	if (bo->base.pages)
+		pages = bo->base.pages;
+	else {
+		pages = kvmalloc_array(bo->base.base.size >> PAGE_SHIFT,
+				       sizeof(*pages), GFP_KERNEL | __GFP_ZERO);
+		if (!pages) {
+			mutex_unlock(&bo->base.pages_lock);
+			return -ENOMEM;
+		}
+
+		bo->base.pages = pages;
+		bo->base.pages_use_count = 1;
+
+		mapping_set_unevictable(mapping);
+	}
+
+	for (i = old_size >> PAGE_SHIFT; i < new_size >> PAGE_SHIFT; i++) {
+		struct page *page = shmem_read_mapping_page(mapping, i);
+		if (IS_ERR(page)) {
+			mutex_unlock(&bo->base.pages_lock);
+			return PTR_ERR(page);
+		}
+		pages[i] = page;
+	}
+
+	mutex_unlock(&bo->base.pages_lock);
+
+	ret = sg_alloc_table_from_pages(&sgt, pages, i, 0, new_size, GFP_KERNEL);
+	if (ret)
+		return ret;
+
+	if (bo->base.sgt) {
+		dma_unmap_sg(dev, bo->base.sgt->sgl, bo->base.sgt->nents, DMA_BIDIRECTIONAL);
+		sg_free_table(bo->base.sgt);
+	} else {
+		bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL);
+		if (!bo->base.sgt) {
+			sg_free_table(&sgt);
+			return -ENOMEM;
+		}
+	}
+
+	dma_map_sg(dev, sgt.sgl, sgt.nents, DMA_BIDIRECTIONAL);
+
+	*bo->base.sgt = sgt;
+
+	if (vm) {
+		ret = lima_vm_map_bo(vm, bo, old_size >> PAGE_SHIFT);
+		if (ret)
+			return ret;
+	}
+
+	bo->heap_size = new_size;
+	return 0;
+}
+
 int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file,
 			   u32 size, u32 flags, u32 *handle)
 {
@@ -22,7 +98,8 @@ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file,
 	gfp_t mask;
 	struct drm_gem_shmem_object *shmem;
 	struct drm_gem_object *obj;
-	struct sg_table *sgt;
+	struct lima_bo *bo;
+	bool is_heap = flags & LIMA_BO_FLAG_HEAP;
 
 	shmem = drm_gem_shmem_create(dev, size);
 	if (IS_ERR(shmem))
@@ -36,10 +113,17 @@ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file,
 	mask |= __GFP_DMA32;
 	mapping_set_gfp_mask(obj->filp->f_mapping, mask);
 
-	sgt = drm_gem_shmem_get_pages_sgt(obj);
-	if (IS_ERR(sgt)) {
-		err = PTR_ERR(sgt);
-		goto out;
+	if (is_heap) {
+		bo = to_lima_bo(obj);
+		err = lima_heap_alloc(bo, NULL);
+		if (err)
+			goto out;
+	} else {
+		struct sg_table *sgt = drm_gem_shmem_get_pages_sgt(obj);
+		if (IS_ERR(sgt)) {
+			err = PTR_ERR(sgt);
+			goto out;
+		}
 	}
 
 	err = drm_gem_handle_create(file, obj, handle);
@@ -79,17 +163,47 @@ static void lima_gem_object_close(struct drm_gem_object *obj, struct drm_file *f
 	lima_vm_bo_del(vm, bo);
 }
 
+static int lima_gem_pin(struct drm_gem_object *obj)
+{
+	struct lima_bo *bo = to_lima_bo(obj);
+
+	if (bo->heap_size)
+		return -EINVAL;
+
+	return drm_gem_shmem_pin(obj);
+}
+
+static void *lima_gem_vmap(struct drm_gem_object *obj)
+{
+	struct lima_bo *bo = to_lima_bo(obj);
+
+	if (bo->heap_size)
+		return ERR_PTR(-EINVAL);
+
+	return drm_gem_shmem_vmap(obj);
+}
+
+static int lima_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
+{
+	struct lima_bo *bo = to_lima_bo(obj);
+
+	if (bo->heap_size)
+		return -EINVAL;
+
+	return drm_gem_shmem_mmap(obj, vma);
+}
+
 static const struct drm_gem_object_funcs lima_gem_funcs = {
 	.free = lima_gem_free_object,
 	.open = lima_gem_object_open,
 	.close = lima_gem_object_close,
 	.print_info = drm_gem_shmem_print_info,
-	.pin = drm_gem_shmem_pin,
+	.pin = lima_gem_pin,
 	.unpin = drm_gem_shmem_unpin,
 	.get_sg_table = drm_gem_shmem_get_sg_table,
-	.vmap = drm_gem_shmem_vmap,
+	.vmap = lima_gem_vmap,
 	.vunmap = drm_gem_shmem_vunmap,
-	.mmap = drm_gem_shmem_mmap,
+	.mmap = lima_gem_mmap,
 };
 
 struct drm_gem_object *lima_gem_create_object(struct drm_device *dev, size_t size)
diff --git a/drivers/gpu/drm/lima/lima_gem.h b/drivers/gpu/drm/lima/lima_gem.h
index 1800feb3e47f..ccea06142f4b 100644
--- a/drivers/gpu/drm/lima/lima_gem.h
+++ b/drivers/gpu/drm/lima/lima_gem.h
@@ -7,12 +7,15 @@
 #include <drm/drm_gem_shmem_helper.h>
 
 struct lima_submit;
+struct lima_vm;
 
 struct lima_bo {
 	struct drm_gem_shmem_object base;
 
 	struct mutex lock;
 	struct list_head va;
+
+	size_t heap_size;
 };
 
 static inline struct lima_bo *
@@ -31,6 +34,7 @@ static inline struct dma_resv *lima_bo_resv(struct lima_bo *bo)
 	return bo->base.base.resv;
 }
 
+int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm);
 struct drm_gem_object *lima_gem_create_object(struct drm_device *dev, size_t size);
 int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file,
 			   u32 size, u32 flags, u32 *handle);
diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c
index d46f2a69ab42..dff97502ca36 100644
--- a/drivers/gpu/drm/lima/lima_vm.c
+++ b/drivers/gpu/drm/lima/lima_vm.c
@@ -155,6 +155,7 @@ int lima_vm_bo_add(struct lima_vm *vm, struct lima_bo *bo, bool create)
 void lima_vm_bo_del(struct lima_vm *vm, struct lima_bo *bo)
 {
 	struct lima_bo_va *bo_va;
+	u32 size;
 
 	mutex_lock(&bo->lock);
 
@@ -166,8 +167,9 @@ void lima_vm_bo_del(struct lima_vm *vm, struct lima_bo *bo)
 
 	mutex_lock(&vm->lock);
 
+	size = bo->heap_size ? bo->heap_size : bo_va->node.size;
 	lima_vm_unmap_range(vm, bo_va->node.start,
-			    bo_va->node.start + bo_va->node.size - 1);
+			    bo_va->node.start + size - 1);
 
 	drm_mm_remove_node(&bo_va->node);
 
diff --git a/include/uapi/drm/lima_drm.h b/include/uapi/drm/lima_drm.h
index 95a00fb867e6..1ec58d652a5a 100644
--- a/include/uapi/drm/lima_drm.h
+++ b/include/uapi/drm/lima_drm.h
@@ -32,12 +32,19 @@ struct drm_lima_get_param {
 	__u64 value; /* out, parameter value */
 };
 
+/*
+ * heap buffer dynamically increase backup memory size when GP task fail
+ * due to lack of heap memory. size field of heap buffer is an up bound of
+ * the backup memory which can be set to a fairly large value.
+ */
+#define LIMA_BO_FLAG_HEAP  (1 << 0)
+
 /**
  * create a buffer for used by GPU
  */
 struct drm_lima_gem_create {
 	__u32 size;    /* in, buffer size */
-	__u32 flags;   /* in, currently no flags, must be zero */
+	__u32 flags;   /* in, buffer flags */
 	__u32 handle;  /* out, GEM buffer handle */
 	__u32 pad;     /* pad, must be zero */
 };
-- 
2.17.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/5] drm/lima: recover task by enlarging heap buffer
  2020-01-16 13:11 [PATCH 0/5] drm/lima: add heap buffer support Qiang Yu
                   ` (2 preceding siblings ...)
  2020-01-16 13:11 ` [PATCH 3/5] drm/lima: support heap buffer creation Qiang Yu
@ 2020-01-16 13:11 ` Qiang Yu
  2020-01-16 13:11 ` [PATCH 5/5] drm/lima: increase driver version to 1.1 Qiang Yu
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Qiang Yu @ 2020-01-16 13:11 UTC (permalink / raw)
  To: dri-devel
  Cc: lima, David Airlie, Vasily Khoruzhick, Andreas Baierl, Qiang Yu,
	Erico Nunes

Increase heap buffer backup memory when GP receive PLBU
out of memory interrupt, then resume the task.

Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
 drivers/gpu/drm/lima/lima_gp.c    | 51 +++++++++++++++++++++++++++++--
 drivers/gpu/drm/lima/lima_mmu.c   |  5 +++
 drivers/gpu/drm/lima/lima_mmu.h   |  1 +
 drivers/gpu/drm/lima/lima_sched.c | 35 ++++++++++++++++++---
 drivers/gpu/drm/lima/lima_sched.h |  6 ++++
 5 files changed, 91 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c
index ccf49faedebf..d1e7826c2d74 100644
--- a/drivers/gpu/drm/lima/lima_gp.c
+++ b/drivers/gpu/drm/lima/lima_gp.c
@@ -11,6 +11,8 @@
 #include "lima_device.h"
 #include "lima_gp.h"
 #include "lima_regs.h"
+#include "lima_gem.h"
+#include "lima_vm.h"
 
 #define gp_write(reg, data) writel(data, ip->iomem + reg)
 #define gp_read(reg) readl(ip->iomem + reg)
@@ -20,6 +22,7 @@ static irqreturn_t lima_gp_irq_handler(int irq, void *data)
 	struct lima_ip *ip = data;
 	struct lima_device *dev = ip->dev;
 	struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp;
+	struct lima_sched_task *task = pipe->current_task;
 	u32 state = gp_read(LIMA_GP_INT_STAT);
 	u32 status = gp_read(LIMA_GP_STATUS);
 	bool done = false;
@@ -29,8 +32,14 @@ static irqreturn_t lima_gp_irq_handler(int irq, void *data)
 		return IRQ_NONE;
 
 	if (state & LIMA_GP_IRQ_MASK_ERROR) {
-		dev_err(dev->dev, "gp error irq state=%x status=%x\n",
-			state, status);
+		if ((state & LIMA_GP_IRQ_MASK_ERROR) == LIMA_GP_IRQ_PLBU_OUT_OF_MEM)
+			dev_dbg(dev->dev, "gp out of heap irq status=%x\n", status);
+		else {
+			dev_err(dev->dev, "gp error irq state=%x status=%x\n",
+				state, status);
+			if (task)
+				task->recoverable = false;
+		}
 
 		/* mask all interrupts before hard reset */
 		gp_write(LIMA_GP_INT_MASK, 0);
@@ -43,6 +52,7 @@ static irqreturn_t lima_gp_irq_handler(int irq, void *data)
 		bool active = status & (LIMA_GP_STATUS_VS_ACTIVE |
 					LIMA_GP_STATUS_PLBU_ACTIVE);
 		done = valid && !active;
+		pipe->error = false;
 	}
 
 	gp_write(LIMA_GP_INT_CLEAR, state);
@@ -121,6 +131,19 @@ static void lima_gp_task_run(struct lima_sched_pipe *pipe,
 	u32 cmd = 0;
 	int i;
 
+	/* update real heap buffer size for GP */
+	for (i = 0; i < task->num_bos; i++) {
+		struct lima_bo *bo = task->bos[i];
+		if (bo->heap_size &&
+		    lima_vm_get_va(task->vm, bo) == f[LIMA_GP_PLBU_ALLOC_START_ADDR >> 2]) {
+			f[LIMA_GP_PLBU_ALLOC_END_ADDR >> 2] =
+				f[LIMA_GP_PLBU_ALLOC_START_ADDR >> 2] + bo->heap_size;
+			task->recoverable = true;
+			task->heap = bo;
+			break;
+		}
+	}
+
 	if (f[LIMA_GP_VSCL_START_ADDR >> 2] !=
 	    f[LIMA_GP_VSCL_END_ADDR >> 2])
 		cmd |= LIMA_GP_CMD_START_VS;
@@ -184,6 +207,29 @@ static void lima_gp_task_mmu_error(struct lima_sched_pipe *pipe)
 	lima_sched_pipe_task_done(pipe);
 }
 
+static int lima_gp_task_recover(struct lima_sched_pipe *pipe)
+{
+	struct lima_ip *ip = pipe->processor[0];
+	struct lima_sched_task *task = pipe->current_task;
+	struct drm_lima_gp_frame *frame = task->frame;
+	u32 *f = frame->frame;
+	size_t fail_size =
+		f[LIMA_GP_PLBU_ALLOC_END_ADDR >> 2] -
+		f[LIMA_GP_PLBU_ALLOC_START_ADDR >> 2];
+
+	if (fail_size == task->heap->heap_size) {
+		int ret = lima_heap_alloc(task->heap, task->vm);
+		if (ret < 0)
+			return ret;
+	}
+
+	gp_write(LIMA_GP_INT_MASK, LIMA_GP_IRQ_MASK_USED);
+	gp_write(LIMA_GP_PLBU_ALLOC_END_ADDR,
+		 f[LIMA_GP_PLBU_ALLOC_START_ADDR >> 2] + task->heap->heap_size);
+	gp_write(LIMA_GP_CMD, LIMA_GP_CMD_UPDATE_PLBU_ALLOC);
+	return 0;
+}
+
 static void lima_gp_print_version(struct lima_ip *ip)
 {
 	u32 version, major, minor;
@@ -270,6 +316,7 @@ int lima_gp_pipe_init(struct lima_device *dev)
 	pipe->task_fini = lima_gp_task_fini;
 	pipe->task_error = lima_gp_task_error;
 	pipe->task_mmu_error = lima_gp_task_mmu_error;
+	pipe->task_recover = lima_gp_task_recover;
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/lima/lima_mmu.c b/drivers/gpu/drm/lima/lima_mmu.c
index 97ec09dee572..f79d2af427e7 100644
--- a/drivers/gpu/drm/lima/lima_mmu.c
+++ b/drivers/gpu/drm/lima/lima_mmu.c
@@ -99,6 +99,11 @@ void lima_mmu_fini(struct lima_ip *ip)
 
 }
 
+void lima_mmu_flush_tlb(struct lima_ip *ip)
+{
+	mmu_write(LIMA_MMU_COMMAND, LIMA_MMU_COMMAND_ZAP_CACHE);
+}
+
 void lima_mmu_switch_vm(struct lima_ip *ip, struct lima_vm *vm)
 {
 	struct lima_device *dev = ip->dev;
diff --git a/drivers/gpu/drm/lima/lima_mmu.h b/drivers/gpu/drm/lima/lima_mmu.h
index 8c78319bcc8e..4f8ccbebcba1 100644
--- a/drivers/gpu/drm/lima/lima_mmu.h
+++ b/drivers/gpu/drm/lima/lima_mmu.h
@@ -10,6 +10,7 @@ struct lima_vm;
 int lima_mmu_init(struct lima_ip *ip);
 void lima_mmu_fini(struct lima_ip *ip);
 
+void lima_mmu_flush_tlb(struct lima_ip *ip);
 void lima_mmu_switch_vm(struct lima_ip *ip, struct lima_vm *vm);
 void lima_mmu_page_fault_resume(struct lima_ip *ip);
 
diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c
index a31a90c380b6..117f1c8408a1 100644
--- a/drivers/gpu/drm/lima/lima_sched.c
+++ b/drivers/gpu/drm/lima/lima_sched.c
@@ -312,6 +312,26 @@ static const struct drm_sched_backend_ops lima_sched_ops = {
 	.free_job = lima_sched_free_job,
 };
 
+static void lima_sched_recover_work(struct work_struct *work)
+{
+	struct lima_sched_pipe *pipe =
+		container_of(work, struct lima_sched_pipe, recover_work);
+	int i;
+
+	for (i = 0; i < pipe->num_l2_cache; i++)
+		lima_l2_cache_flush(pipe->l2_cache[i]);
+
+	if (pipe->bcast_mmu)
+		lima_mmu_flush_tlb(pipe->bcast_mmu);
+	else {
+		for (i = 0; i < pipe->num_mmu; i++)
+			lima_mmu_flush_tlb(pipe->mmu[i]);
+	}
+
+	if (pipe->task_recover(pipe))
+		drm_sched_fault(&pipe->base);
+}
+
 int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name)
 {
 	unsigned int timeout = lima_sched_timeout_ms > 0 ?
@@ -320,6 +340,8 @@ int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name)
 	pipe->fence_context = dma_fence_context_alloc(1);
 	spin_lock_init(&pipe->fence_lock);
 
+	INIT_WORK(&pipe->recover_work, lima_sched_recover_work);
+
 	return drm_sched_init(&pipe->base, &lima_sched_ops, 1, 0,
 			      msecs_to_jiffies(timeout), name);
 }
@@ -331,11 +353,14 @@ void lima_sched_pipe_fini(struct lima_sched_pipe *pipe)
 
 void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe)
 {
-	if (pipe->error)
-		drm_sched_fault(&pipe->base);
-	else {
-		struct lima_sched_task *task = pipe->current_task;
-
+	struct lima_sched_task *task = pipe->current_task;
+
+	if (pipe->error) {
+		if (task && task->recoverable)
+			schedule_work(&pipe->recover_work);
+		else
+			drm_sched_fault(&pipe->base);
+	} else {
 		pipe->task_fini(pipe);
 		dma_fence_signal(task->fence);
 	}
diff --git a/drivers/gpu/drm/lima/lima_sched.h b/drivers/gpu/drm/lima/lima_sched.h
index 1d814fecbcc0..d64393fb50a9 100644
--- a/drivers/gpu/drm/lima/lima_sched.h
+++ b/drivers/gpu/drm/lima/lima_sched.h
@@ -20,6 +20,9 @@ struct lima_sched_task {
 	struct lima_bo **bos;
 	int num_bos;
 
+	bool recoverable;
+	struct lima_bo *heap;
+
 	/* pipe fence */
 	struct dma_fence *fence;
 };
@@ -68,6 +71,9 @@ struct lima_sched_pipe {
 	void (*task_fini)(struct lima_sched_pipe *pipe);
 	void (*task_error)(struct lima_sched_pipe *pipe);
 	void (*task_mmu_error)(struct lima_sched_pipe *pipe);
+	int (*task_recover)(struct lima_sched_pipe *pipe);
+
+	struct work_struct recover_work;
 };
 
 int lima_sched_task_init(struct lima_sched_task *task,
-- 
2.17.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/5] drm/lima: increase driver version to 1.1
  2020-01-16 13:11 [PATCH 0/5] drm/lima: add heap buffer support Qiang Yu
                   ` (3 preceding siblings ...)
  2020-01-16 13:11 ` [PATCH 4/5] drm/lima: recover task by enlarging heap buffer Qiang Yu
@ 2020-01-16 13:11 ` Qiang Yu
  2020-01-26 20:24 ` [PATCH 0/5] drm/lima: add heap buffer support Vasily Khoruzhick
  2020-01-27 10:21 ` Andreas Baierl
  6 siblings, 0 replies; 9+ messages in thread
From: Qiang Yu @ 2020-01-16 13:11 UTC (permalink / raw)
  To: dri-devel
  Cc: lima, David Airlie, Vasily Khoruzhick, Andreas Baierl, Qiang Yu,
	Erico Nunes

Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
 drivers/gpu/drm/lima/lima_drv.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c
index 18f88aaef1a2..2daac64d8955 100644
--- a/drivers/gpu/drm/lima/lima_drv.c
+++ b/drivers/gpu/drm/lima/lima_drv.c
@@ -245,6 +245,12 @@ static const struct drm_ioctl_desc lima_drm_driver_ioctls[] = {
 
 DEFINE_DRM_GEM_FOPS(lima_drm_driver_fops);
 
+/**
+ * Changelog:
+ *
+ * - 1.1.0 - add heap buffer support
+ */
+
 static struct drm_driver lima_drm_driver = {
 	.driver_features    = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ,
 	.open               = lima_drm_driver_open,
@@ -254,9 +260,9 @@ static struct drm_driver lima_drm_driver = {
 	.fops               = &lima_drm_driver_fops,
 	.name               = "lima",
 	.desc               = "lima DRM",
-	.date               = "20190217",
+	.date               = "20191231",
 	.major              = 1,
-	.minor              = 0,
+	.minor              = 1,
 	.patchlevel         = 0,
 
 	.gem_create_object  = lima_gem_create_object,
-- 
2.17.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/5] drm/lima: add heap buffer support
  2020-01-16 13:11 [PATCH 0/5] drm/lima: add heap buffer support Qiang Yu
                   ` (4 preceding siblings ...)
  2020-01-16 13:11 ` [PATCH 5/5] drm/lima: increase driver version to 1.1 Qiang Yu
@ 2020-01-26 20:24 ` Vasily Khoruzhick
  2020-01-27 10:21 ` Andreas Baierl
  6 siblings, 0 replies; 9+ messages in thread
From: Vasily Khoruzhick @ 2020-01-26 20:24 UTC (permalink / raw)
  To: Qiang Yu; +Cc: lima, David Airlie, dri-devel, Andreas Baierl, Erico Nunes

On Thu, Jan 16, 2020 at 5:12 AM Qiang Yu <yuq825@gmail.com> wrote:
>
> Support heap buffer allocation which can grow the back memory
> size when GP has an out of memory interrupt so that user don't
> need to allocate a very large buffer at the beginning.

Whole series:

Reviewed-by: Vasily Khoruzhick <anarsoul@gmail.com>

> Qiang Yu (5):
>   drm/lima: update register info
>   drm/lima: add lima_vm_map_bo
>   drm/lima: support heap buffer creation
>   drm/lima: recover task by enlarging heap buffer
>   drm/lima: increase driver version to 1.1
>
>  drivers/gpu/drm/lima/lima_drv.c   |  16 +++-
>  drivers/gpu/drm/lima/lima_drv.h   |   1 +
>  drivers/gpu/drm/lima/lima_gem.c   | 130 ++++++++++++++++++++++++++++--
>  drivers/gpu/drm/lima/lima_gem.h   |   4 +
>  drivers/gpu/drm/lima/lima_gp.c    |  51 +++++++++++-
>  drivers/gpu/drm/lima/lima_mmu.c   |   5 ++
>  drivers/gpu/drm/lima/lima_mmu.h   |   1 +
>  drivers/gpu/drm/lima/lima_regs.h  |   1 +
>  drivers/gpu/drm/lima/lima_sched.c |  35 ++++++--
>  drivers/gpu/drm/lima/lima_sched.h |   6 ++
>  drivers/gpu/drm/lima/lima_vm.c    |  44 +++++++++-
>  drivers/gpu/drm/lima/lima_vm.h    |   1 +
>  include/uapi/drm/lima_drm.h       |   9 ++-
>  13 files changed, 284 insertions(+), 20 deletions(-)
>
> --
> 2.17.1
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/5] drm/lima: add heap buffer support
  2020-01-16 13:11 [PATCH 0/5] drm/lima: add heap buffer support Qiang Yu
                   ` (5 preceding siblings ...)
  2020-01-26 20:24 ` [PATCH 0/5] drm/lima: add heap buffer support Vasily Khoruzhick
@ 2020-01-27 10:21 ` Andreas Baierl
  2020-01-27 14:21   ` Qiang Yu
  6 siblings, 1 reply; 9+ messages in thread
From: Andreas Baierl @ 2020-01-27 10:21 UTC (permalink / raw)
  To: Qiang Yu, dri-devel
  Cc: David Airlie, Vasily Khoruzhick, Erico Nunes, lima, Andreas Baierl

Am 16.01.2020 um 14:11 schrieb Qiang Yu:
> Support heap buffer allocation which can grow the back memory
> size when GP has an out of memory interrupt so that user don't
> need to allocate a very large buffer at the beginning.
This was

Tested-by: Andreas Baierl <ichgeh@imkreisrum.de>

together with https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3264.
> Qiang Yu (5):
>    drm/lima: update register info
>    drm/lima: add lima_vm_map_bo
>    drm/lima: support heap buffer creation
>    drm/lima: recover task by enlarging heap buffer
>    drm/lima: increase driver version to 1.1
>
>   drivers/gpu/drm/lima/lima_drv.c   |  16 +++-
>   drivers/gpu/drm/lima/lima_drv.h   |   1 +
>   drivers/gpu/drm/lima/lima_gem.c   | 130 ++++++++++++++++++++++++++++--
>   drivers/gpu/drm/lima/lima_gem.h   |   4 +
>   drivers/gpu/drm/lima/lima_gp.c    |  51 +++++++++++-
>   drivers/gpu/drm/lima/lima_mmu.c   |   5 ++
>   drivers/gpu/drm/lima/lima_mmu.h   |   1 +
>   drivers/gpu/drm/lima/lima_regs.h  |   1 +
>   drivers/gpu/drm/lima/lima_sched.c |  35 ++++++--
>   drivers/gpu/drm/lima/lima_sched.h |   6 ++
>   drivers/gpu/drm/lima/lima_vm.c    |  44 +++++++++-
>   drivers/gpu/drm/lima/lima_vm.h    |   1 +
>   include/uapi/drm/lima_drm.h       |   9 ++-
>   13 files changed, 284 insertions(+), 20 deletions(-)
>

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/5] drm/lima: add heap buffer support
  2020-01-27 10:21 ` Andreas Baierl
@ 2020-01-27 14:21   ` Qiang Yu
  0 siblings, 0 replies; 9+ messages in thread
From: Qiang Yu @ 2020-01-27 14:21 UTC (permalink / raw)
  To: Andreas Baierl
  Cc: lima, David Airlie, dri-devel, Vasily Khoruzhick, Andreas Baierl,
	Erico Nunes

Thanks, applied to drm-misc-next.

Regards,
Qiang

On Mon, Jan 27, 2020 at 6:21 PM Andreas Baierl <list@imkreisrum.de> wrote:
>
> Am 16.01.2020 um 14:11 schrieb Qiang Yu:
> > Support heap buffer allocation which can grow the back memory
> > size when GP has an out of memory interrupt so that user don't
> > need to allocate a very large buffer at the beginning.
> This was
>
> Tested-by: Andreas Baierl <ichgeh@imkreisrum.de>
>
> together with https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3264.
> > Qiang Yu (5):
> >    drm/lima: update register info
> >    drm/lima: add lima_vm_map_bo
> >    drm/lima: support heap buffer creation
> >    drm/lima: recover task by enlarging heap buffer
> >    drm/lima: increase driver version to 1.1
> >
> >   drivers/gpu/drm/lima/lima_drv.c   |  16 +++-
> >   drivers/gpu/drm/lima/lima_drv.h   |   1 +
> >   drivers/gpu/drm/lima/lima_gem.c   | 130 ++++++++++++++++++++++++++++--
> >   drivers/gpu/drm/lima/lima_gem.h   |   4 +
> >   drivers/gpu/drm/lima/lima_gp.c    |  51 +++++++++++-
> >   drivers/gpu/drm/lima/lima_mmu.c   |   5 ++
> >   drivers/gpu/drm/lima/lima_mmu.h   |   1 +
> >   drivers/gpu/drm/lima/lima_regs.h  |   1 +
> >   drivers/gpu/drm/lima/lima_sched.c |  35 ++++++--
> >   drivers/gpu/drm/lima/lima_sched.h |   6 ++
> >   drivers/gpu/drm/lima/lima_vm.c    |  44 +++++++++-
> >   drivers/gpu/drm/lima/lima_vm.h    |   1 +
> >   include/uapi/drm/lima_drm.h       |   9 ++-
> >   13 files changed, 284 insertions(+), 20 deletions(-)
> >
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-01-27 14:21 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-16 13:11 [PATCH 0/5] drm/lima: add heap buffer support Qiang Yu
2020-01-16 13:11 ` [PATCH 1/5] drm/lima: update register info Qiang Yu
2020-01-16 13:11 ` [PATCH 2/5] drm/lima: add lima_vm_map_bo Qiang Yu
2020-01-16 13:11 ` [PATCH 3/5] drm/lima: support heap buffer creation Qiang Yu
2020-01-16 13:11 ` [PATCH 4/5] drm/lima: recover task by enlarging heap buffer Qiang Yu
2020-01-16 13:11 ` [PATCH 5/5] drm/lima: increase driver version to 1.1 Qiang Yu
2020-01-26 20:24 ` [PATCH 0/5] drm/lima: add heap buffer support Vasily Khoruzhick
2020-01-27 10:21 ` Andreas Baierl
2020-01-27 14:21   ` Qiang Yu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).