Re: [PATCH 1/3] init: Declare rodata_enabled and mark_rodata_ro() at all time
Hi Christophe, On 31.01.2024 21:07, Christophe Leroy wrote: > Le 31/01/2024 à 16:17, Marek Szyprowski a écrit : >> [Vous ne recevez pas souvent de courriers de m.szyprow...@samsung.com. >> Découvrez pourquoi ceci est important à >> https://aka.ms/LearnAboutSenderIdentification ] >> >> On 31.01.2024 12:58, Christophe Leroy wrote: >>> Le 30/01/2024 à 18:48, Marek Szyprowski a écrit : >>>> [Vous ne recevez pas souvent de courriers de m.szyprow...@samsung.com. >>>> Découvrez pourquoi ceci est important à >>>> https://aka.ms/LearnAboutSenderIdentification ] >>>> >>>> On 30.01.2024 12:03, Christophe Leroy wrote: >>>>> Le 30/01/2024 à 10:16, Chen-Yu Tsai a écrit : >>>>>> [Vous ne recevez pas souvent de courriers de we...@chromium.org. >>>>>> D?couvrez pourquoi ceci est important ? >>>>>> https://aka.ms/LearnAboutSenderIdentification ] >>>>>> >>>>>> On Mon, Jan 29, 2024 at 12:09:50PM -0800, Luis Chamberlain wrote: >>>>>>> On Thu, Dec 21, 2023 at 10:02:46AM +0100, Christophe Leroy wrote: >>>>>>>> Declaring rodata_enabled and mark_rodata_ro() at all time >>>>>>>> helps removing related #ifdefery in C files. >>>>>>>> >>>>>>>> Signed-off-by: Christophe Leroy >>>>>>> Very nice cleanup, thanks!, applied and pushed >>>>>>> >>>>>>> Luis >>>>>> On next-20240130, which has your modules-next branch, and thus this >>>>>> series and the other "module: Use set_memory_rox()" series applied, >>>>>> my kernel crashes in some very weird way. Reverting your branch >>>>>> makes the crash go away. >>>>>> >>>>>> I thought I'd report it right away. Maybe you folks would know what's >>>>>> happening here? This is on arm64. >>>>> That's strange, it seems to bug in module_bug_finalize() which is >>>>> _before_ calls to module_enable_ro() and such. >>>>> >>>>> Can you try to revert the 6 patches one by one to see which one >>>>> introduces the problem ? >>>>> >>>>> In reality, only patch 677bfb9db8a3 really change things. Other ones are >>>>> more on less only cleanup. >>>> I've also run into this issue with today's (20240130) linux-next on my >>>> test farm. The issue is not fully reproducible, so it was a bit hard to >>>> bisect it automatically. I've spent some time on manual testing and it >>>> looks that reverting the following 2 commits on top of linux-next fixes >>>> the problem: >>>> >>>> 65929884f868 ("modules: Remove #ifdef CONFIG_STRICT_MODULE_RWX around >>>> rodata_enabled") >>>> 677bfb9db8a3 ("module: Don't ignore errors from set_memory_XX()") >>>> >>>> This in fact means that commit 677bfb9db8a3 is responsible for this >>>> regression, as 65929884f868 has to be reverted only because the latter >>>> depends on it. Let me know what I can do to help debugging this issue. >>>> >>> Thanks for the bisect. I suspect you hit one of the errors and something >>> goes wrong in the error path. >>> >>> To confirm this assumption, could you try with the following change on >>> top of everything ? >> >> Yes, this is the problem. I've added printing a mod->name to the log. >> Here is a log from kernel build from next-20240130 (sometimes it even >> boots to shell): >> >> # dmesg | grep module_set_memory >> [ 8.061525] module_set_memory(6, , 0) name ipv6 >> returned -22 >> [ 8.067543] WARNING: CPU: 3 PID: 1 at kernel/module/strict_rwx.c:22 >> module_set_memory+0x9c/0xb8 > Would be good if you could show the backtrace too so that we know who is > the caller. I guess what you show here is what you get on the screen ? > The backtrace should be available throught 'dmesg'. Here are relevant parts of the boot log: [ 8.096850] [ cut here ] [ 8.096939] module_set_memory(6, , 0) name ipv6 returned -22 [ 8.102947] WARNING: CPU: 4 PID: 1 at kernel/module/strict_rwx.c:22 module_set_memory+0x9c/0xb8 [ 8.111561] Modules linked in: [ 8.114596] CPU: 4 PID: 1 Comm: systemd Not tainted 6.8.0-rc2-next-20240130-dirty #14429 [ 8.122654] Hardware name: Khadas VIM3 (DT) [ 8.126815] pstate: 6005 (nZCv daif -PAN -UAO -TCO -DIT -
Re: [PATCH 1/3] init: Declare rodata_enabled and mark_rodata_ro() at all time
Hi Christophe, On 31.01.2024 12:58, Christophe Leroy wrote: > Le 30/01/2024 à 18:48, Marek Szyprowski a écrit : >> [Vous ne recevez pas souvent de courriers de m.szyprow...@samsung.com. >> Découvrez pourquoi ceci est important à >> https://aka.ms/LearnAboutSenderIdentification ] >> >> On 30.01.2024 12:03, Christophe Leroy wrote: >>> Le 30/01/2024 à 10:16, Chen-Yu Tsai a écrit : >>>> [Vous ne recevez pas souvent de courriers de we...@chromium.org. D?couvrez >>>> pourquoi ceci est important ? >>>> https://aka.ms/LearnAboutSenderIdentification ] >>>> >>>> On Mon, Jan 29, 2024 at 12:09:50PM -0800, Luis Chamberlain wrote: >>>>> On Thu, Dec 21, 2023 at 10:02:46AM +0100, Christophe Leroy wrote: >>>>>> Declaring rodata_enabled and mark_rodata_ro() at all time >>>>>> helps removing related #ifdefery in C files. >>>>>> >>>>>> Signed-off-by: Christophe Leroy >>>>> Very nice cleanup, thanks!, applied and pushed >>>>> >>>>> Luis >>>> On next-20240130, which has your modules-next branch, and thus this >>>> series and the other "module: Use set_memory_rox()" series applied, >>>> my kernel crashes in some very weird way. Reverting your branch >>>> makes the crash go away. >>>> >>>> I thought I'd report it right away. Maybe you folks would know what's >>>> happening here? This is on arm64. >>> That's strange, it seems to bug in module_bug_finalize() which is >>> _before_ calls to module_enable_ro() and such. >>> >>> Can you try to revert the 6 patches one by one to see which one >>> introduces the problem ? >>> >>> In reality, only patch 677bfb9db8a3 really change things. Other ones are >>> more on less only cleanup. >> I've also run into this issue with today's (20240130) linux-next on my >> test farm. The issue is not fully reproducible, so it was a bit hard to >> bisect it automatically. I've spent some time on manual testing and it >> looks that reverting the following 2 commits on top of linux-next fixes >> the problem: >> >> 65929884f868 ("modules: Remove #ifdef CONFIG_STRICT_MODULE_RWX around >> rodata_enabled") >> 677bfb9db8a3 ("module: Don't ignore errors from set_memory_XX()") >> >> This in fact means that commit 677bfb9db8a3 is responsible for this >> regression, as 65929884f868 has to be reverted only because the latter >> depends on it. Let me know what I can do to help debugging this issue. >> > Thanks for the bisect. I suspect you hit one of the errors and something > goes wrong in the error path. > > To confirm this assumption, could you try with the following change on > top of everything ? Yes, this is the problem. I've added printing a mod->name to the log. Here is a log from kernel build from next-20240130 (sometimes it even boots to shell): # dmesg | grep module_set_memory [ 8.061525] module_set_memory(6, , 0) name ipv6 returned -22 [ 8.067543] WARNING: CPU: 3 PID: 1 at kernel/module/strict_rwx.c:22 module_set_memory+0x9c/0xb8 [ 8.097821] pc : module_set_memory+0x9c/0xb8 [ 8.102068] lr : module_set_memory+0x9c/0xb8 [ 8.183101] module_set_memory+0x9c/0xb8 [ 8.472862] module_set_memory(6, , 0) name x_tables returned -22 [ 8.479215] WARNING: CPU: 2 PID: 1 at kernel/module/strict_rwx.c:22 module_set_memory+0x9c/0xb8 [ 8.510978] pc : module_set_memory+0x9c/0xb8 [ 8.515225] lr : module_set_memory+0x9c/0xb8 [ 8.596259] module_set_memory+0x9c/0xb8 [ 10.529879] module_set_memory(6, , 0) name dm_mod returned -22 [ 10.536087] WARNING: CPU: 3 PID: 127 at kernel/module/strict_rwx.c:22 module_set_memory+0x9c/0xb8 [ 10.568254] pc : module_set_memory+0x9c/0xb8 [ 10.572501] lr : module_set_memory+0x9c/0xb8 [ 10.653535] module_set_memory+0x9c/0xb8 [ 10.853177] module_set_memory(6, , 0) name fuse returned -22 [ 10.859196] WARNING: CPU: 5 PID: 130 at kernel/module/strict_rwx.c:22 module_set_memory+0x9c/0xb8 [ 10.891382] pc : module_set_memory+0x9c/0xb8 [ 10.895629] lr : module_set_memory+0x9c/0xb8 [ 10.976663] module_set_memory+0x9c/0xb8 > diff --git a/kernel/module/strict_rwx.c b/kernel/module/strict_rwx.c > index a14df9655dbe..fdf8484154dd 100644 > --- a/kernel/module/strict_rwx.c > +++ b/kernel/module/strict_rwx.c > @@ -15,9 +15,12 @@ static int module_set_memory(const struct module > *mod, enum mod_mem_type type, > int (*set_memory)(unsigned long start, int > num_pages)) >{ > const struct module_memory *mod_mem = >mem[type]; > + int err; > > set_vm_flush_reset_perms(mod_mem->base); > - return set_memory((unsigned long)mod_mem->base, mod_mem->size >> > PAGE_SHIFT); > + err = set_memory((unsigned long)mod_mem->base, mod_mem->size >> > PAGE_SHIFT); > + WARN(err, "module_set_memory(%d, %px, %x) returned %d\n", type, > mod_mem->base, mod_mem->size, err); > + return err; >} > >/* > > > Thanks for your help > Christophe Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 1/3] init: Declare rodata_enabled and mark_rodata_ro() at all time
Dear All, On 30.01.2024 12:03, Christophe Leroy wrote: > Le 30/01/2024 à 10:16, Chen-Yu Tsai a écrit : >> [Vous ne recevez pas souvent de courriers de we...@chromium.org. D?couvrez >> pourquoi ceci est important ? https://aka.ms/LearnAboutSenderIdentification ] >> >> On Mon, Jan 29, 2024 at 12:09:50PM -0800, Luis Chamberlain wrote: >>> On Thu, Dec 21, 2023 at 10:02:46AM +0100, Christophe Leroy wrote: >>>> Declaring rodata_enabled and mark_rodata_ro() at all time >>>> helps removing related #ifdefery in C files. >>>> >>>> Signed-off-by: Christophe Leroy >>> Very nice cleanup, thanks!, applied and pushed >>> >>> Luis >> On next-20240130, which has your modules-next branch, and thus this >> series and the other "module: Use set_memory_rox()" series applied, >> my kernel crashes in some very weird way. Reverting your branch >> makes the crash go away. >> >> I thought I'd report it right away. Maybe you folks would know what's >> happening here? This is on arm64. > That's strange, it seems to bug in module_bug_finalize() which is > _before_ calls to module_enable_ro() and such. > > Can you try to revert the 6 patches one by one to see which one > introduces the problem ? > > In reality, only patch 677bfb9db8a3 really change things. Other ones are > more on less only cleanup. I've also run into this issue with today's (20240130) linux-next on my test farm. The issue is not fully reproducible, so it was a bit hard to bisect it automatically. I've spent some time on manual testing and it looks that reverting the following 2 commits on top of linux-next fixes the problem: 65929884f868 ("modules: Remove #ifdef CONFIG_STRICT_MODULE_RWX around rodata_enabled") 677bfb9db8a3 ("module: Don't ignore errors from set_memory_XX()") This in fact means that commit 677bfb9db8a3 is responsible for this regression, as 65929884f868 has to be reverted only because the latter depends on it. Let me know what I can do to help debugging this issue. Here is the stack trace I've got on Khadas VIM3 ARM64 board: Unable to handle kernel paging request at virtual address 80007bfeeb30 Mem abort info: ESR = 0x9647 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x07: level 3 translation fault Data abort info: ISV = 0, ISS = 0x0047, ISS2 = 0x CM = 0, WnR = 1, TnD = 0, TagAccess = 0 GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 swapper pgtable: 4k pages, 48-bit VAs, pgdp=0a35a000 [80007bfeeb30] pgd=1000f4806003, p4d=1000f4806003, pud=17ed1003, pmd=17ed2003, pte= Internal error: Oops: 9647 [#1] PREEMPT SMP Modules linked in: CPU: 4 PID: 182 Comm: (udev-worker) Not tainted 6.8.0-rc2-next-20240130 #14391 Hardware name: Khadas VIM3 (DT) pstate: 6005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : module_bug_finalize+0xb0/0xdc lr : module_bug_finalize+0x70/0xdc ... Call trace: module_bug_finalize+0xb0/0xdc load_module+0x182c/0x1c88 init_module_from_file+0x84/0xc0 idempotent_init_module+0x180/0x250 __arm64_sys_finit_module+0x64/0xa0 invoke_syscall+0x48/0x114 el0_svc_common.constprop.0+0xc0/0xe0 do_el0_svc+0x1c/0x28 el0_svc+0x4c/0xe4 el0t_64_sync_handler+0xc0/0xc4 el0t_64_sync+0x190/0x194 Code: 9116e003 f942dc01 a93e8c41 c89ffc73 (f9000433) ---[ end trace ]--- Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v2 10/25] iommu/exynos: Implement an IDENTITY domain
On 16.05.2023 02:00, Jason Gunthorpe wrote: > What exynos calls exynos_iommu_detach_device is actually putting the iommu > into identity mode. > > Move to the new core support for ARM_DMA_USE_IOMMU by defining > ops->identity_domain. > > Signed-off-by: Jason Gunthorpe Acked-by: Marek Szyprowski > --- > drivers/iommu/exynos-iommu.c | 66 +--- > 1 file changed, 32 insertions(+), 34 deletions(-) > > diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c > index c275fe71c4db32..5e12b85dfe8705 100644 > --- a/drivers/iommu/exynos-iommu.c > +++ b/drivers/iommu/exynos-iommu.c > @@ -24,6 +24,7 @@ > > typedef u32 sysmmu_iova_t; > typedef u32 sysmmu_pte_t; > +static struct iommu_domain exynos_identity_domain; > > /* We do not consider super section mapping (16MB) */ > #define SECT_ORDER 20 > @@ -829,7 +830,7 @@ static int __maybe_unused exynos_sysmmu_suspend(struct > device *dev) > struct exynos_iommu_owner *owner = dev_iommu_priv_get(master); > > mutex_lock(>rpm_lock); > - if (data->domain) { > + if (>domain->domain != _identity_domain) { > dev_dbg(data->sysmmu, "saving state\n"); > __sysmmu_disable(data); > } > @@ -847,7 +848,7 @@ static int __maybe_unused exynos_sysmmu_resume(struct > device *dev) > struct exynos_iommu_owner *owner = dev_iommu_priv_get(master); > > mutex_lock(>rpm_lock); > - if (data->domain) { > + if (>domain->domain != _identity_domain) { > dev_dbg(data->sysmmu, "restoring state\n"); > __sysmmu_enable(data); > } > @@ -980,17 +981,20 @@ static void exynos_iommu_domain_free(struct > iommu_domain *iommu_domain) > kfree(domain); > } > > -static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain, > - struct device *dev) > +static int exynos_iommu_identity_attach(struct iommu_domain *identity_domain, > + struct device *dev) > { > - struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain); > struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev); > - phys_addr_t pagetable = virt_to_phys(domain->pgtable); > + struct exynos_iommu_domain *domain; > + phys_addr_t pagetable; > struct sysmmu_drvdata *data, *next; > unsigned long flags; > > - if (!has_sysmmu(dev) || owner->domain != iommu_domain) > - return; > + if (owner->domain == identity_domain) > + return 0; > + > + domain = to_exynos_domain(owner->domain); > + pagetable = virt_to_phys(domain->pgtable); > > mutex_lock(>rpm_lock); > > @@ -1009,15 +1013,25 @@ static void exynos_iommu_detach_device(struct > iommu_domain *iommu_domain, > list_del_init(>domain_node); > spin_unlock(>lock); > } > - owner->domain = NULL; > + owner->domain = identity_domain; > spin_unlock_irqrestore(>lock, flags); > > mutex_unlock(>rpm_lock); > > - dev_dbg(dev, "%s: Detached IOMMU with pgtable %pa\n", __func__, > - ); > + dev_dbg(dev, "%s: Restored IOMMU to IDENTITY from pgtable %pa\n", > + __func__, ); > + return 0; > } > > +static struct iommu_domain_ops exynos_identity_ops = { > + .attach_dev = exynos_iommu_identity_attach, > +}; > + > +static struct iommu_domain exynos_identity_domain = { > + .type = IOMMU_DOMAIN_IDENTITY, > + .ops = _identity_ops, > +}; > + > static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain, > struct device *dev) > { > @@ -1026,12 +1040,11 @@ static int exynos_iommu_attach_device(struct > iommu_domain *iommu_domain, > struct sysmmu_drvdata *data; > phys_addr_t pagetable = virt_to_phys(domain->pgtable); > unsigned long flags; > + int err; > > - if (!has_sysmmu(dev)) > - return -ENODEV; > - > - if (owner->domain) > - exynos_iommu_detach_device(owner->domain, dev); > + err = exynos_iommu_identity_attach(_identity_domain, dev); > + if (err) > + return err; > > mutex_lock(>rpm_lock); > > @@ -1407,26 +1420,12 @@ static struct iommu_device > *exynos_iommu_probe_device(struct device *dev) > return >iommu; > } &
Re: [PATCH v2 00/25] iommu: Make default_domain's mandatory
On 16.05.2023 02:00, Jason Gunthorpe wrote: > [ There was alot of unexpected complication after rc1 with this series, > several new patches were needed ] > > It has been a long time coming, this series completes the default_domain > transition and makes it so that the core IOMMU code will always have a > non-NULL default_domain for every driver on every > platform. set_platform_dma_ops() turned out to be a bad idea, and so > completely remove it. > > This is achieved by changing each driver to either: > > 1 - Convert the existing (or deleted) ops->detach_dev() into an > op->attach_dev() of an IDENTITY domain. > > This is based on the theory that the ARM32 HW is able to function when > the iommu is turned off as so the turned off state is an IDENTITY > translation. > > 2 - Use a new PLATFORM domain type. This is a hack to accommodate drivers > that we don't really know WTF they do. S390 is legitimately using this > to switch to it's platform dma_ops implementation, which is where the > name comes from. > > 3 - Do #1 and force the default domain to be IDENTITY, this corrects > the tegra-smmu case where even an ARM64 system would have a NULL > default_domain. > > Using this we can apply the rules: > > a) ARM_DMA_USE_IOMMU mode always uses either the driver's > ops->default_domain, ops->def_domain_type(), or an IDENTITY domain. > All ARM32 drivers provide one of these three options. > > b) dma-iommu.c mode uses either the driver's ops->default_domain, > ops->def_domain_type or the usual DMA API policy logic based on the > command line/etc to pick IDENTITY/DMA domain types > > c) All other arch's (PPC/S390) use ops->default_domain always. > > See the patch "Require a default_domain for all iommu drivers" for a > per-driver breakdown. > > The conversion broadly teaches a bunch of ARM32 drivers that they can do > IDENTITY domains. There is some educated guessing involved that these are > actual IDENTITY domains. If this turns out to be wrong the driver can be > trivially changed to use a BLOCKING domain type instead. Further, the > domain type only matters for drivers using ARM64's dma-iommu.c mode as it > will select IDENTITY based on the command line and expect IDENTITY to > work. For ARM32 and other arch cases it is purely documentation. > > Finally, based on all the analysis in this series, we can purge > IOMMU_DOMAIN_UNMANAGED/DMA constants from most of the drivers. This > greatly simplifies understanding the driver contract to the core > code. IOMMU drivers should not be involved in policy for how the DMA API > works, that should be a core core decision. > > The main gain from this work is to remove alot of ARM_DMA_USE_IOMMU > specific code and behaviors from drivers. All that remains in iommu > drivers after this series is the calls to arm_iommu_create_mapping(). > > This is a step toward removing ARM_DMA_USE_IOMMU. > > The IDENTITY domains added to the ARM64 supporting drivers can be tested > by booting in ARM64 mode and enabling CONFIG_IOMMU_DEFAULT_PASSTHROUGH. If > the system still boots then most likely the implementation is an IDENTITY > domain. If not we can trivially change it to BLOCKING or at worst PLATFORM > if there is no detail what is going on in the HW. > > I think this is pretty safe for the ARM32 drivers as they don't really > change, the code that was in detach_dev continues to be called in the same > places it was called before. Tested-by: Marek Szyprowski Works fine on ARM 32bit Exynos based boards. > This follows the prior series: > > https://lore.kernel.org/r/0-v5-1b99ae392328+44574-iommu_err_unwind_...@nvidia.com > > This is on github: > https://protect2.fireeye.com/v1/url?k=773809ed-1645e36e-773982a2-74fe48600158-bd3a7b89de1f2061=1=7f176af7-9cf3-429b-a0ce-8812c59dfb5c=https%3A%2F%2Fgithub.com%2Fjgunthorpe%2Flinux%2Fcommits%2Fiommu_all_defdom > > v2: > - FSL is an IDENTITY domain > - Delete terga-gart instead of trying to carry it > - Use the policy determination from iommu_get_default_domain_type() to > drive the arm_iommu mode > - Reorganize and introduce new patches to do the above: > * Split the ops->identity_domain to an independent earlier patch > * Remove the UNMANAGED return from def_domain_type in mtk_v1 earlier >so the new iommu_get_default_domain_type() can work > * Make the driver's def_domain_type have higher policy priority than >untrusted > * Merge the set_platfom_dma_ops hunk from mtk_v1 along with rockchip >into the patch that forced IDENTITY on ARM32 > - Revise sun50i to be cleaner and have a non-NULL internal domain > - Reword loggin
Re: [PATCH 09/30] mtd_blkdevs: use blk_mq_alloc_disk
Hi Christoph, On 15.06.2021 17:58, Christoph Hellwig wrote: > On Tue, Jun 15, 2021 at 05:47:44PM +0200, Marek Szyprowski wrote: >> On 02.06.2021 08:53, Christoph Hellwig wrote: >>> Use the blk_mq_alloc_disk API to simplify the gendisk and request_queue >>> allocation. >>> >>> Signed-off-by: Christoph Hellwig >> This patch landed in linux-next as commit 6966bb921def ("mtd_blkdevs: >> use blk_mq_alloc_disk"). It causes the following regression on my QEMU >> arm64 setup: > Please try the patch below: > > diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c > index 5dc4c966ea73..6ce4bc57f919 100644 > --- a/drivers/mtd/mtd_blkdevs.c > +++ b/drivers/mtd/mtd_blkdevs.c > @@ -382,6 +382,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) > } > > new->disk = gd; > + new->rq = new->disk->queue; > gd->private_data = new; > gd->major = tr->major; > gd->first_minor = (new->devnum) << tr->part_bits; Right, this fixes the issue, thanks. Feel free to add: Reported-by: Marek Szyprowski Tested-by: Marek Szyprowski Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 09/30] mtd_blkdevs: use blk_mq_alloc_disk
zeof(*new->tag_set), GFP_KERNEL); > - if (!new->tag_set) > - goto error3; > - > - new->rq = blk_mq_init_sq_queue(new->tag_set, _mq_ops, 2, > - BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING); > - if (IS_ERR(new->rq)) { > - ret = PTR_ERR(new->rq); > - new->rq = NULL; > - goto error4; > - } > - > if (tr->flush) > blk_queue_write_cache(new->rq, true, false); > > - new->rq->queuedata = new; > blk_queue_logical_block_size(new->rq, tr->blksize); > > blk_queue_flag_set(QUEUE_FLAG_NONROT, new->rq); > @@ -437,13 +433,13 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) > WARN_ON(ret); > } > return 0; > -error4: > + > +out_free_tag_set: > + blk_mq_free_tag_set(new->tag_set); > +out_kfree_tag_set: > kfree(new->tag_set); > -error3: > - put_disk(new->disk); > -error2: > +out_list_del: > list_del(>list); > -error1: > return ret; > } > Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [patch V3 10/37] ARM: highmem: Switch to generic kmap atomic
Hi Thomas, On 03.11.2020 10:27, Thomas Gleixner wrote: > No reason having the same code in every architecture. > > Signed-off-by: Thomas Gleixner > Cc: Russell King > Cc: Arnd Bergmann > Cc: linux-arm-ker...@lists.infradead.org This patch landed in linux-next 20201109 as commit 2a15ba82fa6c ("ARM: highmem: Switch to generic kmap atomic"). However it causes a following warning on my test boards (Samsung Exynos SoC based): Run /sbin/init as init process INIT: version 2.88 booting [ cut here ] WARNING: CPU: 3 PID: 120 at mm/highmem.c:502 kunmap_local_indexed+0x194/0x1d0 Modules linked in: CPU: 3 PID: 120 Comm: init Not tainted 5.10.0-rc2-00010-g2a15ba82fa6c #1924 Hardware name: Samsung Exynos (Flattened Device Tree) [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0xb4/0xd4) [] (dump_stack) from [] (__warn+0x98/0x104) [] (__warn) from [] (warn_slowpath_fmt+0xb0/0xb8) [] (warn_slowpath_fmt) from [] (kunmap_local_indexed+0x194/0x1d0) [] (kunmap_local_indexed) from [] (remove_arg_zero+0xa0/0x158) [] (remove_arg_zero) from [] (load_script+0x250/0x318) [] (load_script) from [] (bprm_execve+0x3d0/0x930) [] (bprm_execve) from [] (do_execveat_common+0x174/0x184) [] (do_execveat_common) from [] (sys_execve+0x30/0x38) [] (sys_execve) from [] (ret_fast_syscall+0x0/0x28) Exception stack(0xc4561fa8 to 0xc4561ff0) 1fa0: b6f2bab8 bef7dac4 bef7dac4 bef7d8fc 004b9b58 bef7dac8 1fc0: b6f2bab8 bef7dac4 bef7d8fc 000b 004b8000 004bac44 bef7da3c bef7d8dc 1fe0: 002f bef7d89c b6d6dc74 b6d6d65c irq event stamp: 1283 hardirqs last enabled at (1293): [] console_unlock+0x430/0x6b0 hardirqs last disabled at (1302): [] console_unlock+0x428/0x6b0 softirqs last enabled at (1282): [] __do_softirq+0x528/0x674 softirqs last disabled at (1269): [] irq_exit+0x1dc/0x1e8 ---[ end trace 6f32a2fb4294655f ]--- I can do more tests to help fixing this issue. Just let me know what to do. ... Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v2 00/16] PCI: dwc: Another round of clean-ups
Hi Rob, On 05.11.2020 22:11, Rob Herring wrote: > Here's another batch of DWC PCI host refactoring. This series primarily > moves more of the MSI, link up, and resource handling to the core > code. Beyond a couple of minor fixes, new in this version is runtime > detection of iATU regions instead of using DT properties. iATU detection seems to work fine with https://lore.kernel.org/linux-samsung-soc/20201029134017.27400-1-m.szyprow...@samsung.com/ on top of your patchset on Samsung Exynos5433 SoC: exynos-pcie 1570.pcie: host bridge /soc@0/pcie@1570 ranges: exynos-pcie 1570.pcie: IO 0x000c001000..0x000c010fff -> 0x00 exynos-pcie 1570.pcie: MEM 0x000c011000..0x000ffe -> 0x000c011000 exynos-pcie 1570.pcie: iATU unroll: disabled exynos-pcie 1570.pcie: Detected iATU regions: 3 outbound, 5 inbound exynos-pcie 1570.pcie: Link up exynos-pcie 1570.pcie: PCI host bridge to bus :00 Fell free to add my: Tested-by: Marek Szyprowski > No doubt I've probably broken something. Please test. I've run this thru > kernelci and checked boards with DWC PCI which currently is just > Layerscape boards (hint: add boards and/or enable PCI). A git branch is > here[1]. > > This is dependent on "PCI: dwc: Restore ATU memory resource setup to use > last entry" which will be in v5.10-rc3. > > Rob > > [1] git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git > pci-more-dwc-cleanup > > Rob Herring (16): >PCI: dwc: Support multiple ATU memory regions >PCI: dwc/intel-gw: Move ATU offset out of driver match data >PCI: dwc: Move "dbi", "dbi2", and "addr_space" resource setup into > common code >PCI: dwc/intel-gw: Remove some unneeded function wrappers >PCI: dwc: Ensure all outbound ATU windows are reset >PCI: dwc/dra7xx: Use the common MSI irq_chip >PCI: dwc: Drop the .set_num_vectors() host op >PCI: dwc: Move MSI interrupt setup into DWC common code >PCI: dwc: Rework MSI initialization >PCI: dwc: Move link handling into common code >PCI: dwc: Move dw_pcie_msi_init() into core >PCI: dwc: Move dw_pcie_setup_rc() to DWC common code >PCI: dwc: Remove unnecessary wrappers around dw_pcie_host_init() >Revert "PCI: dwc/keystone: Drop duplicated 'num-viewport'" >PCI: dwc: Move inbound and outbound windows to common struct >PCI: dwc: Detect number of iATU windows > > drivers/pci/controller/dwc/pci-dra7xx.c | 141 +- > drivers/pci/controller/dwc/pci-exynos.c | 50 ++- > drivers/pci/controller/dwc/pci-imx6.c | 39 + > drivers/pci/controller/dwc/pci-keystone.c | 79 ++ > .../pci/controller/dwc/pci-layerscape-ep.c| 37 + > drivers/pci/controller/dwc/pci-layerscape.c | 67 + > drivers/pci/controller/dwc/pci-meson.c| 53 ++- > drivers/pci/controller/dwc/pcie-al.c | 29 +--- > drivers/pci/controller/dwc/pcie-armada8k.c| 37 ++--- > drivers/pci/controller/dwc/pcie-artpec6.c | 76 +- > .../pci/controller/dwc/pcie-designware-ep.c | 58 +++ > .../pci/controller/dwc/pcie-designware-host.c | 139 ++--- > .../pci/controller/dwc/pcie-designware-plat.c | 70 + > drivers/pci/controller/dwc/pcie-designware.c | 93 +++- > drivers/pci/controller/dwc/pcie-designware.h | 24 +-- > drivers/pci/controller/dwc/pcie-histb.c | 37 ++--- > drivers/pci/controller/dwc/pcie-intel-gw.c| 67 ++--- > drivers/pci/controller/dwc/pcie-kirin.c | 62 +--- > drivers/pci/controller/dwc/pcie-qcom.c| 38 + > drivers/pci/controller/dwc/pcie-spear13xx.c | 62 +++- > drivers/pci/controller/dwc/pcie-tegra194.c| 41 +---- > drivers/pci/controller/dwc/pcie-uniphier-ep.c | 38 + > drivers/pci/controller/dwc/pcie-uniphier.c| 51 +-- > 23 files changed, 356 insertions(+), 1032 deletions(-) > > -- > 2.25.1 > Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 01/13] iommu/exynos: Use dev_iommu_priv_get/set()
On 25.06.2020 15:08, Joerg Roedel wrote: > From: Joerg Roedel > > Remove the use of dev->archdata.iommu and use the private per-device > pointer provided by IOMMU core code instead. > > Signed-off-by: Joerg Roedel Acked-by: Marek Szyprowski > --- > drivers/iommu/exynos-iommu.c | 20 +-- > .../media/platform/s5p-mfc/s5p_mfc_iommu.h| 4 +++- > 2 files changed, 13 insertions(+), 11 deletions(-) > > diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c > index 60c8a56e4a3f..6a9b67302369 100644 > --- a/drivers/iommu/exynos-iommu.c > +++ b/drivers/iommu/exynos-iommu.c > @@ -173,7 +173,7 @@ static u32 lv2ent_offset(sysmmu_iova_t iova) > #define REG_V5_FAULT_AR_VA 0x070 > #define REG_V5_FAULT_AW_VA 0x080 > > -#define has_sysmmu(dev) (dev->archdata.iommu != NULL) > +#define has_sysmmu(dev) (dev_iommu_priv_get(dev) != NULL) > > static struct device *dma_dev; > static struct kmem_cache *lv2table_kmem_cache; > @@ -226,7 +226,7 @@ static const struct sysmmu_fault_info sysmmu_v5_faults[] > = { > }; > > /* > - * This structure is attached to dev.archdata.iommu of the master device > + * This structure is attached to dev->iommu->priv of the master device >* on device add, contains a list of SYSMMU controllers defined by device > tree, >* which are bound to given master device. It is usually referenced by > 'owner' >* pointer. > @@ -670,7 +670,7 @@ static int __maybe_unused exynos_sysmmu_suspend(struct > device *dev) > struct device *master = data->master; > > if (master) { > - struct exynos_iommu_owner *owner = master->archdata.iommu; > + struct exynos_iommu_owner *owner = dev_iommu_priv_get(master); > > mutex_lock(>rpm_lock); > if (data->domain) { > @@ -688,7 +688,7 @@ static int __maybe_unused exynos_sysmmu_resume(struct > device *dev) > struct device *master = data->master; > > if (master) { > - struct exynos_iommu_owner *owner = master->archdata.iommu; > + struct exynos_iommu_owner *owner = dev_iommu_priv_get(master); > > mutex_lock(>rpm_lock); > if (data->domain) { > @@ -837,8 +837,8 @@ static void exynos_iommu_domain_free(struct iommu_domain > *iommu_domain) > static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain, > struct device *dev) > { > - struct exynos_iommu_owner *owner = dev->archdata.iommu; > struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain); > + struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev); > phys_addr_t pagetable = virt_to_phys(domain->pgtable); > struct sysmmu_drvdata *data, *next; > unsigned long flags; > @@ -875,8 +875,8 @@ static void exynos_iommu_detach_device(struct > iommu_domain *iommu_domain, > static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain, > struct device *dev) > { > - struct exynos_iommu_owner *owner = dev->archdata.iommu; > struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain); > + struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev); > struct sysmmu_drvdata *data; > phys_addr_t pagetable = virt_to_phys(domain->pgtable); > unsigned long flags; > @@ -1237,7 +1237,7 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct > iommu_domain *iommu_domain, > > static struct iommu_device *exynos_iommu_probe_device(struct device *dev) > { > - struct exynos_iommu_owner *owner = dev->archdata.iommu; > + struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev); > struct sysmmu_drvdata *data; > > if (!has_sysmmu(dev)) > @@ -1263,7 +1263,7 @@ static struct iommu_device > *exynos_iommu_probe_device(struct device *dev) > > static void exynos_iommu_release_device(struct device *dev) > { > - struct exynos_iommu_owner *owner = dev->archdata.iommu; > + struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev); > struct sysmmu_drvdata *data; > > if (!has_sysmmu(dev)) > @@ -1287,8 +1287,8 @@ static void exynos_iommu_release_device(struct device > *dev) > static int exynos_iommu_of_xlate(struct device *dev, >struct of_phandle_args *spec) > { > - struct exynos_iommu_owner *owner = dev->archdata.iommu; > struct platform_device *sysmmu = of_find_device_by_node(spec->np); > + struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev); &
Re: [PATCH v4 02/14] arm: add support for folded p4d page tables
Hi Mike, On 08.05.2020 19:42, Mike Rapoport wrote: > On Fri, May 08, 2020 at 08:53:27AM +0200, Marek Szyprowski wrote: >> On 07.05.2020 18:11, Mike Rapoport wrote: >>> On Thu, May 07, 2020 at 02:16:56PM +0200, Marek Szyprowski wrote: >>>> On 14.04.2020 17:34, Mike Rapoport wrote: >>>>> From: Mike Rapoport >>>>> >>>>> Implement primitives necessary for the 4th level folding, add walks of p4d >>>>> level where appropriate, and remove __ARCH_USE_5LEVEL_HACK. >>>>> >>>>> Signed-off-by: Mike Rapoport >>>> Today I've noticed that kexec is broken on ARM 32bit. Bisecting between >>>> current linux-next and v5.7-rc1 pointed to this commit. I've tested this >>>> on Odroid XU4 and Raspberry Pi4 boards. Here is the relevant log: >>>> >>>> # kexec --kexec-syscall -l zImage --append "$(cat /proc/cmdline)" >>>> memory_range[0]:0x4000..0xbe9f >>>> memory_range[0]:0x4000..0xbe9f >>>> # kexec -e >>>> kexec_core: Starting new kernel >>>> 8<--- cut here --- >>>> Unable to handle kernel paging request at virtual address c010f1f4 >>>> pgd = c6817793 >>>> [c010f1f4] *pgd=441e(bad) >>>> Internal error: Oops: 80d [#1] PREEMPT ARM >>>> Modules linked in: >>>> CPU: 0 PID: 1329 Comm: kexec Tainted: G W >>>> 5.7.0-rc3-00127-g6cba81ed0f62 #611 >>>> Hardware name: Samsung Exynos (Flattened Device Tree) >>>> PC is at machine_kexec+0x40/0xfc >>> Any chance you have the debug info in this kernel? >>> scripts/faddr2line would come handy here. >> # ./scripts/faddr2line --list vmlinux machine_kexec+0x40 >> machine_kexec+0x40/0xf8: >> >> machine_kexec at arch/arm/kernel/machine_kexec.c:182 >> 177 reboot_code_buffer = >> page_address(image->control_code_page); >> 178 >> 179 /* Prepare parameters for reboot_code_buffer*/ >> 180 set_kernel_text_rw(); >> 181 kexec_start_address = image->start; >> >182< kexec_indirection_page = page_list; >> 183 kexec_mach_type = machine_arch_type; >> 184 kexec_boot_atags = image->arch.kernel_r2; >> 185 >> 186 /* copy our kernel relocation code to the control code >> page */ >> 187 reboot_entry = fncpy(reboot_code_buffer, > Can you please try the patch below: > > diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c > index 963b5284d284..f86b3d17928e 100644 > --- a/arch/arm/mm/init.c > +++ b/arch/arm/mm/init.c > @@ -571,7 +571,7 @@ static inline void section_update(unsigned long addr, > pmdval_t mask, > { > pmd_t *pmd; > > - pmd = pmd_off_k(addr); > + pmd = pmd_offset(pud_offset(p4d_offset(pgd_offset(mm, addr), addr), > addr), addr); > > #ifdef CONFIG_ARM_LPAE > pmd[0] = __pmd((pmd_val(pmd[0]) & mask) | prot); This fixes kexec issue! Thanks! Feel free to add: Reported-by: Marek Szyprowski Fixes: 218f1c390557 ("arm: add support for folded p4d page tables") Tested-by: Marek Szyprowski Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v4 02/14] arm: add support for folded p4d page tables
Hi Mike, On 07.05.2020 18:11, Mike Rapoport wrote: > On Thu, May 07, 2020 at 02:16:56PM +0200, Marek Szyprowski wrote: >> On 14.04.2020 17:34, Mike Rapoport wrote: >>> From: Mike Rapoport >>> >>> Implement primitives necessary for the 4th level folding, add walks of p4d >>> level where appropriate, and remove __ARCH_USE_5LEVEL_HACK. >>> >>> Signed-off-by: Mike Rapoport >> Today I've noticed that kexec is broken on ARM 32bit. Bisecting between >> current linux-next and v5.7-rc1 pointed to this commit. I've tested this >> on Odroid XU4 and Raspberry Pi4 boards. Here is the relevant log: >> >> # kexec --kexec-syscall -l zImage --append "$(cat /proc/cmdline)" >> memory_range[0]:0x4000..0xbe9f >> memory_range[0]:0x4000..0xbe9f >> # kexec -e >> kexec_core: Starting new kernel >> 8<--- cut here --- >> Unable to handle kernel paging request at virtual address c010f1f4 >> pgd = c6817793 >> [c010f1f4] *pgd=441e(bad) >> Internal error: Oops: 80d [#1] PREEMPT ARM >> Modules linked in: >> CPU: 0 PID: 1329 Comm: kexec Tainted: G W >> 5.7.0-rc3-00127-g6cba81ed0f62 #611 >> Hardware name: Samsung Exynos (Flattened Device Tree) >> PC is at machine_kexec+0x40/0xfc > Any chance you have the debug info in this kernel? > scripts/faddr2line would come handy here. # ./scripts/faddr2line --list vmlinux machine_kexec+0x40 machine_kexec+0x40/0xf8: machine_kexec at arch/arm/kernel/machine_kexec.c:182 177 reboot_code_buffer = page_address(image->control_code_page); 178 179 /* Prepare parameters for reboot_code_buffer*/ 180 set_kernel_text_rw(); 181 kexec_start_address = image->start; >182< kexec_indirection_page = page_list; 183 kexec_mach_type = machine_arch_type; 184 kexec_boot_atags = image->arch.kernel_r2; 185 186 /* copy our kernel relocation code to the control code page */ 187 reboot_entry = fncpy(reboot_code_buffer, > ... Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH v4 02/14] arm: add support for folded p4d page tables
Hi On 14.04.2020 17:34, Mike Rapoport wrote: > From: Mike Rapoport > > Implement primitives necessary for the 4th level folding, add walks of p4d > level where appropriate, and remove __ARCH_USE_5LEVEL_HACK. > > Signed-off-by: Mike Rapoport Today I've noticed that kexec is broken on ARM 32bit. Bisecting between current linux-next and v5.7-rc1 pointed to this commit. I've tested this on Odroid XU4 and Raspberry Pi4 boards. Here is the relevant log: # kexec --kexec-syscall -l zImage --append "$(cat /proc/cmdline)" memory_range[0]:0x4000..0xbe9f memory_range[0]:0x4000..0xbe9f # kexec -e kexec_core: Starting new kernel 8<--- cut here --- Unable to handle kernel paging request at virtual address c010f1f4 pgd = c6817793 [c010f1f4] *pgd=441e(bad) Internal error: Oops: 80d [#1] PREEMPT ARM Modules linked in: CPU: 0 PID: 1329 Comm: kexec Tainted: G W 5.7.0-rc3-00127-g6cba81ed0f62 #611 Hardware name: Samsung Exynos (Flattened Device Tree) PC is at machine_kexec+0x40/0xfc LR is at 0x pc : [] lr : [] psr: 6013 sp : ebc13e60 ip : 40008000 fp : 0001 r10: 0058 r9 : fee1dead r8 : 0001 r7 : c121387c r6 : 6c224000 r5 : ece40c00 r4 : ec222000 r3 : c010f1f4 r2 : c110 r1 : c110 r0 : 418d Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none Control: 10c5387d Table: 6bc14059 DAC: 0051 Process kexec (pid: 1329, stack limit = 0x366bb4dc) Stack: (0xebc13e60 to 0xebc14000) ... [] (machine_kexec) from [] (kernel_kexec+0x74/0x7c) [] (kernel_kexec) from [] (__do_sys_reboot+0x1f8/0x210) [] (__do_sys_reboot) from [] (ret_fast_syscall+0x0/0x28) Exception stack(0xebc13fa8 to 0xebc13ff0) ... ---[ end trace 3e8d6c81723c778d ]--- 1329 Segmentation fault ./kexec -e > --- > arch/arm/include/asm/pgtable.h | 1 - > arch/arm/lib/uaccess_with_memcpy.c | 7 +- > arch/arm/mach-sa1100/assabet.c | 2 +- > arch/arm/mm/dump.c | 29 +- > arch/arm/mm/fault-armv.c | 7 +- > arch/arm/mm/fault.c| 22 ++-- > arch/arm/mm/idmap.c| 3 ++- > arch/arm/mm/init.c | 2 +- > arch/arm/mm/ioremap.c | 12 ++--- > arch/arm/mm/mm.h | 2 +- > arch/arm/mm/mmu.c | 35 +- > arch/arm/mm/pgd.c | 40 -- > 12 files changed, 125 insertions(+), 37 deletions(-) > > ... Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 1/3] dma-direct: unify the dma_capable definitions
Hi On 19.11.2019 17:46, Christoph Hellwig wrote: > On Tue, Nov 19, 2019 at 11:26:39AM +0100, Marek Szyprowski wrote: >> Christoph: Let me know if this is a proper fix for you, then I will send >> it as a full patch. > Besides the point from Robin, which is really older than you patch > I'm not a fan of duplicating dma_capable here. Let me know what you > think of the two attached patches. I'm fine with both patches. Acked-by: Marek Szyprowski Tested-by: Marek Szyprowski Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 1/3] dma-direct: unify the dma_capable definitions
Hi Krzysztof, On 19.11.2019 10:44, Krzysztof Kozlowski wrote: > On Tue, 19 Nov 2019 at 17:27, Marek Szyprowski > wrote: >> Hi Christoph, >> >> On 13.11.2019 08:35, Christoph Hellwig wrote: >>> Currently each architectures that wants to override dma_to_phys and >>> phys_to_dma also has to provide dma_capable. But there isn't really >>> any good reason for that. powerpc and mips just have copies of the >>> generic one minus the latests fix, and the arm one was the inspiration >>> for said fix, but misses the bus_dma_mask handling. >>> Make all architectures use the generic version instead. >>> >>> Signed-off-by: Christoph Hellwig >> This patch breaks DMAengine PL330 driver on Samsung Exynos SoCs: > > Thanks Marek for bisecting it. I wonder whether it is also the cause > for boot failures I see on NXP Vybrid VF50 SoC (NXP/Freescale > fsl-edma) since few days: > > [ 2.853428] fsl-edma 40018000.dma-controller: overflow 0x40027007+1 of > DMA mask bus mask 0 > [ 2.862566] [ cut here ] > [ 2.867273] WARNING: CPU: 0 PID: 1 at > /home/buildbot/worker/builddir_yocto/build/build/tmp/work-shared/col-vf50-proceq-mainline-next/kernel-source/kernel/dma/direct.c:35 > report_addr+0xc0/0xfc > [ 2.884380] Modules linked in: > [ 2.887486] CPU: 0 PID: 1 Comm: swapper Tainted: G W > 5.4.0-rc7-next-20191118-g519ead8f6a32 #1 > [ 2.897364] Hardware name: Freescale Vybrid VF5xx/VF6xx (Device Tree) > [ 2.903892] [<8010ddfc>] (unwind_backtrace) from [<8010b4b8>] > (show_stack+0x10/0x14) > [ 2.911712] [<8010b4b8>] (show_stack) from [<8011b08c>] (__warn+0xd4/0xec) > [ 2.918653] [<8011b08c>] (__warn) from [<8011b154>] > (warn_slowpath_fmt+0xb0/0xb8) > [ 2.926218] [<8011b154>] (warn_slowpath_fmt) from [<80155f7c>] > (report_addr+0xc0/0xfc) > [ 2.934221] [<80155f7c>] (report_addr) from [<801561f0>] > (dma_direct_map_resource+0x98/0xa4) > [ 2.942744] [<801561f0>] (dma_direct_map_resource) from [<8041d5d4>] > (fsl_edma_prep_slave_dma+0x12c/0x150) > [ 2.952475] [<8041d5d4>] (fsl_edma_prep_slave_dma) from [<8041d8cc>] > (fsl_edma_prep_dma_cyclic+0x30/0x21c) > [ 2.962213] [<8041d8cc>] (fsl_edma_prep_dma_cyclic) from [<80452e10>] > (lpuart_rx_dma_startup+0x188/0x36c) > [ 2.971871] [<80452e10>] (lpuart_rx_dma_startup) from [<80453058>] > (lpuart_startup+0x64/0x78) > [ 2.980477] [<80453058>] (lpuart_startup) from [<8044e924>] > (uart_startup.part.7+0x110/0x23c) > [ 2.989080] [<8044e924>] (uart_startup.part.7) from [<8044eaa0>] > (uart_port_activate+0x50/0x7c) > [ 2.997857] [<8044eaa0>] (uart_port_activate) from [<80438dc0>] > (tty_port_open+0x74/0xc0) > [ 3.006111] [<80438dc0>] (tty_port_open) from [<8044be30>] > (uart_open+0x18/0x20) > [ 3.013588] [<8044be30>] (uart_open) from [<80431b4c>] (tty_open+0x108/0x428) > [ 3.020794] [<80431b4c>] (tty_open) from [<801edb48>] (chrdev_open+0xac/0x164) > [ 3.028098] [<801edb48>] (chrdev_open) from [<801e55c8>] > (do_dentry_open+0x22c/0x3e4) > [ 3.036010] [<801e55c8>] (do_dentry_open) from [<801f72a8>] > (path_openat+0x4a4/0xf78) > [ 3.043912] [<801f72a8>] (path_openat) from [<801f8d34>] > (do_filp_open+0x70/0xdc) > [ 3.051472] [<801f8d34>] (do_filp_open) from [<801e6998>] > (do_sys_open+0x128/0x1f4) > [ 3.059217] [<801e6998>] (do_sys_open) from [<80a00ee0>] > (kernel_init_freeable+0x150/0x1c4) > [ 3.067658] [<80a00ee0>] (kernel_init_freeable) from [<8068e208>] > (kernel_init+0x8/0x110) > [ 3.075917] [<8068e208>] (kernel_init) from [<801010e8>] > (ret_from_fork+0x14/0x2c) > [ 3.083539] Exception stack(0x86843fb0 to 0x86843ff8) > [ 3.088631] 3fa0: > [ 3.096866] 3fc0: > > [ 3.105103] 3fe0: 0013 > [ 3.111752] ---[ end trace 6fb699802256a309 ]--- > [3.116423] fsl-lpuart 40027000.serial: Cannot prepare cyclic DMA > [3.192968] VFS: Mounted root (nfs4 filesystem) on device 0:13. > [3.201432] devtmpfs: mounted > [3.210985] Freeing unused kernel memory: 1024K > [3.217854] Run /sbin/init as init process > [4.643355] systemd[1]: System time before build time, advancing clock. > [4.774106] random: systemd: uninitialized urandom read (16 bytes read) > [4.838361] systemd[1]: systemd 232 running in system mode. (-PAM > -AUDIT -SELINUX -IMA -APPARMOR -SMACK +SYSVINIT +UTMP -LIBCRYPTSETUP > -GCRYPT -GNUTLS +ACL +XZ -LZ4 -SECCOM
Re: [PATCH 1/3] dma-direct: unify the dma_capable definitions
mask; > -} > - > dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr); > phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr); > > diff --git a/arch/powerpc/include/asm/dma-direct.h > b/arch/powerpc/include/asm/dma-direct.h > index a2912b47102c..e29e8a236b8d 100644 > --- a/arch/powerpc/include/asm/dma-direct.h > +++ b/arch/powerpc/include/asm/dma-direct.h > @@ -2,15 +2,6 @@ > #ifndef ASM_POWERPC_DMA_DIRECT_H > #define ASM_POWERPC_DMA_DIRECT_H 1 > > -static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t > size) > -{ > - if (!dev->dma_mask) > - return false; > - > - return addr + size - 1 <= > - min_not_zero(*dev->dma_mask, dev->bus_dma_mask); > -} > - > static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t > paddr) > { > if (!dev) > diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h > index 6db863c3eb93..991f8aa2676e 100644 > --- a/include/linux/dma-direct.h > +++ b/include/linux/dma-direct.h > @@ -24,6 +24,7 @@ static inline phys_addr_t __dma_to_phys(struct device *dev, > dma_addr_t dev_addr) > > return paddr + ((phys_addr_t)dev->dma_pfn_offset << PAGE_SHIFT); > } > +#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */ > > static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t > size) > { > @@ -38,7 +39,6 @@ static inline bool dma_capable(struct device *dev, > dma_addr_t addr, size_t size) > > return end <= min_not_zero(*dev->dma_mask, dev->bus_dma_mask); > } > -#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */ > > #ifdef CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED > bool force_dma_unencrypted(struct device *dev); Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: fix a layering violation in videobuf2 and improve dma_map_resource v2
Hi All, On 2019-01-18 12:37, Christoph Hellwig wrote: > Hi all, > > this series fixes a rather gross layering violation in videobuf2, which > pokes into arm DMA mapping internals to get a DMA address for memory that > does not have a page structure, and to do so fixes up the dma_map_resource > implementation to not provide a somewhat dangerous default and improve > the error handling. > > Changes since v1: > - don't apply bus offsets in dma_direct_map_resource Works fine on older Exynos based boards with IOMMU and CMA disabled. Tested-by: Marek Szyprowski Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 3/3] videobuf2: replace a layering violation with dma_map_resource
Hi Christoph, On 2019-01-17 18:21, Christoph Hellwig wrote: > On Mon, Jan 14, 2019 at 01:42:26PM +0100, Marek Szyprowski wrote: >> On 2019-01-11 19:17, Christoph Hellwig wrote: >>> vb2_dc_get_userptr pokes into arm direct mapping details to get the >>> resemblance of a dma address for a a physical address that does is >>> not backed by a page struct. Not only is this not portable to other >>> architectures with dma direct mapping offsets, but also not to uses >>> of IOMMUs of any kind. Switch to the proper dma_map_resource / >>> dma_unmap_resource interface instead. >>> >>> Signed-off-by: Christoph Hellwig >> There are checks for IOMMU presence in other places in vb2-dma-contig, >> so it was used only when no IOMMU is available, but I agree that the >> hacky code should be replaced by a generic code if possible. >> >> Tested-by: Marek Szyprowski >> >> V4L2 pipeline works fine on older Exynos-based boards with CMA and IOMMU >> disabled. > Do you know if these rely on the offsets? E.g. would they still work > with the patch below applied on top. That would keep the map_resource > semantics as-is as solve the issue pointed out by Robin for now. AFAIK that code was only used for sharing buffers between hardware modules that are a part of the same SoC, usually implemented as platform devices. AFAIR this never worked for devices on different buses. So far I wasn't aware on ANY which would require an offset for the DMA access. The first version of videobuf2-dc code even incorrectly used paddr instead of dma_addr as a buffer 'address' returned to the client drivers, because in case of those SoC this was exactly the same (see commits 472af2b05bdefcaee7e754e22cbf131110017ad6 and ba7fcb0c954921534707f08ebc4d8beeb2eb17e7). > If not I can only think of a flag to bypass the offseting for now, but > that would be pretty ugly. Or go for the long-term solution of > discovering the relationship between the two devices, as done by the > PCIe P2P code.. > > diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c > index 8e0359b04957..25bd19974223 100644 > --- a/kernel/dma/direct.c > +++ b/kernel/dma/direct.c > @@ -359,7 +359,7 @@ EXPORT_SYMBOL(dma_direct_map_sg); > dma_addr_t dma_direct_map_resource(struct device *dev, phys_addr_t paddr, > size_t size, enum dma_data_direction dir, unsigned long attrs) > { > - dma_addr_t dma_addr = phys_to_dma(dev, paddr); > + dma_addr_t dma_addr = paddr; > > if (unlikely(!dma_direct_possible(dev, dma_addr, size))) { > report_addr(dev, dma_addr, size); > > > Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH 3/3] videobuf2: replace a layering violation with dma_map_resource
Hi Christoph, On 2019-01-11 19:17, Christoph Hellwig wrote: > vb2_dc_get_userptr pokes into arm direct mapping details to get the > resemblance of a dma address for a a physical address that does is > not backed by a page struct. Not only is this not portable to other > architectures with dma direct mapping offsets, but also not to uses > of IOMMUs of any kind. Switch to the proper dma_map_resource / > dma_unmap_resource interface instead. > > Signed-off-by: Christoph Hellwig There are checks for IOMMU presence in other places in vb2-dma-contig, so it was used only when no IOMMU is available, but I agree that the hacky code should be replaced by a generic code if possible. Tested-by: Marek Szyprowski V4L2 pipeline works fine on older Exynos-based boards with CMA and IOMMU disabled. > --- > .../common/videobuf2/videobuf2-dma-contig.c | 41 --- > 1 file changed, 9 insertions(+), 32 deletions(-) > > diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c > b/drivers/media/common/videobuf2/videobuf2-dma-contig.c > index aff0ab7bf83d..82389aead6ed 100644 > --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c > +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c > @@ -439,42 +439,14 @@ static void vb2_dc_put_userptr(void *buf_priv) > set_page_dirty_lock(pages[i]); > sg_free_table(sgt); > kfree(sgt); > + } else { > + dma_unmap_resource(buf->dev, buf->dma_addr, buf->size, > +buf->dma_dir, 0); > } > vb2_destroy_framevec(buf->vec); > kfree(buf); > } > > -/* > - * For some kind of reserved memory there might be no struct page available, > - * so all that can be done to support such 'pages' is to try to convert > - * pfn to dma address or at the last resort just assume that > - * dma address == physical address (like it has been assumed in earlier > version > - * of videobuf2-dma-contig > - */ > - > -#ifdef __arch_pfn_to_dma > -static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long > pfn) > -{ > - return (dma_addr_t)__arch_pfn_to_dma(dev, pfn); > -} > -#elif defined(__pfn_to_bus) > -static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long > pfn) > -{ > - return (dma_addr_t)__pfn_to_bus(pfn); > -} > -#elif defined(__pfn_to_phys) > -static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long > pfn) > -{ > - return (dma_addr_t)__pfn_to_phys(pfn); > -} > -#else > -static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long > pfn) > -{ > - /* really, we cannot do anything better at this point */ > - return (dma_addr_t)(pfn) << PAGE_SHIFT; > -} > -#endif > - > static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr, > unsigned long size, enum dma_data_direction dma_dir) > { > @@ -528,7 +500,12 @@ static void *vb2_dc_get_userptr(struct device *dev, > unsigned long vaddr, > for (i = 1; i < n_pages; i++) > if (nums[i-1] + 1 != nums[i]) > goto fail_pfnvec; > - buf->dma_addr = vb2_dc_pfn_to_dma(buf->dev, nums[0]); > + buf->dma_addr = dma_map_resource(buf->dev, > + __pfn_to_phys(nums[0]), size, buf->dma_dir, 0); > + if (dma_mapping_error(buf->dev, buf->dma_addr)) { > + ret = -ENOMEM; > + goto fail_pfnvec; > + } > goto out; > } > Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: fix a layering violation in videobuf2 and improve dma_map_resource
Hi Christoph, On 2019-01-11 19:17, Christoph Hellwig wrote: > Hi all, > > this series fixes a rather gross layering violation in videobuf2, which > pokes into arm DMA mapping internals to get a DMA address for memory that > does not have a page structure, and to do so fixes up the dma_map_resource > implementation to be practically useful. Thanks for rewriting this 'temporary code'! It predates dma_map_resource() and that time this was the only way to get it working somehow. Good that now it is possible to implement in it a clean way without any unwritten assumptions about the DMA mapping internals. Feel free to add my: Reviewed-by: Marek Szyprowski Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
[PATCH 2/2] dma: remove unsupported gfp_mask parameter from dma_alloc_from_contiguous()
The CMA memory allocator doesn't support standard gfp flags for memory allocation, so there is no point having it as a parameter for dma_alloc_from_contiguous() function. Replace it by a boolean no_warn argument, which covers all the underlaying cma_alloc() function supports. This will help to avoid giving false feeling that this function supports standard gfp flags and callers can pass __GFP_ZERO to get zeroed buffer, what has already been an issue: see commit dd65a941f6ba ("arm64: dma-mapping: clear buffers allocated with FORCE_CONTIGUOUS flag"). Signed-off-by: Marek Szyprowski --- arch/arm/mm/dma-mapping.c | 5 +++-- arch/arm64/mm/dma-mapping.c| 4 ++-- arch/xtensa/kernel/pci-dma.c | 2 +- drivers/iommu/amd_iommu.c | 2 +- drivers/iommu/intel-iommu.c| 3 ++- include/linux/dma-contiguous.h | 4 ++-- kernel/dma/contiguous.c| 7 +++ kernel/dma/direct.c| 3 ++- 8 files changed, 16 insertions(+), 14 deletions(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index be0fa7e39c26..121c6c3ba9e0 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -594,7 +594,7 @@ static void *__alloc_from_contiguous(struct device *dev, size_t size, struct page *page; void *ptr = NULL; - page = dma_alloc_from_contiguous(dev, count, order, gfp); + page = dma_alloc_from_contiguous(dev, count, order, gfp & __GFP_NOWARN); if (!page) return NULL; @@ -1294,7 +1294,8 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, unsigned long order = get_order(size); struct page *page; - page = dma_alloc_from_contiguous(dev, count, order, gfp); + page = dma_alloc_from_contiguous(dev, count, order, +gfp & __GFP_NOWARN); if (!page) goto error; diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 61e93f0b5482..072c51fb07d7 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -355,7 +355,7 @@ static int __init atomic_pool_init(void) if (dev_get_cma_area(NULL)) page = dma_alloc_from_contiguous(NULL, nr_pages, -pool_size_order, GFP_KERNEL); +pool_size_order, false); else page = alloc_pages(GFP_DMA32, pool_size_order); @@ -573,7 +573,7 @@ static void *__iommu_alloc_attrs(struct device *dev, size_t size, struct page *page; page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT, -get_order(size), gfp); + get_order(size), gfp & __GFP_NOWARN); if (!page) return NULL; diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c index ba4640cc0093..b2c7ba91fb08 100644 --- a/arch/xtensa/kernel/pci-dma.c +++ b/arch/xtensa/kernel/pci-dma.c @@ -137,7 +137,7 @@ static void *xtensa_dma_alloc(struct device *dev, size_t size, if (gfpflags_allow_blocking(flag)) page = dma_alloc_from_contiguous(dev, count, get_order(size), -flag); +flag & __GFP_NOWARN); if (!page) page = alloc_pages(flag, get_order(size)); diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 64cfe854e0f5..5ec97ffb561a 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -2622,7 +2622,7 @@ static void *alloc_coherent(struct device *dev, size_t size, return NULL; page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT, -get_order(size), flag); + get_order(size), flag & __GFP_NOWARN); if (!page) return NULL; } diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 869321c594e2..dd2d343428ab 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -3746,7 +3746,8 @@ static void *intel_alloc_coherent(struct device *dev, size_t size, if (gfpflags_allow_blocking(flags)) { unsigned int count = size >> PAGE_SHIFT; - page = dma_alloc_from_contiguous(dev, count, order, flags); + page = dma_alloc_from_contiguous(dev, count, order, +flags & __GFP_NOWARN); if (page && iommu_no_mapping(dev) && page_to_phys(page) + size > dev->coherent_dma_mask) { dma_release_from_contiguous(dev, page, count); di
[PATCH 0/2] CMA: remove unsupported gfp mask parameter
Dear All, The CMA related functions cma_alloc() and dma_alloc_from_contiguous() have gfp mask parameter, but sadly they only support __GFP_NOWARN flag. This gave their users a misleading feeling that any standard memory allocation flags are supported, what resulted in the security issue when caller have set __GFP_ZERO flag and expected the buffer to be cleared. This patchset changes gfp_mask parameter to a simple boolean no_warn argument, which covers all the underlaying code supports. This patchset is a result of the following discussion: https://patchwork.kernel.org/patch/10461919/ Best regards Marek Szyprowski Samsung R Institute Poland Patch summary: Marek Szyprowski (2): mm/cma: remove unsupported gfp_mask parameter from cma_alloc() dma: remove unsupported gfp_mask parameter from dma_alloc_from_contiguous() arch/arm/mm/dma-mapping.c | 5 +++-- arch/arm64/mm/dma-mapping.c| 4 ++-- arch/powerpc/kvm/book3s_hv_builtin.c | 2 +- arch/xtensa/kernel/pci-dma.c | 2 +- drivers/iommu/amd_iommu.c | 2 +- drivers/iommu/intel-iommu.c| 3 ++- drivers/s390/char/vmcp.c | 2 +- drivers/staging/android/ion/ion_cma_heap.c | 2 +- include/linux/cma.h| 2 +- include/linux/dma-contiguous.h | 4 ++-- kernel/dma/contiguous.c| 6 +++--- kernel/dma/direct.c| 3 ++- mm/cma.c | 8 mm/cma_debug.c | 2 +- 14 files changed, 25 insertions(+), 22 deletions(-) -- 2.17.1
[PATCH 1/2] mm/cma: remove unsupported gfp_mask parameter from cma_alloc()
cma_alloc() function doesn't really support gfp flags other than __GFP_NOWARN, so convert gfp_mask parameter to boolean no_warn parameter. This will help to avoid giving false feeling that this function supports standard gfp flags and callers can pass __GFP_ZERO to get zeroed buffer, what has already been an issue: see commit dd65a941f6ba ("arm64: dma-mapping: clear buffers allocated with FORCE_CONTIGUOUS flag"). Signed-off-by: Marek Szyprowski --- arch/powerpc/kvm/book3s_hv_builtin.c | 2 +- drivers/s390/char/vmcp.c | 2 +- drivers/staging/android/ion/ion_cma_heap.c | 2 +- include/linux/cma.h| 2 +- kernel/dma/contiguous.c| 3 ++- mm/cma.c | 8 mm/cma_debug.c | 2 +- 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index d4a3f4da409b..fc6bb9630a9c 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -77,7 +77,7 @@ struct page *kvm_alloc_hpt_cma(unsigned long nr_pages) VM_BUG_ON(order_base_2(nr_pages) < KVM_CMA_CHUNK_ORDER - PAGE_SHIFT); return cma_alloc(kvm_cma, nr_pages, order_base_2(HPT_ALIGN_PAGES), -GFP_KERNEL); +false); } EXPORT_SYMBOL_GPL(kvm_alloc_hpt_cma); diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index 948ce82a7725..0fa1b6b1491a 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c @@ -68,7 +68,7 @@ static void vmcp_response_alloc(struct vmcp_session *session) * anymore the system won't work anyway. */ if (order > 2) - page = cma_alloc(vmcp_cma, nr_pages, 0, GFP_KERNEL); + page = cma_alloc(vmcp_cma, nr_pages, 0, false); if (page) { session->response = (char *)page_to_phys(page); session->cma_alloc = 1; diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index 49718c96bf9e..3fafd013d80a 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -39,7 +39,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, if (align > CONFIG_CMA_ALIGNMENT) align = CONFIG_CMA_ALIGNMENT; - pages = cma_alloc(cma_heap->cma, nr_pages, align, GFP_KERNEL); + pages = cma_alloc(cma_heap->cma, nr_pages, align, false); if (!pages) return -ENOMEM; diff --git a/include/linux/cma.h b/include/linux/cma.h index bf90f0bb42bd..190184b5ff32 100644 --- a/include/linux/cma.h +++ b/include/linux/cma.h @@ -33,7 +33,7 @@ extern int cma_init_reserved_mem(phys_addr_t base, phys_addr_t size, const char *name, struct cma **res_cma); extern struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, - gfp_t gfp_mask); + bool no_warn); extern bool cma_release(struct cma *cma, const struct page *pages, unsigned int count); extern int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data); diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c index d987dcd1bd56..19ea5d70150c 100644 --- a/kernel/dma/contiguous.c +++ b/kernel/dma/contiguous.c @@ -191,7 +191,8 @@ struct page *dma_alloc_from_contiguous(struct device *dev, size_t count, if (align > CONFIG_CMA_ALIGNMENT) align = CONFIG_CMA_ALIGNMENT; - return cma_alloc(dev_get_cma_area(dev), count, align, gfp_mask); + return cma_alloc(dev_get_cma_area(dev), count, align, +gfp_mask & __GFP_NOWARN); } /** diff --git a/mm/cma.c b/mm/cma.c index 5809bbe360d7..4cb76121a3ab 100644 --- a/mm/cma.c +++ b/mm/cma.c @@ -395,13 +395,13 @@ static inline void cma_debug_show_areas(struct cma *cma) { } * @cma: Contiguous memory region for which the allocation is performed. * @count: Requested number of pages. * @align: Requested alignment of pages (in PAGE_SIZE order). - * @gfp_mask: GFP mask to use during compaction + * @no_warn: Avoid printing message about failed allocation * * This function allocates part of contiguous memory on specific * contiguous memory area. */ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, - gfp_t gfp_mask) + bool no_warn) { unsigned long mask, offset; unsigned long pfn = -1; @@ -447,7 +447,7 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, pfn = cma->base_pfn + (bitmap_no << cma->order_per_bit); mutex_lock(_mutex); ret
Re: new dma-mapping tree, was Re: clean up and modularize arch dma_mapping interface V2
Hi Christoph, On 2017-06-20 15:16, Christoph Hellwig wrote: On Tue, Jun 20, 2017 at 11:04:00PM +1000, Stephen Rothwell wrote: git://git.linaro.org/people/mszyprowski/linux-dma-mapping.git#dma-mapping-next Contacts: Marek Szyprowski and Kyungmin Park (cc'd) I have called your tree dma-mapping-hch for now. The other tree has not been updated since 4.9-rc1 and I am not sure how general it is. Marek, Kyungmin, any comments? I'd be happy to join efforts - co-maintainers and reviers are always welcome. I did some dma-mapping unification works in the past and my tree in linux-next was a side effect of that. I think that for now it can be dropped in favor of Christoph's tree. I can also do some review and help in maintainers work if needed, although I was recently busy with other stuff. Christoph: Could you add me to your MAINTAINERS patch, so further dma-mapping related patches hopefully will be also CC: to me? Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland
Re: [PATCH] CMA: generalize CMA reserved area management functionality (fixup)
Hello, On 2014-07-18 00:06, Andrew Morton wrote: On Thu, 17 Jul 2014 11:36:07 +0200 Marek Szyprowski m.szyprow...@samsung.com wrote: MAX_CMA_AREAS is used by other subsystems (i.e. arch/arm/mm/dma-mapping.c), so we need to provide correct definition even if CMA is disabled. This patch fixes this issue. Reported-by: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com --- include/linux/cma.h | 4 1 file changed, 4 insertions(+) diff --git a/include/linux/cma.h b/include/linux/cma.h index 9a18a2b1934c..c077635cad76 100644 --- a/include/linux/cma.h +++ b/include/linux/cma.h @@ -5,7 +5,11 @@ * There is always at least global CMA area and a few optional * areas configured in kernel .config. */ +#ifdef CONFIG_CMA #define MAX_CMA_AREAS (1 + CONFIG_CMA_AREAS) +#else +#define MAX_CMA_AREAS (0) +#endif struct cma; Joonsoo already fixed this up, a bit differently: http://ozlabs.org/~akpm/mmots/broken-out/cma-generalize-cma-reserved-area-management-functionality-fix.patch Which approach makes more sense? CMA_AREAS depends on CMA being enabled, so both approaches works exactly the same way. Please keep Joonsoo's patch and just ignore mine to avoid confusing others by disappearing patches. I'm sorry that I've missed it before sending mine. From: Joonsoo Kim iamjoonsoo@lge.com Subject: CMA: fix ARM build failure related to MAX_CMA_AREAS definition If CMA is disabled, CONFIG_CMA_AREAS isn't defined so compile error happens. To fix it, define MAX_CMA_AREAS if CONFIG_CMA_AREAS isn't defined. Signed-off-by: Joonsoo Kim iamjoonsoo@lge.com Reported-by: Stephen Rothwell s...@canb.auug.org.au Signed-off-by: Andrew Morton a...@linux-foundation.org --- include/linux/cma.h |6 ++ 1 file changed, 6 insertions(+) diff -puN include/linux/cma.h~cma-generalize-cma-reserved-area-management-functionality-fix include/linux/cma.h --- a/include/linux/cma.h~cma-generalize-cma-reserved-area-management-functionality-fix +++ a/include/linux/cma.h @@ -5,8 +5,14 @@ * There is always at least global CMA area and a few optional * areas configured in kernel .config. */ +#ifdef CONFIG_CMA_AREAS #define MAX_CMA_AREAS (1 + CONFIG_CMA_AREAS) +#else +#define MAX_CMA_AREAS (0) + +#endif + struct cma; extern phys_addr_t cma_get_base(struct cma *cma); _ Best regards -- Marek Szyprowski, PhD Samsung RD Institute Poland ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v3 -next 5/9] CMA: generalize CMA reserved area management functionality
--- a/include/linux/dma-contiguous.h +++ b/include/linux/dma-contiguous.h @@ -53,18 +53,13 @@ #ifdef __KERNEL__ +#include linux/device.h + struct cma; struct page; -struct device; #ifdef CONFIG_DMA_CMA -/* - * There is always at least global CMA area and a few optional device - * private areas configured in kernel .config. - */ -#define MAX_CMA_AREAS (1 + CONFIG_CMA_AREAS) - extern struct cma *dma_contiguous_default_area; static inline struct cma *dev_get_cma_area(struct device *dev) @@ -123,8 +118,6 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages, #else -#define MAX_CMA_AREAS (0) - static inline struct cma *dev_get_cma_area(struct device *dev) { return NULL; diff --git a/mm/Kconfig b/mm/Kconfig index 3e9977a..f4899ec 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -508,6 +508,17 @@ config CMA_DEBUG processing calls such as dma_alloc_from_contiguous(). This option does not affect warning and error messages. +config CMA_AREAS + int Maximum count of the CMA areas + depends on CMA + default 7 + help + CMA allows to create CMA areas for particular purpose, mainly, + used as device private area. This parameter sets the maximum + number of CMA area in the system. + + If unsure, leave the default value 7. + config ZBUD tristate default n diff --git a/mm/Makefile b/mm/Makefile index 1eaa70b..bc0422b 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -62,3 +62,4 @@ obj-$(CONFIG_MEMORY_ISOLATION) += page_isolation.o obj-$(CONFIG_ZBUD)+= zbud.o obj-$(CONFIG_ZSMALLOC)+= zsmalloc.o obj-$(CONFIG_GENERIC_EARLY_IOREMAP) += early_ioremap.o +obj-$(CONFIG_CMA) += cma.o diff --git a/mm/cma.c b/mm/cma.c new file mode 100644 index 000..0cf50da --- /dev/null +++ b/mm/cma.c @@ -0,0 +1,333 @@ +/* + * Contiguous Memory Allocator + * + * Copyright (c) 2010-2011 by Samsung Electronics. + * Copyright IBM Corporation, 2013 + * Copyright LG Electronics Inc., 2014 + * Written by: + * Marek Szyprowski m.szyprow...@samsung.com + * Michal Nazarewicz min...@mina86.com + * Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com + * Joonsoo Kim iamjoonsoo@lge.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License or (at your optional) any later version of the license. + */ + +#define pr_fmt(fmt) cma: fmt + +#ifdef CONFIG_CMA_DEBUG +#ifndef DEBUG +# define DEBUG +#endif +#endif + +#include linux/memblock.h +#include linux/err.h +#include linux/mm.h +#include linux/mutex.h +#include linux/sizes.h +#include linux/slab.h +#include linux/log2.h +#include linux/cma.h + +struct cma { + unsigned long base_pfn; + unsigned long count; + unsigned long *bitmap; + unsigned int order_per_bit; /* Order of pages represented by one bit */ + struct mutexlock; +}; + +static struct cma cma_areas[MAX_CMA_AREAS]; +static unsigned cma_area_count; +static DEFINE_MUTEX(cma_mutex); + +phys_addr_t cma_get_base(struct cma *cma) +{ + return PFN_PHYS(cma-base_pfn); +} + +unsigned long cma_get_size(struct cma *cma) +{ + return cma-count PAGE_SHIFT; +} + +static unsigned long cma_bitmap_aligned_mask(struct cma *cma, int align_order) +{ + return (1 (align_order cma-order_per_bit)) - 1; +} + +static unsigned long cma_bitmap_maxno(struct cma *cma) +{ + return cma-count cma-order_per_bit; +} + +static unsigned long cma_bitmap_pages_to_bits(struct cma *cma, + unsigned long pages) +{ + return ALIGN(pages, 1 cma-order_per_bit) cma-order_per_bit; +} + +static void cma_clear_bitmap(struct cma *cma, unsigned long pfn, int count) +{ + unsigned long bitmap_no, bitmap_count; + + bitmap_no = (pfn - cma-base_pfn) cma-order_per_bit; + bitmap_count = cma_bitmap_pages_to_bits(cma, count); + + mutex_lock(cma-lock); + bitmap_clear(cma-bitmap, bitmap_no, bitmap_count); + mutex_unlock(cma-lock); +} + +static int __init cma_activate_area(struct cma *cma) +{ + int bitmap_size = BITS_TO_LONGS(cma_bitmap_maxno(cma)) * sizeof(long); + unsigned long base_pfn = cma-base_pfn, pfn = base_pfn; + unsigned i = cma-count pageblock_order; + struct zone *zone; + + cma-bitmap = kzalloc(bitmap_size, GFP_KERNEL); + + if (!cma-bitmap) + return -ENOMEM; + + WARN_ON_ONCE(!pfn_valid(pfn)); + zone = page_zone(pfn_to_page(pfn)); + + do { + unsigned j; + + base_pfn = pfn; + for (j = pageblock_nr_pages; j; --j, pfn++) { + WARN_ON_ONCE(!pfn_valid(pfn)); + /* +* alloc_contig_range requires the pfn range
[PATCH] CMA: generalize CMA reserved area management functionality (fixup)
MAX_CMA_AREAS is used by other subsystems (i.e. arch/arm/mm/dma-mapping.c), so we need to provide correct definition even if CMA is disabled. This patch fixes this issue. Reported-by: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com --- include/linux/cma.h | 4 1 file changed, 4 insertions(+) diff --git a/include/linux/cma.h b/include/linux/cma.h index 9a18a2b1934c..c077635cad76 100644 --- a/include/linux/cma.h +++ b/include/linux/cma.h @@ -5,7 +5,11 @@ * There is always at least global CMA area and a few optional * areas configured in kernel .config. */ +#ifdef CONFIG_CMA #define MAX_CMA_AREAS (1 + CONFIG_CMA_AREAS) +#else +#define MAX_CMA_AREAS (0) +#endif struct cma; -- 1.9.2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v3 -next 0/9] CMA: generalize CMA reserved area management code
Hello, On 2014-06-18 22:51, Andrew Morton wrote: On Tue, 17 Jun 2014 10:25:07 +0900 Joonsoo Kim iamjoonsoo@lge.com wrote: v2: - Although this patchset looks very different with v1, the end result, that is, mm/cma.c is same with v1's one. So I carry Ack to patch 6-7. This patchset is based on linux-next 20140610. Thanks for taking care of this. I will test it with my setup and if everything goes well, I will take it to my -next tree. If any branch is required for anyone to continue his works on top of those patches, let me know, I will also prepare it. Hello, I'm glad to hear that. :) But, there is one concern. As you already know, I am preparing further patches (Aggressively allocate the pages on CMA reserved memory). It may be highly related to MM branch and also slightly depends on this CMA changes. In this case, what is the best strategy to merge this patchset? IMHO, Anrew's tree is more appropriate branch. If there is no issue in this case, I am willing to develope further patches based on your tree. That's probably easier. Marek, I'll merge these into -mm (and hence -next and git://git.kernel.org/pub/scm/linux/kernel/git/mhocko/mm.git) and shall hold them pending you review/ack/test/etc, OK? Ok. I've tested them and they work fine. I'm sorry that you had to wait for me for a few days. You can now add: Acked-and-tested-by: Marek Szyprowski m.szyprow...@samsung.com I've also rebased my pending patches onto this set (I will send them soon). The question is now if you want to keep the discussed patches in your -mm tree, or should I take them to my -next branch. If you like to keep them, I assume you will also take the patches which depends on the discussed changes. Best regards -- Marek Szyprowski, PhD Samsung RD Institute Poland ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v3 -next 0/9] CMA: generalize CMA reserved area management code
Hello, On 2014-06-16 07:40, Joonsoo Kim wrote: Currently, there are two users on CMA functionality, one is the DMA subsystem and the other is the KVM on powerpc. They have their own code to manage CMA reserved area even if they looks really similar. From my guess, it is caused by some needs on bitmap management. Kvm side wants to maintain bitmap not for 1 page, but for more size. Eventually it use bitmap where one bit represents 64 pages. When I implement CMA related patches, I should change those two places to apply my change and it seem to be painful to me. I want to change this situation and reduce future code management overhead through this patch. This change could also help developer who want to use CMA in their new feature development, since they can use CMA easily without copying pasting this reserved area management code. v3: - Simplify old patch 1(log format fix) and move it to the end of patchset. - Patch 2: Pass aligned base and size to dma_contiguous_early_fixup() - Patch 5: Add some accessor functions to pass aligned base and size to dma_contiguous_early_fixup() function - Patch 5: Move MAX_CMA_AREAS definition to cma.h - Patch 6: Add CMA region zeroing to PPC KVM's CMA alloc function - Patch 8: put 'base' ahead of 'size' in cma_declare_contiguous() - Remaining minor fixes are noted in commit description of each one v2: - Although this patchset looks very different with v1, the end result, that is, mm/cma.c is same with v1's one. So I carry Ack to patch 6-7. This patchset is based on linux-next 20140610. Thanks for taking care of this. I will test it with my setup and if everything goes well, I will take it to my -next tree. If any branch is required for anyone to continue his works on top of those patches, let me know, I will also prepare it. Patch 1-4 prepare some features to cover PPC KVM's requirements. Patch 5-6 generalize CMA reserved area management code and change users to use it. Patch 7-9 clean-up minor things. Joonsoo Kim (9): DMA, CMA: fix possible memory leak DMA, CMA: separate core CMA management codes from DMA APIs DMA, CMA: support alignment constraint on CMA region DMA, CMA: support arbitrary bitmap granularity CMA: generalize CMA reserved area management functionality PPC, KVM, CMA: use general CMA reserved area management framework mm, CMA: clean-up CMA allocation error path mm, CMA: change cma_declare_contiguous() to obey coding convention mm, CMA: clean-up log message arch/arm/mm/dma-mapping.c|1 + arch/powerpc/kvm/book3s_64_mmu_hv.c |4 +- arch/powerpc/kvm/book3s_hv_builtin.c | 19 +- arch/powerpc/kvm/book3s_hv_cma.c | 240 arch/powerpc/kvm/book3s_hv_cma.h | 27 --- drivers/base/Kconfig | 10 - drivers/base/dma-contiguous.c| 210 ++--- include/linux/cma.h | 21 +++ include/linux/dma-contiguous.h | 11 +- mm/Kconfig | 11 ++ mm/Makefile |1 + mm/cma.c | 335 ++ 12 files changed, 397 insertions(+), 493 deletions(-) delete mode 100644 arch/powerpc/kvm/book3s_hv_cma.c delete mode 100644 arch/powerpc/kvm/book3s_hv_cma.h create mode 100644 include/linux/cma.h create mode 100644 mm/cma.c Best regards -- Marek Szyprowski, PhD Samsung RD Institute Poland ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH -V3 1/4] mm/cma: Move dma contiguous changes into a seperate config
drivers to allocate big physically-contiguous blocks of memory for use with @@ -215,17 +213,7 @@ config CMA For more information see include/linux/dma-contiguous.h. If unsure, say n. -if CMA - -config CMA_DEBUG - bool CMA debug messages (DEVELOPMENT) - depends on DEBUG_KERNEL - help - Turns on debug messages in CMA. This produces KERN_DEBUG - messages for every CMA call as well as various messages while - processing calls such as dma_alloc_from_contiguous(). - This option does not affect warning and error messages. - +if DMA_CMA comment Default contiguous memory area size: config CMA_SIZE_MBYTES diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 4e22ce3..5d93bb5 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -6,7 +6,7 @@ obj-y := core.o bus.o dd.o syscore.o \ attribute_container.o transport_class.o \ topology.o obj-$(CONFIG_DEVTMPFS)+= devtmpfs.o -obj-$(CONFIG_CMA) += dma-contiguous.o +obj-$(CONFIG_DMA_CMA) += dma-contiguous.o obj-y += power/ obj-$(CONFIG_HAS_DMA) += dma-mapping.o obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h index 01b5c84..00141d3 100644 --- a/include/linux/dma-contiguous.h +++ b/include/linux/dma-contiguous.h @@ -57,7 +57,7 @@ struct cma; struct page; struct device; -#ifdef CONFIG_CMA +#ifdef CONFIG_DMA_CMA /* * There is always at least global CMA area and a few optional device diff --git a/mm/Kconfig b/mm/Kconfig index e742d06..26a5f81 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -477,3 +477,27 @@ config FRONTSWAP and swap data is stored as normal on the matching swap device. If unsure, say Y to enable frontswap. + +config CMA + bool Contiguous Memory Allocator + depends on HAVE_MEMBLOCK + select MIGRATION + select MEMORY_ISOLATION + help + This enables the Contiguous Memory Allocator which allows other + subsystems to allocate big physically-contiguous blocks of memory. + CMA reserves a region of memory and allows only movable pages to + be allocated from it. This way, the kernel can use the memory for + pagecache and when a subsystem requests for contiguous area, the + allocated pages are migrated away to serve the contiguous request. + + If unsure, say n. + +config CMA_DEBUG + bool CMA debug messages (DEVELOPMENT) + depends on DEBUG_KERNEL CMA + help + Turns on debug messages in CMA. This produces KERN_DEBUG + messages for every CMA call as well as various messages while + processing calls such as dma_alloc_from_contiguous(). + This option does not affect warning and error messages. Best regards -- Marek Szyprowski Samsung RD Institute Poland ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC PATCH 1/3] mm/cma: Move dma contiguous changes into a seperate config
- bool CMA debug messages (DEVELOPMENT) - depends on DEBUG_KERNEL - help - Turns on debug messages in CMA. This produces KERN_DEBUG - messages for every CMA call as well as various messages while - processing calls such as dma_alloc_from_contiguous(). - This option does not affect warning and error messages. - +if DMA_CMA comment Default contiguous memory area size: config CMA_SIZE_MBYTES diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 4e22ce3..5d93bb5 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -6,7 +6,7 @@ obj-y := core.o bus.o dd.o syscore.o \ attribute_container.o transport_class.o \ topology.o obj-$(CONFIG_DEVTMPFS)+= devtmpfs.o -obj-$(CONFIG_CMA) += dma-contiguous.o +obj-$(CONFIG_DMA_CMA) += dma-contiguous.o obj-y += power/ obj-$(CONFIG_HAS_DMA) += dma-mapping.o obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h index 01b5c84..00141d3 100644 --- a/include/linux/dma-contiguous.h +++ b/include/linux/dma-contiguous.h @@ -57,7 +57,7 @@ struct cma; struct page; struct device; -#ifdef CONFIG_CMA +#ifdef CONFIG_DMA_CMA /* * There is always at least global CMA area and a few optional device diff --git a/mm/Kconfig b/mm/Kconfig index e742d06..b362369 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -477,3 +477,23 @@ config FRONTSWAP and swap data is stored as normal on the matching swap device. If unsure, say Y to enable frontswap. + +config CMA + bool Contiguous Memory Allocator + depends on HAVE_MEMBLOCK + select MIGRATION + select MEMORY_ISOLATION + help + This enables the Contiguous Memory Allocator which allows other + subsystem to allocate big physically-contiguous blocks of memory + + If unsure, say n. + +config CMA_DEBUG + bool CMA debug messages (DEVELOPMENT) + depends on DEBUG_KERNEL CMA + help + Turns on debug messages in CMA. This produces KERN_DEBUG + messages for every CMA call as well as various messages while + processing calls such as dma_alloc_from_contiguous(). + This option does not affect warning and error messages. Best regards -- Marek Szyprowski Samsung RD Institute Poland ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 0/9] dma_debug: add debug_dma_mapping_error support to architectures that support DMA_DEBUG_API
On 12/2/2012 3:06 PM, Joerg Roedel wrote: Hi Marek, On Mon, Nov 26, 2012 at 11:57:19AM +0100, Marek Szyprowski wrote: I've took all the patches to the next-dma-debug branch in my tree, I sorry that You have to wait so long for it. My branch is based on Joerg's dma-debug branch and I've included it for testing in linux-next branch. The patches are now two times in next. One version from my tree and one from yours. Please remove the version from your tree, the patches should go upstream via my dma-debug branch. Ok, I've removed them from my dma-mapping-next tree. Please add/cherry-pick the missing patch for ARM architecture, which I've accidentally already pushed to mainline some time ago and then reverted. See commit 871ae57adc5ed092 (and 697575896670ba). Best regards -- Marek Szyprowski Samsung Poland RD Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 0/9] dma_debug: add debug_dma_mapping_error support to architectures that support DMA_DEBUG_API
Hello, On 11/23/2012 10:29 PM, Shuah Khan wrote: An earlier patch added dma mapping error debug feature to dma_debug infrastructure. References: https://lkml.org/lkml/2012/10/8/296 https://lkml.org/lkml/2012/11/3/219 The following series of patches adds the call to debug_dma_mapping_error() to architecture specific dma_mapping_error() interfaces on the following architectures that support CONFIG_DMA_API_DEBUG. I've took all the patches to the next-dma-debug branch in my tree, I sorry that You have to wait so long for it. My branch is based on Joerg's dma-debug branch and I've included it for testing in linux-next branch. Joerg: would You mind if I handle pushing the whole branch to v3.8 via my kernel tree? Those changes should be kept close together to avoid build breaks for bisecting. Best regards -- Marek Szyprowski Samsung Poland RD Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: [PATCH] common: dma-mapping: add support for generic dma_mmap_* calls
Hi, On Friday, June 29, 2012 1:10 PM Clemens Ladisch wrote: Marek Szyprowski wrote: +++ b/drivers/base/dma-mapping.c ... +int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t dma_addr, size_t size) +{ + int ret = -ENXIO; + ... + if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, ret)) + return ret; This will return -ENXIO if dma_mmap_from_coherent() succeeds. Thanks for spotting this! I will fix it in the next version of the patch. Best regards -- Marek Szyprowski Samsung Poland RD Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] common: dma-mapping: add support for generic dma_mmap_* calls
Commit 9adc5374 ('common: dma-mapping: introduce mmap method') added a generic method for implementing mmap user call to dma_map_ops structure. This patch converts ARM and PowerPC architectures (the only providers of dma_mmap_coherent/dma_mmap_writecombine calls) to use this generic dma_map_ops based call and adds a generic cross architecture definition for dma_mmap_attrs, dma_mmap_coherent, dma_mmap_writecombine functions. The generic mmap virt_to_page-based fallback implementation is provided for architectures which don't provide their own implementation for mmap method. Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Reviewed-by: Kyungmin Park kyungmin.p...@samsung.com --- Hello, This patch is a continuation of my works on dma-mapping cleanup and unification. Previous works (commit 58bca4a8fa ('Merge branch 'for-linus' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping') has been merged to v3.4-rc2. Now I've focuses on providing implementation for all architectures so the drivers and some cross-architecture common helpers (like for example videobuf2) can start using this new api. I'm not 100% sure if the PowerPC changes are correct. The cases of dma_iommu_ops and vio_dma_mapping_ops are a bit suspicious for me, but I have no way to test and check if my changes works for that hardware. Best regards Marek Szyprowski Samsung Poland RD Center --- arch/arm/include/asm/dma-mapping.h | 19 --- arch/powerpc/include/asm/dma-mapping.h |8 +++--- arch/powerpc/kernel/dma-iommu.c |1 + arch/powerpc/kernel/dma-swiotlb.c|1 + arch/powerpc/kernel/dma.c| 36 +++- arch/powerpc/kernel/vio.c|1 + drivers/base/dma-mapping.c | 31 + include/asm-generic/dma-coherent.h |1 + include/asm-generic/dma-mapping-common.h | 37 ++ 9 files changed, 95 insertions(+), 40 deletions(-) diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index bbef15d..8645088 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -186,17 +186,6 @@ extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma, void *cpu_addr, dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs); -#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL) - -static inline int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, - void *cpu_addr, dma_addr_t dma_addr, - size_t size, struct dma_attrs *attrs) -{ - struct dma_map_ops *ops = get_dma_ops(dev); - BUG_ON(!ops); - return ops-mmap(dev, vma, cpu_addr, dma_addr, size, attrs); -} - static inline void *dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { @@ -213,14 +202,6 @@ static inline void dma_free_writecombine(struct device *dev, size_t size, return dma_free_attrs(dev, size, cpu_addr, dma_handle, attrs); } -static inline int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma, - void *cpu_addr, dma_addr_t dma_addr, size_t size) -{ - DEFINE_DMA_ATTRS(attrs); - dma_set_attr(DMA_ATTR_WRITE_COMBINE, attrs); - return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, attrs); -} - /* * This can be called during boot to increase the size of the consistent * DMA region above it's default value of 2MB. It must be called before the diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index 62678e3..7816087 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -27,7 +27,10 @@ extern void *dma_direct_alloc_coherent(struct device *dev, size_t size, extern void dma_direct_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs); - +extern int dma_direct_mmap_coherent(struct device *dev, + struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t handle, + size_t size, struct dma_attrs *attrs); #ifdef CONFIG_NOT_COHERENT_CACHE /* @@ -207,11 +210,8 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -extern int dma_mmap_coherent(struct device *, struct vm_area_struct *, -void *, dma_addr_t, size_t); #define ARCH_HAS_DMA_MMAP_COHERENT - static inline void dma_cache_sync(struct device *dev, void *vaddr
[PATCH 03/14 v2] MIPS: adapt for dma_map_ops changes
From: Andrzej Pietrasiewicz andrze...@samsung.com Adapt core MIPS architecture code for dma_map_ops changes: replace alloc/free_coherent with generic alloc/free methods. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com [added missing changes to arch/mips/cavium-octeon/dma-octeon.c] Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- arch/mips/cavium-octeon/dma-octeon.c | 16 arch/mips/include/asm/dma-mapping.h | 18 -- arch/mips/mm/dma-default.c |8 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c index b6bb92c..df70600 100644 --- a/arch/mips/cavium-octeon/dma-octeon.c +++ b/arch/mips/cavium-octeon/dma-octeon.c @@ -157,7 +157,7 @@ static void octeon_dma_sync_sg_for_device(struct device *dev, } static void *octeon_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp) + dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs) { void *ret; @@ -184,7 +184,7 @@ static void *octeon_dma_alloc_coherent(struct device *dev, size_t size, /* Don't invoke OOM killer */ gfp |= __GFP_NORETRY; - ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp); + ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp, attrs); mb(); @@ -192,14 +192,14 @@ static void *octeon_dma_alloc_coherent(struct device *dev, size_t size, } static void octeon_dma_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle) + void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs) { int order = get_order(size); if (dma_release_from_coherent(dev, order, vaddr)) return; - swiotlb_free_coherent(dev, size, vaddr, dma_handle); + swiotlb_free_coherent(dev, size, vaddr, dma_handle, attrs); } static dma_addr_t octeon_unity_phys_to_dma(struct device *dev, phys_addr_t paddr) @@ -240,8 +240,8 @@ EXPORT_SYMBOL(dma_to_phys); static struct octeon_dma_map_ops octeon_linear_dma_map_ops = { .dma_map_ops = { - .alloc_coherent = octeon_dma_alloc_coherent, - .free_coherent = octeon_dma_free_coherent, + .alloc = octeon_dma_alloc_coherent, + .free = octeon_dma_free_coherent, .map_page = octeon_dma_map_page, .unmap_page = swiotlb_unmap_page, .map_sg = octeon_dma_map_sg, @@ -325,8 +325,8 @@ void __init plat_swiotlb_setup(void) #ifdef CONFIG_PCI static struct octeon_dma_map_ops _octeon_pci_dma_map_ops = { .dma_map_ops = { - .alloc_coherent = octeon_dma_alloc_coherent, - .free_coherent = octeon_dma_free_coherent, + .alloc = octeon_dma_alloc_coherent, + .free = octeon_dma_free_coherent, .map_page = octeon_dma_map_page, .unmap_page = swiotlb_unmap_page, .map_sg = octeon_dma_map_sg, diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index 7aa37dd..cbd41f5 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -57,25 +57,31 @@ dma_set_mask(struct device *dev, u64 mask) extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction); -static inline void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp) +#define dma_alloc_coherent(d,s,h,f)dma_alloc_attrs(d,s,h,f,NULL) + +static inline void *dma_alloc_attrs(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, + struct dma_attrs *attrs) { void *ret; struct dma_map_ops *ops = get_dma_ops(dev); - ret = ops-alloc_coherent(dev, size, dma_handle, gfp); + ret = ops-alloc(dev, size, dma_handle, gfp, NULL); debug_dma_alloc_coherent(dev, size, *dma_handle, ret); return ret; } -static inline void dma_free_coherent(struct device *dev, size_t size, -void *vaddr, dma_addr_t dma_handle) +#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) + +static inline void dma_free_attrs(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle, + struct dma_attrs *attrs) { struct dma_map_ops *ops = get_dma_ops(dev); - ops-free_coherent(dev, size, vaddr, dma_handle); + ops-free(dev, size, vaddr, dma_handle, NULL); debug_dma_free_coherent(dev, size, vaddr, dma_handle); } diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 4608491..3fab204 100644 --- a/arch/mips/mm/dma
[PATCH 04/14 v2] PowerPC: adapt for dma_map_ops changes
From: Andrzej Pietrasiewicz andrze...@samsung.com Adapt core PowerPC architecture code for dma_map_ops changes: replace alloc/free_coherent with generic alloc/free methods. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com [added missing changes to arch/powerpc/kernel/vio.c] Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com Reviewed-by: David Gibson da...@gibson.dropbear.id.au --- arch/powerpc/include/asm/dma-mapping.h | 24 arch/powerpc/kernel/dma-iommu.c | 10 ++ arch/powerpc/kernel/dma-swiotlb.c |4 ++-- arch/powerpc/kernel/dma.c | 10 ++ arch/powerpc/kernel/ibmebus.c | 10 ++ arch/powerpc/kernel/vio.c | 14 -- arch/powerpc/platforms/cell/iommu.c | 16 +--- arch/powerpc/platforms/ps3/system-bus.c | 13 +++-- 8 files changed, 60 insertions(+), 41 deletions(-) diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index dd70fac..62678e3 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -22,9 +22,11 @@ /* Some dma direct funcs must be visible for use in other dma_ops */ extern void *dma_direct_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag); + dma_addr_t *dma_handle, gfp_t flag, + struct dma_attrs *attrs); extern void dma_direct_free_coherent(struct device *dev, size_t size, -void *vaddr, dma_addr_t dma_handle); +void *vaddr, dma_addr_t dma_handle, +struct dma_attrs *attrs); #ifdef CONFIG_NOT_COHERENT_CACHE @@ -130,23 +132,29 @@ static inline int dma_supported(struct device *dev, u64 mask) extern int dma_set_mask(struct device *dev, u64 dma_mask); -static inline void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) +#define dma_alloc_coherent(d,s,h,f)dma_alloc_attrs(d,s,h,f,NULL) + +static inline void *dma_alloc_attrs(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag, + struct dma_attrs *attrs) { struct dma_map_ops *dma_ops = get_dma_ops(dev); void *cpu_addr; BUG_ON(!dma_ops); - cpu_addr = dma_ops-alloc_coherent(dev, size, dma_handle, flag); + cpu_addr = dma_ops-alloc(dev, size, dma_handle, flag, attrs); debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr); return cpu_addr; } -static inline void dma_free_coherent(struct device *dev, size_t size, -void *cpu_addr, dma_addr_t dma_handle) +#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) + +static inline void dma_free_attrs(struct device *dev, size_t size, + void *cpu_addr, dma_addr_t dma_handle, + struct dma_attrs *attrs) { struct dma_map_ops *dma_ops = get_dma_ops(dev); @@ -154,7 +162,7 @@ static inline void dma_free_coherent(struct device *dev, size_t size, debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); - dma_ops-free_coherent(dev, size, cpu_addr, dma_handle); + dma_ops-free(dev, size, cpu_addr, dma_handle, attrs); } static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 3f6464b..bcfdcd2 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -17,7 +17,8 @@ * to the dma address (mapping) of the first page. */ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) + dma_addr_t *dma_handle, gfp_t flag, + struct dma_attrs *attrs) { return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size, dma_handle, dev-coherent_dma_mask, flag, @@ -25,7 +26,8 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, } static void dma_iommu_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle) + void *vaddr, dma_addr_t dma_handle, + struct dma_attrs *attrs) { iommu_free_coherent(get_iommu_table_base(dev), size, vaddr, dma_handle); } @@ -105,8 +107,8 @@ static u64 dma_iommu_get_required_mask(struct device *dev) } struct dma_map_ops dma_iommu_ops = { - .alloc_coherent
[PATCH] Hexagon: adapt for dma_map_ops changes
Adapt core Hexagon architecture code for dma_map_ops changes: replace alloc/free_coherent with generic alloc/free methods. Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- Hello, This patch adds Hexagon architecture to the DMA-mapping framework redesign preparation patches. For more information please refer to the following thread: https://lkml.org/lkml/2011/12/23/97 Best regards Marek Szyprowski Samsung Poland RD Center --- arch/hexagon/include/asm/dma-mapping.h | 18 -- arch/hexagon/kernel/dma.c |9 + 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/arch/hexagon/include/asm/dma-mapping.h b/arch/hexagon/include/asm/dma-mapping.h index 448b224..233ed3d 100644 --- a/arch/hexagon/include/asm/dma-mapping.h +++ b/arch/hexagon/include/asm/dma-mapping.h @@ -71,29 +71,35 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) return (dma_addr == bad_dma_address); } -static inline void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) +#define dma_alloc_coherent(d,s,h,f)dma_alloc_attrs(d,s,h,f,NULL) + +static inline void *dma_alloc_attrs(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag, + struct dma_attrs *attrs) { void *ret; struct dma_map_ops *ops = get_dma_ops(dev); BUG_ON(!dma_ops); - ret = ops-alloc_coherent(dev, size, dma_handle, flag); + ret = ops-alloc(dev, size, dma_handle, flag, attrs); debug_dma_alloc_coherent(dev, size, *dma_handle, ret); return ret; } -static inline void dma_free_coherent(struct device *dev, size_t size, -void *cpu_addr, dma_addr_t dma_handle) +#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) + +static inline void dma_free_attrs(struct device *dev, size_t size, + void *cpu_addr, dma_addr_t dma_handle, + struct dma_attrs *attrs) { struct dma_map_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - dma_ops-free_coherent(dev, size, cpu_addr, dma_handle); + dma_ops-free(dev, size, cpu_addr, dma_handle, attrs); debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); } diff --git a/arch/hexagon/kernel/dma.c b/arch/hexagon/kernel/dma.c index e711ace..3730221 100644 --- a/arch/hexagon/kernel/dma.c +++ b/arch/hexagon/kernel/dma.c @@ -54,7 +54,8 @@ static struct gen_pool *coherent_pool; /* Allocates from a pool of uncached memory that was reserved at boot time */ void *hexagon_dma_alloc_coherent(struct device *dev, size_t size, -dma_addr_t *dma_addr, gfp_t flag) +dma_addr_t *dma_addr, gfp_t flag, +struct dma_attrs *attrs) { void *ret; @@ -81,7 +82,7 @@ void *hexagon_dma_alloc_coherent(struct device *dev, size_t size, } static void hexagon_free_coherent(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_addr) + dma_addr_t dma_addr, struct dma_attrs *attrs) { gen_pool_free(coherent_pool, (unsigned long) vaddr, size); } @@ -202,8 +203,8 @@ static void hexagon_sync_single_for_device(struct device *dev, } struct dma_map_ops hexagon_dma_ops = { - .alloc_coherent = hexagon_dma_alloc_coherent, - .free_coherent = hexagon_free_coherent, + .alloc = hexagon_dma_alloc_coherent, + .free = hexagon_free_coherent, .map_sg = hexagon_map_sg, .map_page = hexagon_map_page, .sync_single_for_cpu = hexagon_sync_single_for_cpu, -- 1.7.1.569.g6f426 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 03/14 v3] MIPS: adapt for dma_map_ops changes
From: Andrzej Pietrasiewicz andrze...@samsung.com Adapt core MIPS architecture code for dma_map_ops changes: replace alloc/free_coherent with generic alloc/free methods. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com [added missing changes to arch/mips/cavium-octeon/dma-octeon.c, fixed attrs argument in dma-mapping.h] Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- arch/mips/cavium-octeon/dma-octeon.c | 16 arch/mips/include/asm/dma-mapping.h | 18 -- arch/mips/mm/dma-default.c |8 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c index b6bb92c..df70600 100644 --- a/arch/mips/cavium-octeon/dma-octeon.c +++ b/arch/mips/cavium-octeon/dma-octeon.c @@ -157,7 +157,7 @@ static void octeon_dma_sync_sg_for_device(struct device *dev, } static void *octeon_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp) + dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs) { void *ret; @@ -184,7 +184,7 @@ static void *octeon_dma_alloc_coherent(struct device *dev, size_t size, /* Don't invoke OOM killer */ gfp |= __GFP_NORETRY; - ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp); + ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp, attrs); mb(); @@ -192,14 +192,14 @@ static void *octeon_dma_alloc_coherent(struct device *dev, size_t size, } static void octeon_dma_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle) + void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs) { int order = get_order(size); if (dma_release_from_coherent(dev, order, vaddr)) return; - swiotlb_free_coherent(dev, size, vaddr, dma_handle); + swiotlb_free_coherent(dev, size, vaddr, dma_handle, attrs); } static dma_addr_t octeon_unity_phys_to_dma(struct device *dev, phys_addr_t paddr) @@ -240,8 +240,8 @@ EXPORT_SYMBOL(dma_to_phys); static struct octeon_dma_map_ops octeon_linear_dma_map_ops = { .dma_map_ops = { - .alloc_coherent = octeon_dma_alloc_coherent, - .free_coherent = octeon_dma_free_coherent, + .alloc = octeon_dma_alloc_coherent, + .free = octeon_dma_free_coherent, .map_page = octeon_dma_map_page, .unmap_page = swiotlb_unmap_page, .map_sg = octeon_dma_map_sg, @@ -325,8 +325,8 @@ void __init plat_swiotlb_setup(void) #ifdef CONFIG_PCI static struct octeon_dma_map_ops _octeon_pci_dma_map_ops = { .dma_map_ops = { - .alloc_coherent = octeon_dma_alloc_coherent, - .free_coherent = octeon_dma_free_coherent, + .alloc = octeon_dma_alloc_coherent, + .free = octeon_dma_free_coherent, .map_page = octeon_dma_map_page, .unmap_page = swiotlb_unmap_page, .map_sg = octeon_dma_map_sg, diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index 7aa37dd..be39a12 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -57,25 +57,31 @@ dma_set_mask(struct device *dev, u64 mask) extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction); -static inline void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp) +#define dma_alloc_coherent(d,s,h,f)dma_alloc_attrs(d,s,h,f,NULL) + +static inline void *dma_alloc_attrs(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, + struct dma_attrs *attrs) { void *ret; struct dma_map_ops *ops = get_dma_ops(dev); - ret = ops-alloc_coherent(dev, size, dma_handle, gfp); + ret = ops-alloc(dev, size, dma_handle, gfp, attrs); debug_dma_alloc_coherent(dev, size, *dma_handle, ret); return ret; } -static inline void dma_free_coherent(struct device *dev, size_t size, -void *vaddr, dma_addr_t dma_handle) +#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) + +static inline void dma_free_attrs(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle, + struct dma_attrs *attrs) { struct dma_map_ops *ops = get_dma_ops(dev); - ops-free_coherent(dev, size, vaddr, dma_handle); + ops-free(dev, size, vaddr, dma_handle, attrs); debug_dma_free_coherent(dev, size, vaddr, dma_handle); } diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 4608491
[PULL REQUEST] DMA-mapping framework redesign preparation patches
Hi Stephen, Our patches with DMA-mapping framework redesign proposal have been hanging for over a month with just a few comments. We would like to go further in the development, but first I would like to ask You to give them a try in the linux-next kernel. For everyone interested in this patch series, here is the relevant thread: https://lkml.org/lkml/2011/12/23/97 If there are any problems with our git tree, please contact Marek Szyprowski m.szyprow...@samsung.com or alternatively Kyungmin Park kyungmin.p...@samsung.com. The following changes since commit 62aa2b537c6f5957afd98e29f96897419ed5ebab: Linux 3.3-rc2 (2012-01-31 13:31:54 -0800) are available in the git repository at: git://git.infradead.org/users/kmpark/linux-samsung dma-mapping-next Andrzej Pietrasiewicz (9): X86: adapt for dma_map_ops changes MIPS: adapt for dma_map_ops changes PowerPC: adapt for dma_map_ops changes IA64: adapt for dma_map_ops changes SPARC: adapt for dma_map_ops changes Alpha: adapt for dma_map_ops changes SH: adapt for dma_map_ops changes Microblaze: adapt for dma_map_ops changes Unicore32: adapt for dma_map_ops changes Marek Szyprowski (5): common: dma-mapping: introduce alloc_attrs and free_attrs methods common: dma-mapping: remove old alloc_coherent and free_coherent methods common: dma-mapping: introduce mmap method common: DMA-mapping: add WRITE_COMBINE attribute common: DMA-mapping: add NON-CONSISTENT attribute Documentation/DMA-attributes.txt | 19 +++ arch/alpha/include/asm/dma-mapping.h | 18 -- arch/alpha/kernel/pci-noop.c | 10 ++ arch/alpha/kernel/pci_iommu.c | 10 ++ arch/ia64/hp/common/sba_iommu.c | 11 ++- arch/ia64/include/asm/dma-mapping.h | 18 -- arch/ia64/kernel/pci-swiotlb.c|9 + arch/ia64/sn/pci/pci_dma.c|9 + arch/microblaze/include/asm/dma-mapping.h | 18 -- arch/microblaze/kernel/dma.c | 10 ++ arch/mips/include/asm/dma-mapping.h | 18 -- arch/mips/mm/dma-default.c|8 arch/powerpc/include/asm/dma-mapping.h| 24 arch/powerpc/kernel/dma-iommu.c | 10 ++ arch/powerpc/kernel/dma-swiotlb.c |4 ++-- arch/powerpc/kernel/dma.c | 10 ++ arch/powerpc/kernel/ibmebus.c | 10 ++ arch/powerpc/platforms/cell/iommu.c | 16 +--- arch/powerpc/platforms/ps3/system-bus.c | 13 +++-- arch/sh/include/asm/dma-mapping.h | 28 ++-- arch/sh/kernel/dma-nommu.c|4 ++-- arch/sh/mm/consistent.c |6 -- arch/sparc/include/asm/dma-mapping.h | 18 -- arch/sparc/kernel/iommu.c | 10 ++ arch/sparc/kernel/ioport.c| 18 ++ arch/sparc/kernel/pci_sun4v.c |9 + arch/unicore32/include/asm/dma-mapping.h | 18 -- arch/unicore32/mm/dma-swiotlb.c |4 ++-- arch/x86/include/asm/dma-mapping.h| 26 -- arch/x86/kernel/amd_gart_64.c | 11 ++- arch/x86/kernel/pci-calgary_64.c |9 + arch/x86/kernel/pci-dma.c |3 ++- arch/x86/kernel/pci-nommu.c |6 +++--- arch/x86/kernel/pci-swiotlb.c | 12 +++- arch/x86/xen/pci-swiotlb-xen.c|4 ++-- drivers/iommu/amd_iommu.c | 10 ++ drivers/iommu/intel-iommu.c |9 + drivers/xen/swiotlb-xen.c |5 +++-- include/linux/dma-attrs.h |2 ++ include/linux/dma-mapping.h | 13 + include/linux/swiotlb.h |6 -- include/xen/swiotlb-xen.h |6 -- lib/swiotlb.c |5 +++-- 43 files changed, 305 insertions(+), 182 deletions(-) Best regards Marek Szyprowski Samsung Poland RD Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: [PATCH 00/14] DMA-mapping framework redesign preparation
Hello, To help everyone in testing and adapting our patches for his hardware platform I've rebased our patches onto the latest v3.2 Linux kernel and prepared a few GIT branches in our public repository. These branches contain our memory management related patches posted in the following threads: [PATCHv18 0/11] Contiguous Memory Allocator: http://www.spinics.net/lists/linux-mm/msg28125.html later called CMAv18, [PATCH 00/14] DMA-mapping framework redesign preparation: http://www.spinics.net/lists/linux-sh/msg09777.html and [PATCH 0/8 v4] ARM: DMA-mapping framework redesign: http://www.spinics.net/lists/arm-kernel/msg151147.html with the following update: http://www.spinics.net/lists/arm-kernel/msg154889.html later called DMAv5. These branches are available in our public GIT repository: git://git.infradead.org/users/kmpark/linux-samsung http://git.infradead.org/users/kmpark/linux-samsung/ The following branches are available: 1) 3.2-cma-v18 Vanilla Linux v3.2 with fixed CMA v18 patches (first patch replaced with the one from v17 to fix SMP issues, see the respective thread). 2) 3.2-dma-v5 Vanilla Linux v3.2 + iommu/next (IOMMU maintainer's patches) branch with DMA-preparation and DMA-mapping framework redesign patches. 3) 3.2-cma-v18-dma-v5 Previous two branches merged together (DMA-mapping on top of CMA) 4) 3.2-cma-v18-dma-v5-exynos Previous branch rebased on top of iommu/next + kgene/for-next (Samsung SoC platform maintainer's patches) with new Exynos4 IOMMU driver by KyongHo Cho and relevant glue code. 5) 3.2-dma-v5-exynos Branch from point 2 rebased on top of iommu/next + kgene/for-next (Samsung SoC maintainer's patches) with new Exynos4 IOMMU driver by KyongHo Cho and relevant glue code. I hope everyone will find a branch that suits his needs. :) Best regards -- Marek Szyprowski Samsung Poland RD Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: [PATCH 00/14] DMA-mapping framework redesign preparation
Hello, On Tuesday, December 27, 2011 6:53 PM James Bottomley wrote: On Tue, 2011-12-27 at 09:25 +0100, Marek Szyprowski wrote: [...] Usually these drivers don't touch the buffer data at all, so the mapping in kernel virtual address space is not needed. We can introduce DMA_ATTRIB_NO_KERNEL_MAPPING attribute which lets kernel to skip/ignore creation of kernel virtual mapping. This way we can save previous vmalloc area and simply some mapping operation on a few architectures. I really think this wants to be a separate function. dma_alloc_coherent is for allocating memory to be shared between the kernel and a driver; we already have dma_map_sg for mapping userspace I/O as an alternative interface. This feels like it's something different again rather than an option to dma_alloc_coherent. That is just a starting point for the discussion. I thought about this API a bit and came to conclusion that there is no much difference between a dma_alloc_coherent which creates a mapping in kernel virtual space and the one that does not. It is just a hint from the driver that it will not use that mapping at all. Of course this attribute makes sense only together with adding a dma_mmap_attrs() call, because otherwise drivers won't be able to get access to the buffer data. This depends. On Virtually indexed systems like PA-RISC, there are two ways of making a DMA range coherent. One is to make the range uncached. This is incredibly slow and not what we do by default, but it can be used to make multiple mappings coherent. The other is to load the virtual address up as a coherence index into the IOMMU. This makes it a full peer in the coherence process, but means we can only designate a single virtual range to be coherent (not multiple mappings unless they happen to be congruent). Perhaps it doesn't matter that much, since I don't see a use for this on PA, but if any other architecture works the same, you'd have to designate a single mapping as the coherent one and essentially promise not to use the other mapping if we followed our normal coherence protocols. Obviously, the usual range we currently make coherent is the kernel mapping (that's actually the only virtual address we have by the time we're deep in the iommu code), so designating a different virtual address would need some surgery to the guts of the iommu code. I see, in this case not much can be achieved by dropping the kernel mapping for the allocated buffer. I'm also not sure how to mmap the buffer into userspace meet the cpu requirements? Is it possible to use non-cached mapping in userspace together with coherent mapping in kernel virtual space? However on some other architectures this attribute allows using HIGH_MEM for the allocated coherent buffer. The other possibility is to allocate it in chunks and map them contiguously into dma address space. With NO_KERNEL_MAPPING attribute we avoid consuming vmalloc range for the newly allocated buffer for which we cannot use the linear mapping (because it is scattered). Of course this attribute will be implemented by the architectures where it gives some benefits. All other can simply ignore it and return plain coherent buffer with ordinary kernel virtual mapping. The driver will just ignore it. Best regards -- Marek Szyprowski Samsung Poland RD Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: [PATCH 00/14] DMA-mapping framework redesign preparation
Hello, On Friday, December 23, 2011 5:35 PM Matthew Wilcox wrote: On Fri, Dec 23, 2011 at 01:27:19PM +0100, Marek Szyprowski wrote: The first issue we identified is the fact that on some platform (again, mainly ARM) there are several functions for allocating DMA buffers: dma_alloc_coherent, dma_alloc_writecombine and dma_alloc_noncoherent Is this write-combining from the point of view of the device (ie iommu), or from the point of view of the CPU, or both? It is about write-combining from the CPU point of view. Right now there are no devices with such advanced memory interface to do write combining on the DMA side, but I believe that they might appear at some point in the future as well. The next step in dma mapping framework update is the introduction of dma_mmap/dma_mmap_attrs() function. There are a number of drivers (mainly V4L2 and ALSA) that only exports the DMA buffers to user space. Creating a userspace mapping with correct page attributes is not an easy task for the driver. Also the DMA-mapping framework is the only place where the complete information about the allocated pages is available, especially if the implementation uses IOMMU controller to provide a contiguous buffer in DMA address space which is scattered in physical memory space. Surely we only need a helper which drivrs can call from their mmap routine to solve this? On ARM architecture it is already implemented this way and a bunch of drivers use dma_mmap_coherent/dma_mmap_writecombine calls. We would like to standardize these calls across all architectures. Usually these drivers don't touch the buffer data at all, so the mapping in kernel virtual address space is not needed. We can introduce DMA_ATTRIB_NO_KERNEL_MAPPING attribute which lets kernel to skip/ignore creation of kernel virtual mapping. This way we can save previous vmalloc area and simply some mapping operation on a few architectures. I really think this wants to be a separate function. dma_alloc_coherent is for allocating memory to be shared between the kernel and a driver; we already have dma_map_sg for mapping userspace I/O as an alternative interface. This feels like it's something different again rather than an option to dma_alloc_coherent. That is just a starting point for the discussion. I thought about this API a bit and came to conclusion that there is no much difference between a dma_alloc_coherent which creates a mapping in kernel virtual space and the one that does not. It is just a hint from the driver that it will not use that mapping at all. Of course this attribute makes sense only together with adding a dma_mmap_attrs() call, because otherwise drivers won't be able to get access to the buffer data. On coherent architectures where dma_alloc_coherent is just a simple wrapper around alloc_pages_exact() such attribute can be simply ignored without any impact on the drivers (that's the main idea behind dma attributes!). However such hint will help a lot on non-coherent architectures where additional work need to be done to provide a cohenent mapping in kernel address space. It also saves some precious kernel resources like vmalloc address range. Best regards -- Marek Szyprowski Samsung Poland RD Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 01/14] common: dma-mapping: introduce alloc_attrs and free_attrs methods
Introduce new generic alloc and free methods with attributes argument. Existing alloc_coherent and free_coherent can be implemented on top of the new calls with NULL attributes argument. Later also dma_alloc_non_coherent can be implemented using DMA_ATTR_NONCOHERENT attribute as well as dma_alloc_writecombine with separate DMA_ATTR_WRITECOMBINE attribute. This way the drivers will get more generic, platform independent way of allocating dma buffers with specific parameters. Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- include/linux/dma-mapping.h |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index e13117c..8cc7f95 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -13,6 +13,12 @@ struct dma_map_ops { dma_addr_t *dma_handle, gfp_t gfp); void (*free_coherent)(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle); + void* (*alloc)(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, + struct dma_attrs *attrs); + void (*free)(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle, + struct dma_attrs *attrs); dma_addr_t (*map_page)(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction dir, -- 1.7.1.569.g6f426 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 00/14] DMA-mapping framework redesign preparation
Hello eveyone, On Linaro Memory Management meeting in Budapest (May 2011) we have discussed about the design of DMA mapping framework. We tried to identify the drawbacks and limitations as well as to provide some a solution for them. The discussion was mainly about ARM architecture, but some of the conclusions need to be applied to cross-architecture code. The first issue we identified is the fact that on some platform (again, mainly ARM) there are several functions for allocating DMA buffers: dma_alloc_coherent, dma_alloc_writecombine and dma_alloc_noncoherent (not functional now). For each of them there is a match dma_free_* function. This gives us quite a lot of functions in the public API and complicates things when we need to have several different implementations for different devices selected in runtime (if IOMMU controller is available only for a few devices in the system). Also the drivers which use less common variants are less portable because of the lacks of dma_alloc_writecombine on other architectures. The solution we found is to introduce a new public dma mapping functions with additional attributes argument: dma_alloc_attrs and dma_free_attrs(). This way all different kinds of architecture specific buffer mappings can be hidden behind the attributes without the need of creating several versions of dma_alloc_ function. dma_alloc_coherent() can be wrapped on top of new dma_alloc_attrs() with NULL attrs parameter. dma_alloc_writecombine and dma_alloc_noncoherent can be implemented as a simple wrappers which sets attributes to DMA_ATTRS_WRITECOMBINE or DMA_ATTRS_NON_CONSISTENT respectively. These new attributes will be implemented only on the architectures that really support them, the others will simply ignore them defaulting to the dma_alloc_coherent equivalent. The next step in dma mapping framework update is the introduction of dma_mmap/dma_mmap_attrs() function. There are a number of drivers (mainly V4L2 and ALSA) that only exports the DMA buffers to user space. Creating a userspace mapping with correct page attributes is not an easy task for the driver. Also the DMA-mapping framework is the only place where the complete information about the allocated pages is available, especially if the implementation uses IOMMU controller to provide a contiguous buffer in DMA address space which is scattered in physical memory space. Usually these drivers don't touch the buffer data at all, so the mapping in kernel virtual address space is not needed. We can introduce DMA_ATTRIB_NO_KERNEL_MAPPING attribute which lets kernel to skip/ignore creation of kernel virtual mapping. This way we can save previous vmalloc area and simply some mapping operation on a few architectures. This patch series is a preparation for the above changes in the public dma mapping API. The main goal is to modify dma_map_ops structure and let all users to use for implementation of the new public funtions. The proof-of-concept patches for ARM architecture have been already posted a few times and now they are working resonably well. They perform conversion to dma_map_ops based implementation and add support for generic IOMMU-based dma mapping implementation. To get them merged we first need to get acceptance for the changes in the common, cross-architecture structures. More information about these patches can be found in the following threads: http://www.spinics.net/lists/linux-mm/msg19856.html http://www.spinics.net/lists/linux-mm/msg21241.html http://lists.linaro.org/pipermail/linaro-mm-sig/2011-September/000571.html http://lists.linaro.org/pipermail/linaro-mm-sig/2011-September/000577.html http://www.spinics.net/lists/linux-mm/msg25490.html The patches are prepared on top of Linux Kernel v3.2-rc6. I would appreciate any comments and help with getting this patch series into linux-next tree. The idea apllied in this patch set have been also presented during the Kernel Summit 2011 and ELC-E 2011 in Prague, in the presentation 'ARM DMA-Mapping Framework Redesign and IOMMU integration'. I'm really sorry if I missed any of the relevant architecture mailing lists. I've did my best to include everyone. Feel free to forward this patchset to all interested developers and maintainers. I've already feel like a nasty spammer. Best regards Marek Szyprowski Samsung Poland RD Center Patch summary: Andrzej Pietrasiewicz (9): X86: adapt for dma_map_ops changes MIPS: adapt for dma_map_ops changes PowerPC: adapt for dma_map_ops changes IA64: adapt for dma_map_ops changes SPARC: adapt for dma_map_ops changes Alpha: adapt for dma_map_ops changes SH: adapt for dma_map_ops changes Microblaze: adapt for dma_map_ops changes Unicore32: adapt for dma_map_ops changes Marek Szyprowski (5): common: dma-mapping: introduce alloc_attrs and free_attrs methods common: dma-mapping: remove old alloc_coherent and free_coherent methods common: dma-mapping: introduce mmap method common: DMA-mapping: add WRITE_COMBINE
[PATCH 05/14] IA64: adapt for dma_map_ops changes
From: Andrzej Pietrasiewicz andrze...@samsung.com Adapt core IA64 architecture code for dma_map_ops changes: replace alloc/free_coherent with generic alloc/free methods. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- arch/ia64/hp/common/sba_iommu.c | 11 ++- arch/ia64/include/asm/dma-mapping.h | 18 -- arch/ia64/kernel/pci-swiotlb.c |9 + arch/ia64/sn/pci/pci_dma.c |9 + 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index f5f4ef1..e5eb9c4 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -1130,7 +1130,8 @@ void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, * See Documentation/DMA-API-HOWTO.txt */ static void * -sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags) +sba_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, + gfp_t flags, struct dma_attrs *attrs) { struct ioc *ioc; void *addr; @@ -1192,8 +1193,8 @@ sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp * * See Documentation/DMA-API-HOWTO.txt */ -static void sba_free_coherent (struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_handle) +static void sba_free_coherent(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle, struct dma_attrs *attrs) { sba_unmap_single_attrs(dev, dma_handle, size, 0, NULL); free_pages((unsigned long) vaddr, get_order(size)); @@ -2213,8 +2214,8 @@ sba_page_override(char *str) __setup(sbapagesize=,sba_page_override); struct dma_map_ops sba_dma_ops = { - .alloc_coherent = sba_alloc_coherent, - .free_coherent = sba_free_coherent, + .alloc = sba_alloc_coherent, + .free = sba_free_coherent, .map_page = sba_map_page, .unmap_page = sba_unmap_page, .map_sg = sba_map_sg_attrs, diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h index 4336d08..4f5e814 100644 --- a/arch/ia64/include/asm/dma-mapping.h +++ b/arch/ia64/include/asm/dma-mapping.h @@ -23,23 +23,29 @@ extern void machvec_dma_sync_single(struct device *, dma_addr_t, size_t, extern void machvec_dma_sync_sg(struct device *, struct scatterlist *, int, enum dma_data_direction); -static inline void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *daddr, gfp_t gfp) +#define dma_alloc_coherent(d,s,h,f)dma_alloc_attrs(d,s,h,f,NULL) + +static inline void *dma_alloc_attrs(struct device *dev, size_t size, + dma_addr_t *daddr, gfp_t gfp, + struct dma_attrs *attrs) { struct dma_map_ops *ops = platform_dma_get_ops(dev); void *caddr; - caddr = ops-alloc_coherent(dev, size, daddr, gfp); + caddr = ops-alloc(dev, size, daddr, gfp, attrs); debug_dma_alloc_coherent(dev, size, *daddr, caddr); return caddr; } -static inline void dma_free_coherent(struct device *dev, size_t size, -void *caddr, dma_addr_t daddr) +#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) + +static inline void dma_free_attrs(struct device *dev, size_t size, + void *caddr, dma_addr_t daddr, + struct dma_attrs *attrs) { struct dma_map_ops *ops = platform_dma_get_ops(dev); debug_dma_free_coherent(dev, size, caddr, daddr); - ops-free_coherent(dev, size, caddr, daddr); + ops-free(dev, size, caddr, daddr, attrs); } #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c index d9485d9..cc034c2 100644 --- a/arch/ia64/kernel/pci-swiotlb.c +++ b/arch/ia64/kernel/pci-swiotlb.c @@ -15,16 +15,17 @@ int swiotlb __read_mostly; EXPORT_SYMBOL(swiotlb); static void *ia64_swiotlb_alloc_coherent(struct device *dev, size_t size, -dma_addr_t *dma_handle, gfp_t gfp) +dma_addr_t *dma_handle, gfp_t gfp, +struct dma_attrs *attrs) { if (dev-coherent_dma_mask != DMA_BIT_MASK(64)) gfp |= GFP_DMA; - return swiotlb_alloc_coherent(dev, size, dma_handle, gfp); + return swiotlb_alloc_coherent(dev, size, dma_handle, gfp, attrs); } struct dma_map_ops swiotlb_dma_ops = { - .alloc_coherent
[PATCH 03/14] MIPS: adapt for dma_map_ops changes
From: Andrzej Pietrasiewicz andrze...@samsung.com Adapt core MIPS architecture code for dma_map_ops changes: replace alloc/free_coherent with generic alloc/free methods. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- arch/mips/include/asm/dma-mapping.h | 18 -- arch/mips/mm/dma-default.c |8 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index 7aa37dd..cbd41f5 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -57,25 +57,31 @@ dma_set_mask(struct device *dev, u64 mask) extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction); -static inline void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp) +#define dma_alloc_coherent(d,s,h,f)dma_alloc_attrs(d,s,h,f,NULL) + +static inline void *dma_alloc_attrs(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, + struct dma_attrs *attrs) { void *ret; struct dma_map_ops *ops = get_dma_ops(dev); - ret = ops-alloc_coherent(dev, size, dma_handle, gfp); + ret = ops-alloc(dev, size, dma_handle, gfp, NULL); debug_dma_alloc_coherent(dev, size, *dma_handle, ret); return ret; } -static inline void dma_free_coherent(struct device *dev, size_t size, -void *vaddr, dma_addr_t dma_handle) +#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) + +static inline void dma_free_attrs(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle, + struct dma_attrs *attrs) { struct dma_map_ops *ops = get_dma_ops(dev); - ops-free_coherent(dev, size, vaddr, dma_handle); + ops-free(dev, size, vaddr, dma_handle, NULL); debug_dma_free_coherent(dev, size, vaddr, dma_handle); } diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 4608491..3fab204 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -98,7 +98,7 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size, EXPORT_SYMBOL(dma_alloc_noncoherent); static void *mips_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t * dma_handle, gfp_t gfp) + dma_addr_t * dma_handle, gfp_t gfp, struct dma_attrs *attrs) { void *ret; @@ -132,7 +132,7 @@ void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr, EXPORT_SYMBOL(dma_free_noncoherent); static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_handle) + dma_addr_t dma_handle, struct dma_attrs *attrs) { unsigned long addr = (unsigned long) vaddr; int order = get_order(size); @@ -323,8 +323,8 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size, EXPORT_SYMBOL(dma_cache_sync); static struct dma_map_ops mips_default_dma_map_ops = { - .alloc_coherent = mips_dma_alloc_coherent, - .free_coherent = mips_dma_free_coherent, + .alloc = mips_dma_alloc_coherent, + .free = mips_dma_free_coherent, .map_page = mips_dma_map_page, .unmap_page = mips_dma_unmap_page, .map_sg = mips_dma_map_sg, -- 1.7.1.569.g6f426 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 02/14] X86: adapt for dma_map_ops changes
From: Andrzej Pietrasiewicz andrze...@samsung.com Adapt core X86 architecture code for dma_map_ops changes: replace alloc/free_coherent with generic alloc/free methods. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- arch/x86/include/asm/dma-mapping.h | 26 -- arch/x86/kernel/amd_gart_64.c | 11 ++- arch/x86/kernel/pci-calgary_64.c |9 + arch/x86/kernel/pci-dma.c |3 ++- arch/x86/kernel/pci-nommu.c|6 +++--- arch/x86/kernel/pci-swiotlb.c | 12 +++- arch/x86/xen/pci-swiotlb-xen.c |4 ++-- drivers/iommu/amd_iommu.c | 10 ++ drivers/iommu/intel-iommu.c|9 + drivers/xen/swiotlb-xen.c |5 +++-- include/linux/swiotlb.h|6 -- include/xen/swiotlb-xen.h |6 -- lib/swiotlb.c |5 +++-- 13 files changed, 66 insertions(+), 46 deletions(-) diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h index ed3065f..4b4331d 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h @@ -59,7 +59,8 @@ extern int dma_supported(struct device *hwdev, u64 mask); extern int dma_set_mask(struct device *dev, u64 mask); extern void *dma_generic_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_addr, gfp_t flag); + dma_addr_t *dma_addr, gfp_t flag, + struct dma_attrs *attrs); static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) { @@ -111,9 +112,11 @@ static inline gfp_t dma_alloc_coherent_gfp_flags(struct device *dev, gfp_t gfp) return gfp; } +#define dma_alloc_coherent(d,s,h,f)dma_alloc_attrs(d,s,h,f,NULL) + static inline void * -dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, - gfp_t gfp) +dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle, + gfp_t gfp, struct dma_attrs *attrs) { struct dma_map_ops *ops = get_dma_ops(dev); void *memory; @@ -129,18 +132,21 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, if (!is_device_dma_capable(dev)) return NULL; - if (!ops-alloc_coherent) + if (!ops-alloc) return NULL; - memory = ops-alloc_coherent(dev, size, dma_handle, -dma_alloc_coherent_gfp_flags(dev, gfp)); + memory = ops-alloc(dev, size, dma_handle, + dma_alloc_coherent_gfp_flags(dev, gfp), attrs); debug_dma_alloc_coherent(dev, size, *dma_handle, memory); return memory; } -static inline void dma_free_coherent(struct device *dev, size_t size, -void *vaddr, dma_addr_t bus) +#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) + +static inline void dma_free_attrs(struct device *dev, size_t size, + void *vaddr, dma_addr_t bus, + struct dma_attrs *attrs) { struct dma_map_ops *ops = get_dma_ops(dev); @@ -150,8 +156,8 @@ static inline void dma_free_coherent(struct device *dev, size_t size, return; debug_dma_free_coherent(dev, size, vaddr, bus); - if (ops-free_coherent) - ops-free_coherent(dev, size, vaddr, bus); + if (ops-free) + ops-free(dev, size, vaddr, bus, attrs); } #endif diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c index b1e7c7f..e663112 100644 --- a/arch/x86/kernel/amd_gart_64.c +++ b/arch/x86/kernel/amd_gart_64.c @@ -477,7 +477,7 @@ error: /* allocate and map a coherent mapping */ static void * gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr, - gfp_t flag) + gfp_t flag, struct dma_attrs *attrs) { dma_addr_t paddr; unsigned long align_mask; @@ -500,7 +500,8 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr, } __free_pages(page, get_order(size)); } else - return dma_generic_alloc_coherent(dev, size, dma_addr, flag); + return dma_generic_alloc_coherent(dev, size, dma_addr, flag, + attrs); return NULL; } @@ -508,7 +509,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr, /* free a coherent mapping */ static void gart_free_coherent(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_addr) + dma_addr_t dma_addr, struct dma_attrs *attrs) { gart_unmap_page(dev
[PATCH 07/14] Alpha: adapt for dma_map_ops changes
From: Andrzej Pietrasiewicz andrze...@samsung.com Adapt core Alpha architecture code for dma_map_ops changes: replace alloc/free_coherent with generic alloc/free methods. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- arch/alpha/include/asm/dma-mapping.h | 18 -- arch/alpha/kernel/pci-noop.c | 10 ++ arch/alpha/kernel/pci_iommu.c| 10 ++ 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/arch/alpha/include/asm/dma-mapping.h b/arch/alpha/include/asm/dma-mapping.h index 4567aca..dfa32f0 100644 --- a/arch/alpha/include/asm/dma-mapping.h +++ b/arch/alpha/include/asm/dma-mapping.h @@ -12,16 +12,22 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev) #include asm-generic/dma-mapping-common.h -static inline void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp) +#define dma_alloc_coherent(d,s,h,f)dma_alloc_attrs(d,s,h,f,NULL) + +static inline void *dma_alloc_attrs(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, + struct dma_attrs *attrs) { - return get_dma_ops(dev)-alloc_coherent(dev, size, dma_handle, gfp); + return get_dma_ops(dev)-alloc(dev, size, dma_handle, gfp, attrs); } -static inline void dma_free_coherent(struct device *dev, size_t size, -void *vaddr, dma_addr_t dma_handle) +#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) + +static inline void dma_free_attrs(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle, + struct dma_attrs *attrs) { - get_dma_ops(dev)-free_coherent(dev, size, vaddr, dma_handle); + get_dma_ops(dev)-free(dev, size, vaddr, dma_handle, attrs); } static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c index 246100e..c337fb8 100644 --- a/arch/alpha/kernel/pci-noop.c +++ b/arch/alpha/kernel/pci-noop.c @@ -108,7 +108,8 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn, } static void *alpha_noop_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp) + dma_addr_t *dma_handle, gfp_t gfp, + struct dma_attrs *attrs) { void *ret; @@ -123,7 +124,8 @@ static void *alpha_noop_alloc_coherent(struct device *dev, size_t size, } static void alpha_noop_free_coherent(struct device *dev, size_t size, -void *cpu_addr, dma_addr_t dma_addr) +void *cpu_addr, dma_addr_t dma_addr, +struct dma_attrs *attrs) { free_pages((unsigned long)cpu_addr, get_order(size)); } @@ -174,8 +176,8 @@ static int alpha_noop_set_mask(struct device *dev, u64 mask) } struct dma_map_ops alpha_noop_ops = { - .alloc_coherent = alpha_noop_alloc_coherent, - .free_coherent = alpha_noop_free_coherent, + .alloc = alpha_noop_alloc_coherent, + .free = alpha_noop_free_coherent, .map_page = alpha_noop_map_page, .map_sg = alpha_noop_map_sg, .mapping_error = alpha_noop_mapping_error, diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index 4361080..cd63479 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -434,7 +434,8 @@ static void alpha_pci_unmap_page(struct device *dev, dma_addr_t dma_addr, else DMA_ADDRP is undefined. */ static void *alpha_pci_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_addrp, gfp_t gfp) + dma_addr_t *dma_addrp, gfp_t gfp, + struct dma_attrs *attrs) { struct pci_dev *pdev = alpha_gendev_to_pci(dev); void *cpu_addr; @@ -478,7 +479,8 @@ try_again: DMA_ADDR past this call are illegal. */ static void alpha_pci_free_coherent(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_addr) + void *cpu_addr, dma_addr_t dma_addr, + struct dma_attrs *attrs) { struct pci_dev *pdev = alpha_gendev_to_pci(dev); pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL); @@ -952,8 +954,8 @@ static int alpha_pci_set_mask(struct device *dev, u64 mask) } struct dma_map_ops alpha_pci_ops = { - .alloc_coherent
[PATCH 08/14] SH: adapt for dma_map_ops changes
From: Andrzej Pietrasiewicz andrze...@samsung.com Adapt core SH architecture code for dma_map_ops changes: replace alloc/free_coherent with generic alloc/free methods. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- arch/sh/include/asm/dma-mapping.h | 28 ++-- arch/sh/kernel/dma-nommu.c|4 ++-- arch/sh/mm/consistent.c |6 -- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h index 1a73c3e..8bd965e 100644 --- a/arch/sh/include/asm/dma-mapping.h +++ b/arch/sh/include/asm/dma-mapping.h @@ -52,25 +52,31 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) return dma_addr == 0; } -static inline void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp) +#define dma_alloc_coherent(d,s,h,f)dma_alloc_attrs(d,s,h,f,NULL) + +static inline void *dma_alloc_attrs(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, + struct dma_attrs *attrs) { struct dma_map_ops *ops = get_dma_ops(dev); void *memory; if (dma_alloc_from_coherent(dev, size, dma_handle, memory)) return memory; - if (!ops-alloc_coherent) + if (!ops-alloc) return NULL; - memory = ops-alloc_coherent(dev, size, dma_handle, gfp); + memory = ops-alloc(dev, size, dma_handle, gfp, attrs); debug_dma_alloc_coherent(dev, size, *dma_handle, memory); return memory; } -static inline void dma_free_coherent(struct device *dev, size_t size, -void *vaddr, dma_addr_t dma_handle) +#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) + +static inline void dma_free_attrs(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle, + struct dma_attrs *attrs) { struct dma_map_ops *ops = get_dma_ops(dev); @@ -78,14 +84,16 @@ static inline void dma_free_coherent(struct device *dev, size_t size, return; debug_dma_free_coherent(dev, size, vaddr, dma_handle); - if (ops-free_coherent) - ops-free_coherent(dev, size, vaddr, dma_handle); + if (ops-free) + ops-free(dev, size, vaddr, dma_handle, attrs); } /* arch/sh/mm/consistent.c */ extern void *dma_generic_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_addr, gfp_t flag); + dma_addr_t *dma_addr, gfp_t flag, + struct dma_attrs *attrs); extern void dma_generic_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle); + void *vaddr, dma_addr_t dma_handle, + struct dma_attrs *attrs); #endif /* __ASM_SH_DMA_MAPPING_H */ diff --git a/arch/sh/kernel/dma-nommu.c b/arch/sh/kernel/dma-nommu.c index 3c55b87..5b0bfcd 100644 --- a/arch/sh/kernel/dma-nommu.c +++ b/arch/sh/kernel/dma-nommu.c @@ -63,8 +63,8 @@ static void nommu_sync_sg(struct device *dev, struct scatterlist *sg, #endif struct dma_map_ops nommu_dma_ops = { - .alloc_coherent = dma_generic_alloc_coherent, - .free_coherent = dma_generic_free_coherent, + .alloc = dma_generic_alloc_coherent, + .free = dma_generic_free_coherent, .map_page = nommu_map_page, .map_sg = nommu_map_sg, #ifdef CONFIG_DMA_NONCOHERENT diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c index f251b5f..b81d9db 100644 --- a/arch/sh/mm/consistent.c +++ b/arch/sh/mm/consistent.c @@ -33,7 +33,8 @@ static int __init dma_init(void) fs_initcall(dma_init); void *dma_generic_alloc_coherent(struct device *dev, size_t size, -dma_addr_t *dma_handle, gfp_t gfp) +dma_addr_t *dma_handle, gfp_t gfp, +struct dma_attrs *attrs) { void *ret, *ret_nocache; int order = get_order(size); @@ -64,7 +65,8 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, } void dma_generic_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle) + void *vaddr, dma_addr_t dma_handle, + struct dma_attrs *attrs) { int order = get_order(size); unsigned long pfn = dma_handle PAGE_SHIFT; -- 1.7.1.569.g6f426
[PATCH 04/14] PowerPC: adapt for dma_map_ops changes
From: Andrzej Pietrasiewicz andrze...@samsung.com Adapt core PowerPC architecture code for dma_map_ops changes: replace alloc/free_coherent with generic alloc/free methods. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- arch/powerpc/include/asm/dma-mapping.h | 24 arch/powerpc/kernel/dma-iommu.c | 10 ++ arch/powerpc/kernel/dma-swiotlb.c |4 ++-- arch/powerpc/kernel/dma.c | 10 ++ arch/powerpc/kernel/ibmebus.c | 10 ++ arch/powerpc/platforms/cell/iommu.c | 16 +--- arch/powerpc/platforms/ps3/system-bus.c | 13 +++-- 7 files changed, 52 insertions(+), 35 deletions(-) diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index dd70fac..62678e3 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -22,9 +22,11 @@ /* Some dma direct funcs must be visible for use in other dma_ops */ extern void *dma_direct_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag); + dma_addr_t *dma_handle, gfp_t flag, + struct dma_attrs *attrs); extern void dma_direct_free_coherent(struct device *dev, size_t size, -void *vaddr, dma_addr_t dma_handle); +void *vaddr, dma_addr_t dma_handle, +struct dma_attrs *attrs); #ifdef CONFIG_NOT_COHERENT_CACHE @@ -130,23 +132,29 @@ static inline int dma_supported(struct device *dev, u64 mask) extern int dma_set_mask(struct device *dev, u64 dma_mask); -static inline void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) +#define dma_alloc_coherent(d,s,h,f)dma_alloc_attrs(d,s,h,f,NULL) + +static inline void *dma_alloc_attrs(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag, + struct dma_attrs *attrs) { struct dma_map_ops *dma_ops = get_dma_ops(dev); void *cpu_addr; BUG_ON(!dma_ops); - cpu_addr = dma_ops-alloc_coherent(dev, size, dma_handle, flag); + cpu_addr = dma_ops-alloc(dev, size, dma_handle, flag, attrs); debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr); return cpu_addr; } -static inline void dma_free_coherent(struct device *dev, size_t size, -void *cpu_addr, dma_addr_t dma_handle) +#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) + +static inline void dma_free_attrs(struct device *dev, size_t size, + void *cpu_addr, dma_addr_t dma_handle, + struct dma_attrs *attrs) { struct dma_map_ops *dma_ops = get_dma_ops(dev); @@ -154,7 +162,7 @@ static inline void dma_free_coherent(struct device *dev, size_t size, debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); - dma_ops-free_coherent(dev, size, cpu_addr, dma_handle); + dma_ops-free(dev, size, cpu_addr, dma_handle, attrs); } static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 3f6464b..bcfdcd2 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -17,7 +17,8 @@ * to the dma address (mapping) of the first page. */ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) + dma_addr_t *dma_handle, gfp_t flag, + struct dma_attrs *attrs) { return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size, dma_handle, dev-coherent_dma_mask, flag, @@ -25,7 +26,8 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, } static void dma_iommu_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle) + void *vaddr, dma_addr_t dma_handle, + struct dma_attrs *attrs) { iommu_free_coherent(get_iommu_table_base(dev), size, vaddr, dma_handle); } @@ -105,8 +107,8 @@ static u64 dma_iommu_get_required_mask(struct device *dev) } struct dma_map_ops dma_iommu_ops = { - .alloc_coherent = dma_iommu_alloc_coherent, - .free_coherent = dma_iommu_free_coherent, + .alloc = dma_iommu_alloc_coherent, + .free
[PATCH 09/14] Microblaze: adapt for dma_map_ops changes
From: Andrzej Pietrasiewicz andrze...@samsung.com Adapt core Microblaze architecture code for dma_map_ops changes: replace alloc/free_coherent with generic alloc/free methods. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- arch/microblaze/include/asm/dma-mapping.h | 18 -- arch/microblaze/kernel/dma.c | 10 ++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h index 3a3e5b8..0ee58d2 100644 --- a/arch/microblaze/include/asm/dma-mapping.h +++ b/arch/microblaze/include/asm/dma-mapping.h @@ -123,28 +123,34 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -static inline void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) +#define dma_alloc_coherent(d,s,h,f)dma_alloc_attrs(d,s,h,f,NULL) + +static inline void *dma_alloc_attrs(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag, + struct dma_attrs *attrs) { struct dma_map_ops *ops = get_dma_ops(dev); void *memory; BUG_ON(!ops); - memory = ops-alloc_coherent(dev, size, dma_handle, flag); + memory = ops-alloc(dev, size, dma_handle, flag, attrs); debug_dma_alloc_coherent(dev, size, *dma_handle, memory); return memory; } -static inline void dma_free_coherent(struct device *dev, size_t size, -void *cpu_addr, dma_addr_t dma_handle) +#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) + +static inline void dma_free_attrs(struct device *dev, size_t size, + void *cpu_addr, dma_addr_t dma_handle, + struct dma_attrs *attrs) { struct dma_map_ops *ops = get_dma_ops(dev); BUG_ON(!ops); debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); - ops-free_coherent(dev, size, cpu_addr, dma_handle); + ops-free(dev, size, cpu_addr, dma_handle, attrs); } static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c index 65a4af4..a2bfa2c 100644 --- a/arch/microblaze/kernel/dma.c +++ b/arch/microblaze/kernel/dma.c @@ -33,7 +33,8 @@ static unsigned long get_dma_direct_offset(struct device *dev) #define NOT_COHERENT_CACHE static void *dma_direct_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) + dma_addr_t *dma_handle, gfp_t flag, + struct dma_attrs *attrs) { #ifdef NOT_COHERENT_CACHE return consistent_alloc(flag, size, dma_handle); @@ -57,7 +58,8 @@ static void *dma_direct_alloc_coherent(struct device *dev, size_t size, } static void dma_direct_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle) +void *vaddr, dma_addr_t dma_handle, +struct dma_attrs *attrs) { #ifdef NOT_COHERENT_CACHE consistent_free(size, vaddr); @@ -176,8 +178,8 @@ dma_direct_sync_sg_for_device(struct device *dev, } struct dma_map_ops dma_direct_ops = { - .alloc_coherent = dma_direct_alloc_coherent, - .free_coherent = dma_direct_free_coherent, + .alloc = dma_direct_alloc_coherent, + .free = dma_direct_free_coherent, .map_sg = dma_direct_map_sg, .unmap_sg = dma_direct_unmap_sg, .dma_supported = dma_direct_dma_supported, -- 1.7.1.569.g6f426 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 13/14] common: DMA-mapping: add WRITE_COMBINE attribute
DMA_ATTR_WRITE_COMBINE specifies that writes to the mapping may be buffered to improve performance. It will be used by the replacement for ARM/ARV32 specific dma_alloc_writecombine() function. Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- Documentation/DMA-attributes.txt | 10 ++ include/linux/dma-attrs.h|1 + 2 files changed, 11 insertions(+), 0 deletions(-) diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt index b768cc0..811a5d4 100644 --- a/Documentation/DMA-attributes.txt +++ b/Documentation/DMA-attributes.txt @@ -31,3 +31,13 @@ may be weakly ordered, that is that reads and writes may pass each other. Since it is optional for platforms to implement DMA_ATTR_WEAK_ORDERING, those that do not will simply ignore the attribute and exhibit default behavior. + +DMA_ATTR_WRITE_COMBINE +-- + +DMA_ATTR_WRITE_COMBINE specifies that writes to the mapping may be +buffered to improve performance. + +Since it is optional for platforms to implement DMA_ATTR_WRITE_COMBINE, +those that do not will simply ignore the attribute and exhibit default +behavior. diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h index 71ad34e..ada61e1 100644 --- a/include/linux/dma-attrs.h +++ b/include/linux/dma-attrs.h @@ -13,6 +13,7 @@ enum dma_attr { DMA_ATTR_WRITE_BARRIER, DMA_ATTR_WEAK_ORDERING, + DMA_ATTR_WRITE_COMBINE, DMA_ATTR_MAX, }; -- 1.7.1.569.g6f426 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 12/14] common: dma-mapping: introduce mmap method
Introduce new generic mmap method with attributes argument. This method lets drivers to create a userspace mapping for a DMA buffer in generic, architecture independent way. Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- include/linux/dma-mapping.h |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 2fc413a..b903a20 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -15,6 +15,9 @@ struct dma_map_ops { void (*free)(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs); + int (*mmap)(struct device *, struct vm_area_struct *, + void *, dma_addr_t, size_t, struct dma_attrs *attrs); + dma_addr_t (*map_page)(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction dir, -- 1.7.1.569.g6f426 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 06/14] SPARC: adapt for dma_map_ops changes
From: Andrzej Pietrasiewicz andrze...@samsung.com Adapt core SPARC architecture code for dma_map_ops changes: replace alloc/free_coherent with generic alloc/free methods. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- arch/sparc/include/asm/dma-mapping.h | 18 -- arch/sparc/kernel/iommu.c| 10 ++ arch/sparc/kernel/ioport.c | 18 ++ arch/sparc/kernel/pci_sun4v.c|9 + 4 files changed, 33 insertions(+), 22 deletions(-) diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h index 8c0e4f7..48a7c65 100644 --- a/arch/sparc/include/asm/dma-mapping.h +++ b/arch/sparc/include/asm/dma-mapping.h @@ -26,24 +26,30 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev) #include asm-generic/dma-mapping-common.h -static inline void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) +#define dma_alloc_coherent(d,s,h,f)dma_alloc_attrs(d,s,h,f,NULL) + +static inline void *dma_alloc_attrs(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag, + struct dma_attrs *attrs) { struct dma_map_ops *ops = get_dma_ops(dev); void *cpu_addr; - cpu_addr = ops-alloc_coherent(dev, size, dma_handle, flag); + cpu_addr = ops-alloc(dev, size, dma_handle, flag, attrs); debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr); return cpu_addr; } -static inline void dma_free_coherent(struct device *dev, size_t size, -void *cpu_addr, dma_addr_t dma_handle) +#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) + +static inline void dma_free_attrs(struct device *dev, size_t size, + void *cpu_addr, dma_addr_t dma_handle, + struct dma_attrs *attrs) { struct dma_map_ops *ops = get_dma_ops(dev); debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); - ops-free_coherent(dev, size, cpu_addr, dma_handle); + ops-free(dev, size, cpu_addr, dma_handle, attrs); } static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c index 4643d68..070ed14 100644 --- a/arch/sparc/kernel/iommu.c +++ b/arch/sparc/kernel/iommu.c @@ -280,7 +280,8 @@ static inline void iommu_free_ctx(struct iommu *iommu, int ctx) } static void *dma_4u_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_addrp, gfp_t gfp) + dma_addr_t *dma_addrp, gfp_t gfp, + struct dma_attrs *attrs) { unsigned long flags, order, first_page; struct iommu *iommu; @@ -330,7 +331,8 @@ static void *dma_4u_alloc_coherent(struct device *dev, size_t size, } static void dma_4u_free_coherent(struct device *dev, size_t size, -void *cpu, dma_addr_t dvma) +void *cpu, dma_addr_t dvma, +struct dma_attrs *attrs) { struct iommu *iommu; unsigned long flags, order, npages; @@ -825,8 +827,8 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev, } static struct dma_map_ops sun4u_dma_ops = { - .alloc_coherent = dma_4u_alloc_coherent, - .free_coherent = dma_4u_free_coherent, + .alloc = dma_4u_alloc_coherent, + .free = dma_4u_free_coherent, .map_page = dma_4u_map_page, .unmap_page = dma_4u_unmap_page, .map_sg = dma_4u_map_sg, diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index d0479e2..21bd739 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -261,7 +261,8 @@ EXPORT_SYMBOL(sbus_set_sbus64); * CPU may access them without any explicit flushing. */ static void *sbus_alloc_coherent(struct device *dev, size_t len, -dma_addr_t *dma_addrp, gfp_t gfp) +dma_addr_t *dma_addrp, gfp_t gfp, +struct dma_attrs *attrs) { struct platform_device *op = to_platform_device(dev); unsigned long len_total = PAGE_ALIGN(len); @@ -315,7 +316,7 @@ err_nopages: } static void sbus_free_coherent(struct device *dev, size_t n, void *p, - dma_addr_t ba) + dma_addr_t ba, struct dma_attrs *attrs) { struct resource *res; struct page *pgv; @@ -407,8 +408,8 @@ static void sbus_sync_sg_for_device(struct device *dev, struct
[PATCH 11/14] common: dma-mapping: remove old alloc_coherent and free_coherent methods
Remove old, unused alloc_coherent and free_coherent methods from dma_map_ops structure. Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- include/linux/dma-mapping.h |4 1 files changed, 0 insertions(+), 4 deletions(-) diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 8cc7f95..2fc413a 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -9,10 +9,6 @@ #include linux/scatterlist.h struct dma_map_ops { - void* (*alloc_coherent)(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp); - void (*free_coherent)(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle); void* (*alloc)(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs); -- 1.7.1.569.g6f426 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 10/14] Unicore32: adapt for dma_map_ops changes
From: Andrzej Pietrasiewicz andrze...@samsung.com Adapt core Unicore32 architecture code for dma_map_ops changes: replace alloc/free_coherent with generic alloc/free methods. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- arch/unicore32/include/asm/dma-mapping.h | 18 -- arch/unicore32/mm/dma-swiotlb.c |4 ++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/arch/unicore32/include/asm/dma-mapping.h b/arch/unicore32/include/asm/dma-mapping.h index 9258e59..366460a 100644 --- a/arch/unicore32/include/asm/dma-mapping.h +++ b/arch/unicore32/include/asm/dma-mapping.h @@ -82,20 +82,26 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) return 0; } -static inline void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) +#define dma_alloc_coherent(d,s,h,f)dma_alloc_attrs(d,s,h,f,NULL) + +static inline void *dma_alloc_attrs(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag, + struct dma_attrs *attrs) { struct dma_map_ops *dma_ops = get_dma_ops(dev); - return dma_ops-alloc_coherent(dev, size, dma_handle, flag); + return dma_ops-alloc(dev, size, dma_handle, flag, attrs); } -static inline void dma_free_coherent(struct device *dev, size_t size, -void *cpu_addr, dma_addr_t dma_handle) +#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) + +static inline void dma_free_attrs(struct device *dev, size_t size, + void *cpu_addr, dma_addr_t dma_handle, + struct dma_attrs *attrs) { struct dma_map_ops *dma_ops = get_dma_ops(dev); - dma_ops-free_coherent(dev, size, cpu_addr, dma_handle); + dma_ops-free(dev, size, cpu_addr, dma_handle, attrs); } #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) diff --git a/arch/unicore32/mm/dma-swiotlb.c b/arch/unicore32/mm/dma-swiotlb.c index bfa9fbb..ff70c2d 100644 --- a/arch/unicore32/mm/dma-swiotlb.c +++ b/arch/unicore32/mm/dma-swiotlb.c @@ -18,8 +18,8 @@ #include asm/dma.h struct dma_map_ops swiotlb_dma_map_ops = { - .alloc_coherent = swiotlb_alloc_coherent, - .free_coherent = swiotlb_free_coherent, + .alloc = swiotlb_alloc_coherent, + .free = swiotlb_free_coherent, .map_sg = swiotlb_map_sg_attrs, .unmap_sg = swiotlb_unmap_sg_attrs, .dma_supported = swiotlb_dma_supported, -- 1.7.1.569.g6f426 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 14/14] common: DMA-mapping: add NON-CONSISTENT attribute
DMA_ATTR_NON_CONSISTENT lets the platform to choose to return either consistent or non-consistent memory as it sees fit. By using this API, you are guaranteeing to the platform that you have all the correct and necessary sync points for this memory in the driver should it choose to return non-consistent memory. Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- Documentation/DMA-attributes.txt |9 + include/linux/dma-attrs.h|1 + 2 files changed, 10 insertions(+), 0 deletions(-) diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt index 811a5d4..9120de2 100644 --- a/Documentation/DMA-attributes.txt +++ b/Documentation/DMA-attributes.txt @@ -41,3 +41,12 @@ buffered to improve performance. Since it is optional for platforms to implement DMA_ATTR_WRITE_COMBINE, those that do not will simply ignore the attribute and exhibit default behavior. + +DMA_ATTR_NON_CONSISTENT +--- + +DMA_ATTR_NON_CONSISTENT lets the platform to choose to return either +consistent or non-consistent memory as it sees fit. By using this API, +you are guaranteeing to the platform that you have all the correct and +necessary sync points for this memory in the driver should it choose to +return non-consistent memory. diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h index ada61e1..547ab56 100644 --- a/include/linux/dma-attrs.h +++ b/include/linux/dma-attrs.h @@ -14,6 +14,7 @@ enum dma_attr { DMA_ATTR_WRITE_BARRIER, DMA_ATTR_WEAK_ORDERING, DMA_ATTR_WRITE_COMBINE, + DMA_ATTR_NON_CONSISTENT, DMA_ATTR_MAX, }; -- 1.7.1.569.g6f426 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev