From 6eae41fea75039136707c02cf99431462d590c5f Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 30 Jun 2019 07:21:03 +0200 Subject: drm/etnaviv: drop use of drmP.h Drop use of the deprecated drmP.h header file. Fix fallout in all .c files. The etnaviv_drv.h header file was made self-contained, and missing includes was then added to the .c files that needed them. In a few cases the list of include files was sorted. Signed-off-by: Sam Ravnborg Cc: Lucas Stach Cc: Russell King Cc: Christian Gmeiner Cc: David Airlie Cc: Daniel Vetter Cc: etnaviv@lists.freedesktop.org Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/gpu/drm/etnaviv/etnaviv_drv.c') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 7eb7cf9c3fa8..e823e41f6a6b 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -4,8 +4,16 @@ */ #include +#include #include +#include + +#include +#include +#include +#include #include +#include #include "etnaviv_cmdbuf.h" #include "etnaviv_drv.h" -- cgit From 2e737e520548d4456fc8dfa800ab189e0e4b2939 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 4 Jul 2019 12:43:37 +0200 Subject: drm/etnaviv: clean up includes Drop unused includes, move more includes from the generic etnaviv_drv.h to the units where they are actually used, sort includes. Signed-off-by: Lucas Stach Acked-by: Sam Ravnborg --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/etnaviv/etnaviv_drv.c') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index e823e41f6a6b..9d4404723489 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -5,6 +5,7 @@ #include #include +#include #include #include -- cgit From bffe5db81ae63ec75f5e09d1c97de42c37cb181e Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 5 Jul 2019 19:17:22 +0200 Subject: drm/etnaviv: share a single cmdbuf suballoc region across all GPUs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no need for each GPU to have it's own cmdbuf suballocation region. Only allocate a single one for the the etnaviv virtual device and share it across all GPUs. As the suballoc space is now potentially shared by more hardware jobs running in parallel, double its size to 512KB to avoid contention. Signed-off-by: Lucas Stach Reviewed-by: Philipp Zabel Reviewed-by: Guido Günther --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/etnaviv/etnaviv_drv.c') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 9d4404723489..5fa3aa7bdbc5 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -530,23 +530,32 @@ static int etnaviv_bind(struct device *dev) INIT_LIST_HEAD(&priv->gem_list); priv->num_gpus = 0; + priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev); + if (IS_ERR(priv->cmdbuf_suballoc)) { + dev_err(drm->dev, "Failed to create cmdbuf suballocator\n"); + ret = PTR_ERR(priv->cmdbuf_suballoc); + goto out_free_priv; + } + dev_set_drvdata(dev, drm); ret = component_bind_all(dev, drm); if (ret < 0) - goto out_bind; + goto out_destroy_suballoc; load_gpu(drm); ret = drm_dev_register(drm, 0); if (ret) - goto out_register; + goto out_unbind; return 0; -out_register: +out_unbind: component_unbind_all(dev, drm); -out_bind: +out_destroy_suballoc: + etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc); +out_free_priv: kfree(priv); out_put: drm_dev_put(drm); @@ -565,6 +574,8 @@ static void etnaviv_unbind(struct device *dev) dev->dma_parms = NULL; + etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc); + drm->dev_private = NULL; kfree(priv); -- cgit From 27b67278e007b5475bc14918794bf73cf297a026 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 5 Jul 2019 19:17:24 +0200 Subject: drm/etnaviv: rework MMU handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reworks the MMU handling to make it possible to have multiple MMU contexts. A context is basically one instance of GPU page tables. Currently we have one set of page tables per GPU, which isn't all that clever, as it has the following two consequences: 1. All GPU clients (aka processes) are sharing the same pagetables, which means there is no isolation between clients, but only between GPU assigned memory spaces and the rest of the system. Better than nothing, but also not great. 2. Clients operating on the same set of buffers with different etnaviv GPU cores, e.g. a workload using both the 2D and 3D GPU, need to map the used buffers into the pagetable sets of each used GPU. This patch reworks all the MMU handling to introduce the abstraction of the MMU context. A context can be shared across different GPU cores, as long as they have compatible MMU implementations, which is the case for all systems with Vivante GPUs seen in the wild. As MMUv1 is not able to change pagetables on the fly, without a "stop the world" operation, which stops GPU, changes pagetables via CPU interaction, restarts GPU, the implementation introduces a shared context on MMUv1, which is returned whenever there is a request for a new context. This patch assigns a MMU context to each GPU, so on MMUv2 systems there is still one set of pagetables per GPU, but due to the shared context MMUv1 systems see a change in behavior as now a single pagetable set is used across all GPU cores. Signed-off-by: Lucas Stach Reviewed-by: Philipp Zabel Reviewed-by: Guido Günther --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/etnaviv/etnaviv_drv.c') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 5fa3aa7bdbc5..eb0c23fe979a 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -119,9 +119,9 @@ static int etnaviv_mmu_show(struct etnaviv_gpu *gpu, struct seq_file *m) seq_printf(m, "Active Objects (%s):\n", dev_name(gpu->dev)); - mutex_lock(&gpu->mmu->lock); - drm_mm_print(&gpu->mmu->mm, &p); - mutex_unlock(&gpu->mmu->lock); + mutex_lock(&gpu->mmu_context->lock); + drm_mm_print(&gpu->mmu_context->mm, &p); + mutex_unlock(&gpu->mmu_context->lock); return 0; } -- cgit From 17e4660ae3d7e14120f0b355d3d1995cd10a3e43 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 5 Jul 2019 19:17:27 +0200 Subject: drm/etnaviv: implement per-process address spaces on MMUv2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This builds on top of the MMU contexts introduced earlier. Instead of having one context per GPU core, each GPU client receives its own context. On MMUv1 this still means a single shared pagetable set is used by all clients, but on MMUv2 there is now a distinct set of pagetables for each client. As the command fetch is also translated via the MMU on MMUv2 the kernel command ringbuffer is mapped into each of the client pagetables. As the MMU context switch is a bit of a heavy operation, due to the needed cache and TLB flushing, this patch implements a lazy way of switching the MMU context. The kernel does not have its own MMU context, but reuses the last client context for all of its operations. This has some visible impact, as the GPU can now only be started once a client has submitted some work and we got the client MMU context assigned. Also the MMU context has a different lifetime than the general client context, as the GPU might still execute the kernel command buffer in the context of a client even after the client has completed all GPU work and has been terminated. Only when the GPU is runtime suspended or switches to another clients MMU context is the old context freed up. Signed-off-by: Lucas Stach Reviewed-by: Philipp Zabel Reviewed-by: Guido Günther --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 38 +++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/etnaviv/etnaviv_drv.c') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index eb0c23fe979a..80f1edcbbea0 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -50,12 +50,19 @@ static int etnaviv_open(struct drm_device *dev, struct drm_file *file) { struct etnaviv_drm_private *priv = dev->dev_private; struct etnaviv_file_private *ctx; - int i; + int ret, i; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; + ctx->mmu = etnaviv_iommu_context_init(priv->mmu_global, + priv->cmdbuf_suballoc); + if (!ctx->mmu) { + ret = -ENOMEM; + goto out_free; + } + for (i = 0; i < ETNA_MAX_PIPES; i++) { struct etnaviv_gpu *gpu = priv->gpu[i]; struct drm_sched_rq *rq; @@ -70,6 +77,10 @@ static int etnaviv_open(struct drm_device *dev, struct drm_file *file) file->driver_priv = ctx; return 0; + +out_free: + kfree(ctx); + return ret; } static void etnaviv_postclose(struct drm_device *dev, struct drm_file *file) @@ -85,6 +96,8 @@ static void etnaviv_postclose(struct drm_device *dev, struct drm_file *file) drm_sched_entity_destroy(&ctx->sched_entity[i]); } + etnaviv_iommu_context_put(ctx->mmu); + kfree(ctx); } @@ -116,12 +129,29 @@ static int etnaviv_mm_show(struct drm_device *dev, struct seq_file *m) static int etnaviv_mmu_show(struct etnaviv_gpu *gpu, struct seq_file *m) { struct drm_printer p = drm_seq_file_printer(m); + struct etnaviv_iommu_context *mmu_context; seq_printf(m, "Active Objects (%s):\n", dev_name(gpu->dev)); - mutex_lock(&gpu->mmu_context->lock); - drm_mm_print(&gpu->mmu_context->mm, &p); - mutex_unlock(&gpu->mmu_context->lock); + /* + * Lock the GPU to avoid a MMU context switch just now and elevate + * the refcount of the current context to avoid it disappearing from + * under our feet. + */ + mutex_lock(&gpu->lock); + mmu_context = gpu->mmu_context; + if (mmu_context) + etnaviv_iommu_context_get(mmu_context); + mutex_unlock(&gpu->lock); + + if (!mmu_context) + return 0; + + mutex_lock(&mmu_context->lock); + drm_mm_print(&mmu_context->mm, &p); + mutex_unlock(&mmu_context->lock); + + etnaviv_iommu_context_put(mmu_context); return 0; } -- cgit From 088880ddc0b20086b71bb87b805fb63ff07c35f2 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 2 Aug 2019 14:27:33 +0200 Subject: drm/etnaviv: implement softpin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With softpin we allow the userspace to take control over the GPU virtual address space. The new capability is relected by a bump of the minor DRM version. There are a few restrictions for userspace to take into account: 1. The kernel reserves a bit of the address space to implement zero page faulting and mapping of the kernel internal ring buffer. Userspace can query the kernel for the first usable GPU VM address via ETNAVIV_PARAM_SOFTPIN_START_ADDR. 2. We only allow softpin on GPUs, which implement proper process separation via PPAS. If softpin is not available the softpin start address will be set to ~0. 3. Softpin is all or nothing. A submit using softpin must not use any address fixups via relocs. Signed-off-by: Lucas Stach Reviewed-by: Philipp Zabel Reviewed-by: Guido Günther --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/etnaviv/etnaviv_drv.c') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 80f1edcbbea0..45851d510f62 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -529,7 +529,7 @@ static struct drm_driver etnaviv_drm_driver = { .desc = "etnaviv DRM", .date = "20151214", .major = 1, - .minor = 2, + .minor = 3, }; /* -- cgit