Re: [PATCH V7 00/11] IOMMU probe deferral support

2017-01-28 Thread Bjorn Helgaas
On Mon, Jan 23, 2017 at 09:48:02PM +0530, Sricharan R wrote:
> This series calls the dma ops configuration for the devices
> at a generic place so that it works for all busses.
> The dma_configure_ops for a device is now called during
> the device_attach callback just before the probe of the
> bus/driver is called. Similarly dma_deconfigure is called during
> device/driver_detach path.
> ...

>  arch/arm64/mm/dma-mapping.c   | 132 
> --
>  drivers/acpi/arm64/iort.c |  40 +++-
>  drivers/acpi/glue.c   |   5 --
>  drivers/acpi/scan.c   |   7 +-
>  drivers/base/dd.c |   9 +++
>  drivers/base/dma-mapping.c|  41 
>  drivers/iommu/arm-smmu-v3.c   |  46 +
>  drivers/iommu/arm-smmu.c  |  58 +++--
>  drivers/iommu/of_iommu.c  | 114 +++-
>  drivers/of/address.c  |  20 +-
>  drivers/of/device.c   |  36 ++-
>  drivers/of/platform.c |  10 +--
>  drivers/pci/probe.c   |  28 
>  include/acpi/acpi_bus.h   |   2 +-
>  include/asm-generic/vmlinux.lds.h |   1 -
>  include/linux/acpi.h  |   7 +-
>  include/linux/acpi_iort.h |   3 -
>  include/linux/dma-mapping.h   |   3 +
>  include/linux/of_device.h |  10 ++-
>  19 files changed, 252 insertions(+), 320 deletions(-)

I'm assuming this will go via some other tree, maybe the IOMMU tree?
I acked the PCI parts, so let me know if you need anything more from me.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V7 06/11] of/acpi: Configure dma operations at probe time for platform/amba/pci bus devices

2017-01-28 Thread Bjorn Helgaas
On Mon, Jan 23, 2017 at 09:48:08PM +0530, Sricharan R wrote:
> Configuring DMA ops at probe time will allow deferring device probe when
> the IOMMU isn't available yet. The dma_configure for the device is
> now called from the generic device_attach callback just before the
> bus/driver probe is called. This way, configuring the DMA ops for the
> device would be called at the same place for all bus_types, hence the
> deferred probing mechanism should work for all buses as well.
> 
> pci_bus_add_devices(platform/amba)(_device_create/driver_register)
>| |
> pci_bus_add_device (device_add/driver_register)
>| |
> device_attach   device_initial_probe
>| |
> __device_attach_driver__device_attach_driver
>|
> driver_probe_device
>|
> really_probe
>|
> dma_configure
> 
> Similarly on the device/driver_unregister path __device_release_driver is
> called which inturn calls dma_deconfigure.
> 
> This patch changes the dma ops configuration to probe time for
> both OF and ACPI based platform/amba/pci bus devices.
> 
> Signed-off-by: Sricharan R 

Acked-by: Bjorn Helgaas  (drivers/pci part)

> ---
>  [V6 .. V7]
>   * Updated the subject and commit log as per comments
> 
>  [V5 .. V6]
> * Squashed in patch 10 for configuring the dma ops of
>   ACPI device at probe time from previous post.
> * Fixed a bug in dma_configure pointed out by Robin.
> 
>  drivers/acpi/glue.c |  5 -
>  drivers/base/dd.c   |  9 +
>  drivers/base/dma-mapping.c  | 40 
>  drivers/of/platform.c   |  5 +
>  drivers/pci/probe.c | 28 
>  include/linux/dma-mapping.h |  3 +++
>  6 files changed, 53 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
> index fb19e1c..c05f241 100644
> --- a/drivers/acpi/glue.c
> +++ b/drivers/acpi/glue.c
> @@ -176,7 +176,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device 
> *acpi_dev)
>   struct list_head *physnode_list;
>   unsigned int node_id;
>   int retval = -EINVAL;
> - enum dev_dma_attr attr;
>  
>   if (has_acpi_companion(dev)) {
>   if (acpi_dev) {
> @@ -233,10 +232,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device 
> *acpi_dev)
>   if (!has_acpi_companion(dev))
>   ACPI_COMPANION_SET(dev, acpi_dev);
>  
> - attr = acpi_get_dma_attr(acpi_dev);
> - if (attr != DEV_DMA_NOT_SUPPORTED)
> - acpi_dma_configure(dev, attr);
> -
>   acpi_physnode_link_name(physical_node_name, node_id);
>   retval = sysfs_create_link(_dev->dev.kobj, >kobj,
>  physical_node_name);
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index a1fbf55..4882f06 100644
> --- a/drivers/base/dd.c
> +++ b/drivers/base/dd.c
> @@ -19,6 +19,7 @@
>  
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -356,6 +357,10 @@ static int really_probe(struct device *dev, struct 
> device_driver *drv)
>   if (ret)
>   goto pinctrl_bind_failed;
>  
> + ret = dma_configure(dev);
> + if (ret)
> + goto dma_failed;
> +
>   if (driver_sysfs_add(dev)) {
>   printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
>   __func__, dev_name(dev));
> @@ -417,6 +422,8 @@ static int really_probe(struct device *dev, struct 
> device_driver *drv)
>   goto done;
>  
>  probe_failed:
> + dma_deconfigure(dev);
> +dma_failed:
>   if (dev->bus)
>   blocking_notifier_call_chain(>bus->p->bus_notifier,
>BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
> @@ -826,6 +833,8 @@ static void __device_release_driver(struct device *dev, 
> struct device *parent)
>   drv->remove(dev);
>  
>   device_links_driver_cleanup(dev);
> + dma_deconfigure(dev);
> +
>   devres_release_all(dev);
>   dev->driver = NULL;
>   dev_set_drvdata(dev, NULL);
> diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
> index efd71cf..449b948 100644
> --- a/drivers/base/dma-mapping.c
> +++ b/drivers/base/dma-mapping.c
> @@ -7,9 +7,11 @@
>   * This file is released under the GPLv2.
>   */
>  
> +#include 
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  
> @@ -341,3 +343,41 @@ void dma_common_free_remap(void *cpu_addr, size_t size, 
> unsigned long vm_flags)
>   vunmap(cpu_addr);
>  }
>  #endif
> +
> +/*
> + * Common configuration to enable DMA API use for a device
> + */
> +#include 
> +
> +int dma_configure(struct device *dev)
> +{
> + struct device *bridge = NULL, *dma_dev = dev;
> + enum dev_dma_attr attr;
> +
> + if (dev_is_pci(dev)) {
> +   

Re: [PATCH V7 10/11] iommu/arm-smmu: Clean up early-probing workarounds

2017-01-28 Thread Bjorn Helgaas
On Mon, Jan 23, 2017 at 09:48:12PM +0530, Sricharan R wrote:
> From: Robin Murphy 
> 
> Now that the appropriate ordering is enforced via profe-deferral of

s/profe-deferral/probe-deferral/

> masters in core code, rip it all out and bask in the simplicity.
> 
> Acked-by: Will Deacon 
> Signed-off-by: Robin Murphy 
> [Sricharan: Rebased on top of ACPI IORT SMMU series]
> Signed-off-by: Sricharan R 
> ---
>  drivers/iommu/arm-smmu-v3.c | 46 ++-
>  drivers/iommu/arm-smmu.c| 58 
> +++--
>  2 files changed, 10 insertions(+), 94 deletions(-)

Yay!
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V7 09/11] arm64: dma-mapping: Remove the notifier trick to handle early setting of dma_ops

2017-01-28 Thread Bjorn Helgaas
On Mon, Jan 23, 2017 at 09:48:11PM +0530, Sricharan R wrote:
> With arch_setup_dma_ops now being called late during device's probe after
> the device's iommu is probed, the notifier trick required to handle the
> early setup of dma_ops before the iommu group gets created is not
> required. So removing the notifier's here.

s/notifier's/notifiers/

Personally I'd capitalize "IOMMU" in the English text above, too.

> Acked-by: Will Deacon 
> Signed-off-by: Sricharan R 
> [rm: clean up even more]
> Signed-off-by: Robin Murphy 
> ---
>  arch/arm64/mm/dma-mapping.c | 132 
> 
>  1 file changed, 12 insertions(+), 120 deletions(-)

Nice :)
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V7 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-01-28 Thread Bjorn Helgaas
On Mon, Jan 23, 2017 at 09:48:09PM +0530, Sricharan R wrote:
> From: Laurent Pinchart 
> 
> Failures to look up an IOMMU when parsing the DT iommus property need to
> be handled separately from the .of_xlate() failures to support deferred
> probing.
> 
> The lack of a registered IOMMU can be caused by the lack of a driver for
> the IOMMU, the IOMMU device probe not having been performed yet, having
> been deferred, or having failed.
> 
> The first case occurs when the device tree describes the bus master and
> IOMMU topology correctly but no device driver exists for the IOMMU yet
> or the device driver has not been compiled in. Return NULL, the caller
> will configure the device without an IOMMU.
> 
> The second and third cases are handled by deferring the probe of the bus
> master device which will eventually get reprobed after the IOMMU.
> 
> The last case is currently handled by deferring the probe of the bus
> master device as well. A mechanism to either configure the bus master
> device without an IOMMU or to fail the bus master device probe depending
> on whether the IOMMU is optional or mandatory would be a good
> enhancement.
> 
> Signed-off-by: Laurent Pichart 
> Signed-off-by: Sricharan R 
> ...

> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 349bd1d..9529d6c 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -23,6 +23,7 @@
>  #include 
>  #include 
>  #include 
> +#include 

Why do we need this?

>  #include 
>  
>  static const struct of_device_id __iommu_of_table_sentinel
> @@ -223,7 +224,7 @@ const struct iommu_ops *of_iommu_configure(struct device 
> *dev,
>   ops = ERR_PTR(err);
>   }
>  
> - return IS_ERR(ops) ? NULL : ops;
> + return ops;
>  }
>  
>  static int __init of_iommu_init(void)
> @@ -234,7 +235,7 @@ static int __init of_iommu_init(void)
>   for_each_matching_node_and_match(np, matches, ) {
>   const of_iommu_init_fn init_fn = match->data;
>  
> - if (init_fn(np))
> + if (init_fn && init_fn(np))
>   pr_err("Failed to initialise IOMMU %s\n",
>   of_node_full_name(np));
>   }
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 2/2] arm64: Add support for DMA_ATTR_FORCE_CONTIGUOUS to IOMMU

