From 03533066aa9ece480ada0f1b26e69983bc0ca381 Mon Sep 17 00:00:00 2001 From: Alex Waterman Date: Fri, 2 Dec 2022 21:06:51 +0000 Subject: [PATCH] gpu: nvgpu: Disable compression for k6.1+ dmabuf internals that nvgpu relies upon for storing meta-data for compressible buffers changed in k6.1. For now, disable compression on all k6.1+ kernels. Additionally, fix numerous compilation issues due to the bit rotted compression config. All normal Tegra products support compression and thus have this config enabled. Over the last several years compression dependent code crept in that wasn't protected under the compression config. Bug 3844023 Change-Id: Ie5b9b5a2bcf1a763806c087af99203d62d0cb6e0 Signed-off-by: Alex Waterman Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2820846 Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-cert Reviewed-by: svc-mobile-misra Reviewed-by: Sagar Kamble Reviewed-by: Ankur Kishore Tested-by: Sagar Kamble GVS: Gerrit_Virtual_Submit --- drivers/gpu/nvgpu/Makefile | 6 ++++- drivers/gpu/nvgpu/Makefile.linux.configs | 10 ++++++- drivers/gpu/nvgpu/common/mm/vm.c | 4 ++- drivers/gpu/nvgpu/os/linux/dmabuf_priv.c | 7 ++++- drivers/gpu/nvgpu/os/linux/dmabuf_priv.h | 5 ++++ drivers/gpu/nvgpu/os/linux/driver_common.c | 2 ++ drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c | 17 ++++++------ drivers/gpu/nvgpu/os/linux/module.c | 4 +++ drivers/gpu/nvgpu/os/linux/pci.c | 2 ++ drivers/gpu/nvgpu/os/linux/sysfs.c | 10 ++++++- drivers/gpu/nvgpu/os/linux/vm.c | 31 +++++++++++++++++----- drivers/gpu/nvgpu/os/linux/vm_remap.c | 4 +++ 12 files changed, 81 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index 5120415e1..022259b2e 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile @@ -496,8 +496,12 @@ nvgpu-y += \ os/linux/periodic_timer.o nvgpu-$(CONFIG_NVGPU_IVM_BUILD) += \ - os/linux/nvgpu_ivm.o \ + os/linux/nvgpu_ivm.o + +ifeq ($(CONFIG_NVGPU_COMPRESSION),y) +nvgpu-$(CONFIG_NVGPU_IVM_BUILD) += \ common/cbc/contig_pool.o +endif nvgpu-$(CONFIG_NVGPU_VPR) += os/linux/vpr.o diff --git a/drivers/gpu/nvgpu/Makefile.linux.configs b/drivers/gpu/nvgpu/Makefile.linux.configs index 38e7da4a3..239c03c9a 100644 --- a/drivers/gpu/nvgpu/Makefile.linux.configs +++ b/drivers/gpu/nvgpu/Makefile.linux.configs @@ -36,8 +36,16 @@ CONFIG_NVGPU_HAL_NON_FUSA := y # Support recovery on failure (which may involve engine reset) CONFIG_NVGPU_RECOVERY := y -# Support for compression +# Enable support for compression on pre-K6.1 kernels. K6.1+ changes the +# internals of dma-bufs which breaks some hacks we implemented to support +# compression meta-data tracking. For now, on K6.1+ kernels, just disable +# compression. This is a hack that should be fixed. CONFIG_NVGPU_COMPRESSION := y +ifeq ($(VERSION),6) +ifneq ($(PATCHLEVEL),0) +CONFIG_NVGPU_COMPRESSION := n +endif +endif # Enable MIG Support CONFIG_NVGPU_MIG := y diff --git a/drivers/gpu/nvgpu/common/mm/vm.c b/drivers/gpu/nvgpu/common/mm/vm.c index 07fbcaec3..6d1a76581 100644 --- a/drivers/gpu/nvgpu/common/mm/vm.c +++ b/drivers/gpu/nvgpu/common/mm/vm.c @@ -49,11 +49,11 @@ struct nvgpu_ctag_buffer_info { u32 flags; #ifdef CONFIG_NVGPU_COMPRESSION + u32 ctag_offset; s16 compr_kind; #endif s16 incompr_kind; - u32 ctag_offset; }; #ifdef CONFIG_NVGPU_COMPRESSION @@ -1549,7 +1549,9 @@ int nvgpu_vm_map(struct vm_gk20a *vm, mapped_buffer->kind = map_key_kind; mapped_buffer->va_allocated = va_allocated; mapped_buffer->vm_area = vm_area; +#ifdef CONFIG_NVGPU_COMPRESSION mapped_buffer->ctag_offset = binfo.ctag_offset; +#endif mapped_buffer->rw_flag = rw; mapped_buffer->aperture = aperture; diff --git a/drivers/gpu/nvgpu/os/linux/dmabuf_priv.c b/drivers/gpu/nvgpu/os/linux/dmabuf_priv.c index 3386f52bd..363ee68d4 100644 --- a/drivers/gpu/nvgpu/os/linux/dmabuf_priv.c +++ b/drivers/gpu/nvgpu/os/linux/dmabuf_priv.c @@ -38,7 +38,9 @@ #include "os_linux.h" #include "dmabuf_vidmem.h" +#ifdef CONFIG_NVGPU_COMPRESSION void gk20a_mm_delete_priv(struct gk20a_dmabuf_priv *priv); +#endif enum nvgpu_aperture gk20a_dmabuf_aperture(struct gk20a *g, struct dma_buf *dmabuf) @@ -68,6 +70,7 @@ enum nvgpu_aperture gk20a_dmabuf_aperture(struct gk20a *g, #endif } +#ifdef CONFIG_NVGPU_COMPRESSION static struct gk20a_dmabuf_priv *dma_buf_ops_to_gk20a_priv( struct dma_buf_ops *ops) { @@ -94,7 +97,6 @@ static void nvgpu_dma_buf_release(struct dma_buf *dmabuf) nvgpu_mutex_acquire(&l->dmabuf_priv_list_lock); gk20a_mm_delete_priv(priv); nvgpu_mutex_release(&l->dmabuf_priv_list_lock); - dmabuf->ops->release(dmabuf); } @@ -137,6 +139,7 @@ struct gk20a_dmabuf_priv *gk20a_dma_buf_get_drvdata( return priv; } +#endif struct sg_table *nvgpu_mm_pin(struct device *dev, struct dma_buf *dmabuf, struct dma_buf_attachment **attachment, @@ -178,6 +181,7 @@ void nvgpu_mm_unpin(struct device *dev, /* This function must be called after acquiring the global level * dmabuf_priv_list_lock. */ +#ifdef CONFIG_NVGPU_COMPRESSION void gk20a_mm_delete_priv(struct gk20a_dmabuf_priv *priv) { struct gk20a_buffer_state *s, *s_tmp; @@ -325,6 +329,7 @@ out: *state = s; return err; } +#endif static void *__gk20a_dmabuf_vmap(struct dma_buf *dmabuf) { diff --git a/drivers/gpu/nvgpu/os/linux/dmabuf_priv.h b/drivers/gpu/nvgpu/os/linux/dmabuf_priv.h index 63ec547c1..e0a7d8f6d 100644 --- a/drivers/gpu/nvgpu/os/linux/dmabuf_priv.h +++ b/drivers/gpu/nvgpu/os/linux/dmabuf_priv.h @@ -66,6 +66,7 @@ gk20a_buffer_state_from_list(struct nvgpu_list_node *node) ((uintptr_t)node - offsetof(struct gk20a_buffer_state, list)); }; +#ifdef CONFIG_NVGPU_COMPRESSION struct gk20a_dmabuf_priv { struct nvgpu_mutex lock; @@ -100,6 +101,7 @@ struct gk20a_dmabuf_priv { /* list node for tracking the dmabuf_priv instances per gpu */ struct nvgpu_list_node list; }; +#endif struct sg_table *nvgpu_mm_pin(struct device *dev, struct dma_buf *dmabuf, @@ -111,6 +113,7 @@ void nvgpu_mm_unpin(struct device *dev, struct dma_buf_attachment *attachment, struct sg_table *sgt); +#ifdef CONFIG_NVGPU_COMPRESSION void gk20a_mm_delete_priv(struct gk20a_dmabuf_priv *priv); int gk20a_dmabuf_alloc_or_get_drvdata(struct dma_buf *dmabuf, struct device *dev, @@ -122,6 +125,8 @@ int gk20a_dmabuf_get_state(struct dma_buf *dmabuf, struct gk20a *g, void gk20a_dma_buf_priv_list_clear(struct nvgpu_os_linux *l); struct gk20a_dmabuf_priv *gk20a_dma_buf_get_drvdata( struct dma_buf *dmabuf, struct device *device); +#endif + void *gk20a_dmabuf_vmap(struct dma_buf *dmabuf); void gk20a_dmabuf_vunmap(struct dma_buf *dmabuf, void *addr); diff --git a/drivers/gpu/nvgpu/os/linux/driver_common.c b/drivers/gpu/nvgpu/os/linux/driver_common.c index 0df555f2d..46bd88f23 100644 --- a/drivers/gpu/nvgpu/os/linux/driver_common.c +++ b/drivers/gpu/nvgpu/os/linux/driver_common.c @@ -142,12 +142,14 @@ static void nvgpu_init_vars(struct gk20a *g) static void nvgpu_init_max_comptag(struct gk20a *g) { +#ifdef CONFIG_NVGPU_COMPRESSION #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) nvgpu_log_info(g, "total ram pages : %lu", totalram_pages()); #else nvgpu_log_info(g, "total ram pages : %lu", totalram_pages); #endif g->max_comptag_mem = totalram_size_in_mb; +#endif } static void nvgpu_init_timeout(struct gk20a *g) diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c index 12b98dfef..39155a839 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c @@ -2010,12 +2010,15 @@ out: static int nvgpu_gpu_ioctl_get_buffer_info(struct gk20a *g, struct nvgpu_gpu_get_buffer_info_args *args) { + int err = -EINVAL; +#ifdef CONFIG_NVGPU_COMPRESSION u64 user_metadata_addr = args->in.metadata_addr; u32 in_metadata_size = args->in.metadata_size; struct gk20a_dmabuf_priv *priv = NULL; s32 dmabuf_fd = args->in.dmabuf_fd; struct dma_buf *dmabuf; - int err = 0; + + err = 0; nvgpu_log_fn(g, " "); @@ -2070,13 +2073,11 @@ static int nvgpu_gpu_ioctl_get_buffer_info(struct gk20a *g, NVGPU_GPU_BUFFER_INFO_FLAGS_METADATA_REGISTERED; } -#ifdef CONFIG_NVGPU_COMPRESSION if (nvgpu_is_enabled(g, NVGPU_SUPPORT_COMPRESSION) && priv->comptags.enabled) { args->out.flags |= NVGPU_GPU_BUFFER_INFO_FLAGS_COMPTAGS_ALLOCATED; } -#endif if (priv->mutable_metadata) { args->out.flags |= @@ -2090,6 +2091,7 @@ out_priv_unlock: nvgpu_mutex_release(&priv->lock); out: dma_buf_put(dmabuf); +#endif return err; } @@ -2166,12 +2168,13 @@ static int nvgpu_handle_comptags_control(struct gk20a *g, static int nvgpu_gpu_ioctl_register_buffer(struct gk20a *g, struct nvgpu_gpu_register_buffer_args *args) { + int err = 0; +#ifdef CONFIG_NVGPU_COMPRESSION struct gk20a_dmabuf_priv *priv = NULL; bool mutable_metadata = false; bool modify_metadata = false; struct dma_buf *dmabuf; u8 *blob_copy = NULL; - int err = 0; nvgpu_log_fn(g, " "); @@ -2246,7 +2249,6 @@ static int nvgpu_gpu_ioctl_register_buffer(struct gk20a *g, goto out_priv_unlock; } -#ifdef CONFIG_NVGPU_COMPRESSION /* Comptags allocation */ err = nvgpu_handle_comptags_control(g, dmabuf, priv, args->comptags_alloc_control); @@ -2254,7 +2256,6 @@ static int nvgpu_gpu_ioctl_register_buffer(struct gk20a *g, nvgpu_err(g, "Comptags alloc control failed %d", err); goto out_priv_unlock; } -#endif /* All done, update metadata blob */ nvgpu_kfree(g, priv->metadata_blob); @@ -2270,13 +2271,11 @@ static int nvgpu_gpu_ioctl_register_buffer(struct gk20a *g, /* Output variables */ args->flags = 0; -#ifdef CONFIG_NVGPU_COMPRESSION if (nvgpu_is_enabled(g, NVGPU_SUPPORT_COMPRESSION) && priv->comptags.enabled) { args->flags |= NVGPU_GPU_REGISTER_BUFFER_FLAGS_COMPTAGS_ALLOCATED; } -#endif nvgpu_log_info(g, "buffer registered: mutable: %s, metadata size: %u, flags: 0x%8x", priv->mutable_metadata ? "yes" : "no", priv->metadata_blob_size, @@ -2287,7 +2286,7 @@ out_priv_unlock: out: dma_buf_put(dmabuf); nvgpu_kfree(g, blob_copy); - +#endif return err; } diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c index a9dc5dad9..63ee11042 100644 --- a/drivers/gpu/nvgpu/os/linux/module.c +++ b/drivers/gpu/nvgpu/os/linux/module.c @@ -1912,8 +1912,10 @@ static int gk20a_probe(struct platform_device *dev) if (err) goto return_err; +#ifdef CONFIG_NVGPU_COMPRESSION nvgpu_mutex_init(&l->dmabuf_priv_list_lock); nvgpu_init_list_node(&l->dmabuf_priv_list); +#endif gk20a->probe_done = true; @@ -2045,8 +2047,10 @@ static int __exit gk20a_remove(struct platform_device *pdev) err = nvgpu_remove(dev); +#ifdef CONFIG_NVGPU_COMPRESSION gk20a_dma_buf_priv_list_clear(l); nvgpu_mutex_destroy(&l->dmabuf_priv_list_lock); +#endif unregister_reboot_notifier(&l->nvgpu_reboot_nb); diff --git a/drivers/gpu/nvgpu/os/linux/pci.c b/drivers/gpu/nvgpu/os/linux/pci.c index ee27c60e2..e6229e5f1 100644 --- a/drivers/gpu/nvgpu/os/linux/pci.c +++ b/drivers/gpu/nvgpu/os/linux/pci.c @@ -750,7 +750,9 @@ static void nvgpu_pci_remove(struct pci_dev *pdev) if (gk20a_gpu_is_virtual(dev)) return; +#ifdef CONFIG_NVGPU_COMPRESSION gk20a_dma_buf_priv_list_clear(l); +#endif nvgpu_mutex_destroy(&l->dmabuf_priv_list_lock); err = nvgpu_pci_clear_pci_power(dev_name(dev)); diff --git a/drivers/gpu/nvgpu/os/linux/sysfs.c b/drivers/gpu/nvgpu/os/linux/sysfs.c index c39854837..ed9379e87 100644 --- a/drivers/gpu/nvgpu/os/linux/sysfs.c +++ b/drivers/gpu/nvgpu/os/linux/sysfs.c @@ -1234,6 +1234,7 @@ static ssize_t tsg_timeslice_max_us_store(struct device *dev, static DEVICE_ATTR(tsg_timeslice_max_us, ROOTRW, tsg_timeslice_max_us_read, tsg_timeslice_max_us_store); +#ifdef CONFIG_NVGPU_COMPRESSION static ssize_t comptag_mem_deduct_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1267,6 +1268,7 @@ static ssize_t comptag_mem_deduct_show(struct device *dev, static DEVICE_ATTR(comptag_mem_deduct, ROOTRW, comptag_mem_deduct_show, comptag_mem_deduct_store); +#endif #ifdef CONFIG_NVGPU_MIG static ssize_t mig_mode_config_list_show(struct device *dev, @@ -1527,7 +1529,10 @@ void nvgpu_remove_sysfs(struct device *dev) device_remove_file(dev, &dev_attr_gpu_powered_on); +#ifdef CONFIG_NVGPU_COMPRESSION device_remove_file(dev, &dev_attr_comptag_mem_deduct); +#endif + #ifdef CONFIG_NVGPU_MIG device_remove_file(dev, &dev_attr_mig_mode_config_list); device_remove_file(dev, &dev_attr_mig_mode_config_list_parsable); @@ -1599,7 +1604,10 @@ int nvgpu_create_sysfs(struct device *dev) error |= device_create_file(dev, &dev_attr_gpu_powered_on); - error |= device_create_file(dev, &dev_attr_comptag_mem_deduct); +#ifdef CONFIG_NVGPU_COMPRESSION + device_create_file(dev, &dev_attr_comptag_mem_deduct); +#endif + #ifdef CONFIG_NVGPU_MIG error |= device_create_file(dev, &dev_attr_mig_mode_config_list); error |= device_create_file(dev, &dev_attr_mig_mode_config_list_parsable); diff --git a/drivers/gpu/nvgpu/os/linux/vm.c b/drivers/gpu/nvgpu/os/linux/vm.c index 025b331ef..20df5f516 100644 --- a/drivers/gpu/nvgpu/os/linux/vm.c +++ b/drivers/gpu/nvgpu/os/linux/vm.c @@ -468,9 +468,11 @@ int nvgpu_vm_mapping_modify(struct vm_gk20a *vm, struct nvgpu_sgt *nvgpu_sgt = NULL; u32 pgsz_idx; u32 page_size; - u64 ctag_offset; s16 kind = NV_KIND_INVALID; + u64 ctag_offset = 0UL; +#ifdef CONFIG_NVGPU_COMPRESSION u64 compression_page_size; +#endif nvgpu_mutex_acquire(&vm->update_gmmu_lock); @@ -510,18 +512,31 @@ int nvgpu_vm_mapping_modify(struct vm_gk20a *vm, goto out; } + /* + * Fall back is the incompressible kind. + */ + kind = incompr_kind; + + /* + * If we support compression and there's a compressible kind, use it. + */ +#ifdef CONFIG_NVGPU_COMPRESSION if (mapped_buffer->ctag_offset != 0) { if (compr_kind == NV_KIND_INVALID) { kind = incompr_kind; } else { kind = compr_kind; } - } else { - if (incompr_kind == NV_KIND_INVALID) { - nvgpu_err(g, "invalid incompr_kind specified"); - goto out; - } - kind = incompr_kind; + } +#endif + + /* + * If we don't support compression you still need to have a valid kind + * specified. + */ + if (kind == NV_KIND_INVALID) { + nvgpu_err(g, "invalid incompr_kind specified"); + goto out; } nvgpu_sgt = nvgpu_linux_sgt_create(g, mapped_buffer->os_priv.sgt); @@ -530,6 +545,7 @@ int nvgpu_vm_mapping_modify(struct vm_gk20a *vm, goto out; } +#ifdef CONFIG_NVGPU_COMPRESSION ctag_offset = mapped_buffer->ctag_offset; compression_page_size = g->ops.fb.compression_page_size(g); @@ -537,6 +553,7 @@ int nvgpu_vm_mapping_modify(struct vm_gk20a *vm, ctag_offset += (u32)(buffer_offset >> nvgpu_ilog2(compression_page_size)); +#endif if (g->ops.mm.gmmu.map(vm, map_address + buffer_offset, diff --git a/drivers/gpu/nvgpu/os/linux/vm_remap.c b/drivers/gpu/nvgpu/os/linux/vm_remap.c index 6dc32a30a..17b607295 100644 --- a/drivers/gpu/nvgpu/os/linux/vm_remap.c +++ b/drivers/gpu/nvgpu/os/linux/vm_remap.c @@ -118,12 +118,15 @@ void nvgpu_vm_remap_os_buf_put(struct vm_gk20a *vm, { struct gk20a *g = gk20a_from_vm(vm); struct device *dev = dev_from_gk20a(g); +#ifdef CONFIG_NVGPU_COMPRESSION struct gk20a_comptags comptags; int err = 0; +#endif nvgpu_mm_unpin(dev, remap_os_buf->os_priv.dmabuf, remap_os_buf->os_priv.attachment, remap_os_buf->os_priv.sgt); +#ifdef CONFIG_NVGPU_COMPRESSION gk20a_get_comptags(&remap_os_buf->os_buf, &comptags); /* @@ -139,6 +142,7 @@ void nvgpu_vm_remap_os_buf_put(struct vm_gk20a *vm, return; } } +#endif nvgpu_sgt_free(g, remap_os_buf->nv_sgt);