Received: by 10.223.164.202 with SMTP id h10csp1609621wrb; Thu, 23 Nov 2017 21:59:08 -0800 (PST) X-Google-Smtp-Source: AGs4zMZndhSqQL68+kJiUpze94uRNqvPv3R/XS3q3CjJ2NoVK17Z62YRDRU8NH+IrFAt5Jq4FHIv X-Received: by 10.98.209.75 with SMTP id t11mr11515892pfl.161.1511503147926; Thu, 23 Nov 2017 21:59:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511503147; cv=none; d=google.com; s=arc-20160816; b=AtSxG6hMLGNRbl+IzoiPXg3eAh25a2QS1w30N6xwLwhMrcXVhfQNAXtGvhbEORhRGy O7OMvg20aXP8PYgjk3EdXvUB8j7zv3kOFFn9FwD9dK0v0myoTE5vjfXsMnMtF5iaAYeg NHSiH9hnKjCzxRrL2eS0ZDWLtBt3bgukA6dTBUpmGgB1taedcLcZn87H6A0ucGUrgFMm hEyGNuoeXgjl/Yw1fa8mu9YBpCj0sK4QaBaD8G3NShpAvYWcTrRC87JcUBvE1243AhqB 0nFqxGHcZ74TiQ2zW71W5kpAAOPuP2o/rOcYx8JSg+8fCc+FKxmak1POjJ8yEx8Rpfsu ZiWA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:dlp-filter:cms-type:message-id :date:subject:cc:to:from:dkim-signature:dkim-filter :arc-authentication-results; bh=iDYutmQWGykenTbLxqd+qCkMYFJpZwJRLuHNAV1auz4=; b=EjuXTaIEHj+3bIkXhoLpqVMBUh92aDJQxE5S9YYpk+gWSqmYTSeqHjr0VdGgJj3UOl iUywjs7PMU/C5JTv5zgFH1IbQRcoYwO72mg4deviZMPLKiq7mMv9kALhZWlJEb/rIWJv f/6hpVDbWoKpSSOE+jZ3uSi6i+xJ8dq+patmJxP8x2GtRl1o2PjOrvJ2yKT4XgG6yUHM XA45zwPerYMkApsUp1laC3351ZXilvu2s/QWwll7TWvK3MsK5AVY2a+GpEflCdppLeBM XGeUwwtuCqujAQBvyIH3FrxG3SOngGhiBEJIEBvFIJVSEJahPT8/lhOd9WQrO4uRzetA 0kjA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@samsung.com header.s=mail20170921 header.b=EMQijjkC; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=samsung.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m61si11395249plb.136.2017.11.23.21.58.56; Thu, 23 Nov 2017 21:59:07 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@samsung.com header.s=mail20170921 header.b=EMQijjkC; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=samsung.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752016AbdKXF6Q (ORCPT + 76 others); Fri, 24 Nov 2017 00:58:16 -0500 Received: from mailout1.samsung.com ([203.254.224.24]:62648 "EHLO mailout1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750853AbdKXF6O (ORCPT ); Fri, 24 Nov 2017 00:58:14 -0500 Received: from epcas1p1.samsung.com (unknown [182.195.41.45]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20171124055812epoutp01b47ccfea687dd14297d4c34d1e0d33ea~58A35PqXZ2120121201epoutp01Z; Fri, 24 Nov 2017 05:58:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20171124055812epoutp01b47ccfea687dd14297d4c34d1e0d33ea~58A35PqXZ2120121201epoutp01Z DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1511503092; bh=iDYutmQWGykenTbLxqd+qCkMYFJpZwJRLuHNAV1auz4=; h=From:To:Cc:Subject:Date:References:From; b=EMQijjkCTRMOdyVsxRbf1sLvbWVY0w1OXird1leJx2eg6Mn6NwEmGFAQs6RXD53ta c6i65fO7dy8q5WsiC9AeGsWtCmW/36/TFWTOSSe2bKteLwwEFZeIwjK23KC4SEaZCR 0/aElBH5n8GM9huq6nmYkWKSo/38gCgWUsKsD4hQ= Received: from epsmges1p1.samsung.com (unknown [182.195.40.90]) by epcas1p3.samsung.com (KnoxPortal) with ESMTP id 20171124055812epcas1p349ac3a472d8370de66af5480d1247991~58A3SypwP2023420234epcas1p3E; Fri, 24 Nov 2017 05:58:12 +0000 (GMT) Received: from epcas1p1.samsung.com ( [182.195.41.45]) by epsmges1p1.samsung.com (Symantec Messaging Gateway) with SMTP id FA.8B.04317.4F4B71A5; Fri, 24 Nov 2017 14:58:12 +0900 (KST) Received: from epsmgms2p1new.samsung.com (unknown [182.195.42.142]) by epcas1p3.samsung.com (KnoxPortal) with ESMTP id 20171124055811epcas1p364177b515eb072d25cd9f49573daef72~58A2_ANRv3127831278epcas1p30; Fri, 24 Nov 2017 05:58:11 +0000 (GMT) X-AuditID: b6c32a35-c51ff700000010dd-0f-5a17b4f4d9cc Received: from epmmp2 ( [203.254.227.17]) by epsmgms2p1new.samsung.com (Symantec Messaging Gateway) with SMTP id A0.29.04148.3F4B71A5; Fri, 24 Nov 2017 14:58:11 +0900 (KST) Received: from jaewon-linux.165.213.246.161 ([10.253.100.37]) by mmp2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OZW0087LR8XU9D0@mmp2.samsung.com>; Fri, 24 Nov 2017 14:58:11 +0900 (KST) From: Jaewon Kim To: m.szyprowski@samsung.com, hch@lst.de, robin.murphy@arm.com, gregkh@linuxfoundation.org Cc: iommu@lists.linux-foundation.org, akpm@linux-foundation.org, mhocko@suse.com, vbabka@suse.cz, linux-mm@kvack.org, linux-kernel@vger.kernel.org, jaewon31.kim@gmail.com, Jaewon Kim Subject: [RFC v2] dma-coherent: introduce no-align to avoid allocation failure and save memory Date: Fri, 24 Nov 2017 14:58:33 +0900 Message-id: <20171124055833.10998-1-jaewon31.kim@samsung.com> X-Mailer: git-send-email 2.13.0 X-Brightmail-Tracker: H4sIAAAAAAAAAzWSe0hTYRjG+7az7XhZHGbWl0GOQwUWrp216TFdGEYdSmIQQSxlHvTLzdyl nU0y/GNiFzXzTnbRWNpNXU3nuhfhDbsRlJVFaDct6Ga4zC6EHTf973ne9/d+78PHiwtlj0Ux uMniQHYLm0+Kw7ErvXHx8T/8i/TKtt8Y3ej1iOmSFq+Ybm3vF9DuO8n04a7jgD4y/klAD95o FNMjnmkRfbFvWEK/rkylu7+PiuiTxZUgNZLxnPIA5vqJYQnjm6iVMHeP/cWYO00eCVP34jxg br50iZlKfxtgvP5nGPPQ3SdhAr6lugg9SjEiNgfZ5ciSbc0xWXK15JZthjSDJkFJxVNJdCIp t7BmpCU3pOviN5ry+eykvIDNd/IlHctx5Op1KXar04HkRivn0JI7KUqloJSJCpVKpVAnZq5V aXgkCxlLix9hNt/mvScvxbmAS1sOwnBIqKG7bAIrB+G4jLgG4IvJDkHITAE4NFArmKPeu0Zm Gx0AdjW8FYXMNIAV3hbJDCUmVsFxd61oRi8gMuC/unbJDCQkhgA8Pfgg+FQUkQU7yiqCGiOW w7FAfXBASmhh4ECVOLQuFj79UxUMBYlbYlj+oHc2xwZYOlw+C0XBTwN+fgPO6yXwSb82xB/m E3V6Z/lS3rwxhfQaOBEIgBktJObDb5MVotCsFJYelIUQBl4aGZeE9HrY6n4ZxGVEJuy658eq wWI3mNcGFiIbZ85FHGWjFBxr5pyWXEW21ewDwXNaqbkG6h+l9wACB2Sk1PZuoV4mYgu4QnMP gLiQXCCNHeNL0hy2cB+yWw12Zz7ieoCG/44aYUx0tpU/TovDQKmTlOoElUZDKWk1uUga7X2+ Q0bksg60GyEbss/NCfCwGBeINssjjumink5UN7RSRYPJ989UZhxteJhUt7Xu7a9Ntp++8xea jp5N26cM3HZO9X3f/zWv5HLNlf6sPYcWL28OdG3/0Bz+EW9fEdb7Ws8WGl5dlaUOxCUEvlyt Ltl9zlDf/cb43jvaObRsqQw7fV1/35/nq/pg8sSMFZkyjLs+o7J0EuOMLLVSaOfY/ygzzeNk AwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrJLMWRmVeSWpSXmKPExsVy+t9jQd3PW8SjDPq+a1rMWb+GzaJ58Xo2 i5WrjzJZLNhvbdG9eSajRe/7V0wWl3fNYbO4t+Y/q8XaI3fZLe73OVgc/PCE1WJ2Yx+jA4/H mnlrGD12zrrL7rHp0yR2jxMzfrN47J+7ht1j8o3ljB67bzawefRtWcXosX7LVRaPMwuOsHt8 3iQXwB3FZZOSmpNZllqkb5fAldHReI6lYJNXxex1mg2MDbZdjJwcEgImEo8b7jF1MXJxCAms Y5RY+vg1M4TTyCSxcPkqdpAqNgFtifcLJrGC2CICMRLLnjxjByliFrjOKPG9/wwTSEJYIEFi /ZLdLCA2i4CqxNPPU8AaeAVsJT639rNBrJOXuPKrn2UCI9cCRoZVjJKpBcW56bnFRgWGeanl esWJucWleel6yfm5mxiBAbjtsFbfDsb7S+IPMQpwMCrx8BY8EosSYk0sK67MPcQowcGsJMIr /xQoxJuSWFmVWpQfX1Sak1p8iFGag0VJnPd23rFIIYH0xJLU7NTUgtQimCwTB6dUA6PJ4ktV XbkvztnbhS2LWPN4n9Xfjh+uG/o9Hy4p+RPz+aEby4Gn6pZWy+9PPapRI1xy6v3h+NUK+5Jj j09g0XM6oh/n9Um054FRnpESa19QhNEHQwt16xXcu33XJhmV+EhE/30a81j0gYpLkp+ZXmqi lALLofR3t5pWWs2osnMrNf71bKpfnBJLcUaioRZzUXEiAEJu1MI8AgAA X-CMS-MailID: 20171124055811epcas1p364177b515eb072d25cd9f49573daef72 X-Msg-Generator: CA CMS-TYPE: 101P DLP-Filter: Pass X-CFilter-Loop: Reflected X-CMS-RootMailID: 20171124055811epcas1p364177b515eb072d25cd9f49573daef72 X-RootMTR: 20171124055811epcas1p364177b515eb072d25cd9f49573daef72 References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org dma-coherent uses bitmap APIs which internally consider align based on the requested size. If most of allocations are small size like KBs, using alignment scheme seems to be good for anti-fragmentation. But if large allocation are commonly used, then an allocation could be failed because of the alignment. To avoid the allocation failure, we had to increase total size. This is a example, total size is 30MB, only few memory at front is being used, and 9MB is being requsted. Then 9MB will be aligned to 16MB. The first try on offset 0MB will be failed because others already are using them. The second try on offset 16MB will be failed because of ouf of bound. So if the alignment is not necessary on a specific dma-coherent memory region, we can set no-align property. Then dma-coherent will ignore the alignment only for the memory region. patch changelog: v2: use no-align property rather than forcely using no-align Signed-off-by: Jaewon Kim --- .../bindings/reserved-memory/reserved-memory.txt | 6 +++ arch/arm/mm/dma-mapping-nommu.c | 3 +- drivers/base/dma-coherent.c | 49 ++++++++++++++++------ include/linux/dma-mapping.h | 12 +++--- 4 files changed, 50 insertions(+), 20 deletions(-) diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt index 16291f2a4688..b279e111a7ca 100644 --- a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt +++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt @@ -63,6 +63,12 @@ reusable (optional) - empty property able to reclaim it back. Typically that means that the operating system can use that region to store volatile or cached data that can be otherwise regenerated or migrated elsewhere. +no-align (optional) - empty property + - Depending on a device or its usage pattern, tring to do aligning is not + useful. Because of aligning, allocation can be failed and that leads to + increasing total memory size to avoid the allocation failure. This + property indicates allocator will not try to do aligning on size nor + offset. Linux implementation note: - If a "linux,cma-default" property is present, then Linux will use the diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c index 6db5fc26d154..6512dae5d19b 100644 --- a/arch/arm/mm/dma-mapping-nommu.c +++ b/arch/arm/mm/dma-mapping-nommu.c @@ -75,8 +75,7 @@ static void arm_nommu_dma_free(struct device *dev, size_t size, if (attrs & DMA_ATTR_NON_CONSISTENT) { ops->free(dev, size, cpu_addr, dma_addr, attrs); } else { - int ret = dma_release_from_global_coherent(get_order(size), - cpu_addr); + int ret = dma_release_from_global_coherent(size, cpu_addr); WARN_ON_ONCE(ret == 0); } diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c index 1e6396bb807b..95d96bd764d9 100644 --- a/drivers/base/dma-coherent.c +++ b/drivers/base/dma-coherent.c @@ -17,6 +17,7 @@ struct dma_coherent_mem { int flags; unsigned long *bitmap; spinlock_t spinlock; + bool no_align; bool use_dev_dma_pfn_offset; }; @@ -163,19 +164,35 @@ EXPORT_SYMBOL(dma_mark_declared_memory_occupied); static void *__dma_alloc_from_coherent(struct dma_coherent_mem *mem, ssize_t size, dma_addr_t *dma_handle) { - int order = get_order(size); unsigned long flags; int pageno; void *ret; spin_lock_irqsave(&mem->spinlock, flags); - if (unlikely(size > (mem->size << PAGE_SHIFT))) + if (unlikely(size > (mem->size << PAGE_SHIFT))) { + WARN_ONCE(1, "%s too big size, req-size: %zu total-size: %d\n", + __func__, size, (mem->size << PAGE_SHIFT)); goto err; + } - pageno = bitmap_find_free_region(mem->bitmap, mem->size, order); - if (unlikely(pageno < 0)) - goto err; + if (mem->no_align) { + int nr_page = PAGE_ALIGN(size) >> PAGE_SHIFT; + + pageno = bitmap_find_next_zero_area(mem->bitmap, mem->size, 0, + nr_page, 0); + if (unlikely(pageno >= mem->size)) { + pr_err("%s: alloc failed, req-size: %u pages\n", __func__, nr_page); + goto err; + } + bitmap_set(mem->bitmap, pageno, nr_page); + } else { + int order = get_order(size); + + pageno = bitmap_find_free_region(mem->bitmap, mem->size, order); + if (unlikely(pageno < 0)) + goto err; + } /* * Memory was found in the coherent area. @@ -235,7 +252,7 @@ void *dma_alloc_from_global_coherent(ssize_t size, dma_addr_t *dma_handle) } static int __dma_release_from_coherent(struct dma_coherent_mem *mem, - int order, void *vaddr) + size_t size, void *vaddr) { if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) { @@ -243,7 +260,12 @@ static int __dma_release_from_coherent(struct dma_coherent_mem *mem, unsigned long flags; spin_lock_irqsave(&mem->spinlock, flags); - bitmap_release_region(mem->bitmap, page, order); + if (mem->no_align) + bitmap_clear(mem->bitmap, page, + PAGE_ALIGN(size) >> PAGE_SHIFT); + else + bitmap_release_region(mem->bitmap, page, + get_order(size)); spin_unlock_irqrestore(&mem->spinlock, flags); return 1; } @@ -253,7 +275,7 @@ static int __dma_release_from_coherent(struct dma_coherent_mem *mem, /** * dma_release_from_dev_coherent() - free memory to device coherent memory pool * @dev: device from which the memory was allocated - * @order: the order of pages allocated + * @size: the size of allocated * @vaddr: virtual address of allocated pages * * This checks whether the memory was allocated from the per-device @@ -262,20 +284,20 @@ static int __dma_release_from_coherent(struct dma_coherent_mem *mem, * Returns 1 if we correctly released the memory, or 0 if the caller should * proceed with releasing memory from generic pools. */ -int dma_release_from_dev_coherent(struct device *dev, int order, void *vaddr) +int dma_release_from_dev_coherent(struct device *dev, ssize_t size, void *vaddr) { struct dma_coherent_mem *mem = dev_get_coherent_memory(dev); - return __dma_release_from_coherent(mem, order, vaddr); + return __dma_release_from_coherent(mem, size, vaddr); } EXPORT_SYMBOL(dma_release_from_dev_coherent); -int dma_release_from_global_coherent(int order, void *vaddr) +int dma_release_from_global_coherent(ssize_t size, void *vaddr) { if (!dma_coherent_default_memory) return 0; - return __dma_release_from_coherent(dma_coherent_default_memory, order, + return __dma_release_from_coherent(dma_coherent_default_memory, size, vaddr); } @@ -347,6 +369,7 @@ static struct reserved_mem *dma_reserved_default_memory __initdata; static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev) { struct dma_coherent_mem *mem = rmem->priv; + unsigned long node = rmem->fdt_node; int ret; if (!mem) { @@ -361,6 +384,8 @@ static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev) } mem->use_dev_dma_pfn_offset = true; rmem->priv = mem; + if (of_get_flat_dt_prop(node, "no-align", NULL)) + mem->no_align = true; dma_assign_coherent_memory(dev, mem); return 0; } diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index e8f8e8fb244d..883e4ccb7c59 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -162,20 +162,20 @@ static inline int is_device_dma_capable(struct device *dev) */ int dma_alloc_from_dev_coherent(struct device *dev, ssize_t size, dma_addr_t *dma_handle, void **ret); -int dma_release_from_dev_coherent(struct device *dev, int order, void *vaddr); +int dma_release_from_dev_coherent(struct device *dev, ssize_t size, void *vaddr); int dma_mmap_from_dev_coherent(struct device *dev, struct vm_area_struct *vma, void *cpu_addr, size_t size, int *ret); void *dma_alloc_from_global_coherent(ssize_t size, dma_addr_t *dma_handle); -int dma_release_from_global_coherent(int order, void *vaddr); +int dma_release_from_global_coherent(ssize_t size, void *vaddr); int dma_mmap_from_global_coherent(struct vm_area_struct *vma, void *cpu_addr, size_t size, int *ret); #else #define dma_alloc_from_dev_coherent(dev, size, handle, ret) (0) -#define dma_release_from_dev_coherent(dev, order, vaddr) (0) -#define dma_mmap_from_dev_coherent(dev, vma, vaddr, order, ret) (0) +#define dma_release_from_dev_coherent(dev, size, vaddr) (0) +#define dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, ret) (0) static inline void *dma_alloc_from_global_coherent(ssize_t size, dma_addr_t *dma_handle) @@ -183,7 +183,7 @@ static inline void *dma_alloc_from_global_coherent(ssize_t size, return NULL; } -static inline int dma_release_from_global_coherent(int order, void *vaddr) +static inline int dma_release_from_global_coherent(size_t size, void *vaddr) { return 0; } @@ -536,7 +536,7 @@ static inline void dma_free_attrs(struct device *dev, size_t size, BUG_ON(!ops); WARN_ON(irqs_disabled()); - if (dma_release_from_dev_coherent(dev, get_order(size), cpu_addr)) + if (dma_release_from_dev_coherent(dev, size, cpu_addr)) return; if (!ops->free || !cpu_addr) -- 2.13.0 From 1585322862118562421@xxx Tue Nov 28 15:08:16 +0000 2017 X-GM-THRID: 1585322862118562421 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread