From 46469f558f72ae681080759dc7bf3f7d4d3adeaf Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Wed, 19 Aug 2020 12:45:07 +0100 Subject: arm: fixes for rpi4 --- dma-pool-fixes.patch | 419 +++++++++++++++++++++++++++++++++++++++++++++++++++ kernel.spec | 5 +- 2 files changed, 423 insertions(+), 1 deletion(-) create mode 100644 dma-pool-fixes.patch diff --git a/dma-pool-fixes.patch b/dma-pool-fixes.patch new file mode 100644 index 000000000..e8977c3dd --- /dev/null +++ b/dma-pool-fixes.patch @@ -0,0 +1,419 @@ +From patchwork Fri Aug 14 10:26:23 2020 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Nicolas Saenz Julienne +X-Patchwork-Id: 1287370 +Return-Path: +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 66DB2C433E1 + for ; Fri, 14 Aug 2020 10:26:38 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id 4A18620781 + for ; Fri, 14 Aug 2020 10:26:38 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S1726919AbgHNK0g (ORCPT + ); + Fri, 14 Aug 2020 06:26:36 -0400 +Received: from mx2.suse.de ([195.135.220.15]:54358 "EHLO mx2.suse.de" + rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP + id S1726012AbgHNK0f (ORCPT ); + Fri, 14 Aug 2020 06:26:35 -0400 +X-Virus-Scanned: by amavisd-new at test-mx.suse.de +Received: from relay2.suse.de (unknown [195.135.221.27]) + by mx2.suse.de (Postfix) with ESMTP id B5BB5AD1A; + Fri, 14 Aug 2020 10:26:56 +0000 (UTC) +From: Nicolas Saenz Julienne +To: amit.pundir@linaro.org, hch@lst.de, linux-kernel@vger.kernel.org, + Marek Szyprowski , + Robin Murphy +Cc: rientjes@google.com, jeremy.linton@arm.com, + linux-rpi-kernel@lists.infradead.org, + Nicolas Saenz Julienne , + iommu@lists.linux-foundation.org +Subject: [PATCH v4 1/2] dma-pool: Only allocate from CMA when in same memory + zone +Date: Fri, 14 Aug 2020 12:26:23 +0200 +Message-Id: <20200814102625.25599-2-nsaenzjulienne@suse.de> +X-Mailer: git-send-email 2.28.0 +In-Reply-To: <20200814102625.25599-1-nsaenzjulienne@suse.de> +References: <20200814102625.25599-1-nsaenzjulienne@suse.de> +MIME-Version: 1.0 +Sender: linux-kernel-owner@vger.kernel.org +Precedence: bulk +List-ID: +X-Mailing-List: linux-kernel@vger.kernel.org + +There is no guarantee to CMA's placement, so allocating a zone specific +atomic pool from CMA might return memory from a completely different +memory zone. To get around this double check CMA's placement before +allocating from it. + +Signed-off-by: Nicolas Saenz Julienne +[hch: rebased, added a fallback to the page allocator, allow dipping into + lower CMA pools] +Signed-off-by: Christoph Hellwig +--- + +Changes since v3: + - Do not use memblock_start_of_DRAM() + +Changes since v2: + - Go back to v1 behavior + + kernel/dma/pool.c | 31 ++++++++++++++++++++++++++++++- + 1 file changed, 30 insertions(+), 1 deletion(-) + +diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c +index 6bc74a2d5127..57f4a0f32a92 100644 +--- a/kernel/dma/pool.c ++++ b/kernel/dma/pool.c +@@ -3,7 +3,9 @@ + * Copyright (C) 2012 ARM Ltd. + * Copyright (C) 2020 Google LLC + */ ++#include + #include ++#include + #include + #include + #include +@@ -55,6 +57,29 @@ static void dma_atomic_pool_size_add(gfp_t gfp, size_t size) + pool_size_kernel += size; + } + ++static bool cma_in_zone(gfp_t gfp) ++{ ++ unsigned long size; ++ phys_addr_t end; ++ struct cma *cma; ++ ++ cma = dev_get_cma_area(NULL); ++ if (!cma) ++ return false; ++ ++ size = cma_get_size(cma); ++ if (!size) ++ return false; ++ ++ /* CMA can't cross zone boundaries, see cma_activate_area() */ ++ end = cma_get_base(cma) + size - 1; ++ if (IS_ENABLED(CONFIG_ZONE_DMA) && (gfp & GFP_DMA)) ++ return end <= DMA_BIT_MASK(zone_dma_bits); ++ if (IS_ENABLED(CONFIG_ZONE_DMA32) && (gfp & GFP_DMA32)) ++ return end <= DMA_BIT_MASK(32); ++ return true; ++} ++ + static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size, + gfp_t gfp) + { +@@ -68,7 +93,11 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size, + + do { + pool_size = 1 << (PAGE_SHIFT + order); +- page = alloc_pages(gfp, order); ++ if (cma_in_zone(gfp)) ++ page = dma_alloc_from_contiguous(NULL, 1 << order, ++ order, false); ++ if (!page) ++ page = alloc_pages(gfp, order); + } while (!page && order-- > 0); + if (!page) + goto out; + +From patchwork Fri Aug 14 10:26:24 2020 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Nicolas Saenz Julienne +X-Patchwork-Id: 1287371 +Return-Path: +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 1B283C433E3 + for ; Fri, 14 Aug 2020 10:26:42 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id F3F9820781 + for ; Fri, 14 Aug 2020 10:26:41 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S1726948AbgHNK0k (ORCPT + ); + Fri, 14 Aug 2020 06:26:40 -0400 +Received: from mx2.suse.de ([195.135.220.15]:54380 "EHLO mx2.suse.de" + rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP + id S1726891AbgHNK0i (ORCPT ); + Fri, 14 Aug 2020 06:26:38 -0400 +X-Virus-Scanned: by amavisd-new at test-mx.suse.de +Received: from relay2.suse.de (unknown [195.135.221.27]) + by mx2.suse.de (Postfix) with ESMTP id 9EA78AD41; + Fri, 14 Aug 2020 10:26:57 +0000 (UTC) +From: Nicolas Saenz Julienne +To: amit.pundir@linaro.org, hch@lst.de, linux-kernel@vger.kernel.org, + Joerg Roedel , + Marek Szyprowski , + Robin Murphy +Cc: rientjes@google.com, jeremy.linton@arm.com, + linux-rpi-kernel@lists.infradead.org, + iommu@lists.linux-foundation.org +Subject: [PATCH v4 2/2] dma-pool: fix coherent pool allocations for IOMMU + mappings +Date: Fri, 14 Aug 2020 12:26:24 +0200 +Message-Id: <20200814102625.25599-3-nsaenzjulienne@suse.de> +X-Mailer: git-send-email 2.28.0 +In-Reply-To: <20200814102625.25599-1-nsaenzjulienne@suse.de> +References: <20200814102625.25599-1-nsaenzjulienne@suse.de> +MIME-Version: 1.0 +Sender: linux-kernel-owner@vger.kernel.org +Precedence: bulk +List-ID: +X-Mailing-List: linux-kernel@vger.kernel.org + +From: Christoph Hellwig + +When allocating coherent pool memory for an IOMMU mapping we don't care +about the DMA mask. Move the guess for the initial GFP mask into the +dma_direct_alloc_pages and pass dma_coherent_ok as a function pointer +argument so that it doesn't get applied to the IOMMU case. + +Signed-off-by: Christoph Hellwig +--- + +Changes since v1: + - Check if phys_addr_ok() exists prior calling it + + drivers/iommu/dma-iommu.c | 4 +- + include/linux/dma-direct.h | 3 - + include/linux/dma-mapping.h | 5 +- + kernel/dma/direct.c | 13 ++-- + kernel/dma/pool.c | 114 +++++++++++++++--------------------- + 5 files changed, 62 insertions(+), 77 deletions(-) + +diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c +index 4959f5df21bd..5141d49a046b 100644 +--- a/drivers/iommu/dma-iommu.c ++++ b/drivers/iommu/dma-iommu.c +@@ -1035,8 +1035,8 @@ static void *iommu_dma_alloc(struct device *dev, size_t size, + + if (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) && + !gfpflags_allow_blocking(gfp) && !coherent) +- cpu_addr = dma_alloc_from_pool(dev, PAGE_ALIGN(size), &page, +- gfp); ++ page = dma_alloc_from_pool(dev, PAGE_ALIGN(size), &cpu_addr, ++ gfp, NULL); + else + cpu_addr = iommu_dma_alloc_pages(dev, size, &page, gfp, attrs); + if (!cpu_addr) +diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h +index 5a3ce2a24794..6e87225600ae 100644 +--- a/include/linux/dma-direct.h ++++ b/include/linux/dma-direct.h +@@ -73,9 +73,6 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size, + } + + u64 dma_direct_get_required_mask(struct device *dev); +-gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask, +- u64 *phys_mask); +-bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size); + void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, + gfp_t gfp, unsigned long attrs); + void dma_direct_free(struct device *dev, size_t size, void *cpu_addr, +diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h +index 016b96b384bd..52635e91143b 100644 +--- a/include/linux/dma-mapping.h ++++ b/include/linux/dma-mapping.h +@@ -522,8 +522,9 @@ void *dma_common_pages_remap(struct page **pages, size_t size, + pgprot_t prot, const void *caller); + void dma_common_free_remap(void *cpu_addr, size_t size); + +-void *dma_alloc_from_pool(struct device *dev, size_t size, +- struct page **ret_page, gfp_t flags); ++struct page *dma_alloc_from_pool(struct device *dev, size_t size, ++ void **cpu_addr, gfp_t flags, ++ bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t)); + bool dma_free_from_pool(struct device *dev, void *start, size_t size); + + int +diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c +index bb0041e99659..db6ef07aec3b 100644 +--- a/kernel/dma/direct.c ++++ b/kernel/dma/direct.c +@@ -43,7 +43,7 @@ u64 dma_direct_get_required_mask(struct device *dev) + return (1ULL << (fls64(max_dma) - 1)) * 2 - 1; + } + +-gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask, ++static gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask, + u64 *phys_limit) + { + u64 dma_limit = min_not_zero(dma_mask, dev->bus_dma_limit); +@@ -68,7 +68,7 @@ gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask, + return 0; + } + +-bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size) ++static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size) + { + return phys_to_dma_direct(dev, phys) + size - 1 <= + min_not_zero(dev->coherent_dma_mask, dev->bus_dma_limit); +@@ -161,8 +161,13 @@ void *dma_direct_alloc_pages(struct device *dev, size_t size, + size = PAGE_ALIGN(size); + + if (dma_should_alloc_from_pool(dev, gfp, attrs)) { +- ret = dma_alloc_from_pool(dev, size, &page, gfp); +- if (!ret) ++ u64 phys_mask; ++ ++ gfp |= dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask, ++ &phys_mask); ++ page = dma_alloc_from_pool(dev, size, &ret, gfp, ++ dma_coherent_ok); ++ if (!page) + return NULL; + goto done; + } +diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c +index 57f4a0f32a92..b0aaba4197ae 100644 +--- a/kernel/dma/pool.c ++++ b/kernel/dma/pool.c +@@ -225,93 +225,75 @@ static int __init dma_atomic_pool_init(void) + } + postcore_initcall(dma_atomic_pool_init); + +-static inline struct gen_pool *dma_guess_pool_from_device(struct device *dev) ++static inline struct gen_pool *dma_guess_pool(struct gen_pool *prev, gfp_t gfp) + { +- u64 phys_mask; +- gfp_t gfp; +- +- gfp = dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask, +- &phys_mask); +- if (IS_ENABLED(CONFIG_ZONE_DMA) && gfp == GFP_DMA) ++ if (prev == NULL) { ++ if (IS_ENABLED(CONFIG_ZONE_DMA32) && (gfp & GFP_DMA32)) ++ return atomic_pool_dma32; ++ if (IS_ENABLED(CONFIG_ZONE_DMA) && (gfp & GFP_DMA)) ++ return atomic_pool_dma; ++ return atomic_pool_kernel; ++ } ++ if (prev == atomic_pool_kernel) ++ return atomic_pool_dma32 ? atomic_pool_dma32 : atomic_pool_dma; ++ if (prev == atomic_pool_dma32) + return atomic_pool_dma; +- if (IS_ENABLED(CONFIG_ZONE_DMA32) && gfp == GFP_DMA32) +- return atomic_pool_dma32; +- return atomic_pool_kernel; ++ return NULL; + } + +-static inline struct gen_pool *dma_get_safer_pool(struct gen_pool *bad_pool) ++static struct page *__dma_alloc_from_pool(struct device *dev, size_t size, ++ struct gen_pool *pool, void **cpu_addr, ++ bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t)) + { +- if (bad_pool == atomic_pool_kernel) +- return atomic_pool_dma32 ? : atomic_pool_dma; ++ unsigned long addr; ++ phys_addr_t phys; + +- if (bad_pool == atomic_pool_dma32) +- return atomic_pool_dma; ++ addr = gen_pool_alloc(pool, size); ++ if (!addr) ++ return NULL; + +- return NULL; +-} ++ phys = gen_pool_virt_to_phys(pool, addr); ++ if (phys_addr_ok && !phys_addr_ok(dev, phys, size)) { ++ gen_pool_free(pool, addr, size); ++ return NULL; ++ } + +-static inline struct gen_pool *dma_guess_pool(struct device *dev, +- struct gen_pool *bad_pool) +-{ +- if (bad_pool) +- return dma_get_safer_pool(bad_pool); ++ if (gen_pool_avail(pool) < atomic_pool_size) ++ schedule_work(&atomic_pool_work); + +- return dma_guess_pool_from_device(dev); ++ *cpu_addr = (void *)addr; ++ memset(*cpu_addr, 0, size); ++ return pfn_to_page(__phys_to_pfn(phys)); + } + +-void *dma_alloc_from_pool(struct device *dev, size_t size, +- struct page **ret_page, gfp_t flags) ++struct page *dma_alloc_from_pool(struct device *dev, size_t size, ++ void **cpu_addr, gfp_t gfp, ++ bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t)) + { + struct gen_pool *pool = NULL; +- unsigned long val = 0; +- void *ptr = NULL; +- phys_addr_t phys; +- +- while (1) { +- pool = dma_guess_pool(dev, pool); +- if (!pool) { +- WARN(1, "Failed to get suitable pool for %s\n", +- dev_name(dev)); +- break; +- } +- +- val = gen_pool_alloc(pool, size); +- if (!val) +- continue; +- +- phys = gen_pool_virt_to_phys(pool, val); +- if (dma_coherent_ok(dev, phys, size)) +- break; +- +- gen_pool_free(pool, val, size); +- val = 0; +- } +- +- +- if (val) { +- *ret_page = pfn_to_page(__phys_to_pfn(phys)); +- ptr = (void *)val; +- memset(ptr, 0, size); ++ struct page *page; + +- if (gen_pool_avail(pool) < atomic_pool_size) +- schedule_work(&atomic_pool_work); ++ while ((pool = dma_guess_pool(pool, gfp))) { ++ page = __dma_alloc_from_pool(dev, size, pool, cpu_addr, ++ phys_addr_ok); ++ if (page) ++ return page; + } + +- return ptr; ++ WARN(1, "Failed to get suitable pool for %s\n", dev_name(dev)); ++ return NULL; + } + + bool dma_free_from_pool(struct device *dev, void *start, size_t size) + { + struct gen_pool *pool = NULL; + +- while (1) { +- pool = dma_guess_pool(dev, pool); +- if (!pool) +- return false; +- +- if (gen_pool_has_addr(pool, (unsigned long)start, size)) { +- gen_pool_free(pool, (unsigned long)start, size); +- return true; +- } ++ while ((pool = dma_guess_pool(pool, 0))) { ++ if (!gen_pool_has_addr(pool, (unsigned long)start, size)) ++ continue; ++ gen_pool_free(pool, (unsigned long)start, size); ++ return true; + } ++ ++ return false; + } diff --git a/kernel.spec b/kernel.spec index e1aaeea57..136cb7244 100644 --- a/kernel.spec +++ b/kernel.spec @@ -56,7 +56,7 @@ Summary: The Linux kernel %global zipsed -e 's/\.ko$/\.ko.xz/' %endif -# define buildid .local +%define buildid .rpi1 %if 0%{?fedora} %define primary_target fedora @@ -860,6 +860,9 @@ Patch100: 0001-Work-around-for-gcc-bug-https-gcc.gnu.org-bugzilla-s.patch Patch101: 0001-PCI-Add-MCFG-quirks-for-Tegra194-host-controllers.patch Patch102: 0002-arm64-tegra-Re-order-PCIe-aperture-mappings-to-suppo.patch Patch103: arm64-tegra-Use-valid-PWM-period-for-VDD_GPU-on-Tegra210.patch + +# https://lkml.org/lkml/2020/8/14/221 +Patch104: dma-pool-fixes.patch # END OF PATCH DEFINITIONS %endif -- cgit From c129e1aaf47bdc3380f816ad78ac89fe58f5f123 Mon Sep 17 00:00:00 2001 From: "Justin M. Forbes" Date: Wed, 19 Aug 2020 07:36:59 -0500 Subject: Linux v5.8.2 Signed-off-by: Justin M. Forbes --- kernel.spec | 5 ++++- sources | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/kernel.spec b/kernel.spec index 136cb7244..f2c53e4f1 100644 --- a/kernel.spec +++ b/kernel.spec @@ -92,7 +92,7 @@ Summary: The Linux kernel %if 0%{?released_kernel} # Do we have a -stable update to apply? -%define stable_update 1 +%define stable_update 2 # Set rpm version accordingly %if 0%{?stable_update} %define stablerev %{stable_update} @@ -2967,6 +2967,9 @@ fi # # %changelog +* Wed Aug 19 2020 Justin M. Forbes - 5.8.2-300.rpi1 +- Linux v5.8.2 + * Wed Aug 12 2020 Justin M. Forbes - 5.8.0-1.1 - Linux v5.8.1 diff --git a/sources b/sources index b4ea24bb0..f2c0775d5 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ SHA512 (linux-5.8.tar.xz) = 19c8694bda4533464877e2d976aca95f48c2c40c11efcc1dce0ca91cc5f9826110e277c7de2a49ff99af8ae1c76e275b7c463abf71fbf410956d63066dc4ee53 -SHA512 (patch-5.8.1.xz) = 36073168fe7478f93e5b9dc7f4214891f1eabb9b908c0282032770be21bd49adb51040037dd7a901b24910dfbbc65d507c75d71153b746021e0558d5e9aa30ae +SHA512 (patch-5.8.2.xz) = b83fa3d836c22c858c11a5ba7d19028e9e19586606453e7de99e65225abc9242253b381fc4b4d781dd72a3ba74c496c1c98499cc086b142109f42718de143081 -- cgit From 5b833d6ee8ae0e18c0cb7d345421780ff1713d6a Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Wed, 19 Aug 2020 15:28:21 +0100 Subject: remove local buildid I accidentally pushed --- kernel.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel.spec b/kernel.spec index f2c53e4f1..43e175ff0 100644 --- a/kernel.spec +++ b/kernel.spec @@ -56,7 +56,7 @@ Summary: The Linux kernel %global zipsed -e 's/\.ko$/\.ko.xz/' %endif -%define buildid .rpi1 +# define buildid .local %if 0%{?fedora} %define primary_target fedora -- cgit