From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757328AbdKOREk (ORCPT ); Wed, 15 Nov 2017 12:04:40 -0500 Received: from mailout4.samsung.com ([203.254.224.34]:63451 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753905AbdKOREc (ORCPT ); Wed, 15 Nov 2017 12:04:32 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20171115170430epoutp04578af825c4988a80fd9ef3c33f57a497~3UTDuoYU11519215192epoutp04M X-AuditID: b6c32a38-1d5ff7000000119e-a6-5a0c739e32e0 MIME-version: 1.0 Content-transfer-encoding: 8BIT Content-type: text/plain; charset="utf-8" Subject: Re: [RFC PATCH] drivers: base: dma-coherent: find free region without alignment To: Marek Szyprowski , hch@lst.de, robin.murphy@arm.com, gregkh@linuxfoundation.org, iommu@lists.linux-foundation.org Cc: akpm@linux-foundation.org, mhocko@suse.com, vbabka@suse.cz, linux-mm@kvack.org, linux-kernel@vger.kernel.org, jaewon31.kim@gmail.com From: Jaewon Kim Message-id: <5A0C7391.3090801@samsung.com> Date: Thu, 16 Nov 2017 02:04:17 +0900 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.7.2 In-reply-to: <94f35456-b661-908a-bdc0-ddd74cbaf9ec@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA02SbUhTYRTHeXa3e+fL6jZbPViZXcjQ2tpdm15LU8niUn6QIhCj1kUf5mov truF60v2ZrZMaoboTDH6UNliNVfaq2S+oWZlJiVofYioCNMsMgVr2y3q2/+c8zvnec6fI8Xk DXis1GixI5uFM1F4pPj240S1soGPzle3DMcwF3xenDl2yYczV691ipjGtg3M6eZawLy4ewFn xry/JMz1jlGCeVOZyTyaeCdh6o5Ugswo1tvgBewdzyjB+r+6CbanZlbMttV7Cbbq1WXA3ntd irOVgSbA+gIvxWx/YwfBTvnjcqPyUVoR4gqRLR5ZCqyFRoshndq2Q79Jr0tW00o6lUmh4i2c GaVT2Tm5yi1GU/DbVPxBzuQIpnI5nqfWbkyzWR12FF9k5e3p1C6a1qhodYpKo9GotCm712t0 QWQvKuod6CGKTyhLqqrdeCnoWeECEVJIauHbphrgApFSOdkK4MeJdiJUkJM/ACyfVrqANAz5 +woF5gaAZZc7QYiRkQvgdNWYOMRg5HLYMbg/lMbIRPjhm1ss8GMADg49EIUKMWQ+fHSpBQ8V FpJVANaWNhGhACNdAJ66Uh+eipOr4ZdGt0R4IQk+bx7CQ1pMroTfao+GtYLMg631k2E+gsyA 1ef7woMgeZKAQ8+6xMJu2fBoWfcfHQM/dQcIYZ0lcLAzXeBPA1hx0ycSmPJg8NYo6HXw69QU EPaZB8e/V0iEXhksL5MLCAtr5vyEoLPgk3fXccG5LgDbhhVnwTLPfyZ5/pnk+c+kRoA1gUWo mDcbEE8Xa1U8Z+YdFoOqwGr2g/BtJjGt4P5ATjsgpYCKlj3TR+fLJdxB3mluB1CKUQtlyrxg SlbIOQ8hm1Vvc5gQ3w50QcfOYbGKAmvw0i12Pa1NVWuTNTodrWa01GKZwjecJycNnB3tR6gY 2f72iaQRsaUgAdtz4oztasb6pzuTe2c8t7yTF5Nl1x4m9q9yzI2PuKrjqPFdUYfXbH6S3Tcs ASNO1Hmgxfnrfc4HxValTPlzzH3+c9cKonr+8+zItMECQ0kgo5mL8G81Dizdt+VLhUSbVpOa OXBy5UzgQdbxw+zsgfvbE1iRUy7vrluXMKdZYqLEfBFHJ2E2nvsNJI6L+LEDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpkkeLIzCtJLcpLzFFi42I5/e+xoO7cYp4ogx8/bCzmrF/DZtG8eD2b xcrVR5ksFuy3tujePJPR4vKuOWwW99b8Z7VYe+Quu8X9PgeLgx+esFrMbuxjdOD2WDNvDaPH zll32T02fZrE7nFixm8Wj/1z17B7TL6xnNFj980GNo++LasYPdZvucricWbBEXaPz5vkArij uGxSUnMyy1KL9O0SuDJOnTvBXtCqWzF52iS2BsYTil2MHBwSAiYSm06ndDFycQgJrGOUeLDw EXMXIycHr4CgxI/J91hAapgF5CWOXMqGMNUlpkzJhSh/wCgx5eksNpByYYEoiWOn5rODJEQE JjNKfLy3mx0kISRwglHi3iszkASzQBejxL4FJ1hBEmwC2hLvF0xihVimJXFx8xWwSSwCqhJf ZjaB2aICERKr110DO4hTwF5i2pTT7BMY+WchuW8Wwn2zEO5bwMi8ilEytaA4Nz232KjAMC+1 XK84Mbe4NC9dLzk/dxMjMGK2Hdbq28F4f0n8IUYBDkYlHl6NJJ4oIdbEsuLK3EOMEhzMSiK8 uhFAId6UxMqq1KL8+KLSnNTiQ4zSHCxK4ry3845FCgmkJ5akZqemFqQWwWSZODilGhh1/Oze f58cOfN5cvs5dT0vNpdbbQ4N1d9c67dmbRCRSa5nb689IMG7z+pKUuhN85qdYb/m8HlfN50v te7BOXWOw3uTXd5Janz2zpynYPOI+5FleMLbWtvoOfO8ah4XGNneaaoznTrHZWvPSrPy/WVM aQ7h/frPuJcI3Hv5/YTxy+bZUp0e65RYijMSDbWYi4oTAUM87j2UAgAA X-CMS-MailID: 20171115170430epcas1p324d530f30d72b365e79b7f00ca23dfbe X-Msg-Generator: CA CMS-TYPE: 101P DLP-Filter: Pass X-CFilter-Loop: Reflected X-CMS-RootMailID: 20171114084234epcas2p44ac00494b49aa798f709c5bbdf92127a X-RootMTR: 20171114084234epcas2p44ac00494b49aa798f709c5bbdf92127a References: <20171114084229.13512-1-jaewon31.kim@samsung.com> <94f35456-b661-908a-bdc0-ddd74cbaf9ec@samsung.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hello Marek On 2017년 11월 14일 20:07, Marek Szyprowski wrote: > Hi Jaewon, > > On 2017-11-14 09:42, Jaewon Kim wrote: >> dma-coherent uses bitmap API which internally consider align based on the >> requested size. Depending on some usage pattern, using align, I think, may >> be good for fast search and anti-fragmentation. But with the align, an >> allocation may be failed. >> >> 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 of others already using. The >> second try on offset 16MB will be failed because of ouf of bound. >> >> So if the align is not necessary on dma-coherent, this patch removes the >> align policy to allow allocation without increasing the total size. > > You are right that keeping strict alignment is waste of memory for large > allocations. However for the smaller ones, typically under 1MiB, it helps > to reduce memory fragmentation. The alignment of the allocated buffers is > de-facto guaranteed by the memory management framework in Linux kernel > and there are drivers that depends on this feature. > > Maybe it would make sense to keep alignment for buffers smaller than some > predefined value (like 1MiB), something similar to config > ARM_DMA_IOMMU_ALIGNMENT in arch/arm/Kconfig. Otherwise I would expect that > some drivers will be broken by this patch. Thank you for your comment. I looked ARM_DMA_IOMMU_ALIGNMENT in ARM, it looks similar but it is using bitmap_find_next_zero_area rather than bitmap_find_free_region. bitmap_find_next_zero_area apply aligning only onto offset but not onto size. So I think ARM_DMA_IOMMU_ALIGNMENT way is not perfect on this dma-coherent APIs which tries to align even on size. Let me say another way where each reserved_mem from device tree can decide if it wants aligning. This could be implemented like below. I need to change other dma-coherent APIs though. I will wait for your comment on this. --- a/drivers/base/dma-coherent.c +++ b/drivers/base/dma-coherent.c @@ -17,6 +17,7 @@ struct dma_coherent_mem { unsigned long *bitmap; spinlock_t spinlock; bool use_dev_dma_pfn_offset; + bool no_align; }; static struct dma_coherent_mem *dma_coherent_default_memory __ro_after_init; @@ -162,7 +163,6 @@ 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; @@ -172,9 +172,21 @@ static void *__dma_alloc_from_coherent(struct dma_coherent_mem *mem, if (unlikely(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)) + 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. @@ -346,6 +358,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) { @@ -360,6 +373,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; } > >> Signed-off-by: Jaewon Kim >> --- >> drivers/base/dma-coherent.c | 8 +++++--- >> 1 file changed, 5 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c >> index 744f64f43454..b86a96d0cd07 100644 >> --- a/drivers/base/dma-coherent.c >> +++ b/drivers/base/dma-coherent.c >> @@ -162,7 +162,7 @@ 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); >> + int nr_page = PAGE_ALIGN(size) >> PAGE_SHIFT; >> unsigned long flags; >> int pageno; >> void *ret; >> @@ -172,9 +172,11 @@ static void *__dma_alloc_from_coherent(struct dma_coherent_mem *mem, >> if (unlikely(size > (mem->size << PAGE_SHIFT))) >> goto err; >> - pageno = bitmap_find_free_region(mem->bitmap, mem->size, order); >> - if (unlikely(pageno < 0)) >> + pageno = bitmap_find_next_zero_area(mem->bitmap, mem->size, 0, >> + nr_page, 0); >> + if (unlikely(pageno >= mem->size)) { >> goto err; >> + bitmap_set(mem->bitmap, pageno, nr_page); >> /* >> * Memory was found in the coherent area. > > Best regards