2017-01-28 Thread Laurent Pinchart
Hi Geert,

Thank you for the patch.

On Friday 27 Jan 2017 16:34:19 Geert Uytterhoeven wrote:
> Add support for allocation physically contiguous DMA buffers on arm64
> systems with an IOMMU, by dispatching DMA buffer allocations with the
> DMA_ATTR_FORCE_CONTIGUOUS attribute to the appropriate IOMMU DMA
> helpers.
> 
> Note that as this uses the CMA allocator, setting this attribute has a
> runtime-dependency on CONFIG_DMA_CMA, just like on arm32.
> 
> For arm64 systems using swiotlb, no changes are needed to support the
> allocation of physically contiguous DMA buffers:
>   - swiotlb always uses physically contiguous buffers (up to
> IO_TLB_SEGSIZE = 128 pages),
>   - arm64's __dma_alloc_coherent() already calls
> dma_alloc_from_contiguous() when CMA is available.
> 
> Signed-off-by: Geert Uytterhoeven 
> ---
> v2:
>   - New, handle dispatching in the arch (arm64) code, as requested by
> Robin Murphy.
> ---
>  arch/arm64/mm/dma-mapping.c | 51 +-
>  1 file changed, 37 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index 1d7d5d2881db7c19..325803e0ba79ef26 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -577,20 +577,7 @@ static void *__iommu_alloc_attrs(struct device *dev,
> size_t size, */
>   gfp |= __GFP_ZERO;
> 
> - if (gfpflags_allow_blocking(gfp)) {
> - struct page **pages;
> - pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL, 
coherent);
> -
> - pages = iommu_dma_alloc(dev, iosize, gfp, attrs, ioprot,
> - handle, flush_page);
> - if (!pages)
> - return NULL;
> -
> - addr = dma_common_pages_remap(pages, size, VM_USERMAP, prot,
> -   __builtin_return_address(0));
> - if (!addr)
> - iommu_dma_free(dev, pages, iosize, handle);
> - } else {
> + if (!gfpflags_allow_blocking(gfp)) {
>   struct page *page;
>   /*
>* In atomic context we can't remap anything, so we'll only
> @@ -614,6 +601,35 @@ static void *__iommu_alloc_attrs(struct device *dev,
> size_t size, __free_from_pool(addr, size);
>   addr = NULL;
>   }
> + } else if (attrs & DMA_ATTR_FORCE_CONTIGUOUS) {
> + pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL, 
coherent);
> + struct page *page;
> +
> + page = iommu_dma_alloc_contiguous(dev, iosize, ioprot, 
handle);
> + if (!page)
> + return NULL;
> +
> + if (!coherent)
> + __dma_flush_area(page_to_virt(page), iosize);
> +
> + addr = dma_common_contiguous_remap(page, size, VM_USERMAP,
> +prot,
> +
__builtin_return_address(0));
> + if (!addr)
> + iommu_dma_free_contiguous(dev, page, iosize, handle);
> + } else {
> + pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL, 
coherent);
> + struct page **pages;
> +
> + pages = iommu_dma_alloc(dev, iosize, gfp, attrs, ioprot,
> + handle, flush_page);
> + if (!pages)
> + return NULL;
> +
> + addr = dma_common_pages_remap(pages, size, VM_USERMAP, prot,
> +   __builtin_return_address(0));
> + if (!addr)
> + iommu_dma_free(dev, pages, iosize, handle);
>   }
>   return addr;
>  }
> @@ -626,6 +642,8 @@ static void __iommu_free_attrs(struct device *dev,
> size_t size, void *cpu_addr, size = PAGE_ALIGN(size);
>   /*
>* @cpu_addr will be one of 3 things depending on how it was 
allocated:

s/one of 3/one of 4/

Apart from that,

Acked-by: Laurent Pinchart 

> +  * - A remapped array of pages from iommu_dma_alloc_contiguous()
> +  *   for contiguous allocations.
>* - A remapped array of pages from iommu_dma_alloc(), for all
>*   non-atomic allocations.
>* - A non-cacheable alias from the atomic pool, for atomic
> @@ -637,6 +655,11 @@ static void __iommu_free_attrs(struct device *dev,
> size_t size, void *cpu_addr, if (__in_atomic_pool(cpu_addr, size)) {
>   iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
>   __free_from_pool(cpu_addr, size);
> + } else if (attrs & DMA_ATTR_FORCE_CONTIGUOUS) {
> + struct page *page = phys_to_page(dma_to_phys(dev, handle));
> +
> + iommu_dma_free_contiguous(dev, page, iosize, );
> + dma_common_free_remap(cpu_addr, size, VM_USERMAP);
>   } else if (is_vmalloc_addr(cpu_addr)){
>   struct vm_struct 

Re: [PATCH v2 1/3] mm: alloc_contig_range: allow to specify GFP mask

2017-01-28 Thread Vlastimil Babka

On 01/27/2017 06:23 PM, Lucas Stach wrote:

Currently alloc_contig_range assumes that the compaction should
be done with the default GFP_KERNEL flags. This is probably
right for all current uses of this interface, but may change as
CMA is used in more use-cases (including being the default DMA
memory allocator on some platforms).

Change the function prototype, to allow for passing through the
GFP mask set by upper layers.

Also respect global restrictions by applying memalloc_noio_flags
to the passed in flags.

Signed-off-by: Lucas Stach 
Acked-by: Michal Hocko 



Acked-by: Vlastimil Babka 


---
v2: add memalloc_noio restriction
---
 include/linux/gfp.h | 2 +-
 mm/cma.c| 3 ++-
 mm/hugetlb.c| 3 ++-
 mm/page_alloc.c | 5 +++--
 4 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 4175dca4ac39..1efa221e0e1d 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -549,7 +549,7 @@ static inline bool pm_suspended_storage(void)
 #if (defined(CONFIG_MEMORY_ISOLATION) && defined(CONFIG_COMPACTION)) || 
defined(CONFIG_CMA)
 /* The below functions must be run on a range from a single zone. */
 extern int alloc_contig_range(unsigned long start, unsigned long end,
- unsigned migratetype);
+ unsigned migratetype, gfp_t gfp_mask);
 extern void free_contig_range(unsigned long pfn, unsigned nr_pages);
 #endif

diff --git a/mm/cma.c b/mm/cma.c
index c960459eda7e..fbd67d866f67 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -407,7 +407,8 @@ 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 = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA);
+   ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA,
+GFP_KERNEL);
mutex_unlock(_mutex);
if (ret == 0) {
page = pfn_to_page(pfn);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 3edb759c5c7d..6ed8b160fc0d 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1051,7 +1051,8 @@ static int __alloc_gigantic_page(unsigned long start_pfn,
unsigned long nr_pages)
 {
unsigned long end_pfn = start_pfn + nr_pages;
-   return alloc_contig_range(start_pfn, end_pfn, MIGRATE_MOVABLE);
+   return alloc_contig_range(start_pfn, end_pfn, MIGRATE_MOVABLE,
+ GFP_KERNEL);
 }

 static bool pfn_range_valid_gigantic(struct zone *z,
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index eced9fee582b..c5a745b521c0 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -7230,6 +7230,7 @@ static int __alloc_contig_migrate_range(struct 
compact_control *cc,
  * #MIGRATE_MOVABLE or #MIGRATE_CMA).  All pageblocks
  * in range must have the same migratetype and it must
  * be either of the two.
+ * @gfp_mask:  GFP mask to use during compaction
  *
  * The PFN range does not have to be pageblock or MAX_ORDER_NR_PAGES
  * aligned, however it's the caller's responsibility to guarantee that
@@ -7243,7 +7244,7 @@ static int __alloc_contig_migrate_range(struct 
compact_control *cc,
  * need to be freed with free_contig_range().
  */
 int alloc_contig_range(unsigned long start, unsigned long end,
-  unsigned migratetype)
+  unsigned migratetype, gfp_t gfp_mask)
 {
unsigned long outer_start, outer_end;
unsigned int order;
@@ -7255,7 +7256,7 @@ int alloc_contig_range(unsigned long start, unsigned long 
end,
.zone = page_zone(pfn_to_page(start)),
.mode = MIGRATE_SYNC,
.ignore_skip_hint = true,
-   .gfp_mask = GFP_KERNEL,
+   .gfp_mask = memalloc_noio_flags(gfp_mask),
};
INIT_LIST_HEAD();




___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu