From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: Nishanth Aravamudan <nacc@us.ibm.com>
Cc: Anton Vorontsov <avorontsov@mvista.com>,
miltonm@bga.com, linux-kernel@vger.kernel.org,
FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>,
Paul Mackerras <paulus@samba.org>,
Scott Wood <scottwood@freescale.com>,
Andrew Morton <akpm@linux-foundation.org>,
linuxppc-dev@lists.ozlabs.org
Subject: Re: [RFC PATCH 03/11] ppc: Create ops to choose between direct window and iommu based on device mask
Date: Sat, 09 Oct 2010 10:44:53 +1100 [thread overview]
Message-ID: <1286581493.2463.428.camel@pasglop> (raw)
In-Reply-To: <1286559192-10898-4-git-send-email-nacc@us.ibm.com>
On Fri, 2010-10-08 at 10:33 -0700, Nishanth Aravamudan wrote:
> Also allow the coherent ops to be iommu if only the coherent mask is too
> small, mostly for driver that do not set set the coherent mask but also
> don't use the coherent api.
You are doing the transition at map_sg time which is a hot path, I don't
like that. Also you add all those "choose" variants of the dma ops...
not very nice at all.
You may want to look at the patches I posted to the list a while back
for doing direct DMA on Bimini:
[PATCH 1/2] powerpc/dma: Add optional platform override of dma_set_mask()
[PATCH 2/2] powerpc/dart_iommu: Support for 64-bit iommu bypass window on PCIe
Cheers,
Ben.
> Signed-off-by: Milton Miller <miltonm@bga.com>
> Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
> ---
> arch/powerpc/include/asm/dma-mapping.h | 2 +
> arch/powerpc/kernel/Makefile | 2 +-
> arch/powerpc/kernel/dma-choose64.c | 167 ++++++++++++++++++++++++++++++++
> 3 files changed, 170 insertions(+), 1 deletions(-)
> create mode 100644 arch/powerpc/kernel/dma-choose64.c
>
> diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
> index 644103a..9ffb16a 100644
> --- a/arch/powerpc/include/asm/dma-mapping.h
> +++ b/arch/powerpc/include/asm/dma-mapping.h
> @@ -68,6 +68,8 @@ static inline unsigned long device_to_mask(struct device *dev)
> */
> #ifdef CONFIG_PPC64
> extern struct dma_map_ops dma_iommu_ops;
> +extern struct dma_map_ops dma_choose64_ops;
> +extern struct dma_map_ops dma_iommu_coherent_ops;
> #endif
> extern struct dma_map_ops dma_direct_ops;
>
> diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
> index 1dda701..21b8ea1 100644
> --- a/arch/powerpc/kernel/Makefile
> +++ b/arch/powerpc/kernel/Makefile
> @@ -82,7 +82,7 @@ obj-y += time.o prom.o traps.o setup-common.o \
> udbg.o misc.o io.o dma.o \
> misc_$(CONFIG_WORD_SIZE).o
> obj-$(CONFIG_PPC32) += entry_32.o setup_32.o
> -obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o
> +obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o dma-choose64.o
> obj-$(CONFIG_KGDB) += kgdb.o
> obj-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init.o
> obj-$(CONFIG_MODULES) += ppc_ksyms.o
> diff --git a/arch/powerpc/kernel/dma-choose64.c b/arch/powerpc/kernel/dma-choose64.c
> new file mode 100644
> index 0000000..17c716f
> --- /dev/null
> +++ b/arch/powerpc/kernel/dma-choose64.c
> @@ -0,0 +1,167 @@
> +/*
> + * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation
> + *
> + * Provide default implementations of the DMA mapping callbacks for
> + * directly mapped busses.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/bug.h>
> +
> +/*
> + * DMA operations that choose between a 64-bit direct mapping and and iommu
> + *
> + * This set of dma ops chooses between directing to a static 1:1 mapping
> + * that may require a 64 bit address and a iommu based on the declared
> + * streaming and coherent masks for the device. The choice is made on
> + * the first dma map call.
> + */
> +
> +/* first BUG ops for calls out of sequence */
> +
> +void *dma_bug_alloc_coherent(struct device *dev, size_t size,
> + dma_addr_t *dma_handle, gfp_t flag)
> +{
> + BUG();
> +
> + return NULL;
> +}
> +
> +void dma_bug_free_coherent(struct device *dev, size_t size,
> + void *vaddr, dma_addr_t dma_handle)
> +{
> + BUG();
> +}
> +
> +static int dma_bug_dma_supported(struct device *dev, u64 mask)
> +{
> + BUG();
> +
> + return 0;
> +}
> +
> +static int dma_bug_map_sg(struct device *dev, struct scatterlist *sgl,
> + int nents, enum dma_data_direction direction,
> + struct dma_attrs *attrs)
> +{
> + BUG();
> +
> + return 0;
> +}
> +
> +
> +static void dma_bug_unmap_sg(struct device *dev, struct scatterlist *sg,
> + int nents, enum dma_data_direction direction,
> + struct dma_attrs *attrs)
> +{
> + BUG();
> +}
> +
> +static dma_addr_t dma_bug_map_page(struct device *dev,
> + struct page *page,
> + unsigned long offset,
> + size_t size,
> + enum dma_data_direction dir,
> + struct dma_attrs *attrs)
> +{
> + BUG();
> +
> + return DMA_ERROR_CODE;
> +}
> +
> +
> +static void dma_bug_unmap_page(struct device *dev,
> + dma_addr_t dma_address,
> + size_t size,
> + enum dma_data_direction direction,
> + struct dma_attrs *attrs)
> +{
> + BUG();
> +}
> +
> +
> +static struct dma_map_ops *choose(struct device *dev)
> +{
> + if (dma_direct_ops.dma_supported(dev, device_to_mask(dev))) {
> + if (dma_direct_ops.dma_supported(dev, dev->coherent_dma_mask))
> + return &dma_direct_ops;
> + return &dma_iommu_coherent_ops;
> + }
> + return &dma_iommu_ops;
> +}
> +
> +void *dma_choose64_alloc_coherent(struct device *dev, size_t size,
> + dma_addr_t *dma_handle, gfp_t flag)
> +{
> + struct dma_map_ops *new = choose(dev);
> +
> + set_dma_ops(dev, new);
> + return new->alloc_coherent(dev, size, dma_handle, flag);
> +}
> +
> +static int dma_choose64_map_sg(struct device *dev, struct scatterlist *sgl,
> + int nents, enum dma_data_direction direction,
> + struct dma_attrs *attrs)
> +{
> + struct dma_map_ops *new = choose(dev);
> +
> + set_dma_ops(dev, new);
> + return new->map_sg(dev, sgl, nents, direction, attrs);
> +}
> +
> +
> +static int dma_choose64_dma_supported(struct device *dev, u64 mask)
> +{
> + return dma_direct_ops.dma_supported(dev, mask) ||
> + dma_iommu_ops.dma_supported(dev, mask);
> +}
> +
> +static dma_addr_t dma_choose64_map_page(struct device *dev,
> + struct page *page,
> + unsigned long offset,
> + size_t size,
> + enum dma_data_direction dir,
> + struct dma_attrs *attrs)
> +{
> + struct dma_map_ops *new = choose(dev);
> +
> + set_dma_ops(dev, new);
> + return new->map_page(dev, page, offset, size, dir, attrs);
> +}
> +
> +struct dma_map_ops dma_choose64_ops = {
> + .alloc_coherent = dma_choose64_alloc_coherent,
> + .free_coherent = dma_bug_free_coherent,
> + .map_sg = dma_choose64_map_sg,
> + .unmap_sg = dma_bug_unmap_sg,
> + .dma_supported = dma_choose64_dma_supported,
> + .map_page = dma_choose64_map_page,
> + .unmap_page = dma_bug_unmap_page,
> +};
> +EXPORT_SYMBOL(dma_choose64_ops);
> +
> +/* set these up to BUG() until we initialze them in the arch initcall below */
> +struct dma_map_ops dma_iommu_coherent_ops = {
> + .alloc_coherent = dma_bug_alloc_coherent,
> + .free_coherent = dma_bug_free_coherent,
> + .map_sg = dma_bug_map_sg,
> + .unmap_sg = dma_bug_unmap_sg,
> + .dma_supported = dma_bug_dma_supported,
> + .map_page = dma_bug_map_page,
> + .unmap_page = dma_bug_unmap_page,
> +};
> +EXPORT_SYMBOL(dma_iommu_coherent_ops);
> +
> +static int setup_choose64_ops(void)
> +{
> + dma_iommu_coherent_ops = dma_direct_ops;
> + dma_iommu_coherent_ops.alloc_coherent = dma_iommu_ops.alloc_coherent;
> + dma_iommu_coherent_ops.free_coherent = dma_iommu_ops.free_coherent;
> +
> + /* should we be stricter? */
> + dma_iommu_coherent_ops.dma_supported = dma_choose64_dma_supported;
> +
> + return 0;
> +}
> +arch_initcall(setup_choose64_ops);
next prev parent reply other threads:[~2010-10-08 23:49 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-08 17:33 [RFC PATCH 00/11] ppc: enable dynamic dma window support Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 01/11] macio: ensure all dma routines get copied over Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 02/11] ppc: allow direct and iommu to coexist Nishanth Aravamudan
2010-10-08 23:38 ` Benjamin Herrenschmidt
2010-10-08 17:33 ` [RFC PATCH 03/11] ppc: Create ops to choose between direct window and iommu based on device mask Nishanth Aravamudan
2010-10-08 23:43 ` Benjamin Herrenschmidt
2010-10-08 23:44 ` Benjamin Herrenschmidt [this message]
2010-10-10 15:09 ` FUJITA Tomonori
2010-10-10 23:41 ` Benjamin Herrenschmidt
2010-10-08 17:33 ` [RFC PATCH 04/11] ppc: add memory_hotplug_max Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 05/11] ppc: do not search for dma-window property on dlpar remove Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 06/11] ppc: checking for pdn->parent is redundant Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 07/11] ppc/iommu: do not need to check for dma_window == NULL Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 08/11] ppc/iommu: remove unneeded pci_dma_bus_setup_pSeriesLP Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 09/11] ppc/iommu: pass phb only to iommu_table_setparms_lpar Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 10/11] ppc/iommu: add routines to pseries iommu to map tces 1-1 Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 11/11] ppc: add dynamic dma window support Nishanth Aravamudan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1286581493.2463.428.camel@pasglop \
--to=benh@kernel.crashing.org \
--cc=akpm@linux-foundation.org \
--cc=avorontsov@mvista.com \
--cc=fujita.tomonori@lab.ntt.co.jp \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=miltonm@bga.com \
--cc=nacc@us.ibm.com \
--cc=paulus@samba.org \
--cc=scottwood@freescale.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).