From patchwork Wed Jan 16 15:31:22 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 14086 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 7BDB523E57 for ; Wed, 16 Jan 2013 15:32:08 +0000 (UTC) Received: from mail-vb0-f43.google.com (mail-vb0-f43.google.com [209.85.212.43]) by fiordland.canonical.com (Postfix) with ESMTP id 1A17FA1934D for ; Wed, 16 Jan 2013 15:32:08 +0000 (UTC) Received: by mail-vb0-f43.google.com with SMTP id fs19so1442715vbb.2 for ; Wed, 16 Jan 2013 07:32:07 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:x-forwarded-to:x-forwarded-for:delivered-to:x-received :received-spf:x-auditid:from:to:date:message-id:x-mailer:in-reply-to :references:x-brightmail-tracker:cc:subject:x-beenthere :x-mailman-version:precedence:list-id:list-unsubscribe:list-archive :list-post:list-help:list-subscribe:mime-version:content-type :content-transfer-encoding:sender:errors-to:x-gm-message-state; bh=BVeggZ7E+HZrenbtcSeBy49MfH4EmWpwyzC9kH4RDKQ=; b=DFj4TARt0wRmjs2giowKqurbKP+4ssJh7HCWLjidP0bQEDBnj3vGrnRO29kdDXXjwh +Dl312HAHSxaVC4cQOZuenviRppU2dcB6cJOSEo5/K9bcNDD/ZSKQ4ZKWbkSCbUqvHBz +GHoQTO+OQnSrZ8Lx8BD+AIlbGaxsPcKgkGBPzl+slo8zjVB9Rp1P7ampYEwBitFkif2 ALIWM5ETUroTGatcTtru8aTLX+L+5a8sLcs6ywlCaJfu4k8BXrkP88ySr5968zVKx5sF w2WMwAaczSoJyaiYvIsM3OwDKlBnl3NXWLgb8wxOtSqFMm2d1ktl94b9LsPAU3Tw9Z40 Y0Ew== X-Received: by 10.52.97.7 with SMTP id dw7mr1409166vdb.38.1358350327586; Wed, 16 Jan 2013 07:32:07 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.58.145.101 with SMTP id st5csp172794veb; Wed, 16 Jan 2013 07:32:06 -0800 (PST) X-Received: by 10.204.128.203 with SMTP id l11mr509638bks.70.1358350325278; Wed, 16 Jan 2013 07:32:05 -0800 (PST) Received: from mombin.canonical.com (mombin.canonical.com. [91.189.95.16]) by mx.google.com with ESMTP id gg7si33017778bkc.131.2013.01.16.07.32.02; Wed, 16 Jan 2013 07:32:05 -0800 (PST) Received-SPF: neutral (google.com: 91.189.95.16 is neither permitted nor denied by best guess record for domain of linaro-mm-sig-bounces@lists.linaro.org) client-ip=91.189.95.16; Authentication-Results: mx.google.com; spf=neutral (google.com: 91.189.95.16 is neither permitted nor denied by best guess record for domain of linaro-mm-sig-bounces@lists.linaro.org) smtp.mail=linaro-mm-sig-bounces@lists.linaro.org Received: from localhost ([127.0.0.1] helo=mombin.canonical.com) by mombin.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1TvUy3-0003Ne-7Q; Wed, 16 Jan 2013 15:31:55 +0000 Received: from mailout1.samsung.com ([203.254.224.24]) by mombin.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1TvUy2-0003NZ-4C for linaro-mm-sig@lists.linaro.org; Wed, 16 Jan 2013 15:31:54 +0000 Received: from epcpsbgm2.samsung.com (epcpsbgm2 [203.254.230.27]) by mailout1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MGQ00FD45T2AD20@mailout1.samsung.com> for linaro-mm-sig@lists.linaro.org; Thu, 17 Jan 2013 00:31:50 +0900 (KST) X-AuditID: cbfee61b-b7f616d00000319b-f6-50f6c7e6ae43 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 55.98.12699.6E7C6F05; Thu, 17 Jan 2013 00:31:50 +0900 (KST) Received: from localhost.localdomain ([106.116.147.30]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MGQ00DNK5SNVP80@mmp1.samsung.com> for linaro-mm-sig@lists.linaro.org; Thu, 17 Jan 2013 00:31:50 +0900 (KST) From: Marek Szyprowski To: linux-arm-kernel@lists.infradead.org, linaro-mm-sig@lists.linaro.org Date: Wed, 16 Jan 2013 16:31:22 +0100 Message-id: <1358350284-6972-2-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1358350284-6972-1-git-send-email-m.szyprowski@samsung.com> References: <1358350284-6972-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrEJMWRmVeSWpSXmKPExsVy+t9jAd1nx78FGNzolLP4cuUhkwOjx+1/ j5kDGKO4bFJSczLLUov07RK4Ms7euc9UMEOl4tmcdSwNjFdluhg5OSQETCQ2vOpng7DFJC7c Ww9kc3EICSxilNgzewUjhLOKSeJ7xzmwKjYBQ4mut11gtoiAh8STFeeYQWxmgcNMEtMnRIDY wgLREl83v2EFsVkEVCWmb1/FBGLzCrhLTG34BRTnANqmIDFnkg1ImBNozJc998FGCgGVTJvS yzaBkXcBI8MqRtHUguSC4qT0XCO94sTc4tK8dL3k/NxNjGCfP5PewbiqweIQowAHoxIPr2fh 1wAh1sSy4srcQ4wSHMxKIrw2e78FCPGmJFZWpRblxxeV5qQWH2KU5mBREudlPPUkQEggPbEk NTs1tSC1CCbLxMEp1cCo8YiBdYr5y218LyZZPkx/e37NI+NTMe4vWE+Znyk6vMveuM31hNBm swK1L28uGah1Tg5Z8qNmt0zsZ5vHu1YfVX38dyeX6SdGf7beVpFtTWKXZuQ0sRzefDGhn194 lbD+vYsharH+k9aJem8Rv8p1c+PSBl3DsmlioWv6ny3Mj7xxwMTcsctWiaU4I9FQi7moOBEA fpRU3vUBAAA= Cc: Russell King - ARM Linux , Arnd Bergmann , Michal Nazarewicz , heesub.shin@samsung.com, Minchan Kim , Kyungmin Park , sj2202.park@samsung.com, lauraa@quicinc.com Subject: [Linaro-mm-sig] [PATCH 1/2] ARM: dma-mapping: add support for CMA regions placed in highmem zone X-BeenThere: linaro-mm-sig@lists.linaro.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Unified memory management interest group." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linaro-mm-sig-bounces@lists.linaro.org Errors-To: linaro-mm-sig-bounces@lists.linaro.org X-Gm-Message-State: ALoCoQlNinc/yPmlKs5fCRFwsrkFVXEDNibgiANgv9ENsgSXgHRWMaZzCyqPSXySK4JH3NoQGMf4 This patch adds missing pieces to correctly support memory pages served from CMA regions placed in high memory zones. Please note that the default global CMA area is still put into lowmem and is limited by optional architecture specific DMA zone. One can however put device specific CMA regions in high memory zone to reduce lowmem usage. Signed-off-by: Marek Szyprowski --- arch/arm/mm/dma-mapping.c | 61 +++++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 6b2fb87..4080c37 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -186,16 +186,29 @@ static u64 get_coherent_dma_mask(struct device *dev) static void __dma_clear_buffer(struct page *page, size_t size) { - void *ptr; /* * Ensure that the allocated pages are zeroed, and that any data * lurking in the kernel direct-mapped region is invalidated. */ - ptr = page_address(page); - if (ptr) { - memset(ptr, 0, size); - dmac_flush_range(ptr, ptr + size); - outer_flush_range(__pa(ptr), __pa(ptr) + size); + if (!PageHighMem(page)) { + void *ptr = page_address(page); + if (ptr) { + memset(ptr, 0, size); + dmac_flush_range(ptr, ptr + size); + outer_flush_range(__pa(ptr), __pa(ptr) + size); + } + } else { + phys_addr_t base = __pfn_to_phys(page_to_pfn(page)); + phys_addr_t end = base + size; + while (size > 0) { + void *ptr = kmap_atomic(page); + memset(ptr, 0, PAGE_SIZE); + dmac_flush_range(ptr, ptr + PAGE_SIZE); + kunmap_atomic(ptr); + page++; + size -= PAGE_SIZE; + } + outer_flush_range(base, end); } } @@ -243,7 +256,8 @@ static void __dma_free_buffer(struct page *page, size_t size) #endif static void *__alloc_from_contiguous(struct device *dev, size_t size, - pgprot_t prot, struct page **ret_page); + pgprot_t prot, struct page **ret_page, + const void *caller); static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp, pgprot_t prot, struct page **ret_page, @@ -346,10 +360,11 @@ static int __init atomic_pool_init(void) goto no_pages; if (IS_ENABLED(CONFIG_CMA)) - ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page); + ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page, + atomic_pool_init); else ptr = __alloc_remap_buffer(NULL, pool->size, GFP_KERNEL, prot, - &page, NULL); + &page, atomic_pool_init); if (ptr) { int i; @@ -542,27 +557,41 @@ static int __free_from_pool(void *start, size_t size) } static void *__alloc_from_contiguous(struct device *dev, size_t size, - pgprot_t prot, struct page **ret_page) + pgprot_t prot, struct page **ret_page, + const void *caller) { unsigned long order = get_order(size); size_t count = size >> PAGE_SHIFT; struct page *page; + void *ptr; page = dma_alloc_from_contiguous(dev, count, order); if (!page) return NULL; __dma_clear_buffer(page, size); - __dma_remap(page, size, prot); + if (!PageHighMem(page)) { + __dma_remap(page, size, prot); + ptr = page_address(page); + } else { + ptr = __dma_alloc_remap(page, size, GFP_KERNEL, prot, caller); + if (!ptr) { + dma_release_from_contiguous(dev, page, count); + return NULL; + } + } *ret_page = page; - return page_address(page); + return ptr; } static void __free_from_contiguous(struct device *dev, struct page *page, - size_t size) + void *cpu_addr, size_t size) { - __dma_remap(page, size, pgprot_kernel); + if (!PageHighMem(page)) + __dma_remap(page, size, pgprot_kernel); + else + __dma_free_remap(cpu_addr, size); dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT); } @@ -645,7 +674,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, else if (!IS_ENABLED(CONFIG_CMA)) addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller); else - addr = __alloc_from_contiguous(dev, size, prot, &page); + addr = __alloc_from_contiguous(dev, size, prot, &page, caller); if (addr) *handle = pfn_to_dma(dev, page_to_pfn(page)); @@ -739,7 +768,7 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr, * Non-atomic allocations cannot be freed with IRQs disabled */ WARN_ON(irqs_disabled()); - __free_from_contiguous(dev, page, size); + __free_from_contiguous(dev, page, cpu_addr, size); } }