All of lore.kernel.org
 help / color / mirror / Atom feed
* using DMA-API on ARM
@ 2014-12-05  9:22 ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-05  9:22 UTC (permalink / raw)
  To: Russell King
  Cc: linux-arm-kernel, David Miller, linux-kernel, brcm80211-dev-list,
	linux-wireless

Hi Russell,

For our brcm80211 development we are working on getting brcmfmac driver
up and running on a Broadcom ARM-based platform. The wireless device is
a PCIe device, which is hooked up to the system behind a PCIe host
bridge, and we transfer information between host and device using a
descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
tested on x86 and seen no issue. However, on this ARM platform
(single-core A9) we detect occasionally that the descriptor content is
invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
retried a number of times if the problem persists. Actually, found out
that someone made a mistake by using virt_to_dma(va) to get the
dma_handle parameter. So probably we only provided a delay in the retry
loop. After fixing that a single call to dma_sync_single_for_cpu() is
sufficient. The DMA-API-HOWTO clearly states that:

"""
the hardware should guarantee that the device and the CPU can access the
data in parallel and will see updates made by each other without any
explicit software flushing.
"""

So it seems incorrect that we would need to do a dma_sync for this
memory. That we do need it seems like this memory can end up in
cache(?), or whatever happens, in some rare condition. Is there anyway
to investigate this situation either through DMA-API or some low-level
ARM specific functions.

Regards,
Arend

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05  9:22 ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-05  9:22 UTC (permalink / raw)
  To: Russell King
  Cc: linux-arm-kernel, David Miller, linux-kernel, brcm80211-dev-list,
	linux-wireless

Hi Russell,

For our brcm80211 development we are working on getting brcmfmac driver
up and running on a Broadcom ARM-based platform. The wireless device is
a PCIe device, which is hooked up to the system behind a PCIe host
bridge, and we transfer information between host and device using a
descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
tested on x86 and seen no issue. However, on this ARM platform
(single-core A9) we detect occasionally that the descriptor content is
invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
retried a number of times if the problem persists. Actually, found out
that someone made a mistake by using virt_to_dma(va) to get the
dma_handle parameter. So probably we only provided a delay in the retry
loop. After fixing that a single call to dma_sync_single_for_cpu() is
sufficient. The DMA-API-HOWTO clearly states that:

"""
the hardware should guarantee that the device and the CPU can access the
data in parallel and will see updates made by each other without any
explicit software flushing.
"""

So it seems incorrect that we would need to do a dma_sync for this
memory. That we do need it seems like this memory can end up in
cache(?), or whatever happens, in some rare condition. Is there anyway
to investigate this situation either through DMA-API or some low-level
ARM specific functions.

Regards,
Arend

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05  9:22 ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-05  9:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

For our brcm80211 development we are working on getting brcmfmac driver
up and running on a Broadcom ARM-based platform. The wireless device is
a PCIe device, which is hooked up to the system behind a PCIe host
bridge, and we transfer information between host and device using a
descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
tested on x86 and seen no issue. However, on this ARM platform
(single-core A9) we detect occasionally that the descriptor content is
invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
retried a number of times if the problem persists. Actually, found out
that someone made a mistake by using virt_to_dma(va) to get the
dma_handle parameter. So probably we only provided a delay in the retry
loop. After fixing that a single call to dma_sync_single_for_cpu() is
sufficient. The DMA-API-HOWTO clearly states that:

"""
the hardware should guarantee that the device and the CPU can access the
data in parallel and will see updates made by each other without any
explicit software flushing.
"""

So it seems incorrect that we would need to do a dma_sync for this
memory. That we do need it seems like this memory can end up in
cache(?), or whatever happens, in some rare condition. Is there anyway
to investigate this situation either through DMA-API or some low-level
ARM specific functions.

Regards,
Arend

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05  9:22 ` Arend van Spriel
  (?)
@ 2014-12-05  9:45   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05  9:45 UTC (permalink / raw)
  To: Arend van Spriel, Marek Szyprowski, Will Deacon
  Cc: linux-arm-kernel, David Miller, linux-kernel, brcm80211-dev-list,
	linux-wireless

On Fri, Dec 05, 2014 at 10:22:22AM +0100, Arend van Spriel wrote:
> For our brcm80211 development we are working on getting brcmfmac driver
> up and running on a Broadcom ARM-based platform. The wireless device is
> a PCIe device, which is hooked up to the system behind a PCIe host
> bridge, and we transfer information between host and device using a
> descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> tested on x86 and seen no issue. However, on this ARM platform
> (single-core A9) we detect occasionally that the descriptor content is
> invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> retried a number of times if the problem persists. Actually, found out
> that someone made a mistake by using virt_to_dma(va) to get the
> dma_handle parameter. So probably we only provided a delay in the retry
> loop. After fixing that a single call to dma_sync_single_for_cpu() is
> sufficient. The DMA-API-HOWTO clearly states that:
> 
> """
> the hardware should guarantee that the device and the CPU can access the
> data in parallel and will see updates made by each other without any
> explicit software flushing.
> """
> 
> So it seems incorrect that we would need to do a dma_sync for this
> memory. That we do need it seems like this memory can end up in
> cache(?), or whatever happens, in some rare condition. Is there anyway
> to investigate this situation either through DMA-API or some low-level
> ARM specific functions.

It's been a long while since I looked at the code, and the code for
dma_alloc_coherent() has completely changed since then with the
addition of CMA.  I'm afraid that anything I would say about it would
not be accurate without research into the possible paths through that
code - it's no longer just a simple allocator.

What you say is correct however: the memory should not have any cache
lines associated with it, if it does, there's a bug somewhere.

Also, the memory will be weakly ordered, which means that writes to such
memory can be reordered.  If ordering matters, barriers should be used.
rmb() and wmb() can be used for this.

(Added Marek for comment on dma_alloc_coherent(), Will for comment on
barrier stuff.)

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-05  9:45   ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05  9:45 UTC (permalink / raw)
  To: Arend van Spriel, Marek Szyprowski, Will Deacon
  Cc: linux-arm-kernel, David Miller, linux-kernel, brcm80211-dev-list,
	linux-wireless

On Fri, Dec 05, 2014 at 10:22:22AM +0100, Arend van Spriel wrote:
> For our brcm80211 development we are working on getting brcmfmac driver
> up and running on a Broadcom ARM-based platform. The wireless device is
> a PCIe device, which is hooked up to the system behind a PCIe host
> bridge, and we transfer information between host and device using a
> descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> tested on x86 and seen no issue. However, on this ARM platform
> (single-core A9) we detect occasionally that the descriptor content is
> invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> retried a number of times if the problem persists. Actually, found out
> that someone made a mistake by using virt_to_dma(va) to get the
> dma_handle parameter. So probably we only provided a delay in the retry
> loop. After fixing that a single call to dma_sync_single_for_cpu() is
> sufficient. The DMA-API-HOWTO clearly states that:
> 
> """
> the hardware should guarantee that the device and the CPU can access the
> data in parallel and will see updates made by each other without any
> explicit software flushing.
> """
> 
> So it seems incorrect that we would need to do a dma_sync for this
> memory. That we do need it seems like this memory can end up in
> cache(?), or whatever happens, in some rare condition. Is there anyway
> to investigate this situation either through DMA-API or some low-level
> ARM specific functions.

It's been a long while since I looked at the code, and the code for
dma_alloc_coherent() has completely changed since then with the
addition of CMA.  I'm afraid that anything I would say about it would
not be accurate without research into the possible paths through that
code - it's no longer just a simple allocator.

What you say is correct however: the memory should not have any cache
lines associated with it, if it does, there's a bug somewhere.

Also, the memory will be weakly ordered, which means that writes to such
memory can be reordered.  If ordering matters, barriers should be used.
rmb() and wmb() can be used for this.

(Added Marek for comment on dma_alloc_coherent(), Will for comment on
barrier stuff.)

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05  9:45   ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05  9:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 05, 2014 at 10:22:22AM +0100, Arend van Spriel wrote:
> For our brcm80211 development we are working on getting brcmfmac driver
> up and running on a Broadcom ARM-based platform. The wireless device is
> a PCIe device, which is hooked up to the system behind a PCIe host
> bridge, and we transfer information between host and device using a
> descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> tested on x86 and seen no issue. However, on this ARM platform
> (single-core A9) we detect occasionally that the descriptor content is
> invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> retried a number of times if the problem persists. Actually, found out
> that someone made a mistake by using virt_to_dma(va) to get the
> dma_handle parameter. So probably we only provided a delay in the retry
> loop. After fixing that a single call to dma_sync_single_for_cpu() is
> sufficient. The DMA-API-HOWTO clearly states that:
> 
> """
> the hardware should guarantee that the device and the CPU can access the
> data in parallel and will see updates made by each other without any
> explicit software flushing.
> """
> 
> So it seems incorrect that we would need to do a dma_sync for this
> memory. That we do need it seems like this memory can end up in
> cache(?), or whatever happens, in some rare condition. Is there anyway
> to investigate this situation either through DMA-API or some low-level
> ARM specific functions.

It's been a long while since I looked at the code, and the code for
dma_alloc_coherent() has completely changed since then with the
addition of CMA.  I'm afraid that anything I would say about it would
not be accurate without research into the possible paths through that
code - it's no longer just a simple allocator.

What you say is correct however: the memory should not have any cache
lines associated with it, if it does, there's a bug somewhere.

Also, the memory will be weakly ordered, which means that writes to such
memory can be reordered.  If ordering matters, barriers should be used.
rmb() and wmb() can be used for this.

(Added Marek for comment on dma_alloc_coherent(), Will for comment on
barrier stuff.)

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05  9:22 ` Arend van Spriel
@ 2014-12-05  9:52   ` Arnd Bergmann
  -1 siblings, 0 replies; 115+ messages in thread
From: Arnd Bergmann @ 2014-12-05  9:52 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Arend van Spriel, Russell King, linux-wireless,
	brcm80211-dev-list, David Miller, linux-kernel

On Friday 05 December 2014 10:22:22 Arend van Spriel wrote:
> Hi Russell,
> 
> For our brcm80211 development we are working on getting brcmfmac driver
> up and running on a Broadcom ARM-based platform. The wireless device is
> a PCIe device, which is hooked up to the system behind a PCIe host
> bridge, and we transfer information between host and device using a
> descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> tested on x86 and seen no issue. However, on this ARM platform
> (single-core A9) we detect occasionally that the descriptor content is
> invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> retried a number of times if the problem persists. Actually, found out
> that someone made a mistake by using virt_to_dma(va) to get the
> dma_handle parameter. So probably we only provided a delay in the retry
> loop. After fixing that a single call to dma_sync_single_for_cpu() is
> sufficient. The DMA-API-HOWTO clearly states that:
> 
> """
> the hardware should guarantee that the device and the CPU can access the
> data in parallel and will see updates made by each other without any
> explicit software flushing.
> """
> 
> So it seems incorrect that we would need to do a dma_sync for this
> memory. That we do need it seems like this memory can end up in
> cache(?), or whatever happens, in some rare condition. Is there anyway
> to investigate this situation either through DMA-API or some low-level
> ARM specific functions.

I think the problem comes down to not following the advice from this
comment in asm/dma-mapping.h:

/*
 * dma_to_pfn/pfn_to_dma/dma_to_virt/virt_to_dma are architecture private
 * functions used internally by the DMA-mapping API to provide DMA
 * addresses. They must not be used by drivers.
 */

The previous behavior of the driver is clearly wrong and cannot work
on any architecture that has noncoherent PCI DMA or uses swiotlb, and
that includes some older 64-bit x86 machines (Pentium D and similar).

I'm still puzzled why you'd need a single dma_sync_single_for_cpu()
after dma_alloc_coherent though, you should not need any. Is it possible
that the driver accidentally uses __raw_readl() instead of readl()
in some places and you are just lacking an appropriate barrier?

	Arnd

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05  9:52   ` Arnd Bergmann
  0 siblings, 0 replies; 115+ messages in thread
From: Arnd Bergmann @ 2014-12-05  9:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 05 December 2014 10:22:22 Arend van Spriel wrote:
> Hi Russell,
> 
> For our brcm80211 development we are working on getting brcmfmac driver
> up and running on a Broadcom ARM-based platform. The wireless device is
> a PCIe device, which is hooked up to the system behind a PCIe host
> bridge, and we transfer information between host and device using a
> descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> tested on x86 and seen no issue. However, on this ARM platform
> (single-core A9) we detect occasionally that the descriptor content is
> invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> retried a number of times if the problem persists. Actually, found out
> that someone made a mistake by using virt_to_dma(va) to get the
> dma_handle parameter. So probably we only provided a delay in the retry
> loop. After fixing that a single call to dma_sync_single_for_cpu() is
> sufficient. The DMA-API-HOWTO clearly states that:
> 
> """
> the hardware should guarantee that the device and the CPU can access the
> data in parallel and will see updates made by each other without any
> explicit software flushing.
> """
> 
> So it seems incorrect that we would need to do a dma_sync for this
> memory. That we do need it seems like this memory can end up in
> cache(?), or whatever happens, in some rare condition. Is there anyway
> to investigate this situation either through DMA-API or some low-level
> ARM specific functions.

I think the problem comes down to not following the advice from this
comment in asm/dma-mapping.h:

/*
 * dma_to_pfn/pfn_to_dma/dma_to_virt/virt_to_dma are architecture private
 * functions used internally by the DMA-mapping API to provide DMA
 * addresses. They must not be used by drivers.
 */

The previous behavior of the driver is clearly wrong and cannot work
on any architecture that has noncoherent PCI DMA or uses swiotlb, and
that includes some older 64-bit x86 machines (Pentium D and similar).

I'm still puzzled why you'd need a single dma_sync_single_for_cpu()
after dma_alloc_coherent though, you should not need any. Is it possible
that the driver accidentally uses __raw_readl() instead of readl()
in some places and you are just lacking an appropriate barrier?

	Arnd

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05  9:52   ` Arnd Bergmann
@ 2014-12-05 11:11     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 11:11 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Arend van Spriel, linux-wireless,
	brcm80211-dev-list, David Miller, linux-kernel

On Fri, Dec 05, 2014 at 10:52:02AM +0100, Arnd Bergmann wrote:
> I'm still puzzled why you'd need a single dma_sync_single_for_cpu()
> after dma_alloc_coherent though, you should not need any. Is it possible
> that the driver accidentally uses __raw_readl() instead of readl()
> in some places and you are just lacking an appropriate barrier?

Digging into the driver, it looks like individual DMA buffers are
allocated (via brcmf_pcie_init_dmabuffer_for_device) and registered
into a "commonring" layer.

Whenever the buffer is written to, space is first allocated via a call
to brcmf_commonring_reserve_for_write() or
brcmf_commonring_reserve_for_write_multiple(), data written to the
buffer, followed by a call to brcmf_commonring_write_complete().

brcmf_commonring_write_complete() calls two methods at that point:
cr_write_wptr() and cr_ring_bell(), which will be
brcmf_pcie_ring_mb_write_wptr() and brcmf_pcie_ring_mb_ring_bell().

The first calls brcmf_pcie_write_tcm16(), which uses iowrite16(),
which contains the appropriate barrier.  The bell ringing functions
also use ioread*/iowrite*().

So, on the write side, it looks fine from the barrier perspective.

On the read side, brcmf_commonring_get_read_ptr() is used before
a read access to the ring - which calls the cr_update_wptr() method,
which in turn uses an ioread16() call.  After the CPU has read data
from the ring, brcmf_commonring_read_complete() is used, which uses
iowrite16().

So, I don't see a barrier problem on the read side.

However, I did trip over this:

static void *
brcmf_pcie_init_dmabuffer_for_device(struct brcmf_pciedev_info *devinfo,
                                     u32 size, u32 tcm_dma_phys_addr,
                                     dma_addr_t *dma_handle)
{
        void *ring;
        long long address;

        ring = dma_alloc_coherent(&devinfo->pdev->dev, size, dma_handle,
                                  GFP_KERNEL);
        if (!ring)
                return NULL;

        address = (long long)(long)*dma_handle;

Casting to (long) will truncate the DMA handle to 32-bits on a 32-bit
architecture, even if it supports 64-bit DMA addresses.  There's a couple
of other places where this same truncation occurs:

        address = (long long)(long)devinfo->shared.scratch_dmahandle;

and

        address = (long long)(long)devinfo->shared.ringupd_dmahandle;

In any case, wouldn't using a u64 type for "address" be better - isn't
"long long" 128-bit on 64-bit architectures?

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 11:11     ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 11:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 05, 2014 at 10:52:02AM +0100, Arnd Bergmann wrote:
> I'm still puzzled why you'd need a single dma_sync_single_for_cpu()
> after dma_alloc_coherent though, you should not need any. Is it possible
> that the driver accidentally uses __raw_readl() instead of readl()
> in some places and you are just lacking an appropriate barrier?

Digging into the driver, it looks like individual DMA buffers are
allocated (via brcmf_pcie_init_dmabuffer_for_device) and registered
into a "commonring" layer.

Whenever the buffer is written to, space is first allocated via a call
to brcmf_commonring_reserve_for_write() or
brcmf_commonring_reserve_for_write_multiple(), data written to the
buffer, followed by a call to brcmf_commonring_write_complete().

brcmf_commonring_write_complete() calls two methods at that point:
cr_write_wptr() and cr_ring_bell(), which will be
brcmf_pcie_ring_mb_write_wptr() and brcmf_pcie_ring_mb_ring_bell().

The first calls brcmf_pcie_write_tcm16(), which uses iowrite16(),
which contains the appropriate barrier.  The bell ringing functions
also use ioread*/iowrite*().

So, on the write side, it looks fine from the barrier perspective.

On the read side, brcmf_commonring_get_read_ptr() is used before
a read access to the ring - which calls the cr_update_wptr() method,
which in turn uses an ioread16() call.  After the CPU has read data
from the ring, brcmf_commonring_read_complete() is used, which uses
iowrite16().

So, I don't see a barrier problem on the read side.

However, I did trip over this:

static void *
brcmf_pcie_init_dmabuffer_for_device(struct brcmf_pciedev_info *devinfo,
                                     u32 size, u32 tcm_dma_phys_addr,
                                     dma_addr_t *dma_handle)
{
        void *ring;
        long long address;

        ring = dma_alloc_coherent(&devinfo->pdev->dev, size, dma_handle,
                                  GFP_KERNEL);
        if (!ring)
                return NULL;

        address = (long long)(long)*dma_handle;

Casting to (long) will truncate the DMA handle to 32-bits on a 32-bit
architecture, even if it supports 64-bit DMA addresses.  There's a couple
of other places where this same truncation occurs:

        address = (long long)(long)devinfo->shared.scratch_dmahandle;

and

        address = (long long)(long)devinfo->shared.ringupd_dmahandle;

In any case, wouldn't using a u64 type for "address" be better - isn't
"long long" 128-bit on 64-bit architectures?

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* RE: using DMA-API on ARM
  2014-12-05 11:11     ` Russell King - ARM Linux
  (?)
@ 2014-12-05 11:49       ` Hante Meuleman
  -1 siblings, 0 replies; 115+ messages in thread
From: Hante Meuleman @ 2014-12-05 11:49 UTC (permalink / raw)
  To: Russell King - ARM Linux, Arnd Bergmann
  Cc: linux-arm-kernel, Arend Van Spriel, linux-wireless,
	brcm80211-dev-list, David Miller, linux-kernel

Thank you for investigating. Your analysis matches what was intended to be done. Regarding the cast, you're right, I'll improve it. My idea was that long long is always 64bit, but when casting directly to long long I get a compiler (when using C=2) warning: "warning: right shift by bigger than source value". Probably I concluded wrongly that I should cast it to long first. On the targets used the high address was always 0, so I got away with it thusfar, but indeed it should and shall be fixed.

Regards,
Hante

-----Original Message-----
From: Russell King - ARM Linux [mailto:linux@arm.linux.org.uk] 
Sent: vrijdag 5 december 2014 12:11
To: Arnd Bergmann
Cc: linux-arm-kernel@lists.infradead.org; Arend Van Spriel; linux-wireless; brcm80211-dev-list; David Miller; linux-kernel@vger.kernel.org
Subject: Re: using DMA-API on ARM

On Fri, Dec 05, 2014 at 10:52:02AM +0100, Arnd Bergmann wrote:
> I'm still puzzled why you'd need a single dma_sync_single_for_cpu()
> after dma_alloc_coherent though, you should not need any. Is it possible
> that the driver accidentally uses __raw_readl() instead of readl()
> in some places and you are just lacking an appropriate barrier?

Digging into the driver, it looks like individual DMA buffers are
allocated (via brcmf_pcie_init_dmabuffer_for_device) and registered
into a "commonring" layer.

Whenever the buffer is written to, space is first allocated via a call
to brcmf_commonring_reserve_for_write() or
brcmf_commonring_reserve_for_write_multiple(), data written to the
buffer, followed by a call to brcmf_commonring_write_complete().

brcmf_commonring_write_complete() calls two methods at that point:
cr_write_wptr() and cr_ring_bell(), which will be
brcmf_pcie_ring_mb_write_wptr() and brcmf_pcie_ring_mb_ring_bell().

The first calls brcmf_pcie_write_tcm16(), which uses iowrite16(),
which contains the appropriate barrier.  The bell ringing functions
also use ioread*/iowrite*().

So, on the write side, it looks fine from the barrier perspective.

On the read side, brcmf_commonring_get_read_ptr() is used before
a read access to the ring - which calls the cr_update_wptr() method,
which in turn uses an ioread16() call.  After the CPU has read data
from the ring, brcmf_commonring_read_complete() is used, which uses
iowrite16().

So, I don't see a barrier problem on the read side.

However, I did trip over this:

static void *
brcmf_pcie_init_dmabuffer_for_device(struct brcmf_pciedev_info *devinfo,
                                     u32 size, u32 tcm_dma_phys_addr,
                                     dma_addr_t *dma_handle)
{
        void *ring;
        long long address;

        ring = dma_alloc_coherent(&devinfo->pdev->dev, size, dma_handle,
                                  GFP_KERNEL);
        if (!ring)
                return NULL;

        address = (long long)(long)*dma_handle;

Casting to (long) will truncate the DMA handle to 32-bits on a 32-bit
architecture, even if it supports 64-bit DMA addresses.  There's a couple
of other places where this same truncation occurs:

        address = (long long)(long)devinfo->shared.scratch_dmahandle;

and

        address = (long long)(long)devinfo->shared.ringupd_dmahandle;

In any case, wouldn't using a u64 type for "address" be better - isn't
"long long" 128-bit on 64-bit architectures?

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* RE: using DMA-API on ARM
@ 2014-12-05 11:49       ` Hante Meuleman
  0 siblings, 0 replies; 115+ messages in thread
From: Hante Meuleman @ 2014-12-05 11:49 UTC (permalink / raw)
  To: Russell King - ARM Linux, Arnd Bergmann
  Cc: linux-arm-kernel, Arend Van Spriel, linux-wireless,
	brcm80211-dev-list, David Miller, linux-kernel

Thank you for investigating. Your analysis matches what was intended to be done. Regarding the cast, you're right, I'll improve it. My idea was that long long is always 64bit, but when casting directly to long long I get a compiler (when using C=2) warning: "warning: right shift by bigger than source value". Probably I concluded wrongly that I should cast it to long first. On the targets used the high address was always 0, so I got away with it thusfar, but indeed it should and shall be fixed.

Regards,
Hante

-----Original Message-----
From: Russell King - ARM Linux [mailto:linux@arm.linux.org.uk] 
Sent: vrijdag 5 december 2014 12:11
To: Arnd Bergmann
Cc: linux-arm-kernel@lists.infradead.org; Arend Van Spriel; linux-wireless; brcm80211-dev-list; David Miller; linux-kernel@vger.kernel.org
Subject: Re: using DMA-API on ARM

On Fri, Dec 05, 2014 at 10:52:02AM +0100, Arnd Bergmann wrote:
> I'm still puzzled why you'd need a single dma_sync_single_for_cpu()
> after dma_alloc_coherent though, you should not need any. Is it possible
> that the driver accidentally uses __raw_readl() instead of readl()
> in some places and you are just lacking an appropriate barrier?

Digging into the driver, it looks like individual DMA buffers are
allocated (via brcmf_pcie_init_dmabuffer_for_device) and registered
into a "commonring" layer.

Whenever the buffer is written to, space is first allocated via a call
to brcmf_commonring_reserve_for_write() or
brcmf_commonring_reserve_for_write_multiple(), data written to the
buffer, followed by a call to brcmf_commonring_write_complete().

brcmf_commonring_write_complete() calls two methods at that point:
cr_write_wptr() and cr_ring_bell(), which will be
brcmf_pcie_ring_mb_write_wptr() and brcmf_pcie_ring_mb_ring_bell().

The first calls brcmf_pcie_write_tcm16(), which uses iowrite16(),
which contains the appropriate barrier.  The bell ringing functions
also use ioread*/iowrite*().

So, on the write side, it looks fine from the barrier perspective.

On the read side, brcmf_commonring_get_read_ptr() is used before
a read access to the ring - which calls the cr_update_wptr() method,
which in turn uses an ioread16() call.  After the CPU has read data
from the ring, brcmf_commonring_read_complete() is used, which uses
iowrite16().

So, I don't see a barrier problem on the read side.

However, I did trip over this:

static void *
brcmf_pcie_init_dmabuffer_for_device(struct brcmf_pciedev_info *devinfo,
                                     u32 size, u32 tcm_dma_phys_addr,
                                     dma_addr_t *dma_handle)
{
        void *ring;
        long long address;

        ring = dma_alloc_coherent(&devinfo->pdev->dev, size, dma_handle,
                                  GFP_KERNEL);
        if (!ring)
                return NULL;

        address = (long long)(long)*dma_handle;

Casting to (long) will truncate the DMA handle to 32-bits on a 32-bit
architecture, even if it supports 64-bit DMA addresses.  There's a couple
of other places where this same truncation occurs:

        address = (long long)(long)devinfo->shared.scratch_dmahandle;

and

        address = (long long)(long)devinfo->shared.ringupd_dmahandle;

In any case, wouldn't using a u64 type for "address" be better - isn't
"long long" 128-bit on 64-bit architectures?

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 11:49       ` Hante Meuleman
  0 siblings, 0 replies; 115+ messages in thread
From: Hante Meuleman @ 2014-12-05 11:49 UTC (permalink / raw)
  To: linux-arm-kernel

Thank you for investigating. Your analysis matches what was intended to be done. Regarding the cast, you're right, I'll improve it. My idea was that long long is always 64bit, but when casting directly to long long I get a compiler (when using C=2) warning: "warning: right shift by bigger than source value". Probably I concluded wrongly that I should cast it to long first. On the targets used the high address was always 0, so I got away with it thusfar, but indeed it should and shall be fixed.

Regards,
Hante

-----Original Message-----
From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk] 
Sent: vrijdag 5 december 2014 12:11
To: Arnd Bergmann
Cc: linux-arm-kernel at lists.infradead.org; Arend Van Spriel; linux-wireless; brcm80211-dev-list; David Miller; linux-kernel at vger.kernel.org
Subject: Re: using DMA-API on ARM

On Fri, Dec 05, 2014 at 10:52:02AM +0100, Arnd Bergmann wrote:
> I'm still puzzled why you'd need a single dma_sync_single_for_cpu()
> after dma_alloc_coherent though, you should not need any. Is it possible
> that the driver accidentally uses __raw_readl() instead of readl()
> in some places and you are just lacking an appropriate barrier?

Digging into the driver, it looks like individual DMA buffers are
allocated (via brcmf_pcie_init_dmabuffer_for_device) and registered
into a "commonring" layer.

Whenever the buffer is written to, space is first allocated via a call
to brcmf_commonring_reserve_for_write() or
brcmf_commonring_reserve_for_write_multiple(), data written to the
buffer, followed by a call to brcmf_commonring_write_complete().

brcmf_commonring_write_complete() calls two methods at that point:
cr_write_wptr() and cr_ring_bell(), which will be
brcmf_pcie_ring_mb_write_wptr() and brcmf_pcie_ring_mb_ring_bell().

The first calls brcmf_pcie_write_tcm16(), which uses iowrite16(),
which contains the appropriate barrier.  The bell ringing functions
also use ioread*/iowrite*().

So, on the write side, it looks fine from the barrier perspective.

On the read side, brcmf_commonring_get_read_ptr() is used before
a read access to the ring - which calls the cr_update_wptr() method,
which in turn uses an ioread16() call.  After the CPU has read data
from the ring, brcmf_commonring_read_complete() is used, which uses
iowrite16().

So, I don't see a barrier problem on the read side.

However, I did trip over this:

static void *
brcmf_pcie_init_dmabuffer_for_device(struct brcmf_pciedev_info *devinfo,
                                     u32 size, u32 tcm_dma_phys_addr,
                                     dma_addr_t *dma_handle)
{
        void *ring;
        long long address;

        ring = dma_alloc_coherent(&devinfo->pdev->dev, size, dma_handle,
                                  GFP_KERNEL);
        if (!ring)
                return NULL;

        address = (long long)(long)*dma_handle;

Casting to (long) will truncate the DMA handle to 32-bits on a 32-bit
architecture, even if it supports 64-bit DMA addresses.  There's a couple
of other places where this same truncation occurs:

        address = (long long)(long)devinfo->shared.scratch_dmahandle;

and

        address = (long long)(long)devinfo->shared.ringupd_dmahandle;

In any case, wouldn't using a u64 type for "address" be better - isn't
"long long" 128-bit on 64-bit architectures?

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05  9:45   ` Russell King - ARM Linux
  (?)
@ 2014-12-05 12:24     ` Will Deacon
  -1 siblings, 0 replies; 115+ messages in thread
From: Will Deacon @ 2014-12-05 12:24 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Arend van Spriel, Marek Szyprowski, linux-arm-kernel,
	David Miller, linux-kernel, brcm80211-dev-list, linux-wireless

On Fri, Dec 05, 2014 at 09:45:08AM +0000, Russell King - ARM Linux wrote:
> On Fri, Dec 05, 2014 at 10:22:22AM +0100, Arend van Spriel wrote:
> > For our brcm80211 development we are working on getting brcmfmac driver
> > up and running on a Broadcom ARM-based platform. The wireless device is
> > a PCIe device, which is hooked up to the system behind a PCIe host
> > bridge, and we transfer information between host and device using a
> > descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> > tested on x86 and seen no issue. However, on this ARM platform
> > (single-core A9) we detect occasionally that the descriptor content is
> > invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> > retried a number of times if the problem persists. Actually, found out
> > that someone made a mistake by using virt_to_dma(va) to get the
> > dma_handle parameter. So probably we only provided a delay in the retry
> > loop. After fixing that a single call to dma_sync_single_for_cpu() is
> > sufficient. The DMA-API-HOWTO clearly states that:
> > 
> > """
> > the hardware should guarantee that the device and the CPU can access the
> > data in parallel and will see updates made by each other without any
> > explicit software flushing.
> > """
> > 
> > So it seems incorrect that we would need to do a dma_sync for this
> > memory. That we do need it seems like this memory can end up in
> > cache(?), or whatever happens, in some rare condition. Is there anyway
> > to investigate this situation either through DMA-API or some low-level
> > ARM specific functions.
> 
> It's been a long while since I looked at the code, and the code for
> dma_alloc_coherent() has completely changed since then with the
> addition of CMA.  I'm afraid that anything I would say about it would
> not be accurate without research into the possible paths through that
> code - it's no longer just a simple allocator.
> 
> What you say is correct however: the memory should not have any cache
> lines associated with it, if it does, there's a bug somewhere.
> 
> Also, the memory will be weakly ordered, which means that writes to such
> memory can be reordered.  If ordering matters, barriers should be used.
> rmb() and wmb() can be used for this.
> 
> (Added Marek for comment on dma_alloc_coherent(), Will for comment on
> barrier stuff.)

I'm not quite clear on the issue being seen here: is this on write from
the CPU to the descriptor ring, or the other way around (or both?).

Either way, you need barriers on the CPU side to ensure ordering of
accesses to the buffer. rmb/wmb will work, but are heavier than what you
need (relaxed versions have been proposed on LKML recently).

Will

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-05 12:24     ` Will Deacon
  0 siblings, 0 replies; 115+ messages in thread
From: Will Deacon @ 2014-12-05 12:24 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Arend van Spriel, Marek Szyprowski, linux-arm-kernel,
	David Miller, linux-kernel, brcm80211-dev-list, linux-wireless

On Fri, Dec 05, 2014 at 09:45:08AM +0000, Russell King - ARM Linux wrote:
> On Fri, Dec 05, 2014 at 10:22:22AM +0100, Arend van Spriel wrote:
> > For our brcm80211 development we are working on getting brcmfmac driver
> > up and running on a Broadcom ARM-based platform. The wireless device is
> > a PCIe device, which is hooked up to the system behind a PCIe host
> > bridge, and we transfer information between host and device using a
> > descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> > tested on x86 and seen no issue. However, on this ARM platform
> > (single-core A9) we detect occasionally that the descriptor content is
> > invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> > retried a number of times if the problem persists. Actually, found out
> > that someone made a mistake by using virt_to_dma(va) to get the
> > dma_handle parameter. So probably we only provided a delay in the retry
> > loop. After fixing that a single call to dma_sync_single_for_cpu() is
> > sufficient. The DMA-API-HOWTO clearly states that:
> > 
> > """
> > the hardware should guarantee that the device and the CPU can access the
> > data in parallel and will see updates made by each other without any
> > explicit software flushing.
> > """
> > 
> > So it seems incorrect that we would need to do a dma_sync for this
> > memory. That we do need it seems like this memory can end up in
> > cache(?), or whatever happens, in some rare condition. Is there anyway
> > to investigate this situation either through DMA-API or some low-level
> > ARM specific functions.
> 
> It's been a long while since I looked at the code, and the code for
> dma_alloc_coherent() has completely changed since then with the
> addition of CMA.  I'm afraid that anything I would say about it would
> not be accurate without research into the possible paths through that
> code - it's no longer just a simple allocator.
> 
> What you say is correct however: the memory should not have any cache
> lines associated with it, if it does, there's a bug somewhere.
> 
> Also, the memory will be weakly ordered, which means that writes to such
> memory can be reordered.  If ordering matters, barriers should be used.
> rmb() and wmb() can be used for this.
> 
> (Added Marek for comment on dma_alloc_coherent(), Will for comment on
> barrier stuff.)

I'm not quite clear on the issue being seen here: is this on write from
the CPU to the descriptor ring, or the other way around (or both?).

Either way, you need barriers on the CPU side to ensure ordering of
accesses to the buffer. rmb/wmb will work, but are heavier than what you
need (relaxed versions have been proposed on LKML recently).

Will

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 12:24     ` Will Deacon
  0 siblings, 0 replies; 115+ messages in thread
From: Will Deacon @ 2014-12-05 12:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 05, 2014 at 09:45:08AM +0000, Russell King - ARM Linux wrote:
> On Fri, Dec 05, 2014 at 10:22:22AM +0100, Arend van Spriel wrote:
> > For our brcm80211 development we are working on getting brcmfmac driver
> > up and running on a Broadcom ARM-based platform. The wireless device is
> > a PCIe device, which is hooked up to the system behind a PCIe host
> > bridge, and we transfer information between host and device using a
> > descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> > tested on x86 and seen no issue. However, on this ARM platform
> > (single-core A9) we detect occasionally that the descriptor content is
> > invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> > retried a number of times if the problem persists. Actually, found out
> > that someone made a mistake by using virt_to_dma(va) to get the
> > dma_handle parameter. So probably we only provided a delay in the retry
> > loop. After fixing that a single call to dma_sync_single_for_cpu() is
> > sufficient. The DMA-API-HOWTO clearly states that:
> > 
> > """
> > the hardware should guarantee that the device and the CPU can access the
> > data in parallel and will see updates made by each other without any
> > explicit software flushing.
> > """
> > 
> > So it seems incorrect that we would need to do a dma_sync for this
> > memory. That we do need it seems like this memory can end up in
> > cache(?), or whatever happens, in some rare condition. Is there anyway
> > to investigate this situation either through DMA-API or some low-level
> > ARM specific functions.
> 
> It's been a long while since I looked at the code, and the code for
> dma_alloc_coherent() has completely changed since then with the
> addition of CMA.  I'm afraid that anything I would say about it would
> not be accurate without research into the possible paths through that
> code - it's no longer just a simple allocator.
> 
> What you say is correct however: the memory should not have any cache
> lines associated with it, if it does, there's a bug somewhere.
> 
> Also, the memory will be weakly ordered, which means that writes to such
> memory can be reordered.  If ordering matters, barriers should be used.
> rmb() and wmb() can be used for this.
> 
> (Added Marek for comment on dma_alloc_coherent(), Will for comment on
> barrier stuff.)

I'm not quite clear on the issue being seen here: is this on write from
the CPU to the descriptor ring, or the other way around (or both?).

Either way, you need barriers on the CPU side to ensure ordering of
accesses to the buffer. rmb/wmb will work, but are heavier than what you
need (relaxed versions have been proposed on LKML recently).

Will

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05  9:45   ` Russell King - ARM Linux
  (?)
@ 2014-12-05 12:43     ` Arend van Spriel
  -1 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-05 12:43 UTC (permalink / raw)
  To: Russell King - ARM Linux, Marek Szyprowski, Will Deacon
  Cc: linux-arm-kernel, David Miller, linux-kernel, brcm80211-dev-list,
	linux-wireless, Arnd Bergmann

On 05-12-14 10:45, Russell King - ARM Linux wrote:
> On Fri, Dec 05, 2014 at 10:22:22AM +0100, Arend van Spriel wrote:
>> For our brcm80211 development we are working on getting brcmfmac driver
>> up and running on a Broadcom ARM-based platform. The wireless device is
>> a PCIe device, which is hooked up to the system behind a PCIe host
>> bridge, and we transfer information between host and device using a
>> descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
>> tested on x86 and seen no issue. However, on this ARM platform
>> (single-core A9) we detect occasionally that the descriptor content is
>> invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
>> retried a number of times if the problem persists. Actually, found out
>> that someone made a mistake by using virt_to_dma(va) to get the
>> dma_handle parameter. So probably we only provided a delay in the retry
>> loop. After fixing that a single call to dma_sync_single_for_cpu() is
>> sufficient. The DMA-API-HOWTO clearly states that:
>>
>> """
>> the hardware should guarantee that the device and the CPU can access the
>> data in parallel and will see updates made by each other without any
>> explicit software flushing.
>> """
>>
>> So it seems incorrect that we would need to do a dma_sync for this
>> memory. That we do need it seems like this memory can end up in
>> cache(?), or whatever happens, in some rare condition. Is there anyway
>> to investigate this situation either through DMA-API or some low-level
>> ARM specific functions.
>
> It's been a long while since I looked at the code, and the code for
> dma_alloc_coherent() has completely changed since then with the
> addition of CMA.  I'm afraid that anything I would say about it would
> not be accurate without research into the possible paths through that
> code - it's no longer just a simple allocator.

I know. On this particular platform we are not using CMA.

> What you say is correct however: the memory should not have any cache
> lines associated with it, if it does, there's a bug somewhere.
>
> Also, the memory will be weakly ordered, which means that writes to such
> memory can be reordered.  If ordering matters, barriers should be used.
> rmb() and wmb() can be used for this.

Ok. You already had a peek in our code checking the memory barriers, 
which does not have the dma_sync_single_for_cpu() "workaround" yet. So 
here some more background. The problem is in DMA_FROM_DEVICE direction. 
Because of the possible reordering issue we first tried using rmb() in 
the retry loop but that did not solve it. Another experiment was to 
ignore the failed ring descriptor entry and proceed. So we get interrupt 
from device and access the ring descriptor entry. This should contain 
expected value X, however we get X-1 back. When proceeding everything 
works find until hitting the same ring descriptor entry again reading 
X-1 when X+1 would be valid. This lead us to the assumption that somehow 
this entry ended up in cache lines. The issue goes away using the 
dma_sync_single_for_cpu() with DMA_FROM_DEVICE in direction parameter. 
We are not longer using virt_to_dma() so that is no longer an issue. So 
is there any function interface to verify cache status.

Regards,
Arend

> (Added Marek for comment on dma_alloc_coherent(), Will for comment on
> barrier stuff.)
>


^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-05 12:43     ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-05 12:43 UTC (permalink / raw)
  To: Russell King - ARM Linux, Marek Szyprowski, Will Deacon
  Cc: linux-arm-kernel, David Miller, linux-kernel, brcm80211-dev-list,
	linux-wireless, Arnd Bergmann

On 05-12-14 10:45, Russell King - ARM Linux wrote:
> On Fri, Dec 05, 2014 at 10:22:22AM +0100, Arend van Spriel wrote:
>> For our brcm80211 development we are working on getting brcmfmac driver
>> up and running on a Broadcom ARM-based platform. The wireless device is
>> a PCIe device, which is hooked up to the system behind a PCIe host
>> bridge, and we transfer information between host and device using a
>> descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
>> tested on x86 and seen no issue. However, on this ARM platform
>> (single-core A9) we detect occasionally that the descriptor content is
>> invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
>> retried a number of times if the problem persists. Actually, found out
>> that someone made a mistake by using virt_to_dma(va) to get the
>> dma_handle parameter. So probably we only provided a delay in the retry
>> loop. After fixing that a single call to dma_sync_single_for_cpu() is
>> sufficient. The DMA-API-HOWTO clearly states that:
>>
>> """
>> the hardware should guarantee that the device and the CPU can access the
>> data in parallel and will see updates made by each other without any
>> explicit software flushing.
>> """
>>
>> So it seems incorrect that we would need to do a dma_sync for this
>> memory. That we do need it seems like this memory can end up in
>> cache(?), or whatever happens, in some rare condition. Is there anyway
>> to investigate this situation either through DMA-API or some low-level
>> ARM specific functions.
>
> It's been a long while since I looked at the code, and the code for
> dma_alloc_coherent() has completely changed since then with the
> addition of CMA.  I'm afraid that anything I would say about it would
> not be accurate without research into the possible paths through that
> code - it's no longer just a simple allocator.

I know. On this particular platform we are not using CMA.

> What you say is correct however: the memory should not have any cache
> lines associated with it, if it does, there's a bug somewhere.
>
> Also, the memory will be weakly ordered, which means that writes to such
> memory can be reordered.  If ordering matters, barriers should be used.
> rmb() and wmb() can be used for this.

Ok. You already had a peek in our code checking the memory barriers, 
which does not have the dma_sync_single_for_cpu() "workaround" yet. So 
here some more background. The problem is in DMA_FROM_DEVICE direction. 
Because of the possible reordering issue we first tried using rmb() in 
the retry loop but that did not solve it. Another experiment was to 
ignore the failed ring descriptor entry and proceed. So we get interrupt 
from device and access the ring descriptor entry. This should contain 
expected value X, however we get X-1 back. When proceeding everything 
works find until hitting the same ring descriptor entry again reading 
X-1 when X+1 would be valid. This lead us to the assumption that somehow 
this entry ended up in cache lines. The issue goes away using the 
dma_sync_single_for_cpu() with DMA_FROM_DEVICE in direction parameter. 
We are not longer using virt_to_dma() so that is no longer an issue. So 
is there any function interface to verify cache status.

Regards,
Arend

> (Added Marek for comment on dma_alloc_coherent(), Will for comment on
> barrier stuff.)
>


^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 12:43     ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-05 12:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 05-12-14 10:45, Russell King - ARM Linux wrote:
> On Fri, Dec 05, 2014 at 10:22:22AM +0100, Arend van Spriel wrote:
>> For our brcm80211 development we are working on getting brcmfmac driver
>> up and running on a Broadcom ARM-based platform. The wireless device is
>> a PCIe device, which is hooked up to the system behind a PCIe host
>> bridge, and we transfer information between host and device using a
>> descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
>> tested on x86 and seen no issue. However, on this ARM platform
>> (single-core A9) we detect occasionally that the descriptor content is
>> invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
>> retried a number of times if the problem persists. Actually, found out
>> that someone made a mistake by using virt_to_dma(va) to get the
>> dma_handle parameter. So probably we only provided a delay in the retry
>> loop. After fixing that a single call to dma_sync_single_for_cpu() is
>> sufficient. The DMA-API-HOWTO clearly states that:
>>
>> """
>> the hardware should guarantee that the device and the CPU can access the
>> data in parallel and will see updates made by each other without any
>> explicit software flushing.
>> """
>>
>> So it seems incorrect that we would need to do a dma_sync for this
>> memory. That we do need it seems like this memory can end up in
>> cache(?), or whatever happens, in some rare condition. Is there anyway
>> to investigate this situation either through DMA-API or some low-level
>> ARM specific functions.
>
> It's been a long while since I looked at the code, and the code for
> dma_alloc_coherent() has completely changed since then with the
> addition of CMA.  I'm afraid that anything I would say about it would
> not be accurate without research into the possible paths through that
> code - it's no longer just a simple allocator.

I know. On this particular platform we are not using CMA.

> What you say is correct however: the memory should not have any cache
> lines associated with it, if it does, there's a bug somewhere.
>
> Also, the memory will be weakly ordered, which means that writes to such
> memory can be reordered.  If ordering matters, barriers should be used.
> rmb() and wmb() can be used for this.

Ok. You already had a peek in our code checking the memory barriers, 
which does not have the dma_sync_single_for_cpu() "workaround" yet. So 
here some more background. The problem is in DMA_FROM_DEVICE direction. 
Because of the possible reordering issue we first tried using rmb() in 
the retry loop but that did not solve it. Another experiment was to 
ignore the failed ring descriptor entry and proceed. So we get interrupt 
from device and access the ring descriptor entry. This should contain 
expected value X, however we get X-1 back. When proceeding everything 
works find until hitting the same ring descriptor entry again reading 
X-1 when X+1 would be valid. This lead us to the assumption that somehow 
this entry ended up in cache lines. The issue goes away using the 
dma_sync_single_for_cpu() with DMA_FROM_DEVICE in direction parameter. 
We are not longer using virt_to_dma() so that is no longer an issue. So 
is there any function interface to verify cache status.

Regards,
Arend

> (Added Marek for comment on dma_alloc_coherent(), Will for comment on
> barrier stuff.)
>

^ permalink raw reply	[flat|nested] 115+ messages in thread

* RE: using DMA-API on ARM
  2014-12-05 12:24     ` Will Deacon
  (?)
@ 2014-12-05 12:56       ` Hante Meuleman
  -1 siblings, 0 replies; 115+ messages in thread
From: Hante Meuleman @ 2014-12-05 12:56 UTC (permalink / raw)
  To: Will Deacon, Russell King - ARM Linux
  Cc: Arend Van Spriel, Marek Szyprowski, linux-arm-kernel,
	David Miller, linux-kernel, brcm80211-dev-list, linux-wireless

The problem is with data coming from device, so DMA from device to host. The DMA takes place from device local memory to host memory, where the host memory is allocated with dma_alloc_coherent, which we thought should not be cached. The host is an ARM (as is the device). The data being DMA'ed ends up in a ring buffer. This ring is only being read by host when it is a d2h ring (device to host). Each entry in the ring is 32 bytes, and contains a sequence number. The sequence number is a modulo 253 and the ring has 256 entries. At some point we read a sequence number which was "old". Then we loop to see if the sequence number changes. The loop is 1024 times and uses an rmb() call. This does not help. After looping 1024 times it is still reading the same value for sequence number. Now it can happen that 256 entries further we are still reading this old sequence (so iso reading a seqnum which is off by 3, it is off by 6). This was an indication that it was cached. So instead of using rmb() we used dma_sync_single_for_cpu. When using that call the problem was fixed. Whenever an old sequence number was read a single call to dma_sync_single_for_cpu would flush the cache and the next read would be correct. 

However: this indicates that dma_alloc_coherent on an ARM target may result in a memory buffer which can be cached which conflicts with the API of this function. This problem has sofar not been observed on x86 hosts.

Regards,
Hante

-----Original Message-----
From: Will Deacon [mailto:will.deacon@arm.com] 
Sent: vrijdag 5 december 2014 13:24
To: Russell King - ARM Linux
Cc: Arend Van Spriel; Marek Szyprowski; linux-arm-kernel@lists.infradead.org; David Miller; linux-kernel@vger.kernel.org; brcm80211-dev-list; linux-wireless
Subject: Re: using DMA-API on ARM

On Fri, Dec 05, 2014 at 09:45:08AM +0000, Russell King - ARM Linux wrote:
> On Fri, Dec 05, 2014 at 10:22:22AM +0100, Arend van Spriel wrote:
> > For our brcm80211 development we are working on getting brcmfmac driver
> > up and running on a Broadcom ARM-based platform. The wireless device is
> > a PCIe device, which is hooked up to the system behind a PCIe host
> > bridge, and we transfer information between host and device using a
> > descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> > tested on x86 and seen no issue. However, on this ARM platform
> > (single-core A9) we detect occasionally that the descriptor content is
> > invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> > retried a number of times if the problem persists. Actually, found out
> > that someone made a mistake by using virt_to_dma(va) to get the
> > dma_handle parameter. So probably we only provided a delay in the retry
> > loop. After fixing that a single call to dma_sync_single_for_cpu() is
> > sufficient. The DMA-API-HOWTO clearly states that:
> > 
> > """
> > the hardware should guarantee that the device and the CPU can access the
> > data in parallel and will see updates made by each other without any
> > explicit software flushing.
> > """
> > 
> > So it seems incorrect that we would need to do a dma_sync for this
> > memory. That we do need it seems like this memory can end up in
> > cache(?), or whatever happens, in some rare condition. Is there anyway
> > to investigate this situation either through DMA-API or some low-level
> > ARM specific functions.
> 
> It's been a long while since I looked at the code, and the code for
> dma_alloc_coherent() has completely changed since then with the
> addition of CMA.  I'm afraid that anything I would say about it would
> not be accurate without research into the possible paths through that
> code - it's no longer just a simple allocator.
> 
> What you say is correct however: the memory should not have any cache
> lines associated with it, if it does, there's a bug somewhere.
> 
> Also, the memory will be weakly ordered, which means that writes to such
> memory can be reordered.  If ordering matters, barriers should be used.
> rmb() and wmb() can be used for this.
> 
> (Added Marek for comment on dma_alloc_coherent(), Will for comment on
> barrier stuff.)

I'm not quite clear on the issue being seen here: is this on write from
the CPU to the descriptor ring, or the other way around (or both?).

Either way, you need barriers on the CPU side to ensure ordering of
accesses to the buffer. rmb/wmb will work, but are heavier than what you
need (relaxed versions have been proposed on LKML recently).

Will

^ permalink raw reply	[flat|nested] 115+ messages in thread

* RE: using DMA-API on ARM
@ 2014-12-05 12:56       ` Hante Meuleman
  0 siblings, 0 replies; 115+ messages in thread
From: Hante Meuleman @ 2014-12-05 12:56 UTC (permalink / raw)
  To: Will Deacon, Russell King - ARM Linux
  Cc: Arend Van Spriel, Marek Szyprowski, linux-arm-kernel,
	David Miller, linux-kernel, brcm80211-dev-list, linux-wireless

The problem is with data coming from device, so DMA from device to host. The DMA takes place from device local memory to host memory, where the host memory is allocated with dma_alloc_coherent, which we thought should not be cached. The host is an ARM (as is the device). The data being DMA'ed ends up in a ring buffer. This ring is only being read by host when it is a d2h ring (device to host). Each entry in the ring is 32 bytes, and contains a sequence number. The sequence number is a modulo 253 and the ring has 256 entries. At some point we read a sequence number which was "old". Then we loop to see if the sequence number changes. The loop is 1024 times and uses an rmb() call. This does not help. After looping 1024 times it is still reading the same value for sequence number. Now it can happen that 256 entries further we are still reading this old sequence (so iso reading a seqnum which is off by 3, it is off by 6). This was an indication that it was cached. So instead of using rmb() we used dma_sync_single_for_cpu. When using that call the problem was fixed. Whenever an old sequence number was read a single call to dma_sync_single_for_cpu would flush the cache and the next read would be correct. 

However: this indicates that dma_alloc_coherent on an ARM target may result in a memory buffer which can be cached which conflicts with the API of this function. This problem has sofar not been observed on x86 hosts.

Regards,
Hante

-----Original Message-----
From: Will Deacon [mailto:will.deacon@arm.com] 
Sent: vrijdag 5 december 2014 13:24
To: Russell King - ARM Linux
Cc: Arend Van Spriel; Marek Szyprowski; linux-arm-kernel@lists.infradead.org; David Miller; linux-kernel@vger.kernel.org; brcm80211-dev-list; linux-wireless
Subject: Re: using DMA-API on ARM

On Fri, Dec 05, 2014 at 09:45:08AM +0000, Russell King - ARM Linux wrote:
> On Fri, Dec 05, 2014 at 10:22:22AM +0100, Arend van Spriel wrote:
> > For our brcm80211 development we are working on getting brcmfmac driver
> > up and running on a Broadcom ARM-based platform. The wireless device is
> > a PCIe device, which is hooked up to the system behind a PCIe host
> > bridge, and we transfer information between host and device using a
> > descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> > tested on x86 and seen no issue. However, on this ARM platform
> > (single-core A9) we detect occasionally that the descriptor content is
> > invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> > retried a number of times if the problem persists. Actually, found out
> > that someone made a mistake by using virt_to_dma(va) to get the
> > dma_handle parameter. So probably we only provided a delay in the retry
> > loop. After fixing that a single call to dma_sync_single_for_cpu() is
> > sufficient. The DMA-API-HOWTO clearly states that:
> > 
> > """
> > the hardware should guarantee that the device and the CPU can access the
> > data in parallel and will see updates made by each other without any
> > explicit software flushing.
> > """
> > 
> > So it seems incorrect that we would need to do a dma_sync for this
> > memory. That we do need it seems like this memory can end up in
> > cache(?), or whatever happens, in some rare condition. Is there anyway
> > to investigate this situation either through DMA-API or some low-level
> > ARM specific functions.
> 
> It's been a long while since I looked at the code, and the code for
> dma_alloc_coherent() has completely changed since then with the
> addition of CMA.  I'm afraid that anything I would say about it would
> not be accurate without research into the possible paths through that
> code - it's no longer just a simple allocator.
> 
> What you say is correct however: the memory should not have any cache
> lines associated with it, if it does, there's a bug somewhere.
> 
> Also, the memory will be weakly ordered, which means that writes to such
> memory can be reordered.  If ordering matters, barriers should be used.
> rmb() and wmb() can be used for this.
> 
> (Added Marek for comment on dma_alloc_coherent(), Will for comment on
> barrier stuff.)

I'm not quite clear on the issue being seen here: is this on write from
the CPU to the descriptor ring, or the other way around (or both?).

Either way, you need barriers on the CPU side to ensure ordering of
accesses to the buffer. rmb/wmb will work, but are heavier than what you
need (relaxed versions have been proposed on LKML recently).

Will

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 12:56       ` Hante Meuleman
  0 siblings, 0 replies; 115+ messages in thread
From: Hante Meuleman @ 2014-12-05 12:56 UTC (permalink / raw)
  To: linux-arm-kernel

The problem is with data coming from device, so DMA from device to host. The DMA takes place from device local memory to host memory, where the host memory is allocated with dma_alloc_coherent, which we thought should not be cached. The host is an ARM (as is the device). The data being DMA'ed ends up in a ring buffer. This ring is only being read by host when it is a d2h ring (device to host). Each entry in the ring is 32 bytes, and contains a sequence number. The sequence number is a modulo 253 and the ring has 256 entries. At some point we read a sequence number which was "old". Then we loop to see if the sequence number changes. The loop is 1024 times and uses an rmb() call. This does not help. After looping 1024 times it is still reading the same value for sequence number. Now it can happen that 256 entries further we are still reading this old sequence (so iso reading a seqnum which is off by 3, it is off by 6). This was an indication that it was cached. So instead of using rmb() we used dma_sync_single_for_cpu. When using that call the problem was fixed. Whenever an old sequence number was read a single call to dma_sync_single_for_cpu would flush the cache and the next read would be correct. 

However: this indicates that dma_alloc_coherent on an ARM target may result in a memory buffer which can be cached which conflicts with the API of this function. This problem has sofar not been observed on x86 hosts.

Regards,
Hante

-----Original Message-----
From: Will Deacon [mailto:will.deacon at arm.com] 
Sent: vrijdag 5 december 2014 13:24
To: Russell King - ARM Linux
Cc: Arend Van Spriel; Marek Szyprowski; linux-arm-kernel at lists.infradead.org; David Miller; linux-kernel at vger.kernel.org; brcm80211-dev-list; linux-wireless
Subject: Re: using DMA-API on ARM

On Fri, Dec 05, 2014 at 09:45:08AM +0000, Russell King - ARM Linux wrote:
> On Fri, Dec 05, 2014 at 10:22:22AM +0100, Arend van Spriel wrote:
> > For our brcm80211 development we are working on getting brcmfmac driver
> > up and running on a Broadcom ARM-based platform. The wireless device is
> > a PCIe device, which is hooked up to the system behind a PCIe host
> > bridge, and we transfer information between host and device using a
> > descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> > tested on x86 and seen no issue. However, on this ARM platform
> > (single-core A9) we detect occasionally that the descriptor content is
> > invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> > retried a number of times if the problem persists. Actually, found out
> > that someone made a mistake by using virt_to_dma(va) to get the
> > dma_handle parameter. So probably we only provided a delay in the retry
> > loop. After fixing that a single call to dma_sync_single_for_cpu() is
> > sufficient. The DMA-API-HOWTO clearly states that:
> > 
> > """
> > the hardware should guarantee that the device and the CPU can access the
> > data in parallel and will see updates made by each other without any
> > explicit software flushing.
> > """
> > 
> > So it seems incorrect that we would need to do a dma_sync for this
> > memory. That we do need it seems like this memory can end up in
> > cache(?), or whatever happens, in some rare condition. Is there anyway
> > to investigate this situation either through DMA-API or some low-level
> > ARM specific functions.
> 
> It's been a long while since I looked at the code, and the code for
> dma_alloc_coherent() has completely changed since then with the
> addition of CMA.  I'm afraid that anything I would say about it would
> not be accurate without research into the possible paths through that
> code - it's no longer just a simple allocator.
> 
> What you say is correct however: the memory should not have any cache
> lines associated with it, if it does, there's a bug somewhere.
> 
> Also, the memory will be weakly ordered, which means that writes to such
> memory can be reordered.  If ordering matters, barriers should be used.
> rmb() and wmb() can be used for this.
> 
> (Added Marek for comment on dma_alloc_coherent(), Will for comment on
> barrier stuff.)

I'm not quite clear on the issue being seen here: is this on write from
the CPU to the descriptor ring, or the other way around (or both?).

Either way, you need barriers on the CPU side to ensure ordering of
accesses to the buffer. rmb/wmb will work, but are heavier than what you
need (relaxed versions have been proposed on LKML recently).

Will

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05 12:43     ` Arend van Spriel
  (?)
@ 2014-12-05 12:59       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 12:59 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Marek Szyprowski, Will Deacon, linux-arm-kernel, David Miller,
	linux-kernel, brcm80211-dev-list, linux-wireless, Arnd Bergmann

On Fri, Dec 05, 2014 at 01:43:01PM +0100, Arend van Spriel wrote:
> Ok. You already had a peek in our code checking the memory barriers, which
> does not have the dma_sync_single_for_cpu() "workaround" yet. So here some
> more background. The problem is in DMA_FROM_DEVICE direction. Because of the
> possible reordering issue we first tried using rmb() in the retry loop but
> that did not solve it. Another experiment was to ignore the failed ring
> descriptor entry and proceed. So we get interrupt from device and access the
> ring descriptor entry. This should contain expected value X, however we get
> X-1 back. When proceeding everything works find until hitting the same ring
> descriptor entry again reading X-1 when X+1 would be valid. This lead us to
> the assumption that somehow this entry ended up in cache lines. The issue
> goes away using the dma_sync_single_for_cpu() with DMA_FROM_DEVICE in
> direction parameter.

Can you give some further detail - I think it would help understanding
if you could give:

- the initial numerical state of the descriptor (presumably setup by
  msgbuf.c calling brcmf_commonring_reserve_for_write(), and then
  writing the contents into the ring buffer, followed by
  brcmf_commonring_write_complete().

- time passes, the hardware processes the entry

- the numerical state of the descriptor (which is in error) which you
  read back

- the expected numerical state of the descriptor

> So is there any function interface to verify cache status.

There isn't, but if you dump the virtual address, and you have debugfs
enabled, along with CONFIG_ARM_PTDUMP, you should be able to find the
mapping in /sys/kernel/debug/kernel_page_tables, which will tell you
the attributes that it's mapped using.

What it won't tell you is whether there's an alias of the mapping with
differing attributes.  If you use dma_to_pfn() to convert the DMA handle
into a PFN, we can use that to see whether there could be another mapping
from the kernel page table dump (by checking whether the PFN would be a
lowmem PFN, and therefore whether it's already mapped at it's lowmem
address.)

If you'd like to mail me (in addition to the ring contents above):

- the kernel_page_tables dump
- virtual address of the ring buffer
- dma_to_pfn() converted DMA handle of the ring buffer
- PHYS_PFN_OFFSET for your platform

then I can see whether there is.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-05 12:59       ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 12:59 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Marek Szyprowski, Will Deacon, linux-arm-kernel, David Miller,
	linux-kernel, brcm80211-dev-list, linux-wireless, Arnd Bergmann

On Fri, Dec 05, 2014 at 01:43:01PM +0100, Arend van Spriel wrote:
> Ok. You already had a peek in our code checking the memory barriers, which
> does not have the dma_sync_single_for_cpu() "workaround" yet. So here some
> more background. The problem is in DMA_FROM_DEVICE direction. Because of the
> possible reordering issue we first tried using rmb() in the retry loop but
> that did not solve it. Another experiment was to ignore the failed ring
> descriptor entry and proceed. So we get interrupt from device and access the
> ring descriptor entry. This should contain expected value X, however we get
> X-1 back. When proceeding everything works find until hitting the same ring
> descriptor entry again reading X-1 when X+1 would be valid. This lead us to
> the assumption that somehow this entry ended up in cache lines. The issue
> goes away using the dma_sync_single_for_cpu() with DMA_FROM_DEVICE in
> direction parameter.

Can you give some further detail - I think it would help understanding
if you could give:

- the initial numerical state of the descriptor (presumably setup by
  msgbuf.c calling brcmf_commonring_reserve_for_write(), and then
  writing the contents into the ring buffer, followed by
  brcmf_commonring_write_complete().

- time passes, the hardware processes the entry

- the numerical state of the descriptor (which is in error) which you
  read back

- the expected numerical state of the descriptor

> So is there any function interface to verify cache status.

There isn't, but if you dump the virtual address, and you have debugfs
enabled, along with CONFIG_ARM_PTDUMP, you should be able to find the
mapping in /sys/kernel/debug/kernel_page_tables, which will tell you
the attributes that it's mapped using.

What it won't tell you is whether there's an alias of the mapping with
differing attributes.  If you use dma_to_pfn() to convert the DMA handle
into a PFN, we can use that to see whether there could be another mapping
from the kernel page table dump (by checking whether the PFN would be a
lowmem PFN, and therefore whether it's already mapped at it's lowmem
address.)

If you'd like to mail me (in addition to the ring contents above):

- the kernel_page_tables dump
- virtual address of the ring buffer
- dma_to_pfn() converted DMA handle of the ring buffer
- PHYS_PFN_OFFSET for your platform

then I can see whether there is.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 12:59       ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 05, 2014 at 01:43:01PM +0100, Arend van Spriel wrote:
> Ok. You already had a peek in our code checking the memory barriers, which
> does not have the dma_sync_single_for_cpu() "workaround" yet. So here some
> more background. The problem is in DMA_FROM_DEVICE direction. Because of the
> possible reordering issue we first tried using rmb() in the retry loop but
> that did not solve it. Another experiment was to ignore the failed ring
> descriptor entry and proceed. So we get interrupt from device and access the
> ring descriptor entry. This should contain expected value X, however we get
> X-1 back. When proceeding everything works find until hitting the same ring
> descriptor entry again reading X-1 when X+1 would be valid. This lead us to
> the assumption that somehow this entry ended up in cache lines. The issue
> goes away using the dma_sync_single_for_cpu() with DMA_FROM_DEVICE in
> direction parameter.

Can you give some further detail - I think it would help understanding
if you could give:

- the initial numerical state of the descriptor (presumably setup by
  msgbuf.c calling brcmf_commonring_reserve_for_write(), and then
  writing the contents into the ring buffer, followed by
  brcmf_commonring_write_complete().

- time passes, the hardware processes the entry

- the numerical state of the descriptor (which is in error) which you
  read back

- the expected numerical state of the descriptor

> So is there any function interface to verify cache status.

There isn't, but if you dump the virtual address, and you have debugfs
enabled, along with CONFIG_ARM_PTDUMP, you should be able to find the
mapping in /sys/kernel/debug/kernel_page_tables, which will tell you
the attributes that it's mapped using.

What it won't tell you is whether there's an alias of the mapping with
differing attributes.  If you use dma_to_pfn() to convert the DMA handle
into a PFN, we can use that to see whether there could be another mapping
from the kernel page table dump (by checking whether the PFN would be a
lowmem PFN, and therefore whether it's already mapped at it's lowmem
address.)

If you'd like to mail me (in addition to the ring contents above):

- the kernel_page_tables dump
- virtual address of the ring buffer
- dma_to_pfn() converted DMA handle of the ring buffer
- PHYS_PFN_OFFSET for your platform

then I can see whether there is.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05 12:56       ` Hante Meuleman
  (?)
@ 2014-12-05 13:23         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 13:23 UTC (permalink / raw)
  To: Hante Meuleman
  Cc: Will Deacon, Arend Van Spriel, Marek Szyprowski,
	linux-arm-kernel, David Miller, linux-kernel, brcm80211-dev-list,
	linux-wireless

Please wrap your message - replying to a message which looks like this in
my editor is far from easy, and gives me much more work to /manually/
reformat it before I can reply to it:

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> The problem is with data coming from device, so DMA from device to host. The $
>
> However: this indicates that dma_alloc_coherent on an ARM target may result i$
>
> Regards,
> Hante

Thanks.

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> However: this indicates that dma_alloc_coherent on an ARM target may
> result in a memory buffer which can be cached which conflicts with
> the API of this function.

If the memory has an alias which is cacheable, it is possible for cache
lines to get allocated via that alias, even if the alias has no explicit
accesses to it.

This is something which I've been going on for quite literally /years/ -
mismatched cache attributes can cause unpredictable behaviour.  I've had
a lot of push back from people who are of the opinion that "if it works
for me, then there isn't a problem" and I eventually gave up fighting
the battle, especially as the ARM architecture people weakened my
reasoning behind it by publishing a relaxation of the "no differing
attributes" issue.  This was particularly true of those who wanted to
use ioremap() on system memory - and cases such as
dma_init_coherent_memory().

So, I never fixed this problem in the original DMA allocator code; I
basically gave up with it.  It's a latent bug which did need to be fixed,
and is still present today in the non-CMA case.

The symptoms which you are reporting sound very much like this kind of
problem - the virtual address for the memory returned by
dma_alloc_coherent() will not be cacheable memory - it will have been
remapped using map_vm_area().  However, there could very well be a fully
cacheable lowmem mapping of that memory, which if a read (speculative or
otherwise) will bring a cache line in, and because the caches are VIPT
or PIPT, that cache line can be hit via the non-cacheable mapping too.

What I /really/ need is more evidence of this to tell those disbelievers
where to stick their flawed arguments. :)

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-05 13:23         ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 13:23 UTC (permalink / raw)
  To: Hante Meuleman
  Cc: Will Deacon, Arend Van Spriel, Marek Szyprowski,
	linux-arm-kernel, David Miller, linux-kernel, brcm80211-dev-list,
	linux-wireless

Please wrap your message - replying to a message which looks like this in
my editor is far from easy, and gives me much more work to /manually/
reformat it before I can reply to it:

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> The problem is with data coming from device, so DMA from device to host. The $
>
> However: this indicates that dma_alloc_coherent on an ARM target may result i$
>
> Regards,
> Hante

Thanks.

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> However: this indicates that dma_alloc_coherent on an ARM target may
> result in a memory buffer which can be cached which conflicts with
> the API of this function.

If the memory has an alias which is cacheable, it is possible for cache
lines to get allocated via that alias, even if the alias has no explicit
accesses to it.

This is something which I've been going on for quite literally /years/ -
mismatched cache attributes can cause unpredictable behaviour.  I've had
a lot of push back from people who are of the opinion that "if it works
for me, then there isn't a problem" and I eventually gave up fighting
the battle, especially as the ARM architecture people weakened my
reasoning behind it by publishing a relaxation of the "no differing
attributes" issue.  This was particularly true of those who wanted to
use ioremap() on system memory - and cases such as
dma_init_coherent_memory().

So, I never fixed this problem in the original DMA allocator code; I
basically gave up with it.  It's a latent bug which did need to be fixed,
and is still present today in the non-CMA case.

The symptoms which you are reporting sound very much like this kind of
problem - the virtual address for the memory returned by
dma_alloc_coherent() will not be cacheable memory - it will have been
remapped using map_vm_area().  However, there could very well be a fully
cacheable lowmem mapping of that memory, which if a read (speculative or
otherwise) will bring a cache line in, and because the caches are VIPT
or PIPT, that cache line can be hit via the non-cacheable mapping too.

What I /really/ need is more evidence of this to tell those disbelievers
where to stick their flawed arguments. :)

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 13:23         ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 13:23 UTC (permalink / raw)
  To: linux-arm-kernel

Please wrap your message - replying to a message which looks like this in
my editor is far from easy, and gives me much more work to /manually/
reformat it before I can reply to it:

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> The problem is with data coming from device, so DMA from device to host. The $
>
> However: this indicates that dma_alloc_coherent on an ARM target may result i$
>
> Regards,
> Hante

Thanks.

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> However: this indicates that dma_alloc_coherent on an ARM target may
> result in a memory buffer which can be cached which conflicts with
> the API of this function.

If the memory has an alias which is cacheable, it is possible for cache
lines to get allocated via that alias, even if the alias has no explicit
accesses to it.

This is something which I've been going on for quite literally /years/ -
mismatched cache attributes can cause unpredictable behaviour.  I've had
a lot of push back from people who are of the opinion that "if it works
for me, then there isn't a problem" and I eventually gave up fighting
the battle, especially as the ARM architecture people weakened my
reasoning behind it by publishing a relaxation of the "no differing
attributes" issue.  This was particularly true of those who wanted to
use ioremap() on system memory - and cases such as
dma_init_coherent_memory().

So, I never fixed this problem in the original DMA allocator code; I
basically gave up with it.  It's a latent bug which did need to be fixed,
and is still present today in the non-CMA case.

The symptoms which you are reporting sound very much like this kind of
problem - the virtual address for the memory returned by
dma_alloc_coherent() will not be cacheable memory - it will have been
remapped using map_vm_area().  However, there could very well be a fully
cacheable lowmem mapping of that memory, which if a read (speculative or
otherwise) will bring a cache line in, and because the caches are VIPT
or PIPT, that cache line can be hit via the non-cacheable mapping too.

What I /really/ need is more evidence of this to tell those disbelievers
where to stick their flawed arguments. :)

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* RE: using DMA-API on ARM
  2014-12-05 13:23         ` Russell King - ARM Linux
  (?)
@ 2014-12-05 14:20           ` Hante Meuleman
  -1 siblings, 0 replies; 115+ messages in thread
From: Hante Meuleman @ 2014-12-05 14:20 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Will Deacon, Arend Van Spriel, Marek Szyprowski,
	linux-arm-kernel, David Miller, linux-kernel, brcm80211-dev-list,
	linux-wireless

Ok, I'll add the necessary debug to get all the information out, 
but it will take some time to get it done, so I won't have anything 
before Monday.

-----Original Message-----
From: Russell King - ARM Linux [mailto:linux@arm.linux.org.uk] 
Sent: vrijdag 5 december 2014 14:24
To: Hante Meuleman
Cc: Will Deacon; Arend Van Spriel; Marek Szyprowski; linux-arm-kernel@lists.infradead.org; David Miller; linux-kernel@vger.kernel.org; brcm80211-dev-list; linux-wireless
Subject: Re: using DMA-API on ARM

Please wrap your message - replying to a message which looks like this in
my editor is far from easy, and gives me much more work to /manually/
reformat it before I can reply to it:

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> The problem is with data coming from device, so DMA from device to host. The $
>
> However: this indicates that dma_alloc_coherent on an ARM target may result i$
>
> Regards,
> Hante

Thanks.

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> However: this indicates that dma_alloc_coherent on an ARM target may
> result in a memory buffer which can be cached which conflicts with
> the API of this function.

If the memory has an alias which is cacheable, it is possible for cache
lines to get allocated via that alias, even if the alias has no explicit
accesses to it.

This is something which I've been going on for quite literally /years/ -
mismatched cache attributes can cause unpredictable behaviour.  I've had
a lot of push back from people who are of the opinion that "if it works
for me, then there isn't a problem" and I eventually gave up fighting
the battle, especially as the ARM architecture people weakened my
reasoning behind it by publishing a relaxation of the "no differing
attributes" issue.  This was particularly true of those who wanted to
use ioremap() on system memory - and cases such as
dma_init_coherent_memory().

So, I never fixed this problem in the original DMA allocator code; I
basically gave up with it.  It's a latent bug which did need to be fixed,
and is still present today in the non-CMA case.

The symptoms which you are reporting sound very much like this kind of
problem - the virtual address for the memory returned by
dma_alloc_coherent() will not be cacheable memory - it will have been
remapped using map_vm_area().  However, there could very well be a fully
cacheable lowmem mapping of that memory, which if a read (speculative or
otherwise) will bring a cache line in, and because the caches are VIPT
or PIPT, that cache line can be hit via the non-cacheable mapping too.

What I /really/ need is more evidence of this to tell those disbelievers
where to stick their flawed arguments. :)

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* RE: using DMA-API on ARM
@ 2014-12-05 14:20           ` Hante Meuleman
  0 siblings, 0 replies; 115+ messages in thread
From: Hante Meuleman @ 2014-12-05 14:20 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Will Deacon, Arend Van Spriel, Marek Szyprowski,
	linux-arm-kernel, David Miller, linux-kernel, brcm80211-dev-list,
	linux-wireless

Ok, I'll add the necessary debug to get all the information out, 
but it will take some time to get it done, so I won't have anything 
before Monday.

-----Original Message-----
From: Russell King - ARM Linux [mailto:linux@arm.linux.org.uk] 
Sent: vrijdag 5 december 2014 14:24
To: Hante Meuleman
Cc: Will Deacon; Arend Van Spriel; Marek Szyprowski; linux-arm-kernel@lists.infradead.org; David Miller; linux-kernel@vger.kernel.org; brcm80211-dev-list; linux-wireless
Subject: Re: using DMA-API on ARM

Please wrap your message - replying to a message which looks like this in
my editor is far from easy, and gives me much more work to /manually/
reformat it before I can reply to it:

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> The problem is with data coming from device, so DMA from device to host. The $
>
> However: this indicates that dma_alloc_coherent on an ARM target may result i$
>
> Regards,
> Hante

Thanks.

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> However: this indicates that dma_alloc_coherent on an ARM target may
> result in a memory buffer which can be cached which conflicts with
> the API of this function.

If the memory has an alias which is cacheable, it is possible for cache
lines to get allocated via that alias, even if the alias has no explicit
accesses to it.

This is something which I've been going on for quite literally /years/ -
mismatched cache attributes can cause unpredictable behaviour.  I've had
a lot of push back from people who are of the opinion that "if it works
for me, then there isn't a problem" and I eventually gave up fighting
the battle, especially as the ARM architecture people weakened my
reasoning behind it by publishing a relaxation of the "no differing
attributes" issue.  This was particularly true of those who wanted to
use ioremap() on system memory - and cases such as
dma_init_coherent_memory().

So, I never fixed this problem in the original DMA allocator code; I
basically gave up with it.  It's a latent bug which did need to be fixed,
and is still present today in the non-CMA case.

The symptoms which you are reporting sound very much like this kind of
problem - the virtual address for the memory returned by
dma_alloc_coherent() will not be cacheable memory - it will have been
remapped using map_vm_area().  However, there could very well be a fully
cacheable lowmem mapping of that memory, which if a read (speculative or
otherwise) will bring a cache line in, and because the caches are VIPT
or PIPT, that cache line can be hit via the non-cacheable mapping too.

What I /really/ need is more evidence of this to tell those disbelievers
where to stick their flawed arguments. :)

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 14:20           ` Hante Meuleman
  0 siblings, 0 replies; 115+ messages in thread
From: Hante Meuleman @ 2014-12-05 14:20 UTC (permalink / raw)
  To: linux-arm-kernel

Ok, I'll add the necessary debug to get all the information out, 
but it will take some time to get it done, so I won't have anything 
before Monday.

-----Original Message-----
From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk] 
Sent: vrijdag 5 december 2014 14:24
To: Hante Meuleman
Cc: Will Deacon; Arend Van Spriel; Marek Szyprowski; linux-arm-kernel at lists.infradead.org; David Miller; linux-kernel at vger.kernel.org; brcm80211-dev-list; linux-wireless
Subject: Re: using DMA-API on ARM

Please wrap your message - replying to a message which looks like this in
my editor is far from easy, and gives me much more work to /manually/
reformat it before I can reply to it:

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> The problem is with data coming from device, so DMA from device to host. The $
>
> However: this indicates that dma_alloc_coherent on an ARM target may result i$
>
> Regards,
> Hante

Thanks.

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> However: this indicates that dma_alloc_coherent on an ARM target may
> result in a memory buffer which can be cached which conflicts with
> the API of this function.

If the memory has an alias which is cacheable, it is possible for cache
lines to get allocated via that alias, even if the alias has no explicit
accesses to it.

This is something which I've been going on for quite literally /years/ -
mismatched cache attributes can cause unpredictable behaviour.  I've had
a lot of push back from people who are of the opinion that "if it works
for me, then there isn't a problem" and I eventually gave up fighting
the battle, especially as the ARM architecture people weakened my
reasoning behind it by publishing a relaxation of the "no differing
attributes" issue.  This was particularly true of those who wanted to
use ioremap() on system memory - and cases such as
dma_init_coherent_memory().

So, I never fixed this problem in the original DMA allocator code; I
basically gave up with it.  It's a latent bug which did need to be fixed,
and is still present today in the non-CMA case.

The symptoms which you are reporting sound very much like this kind of
problem - the virtual address for the memory returned by
dma_alloc_coherent() will not be cacheable memory - it will have been
remapped using map_vm_area().  However, there could very well be a fully
cacheable lowmem mapping of that memory, which if a read (speculative or
otherwise) will bring a cache line in, and because the caches are VIPT
or PIPT, that cache line can be hit via the non-cacheable mapping too.

What I /really/ need is more evidence of this to tell those disbelievers
where to stick their flawed arguments. :)

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05 14:20           ` Hante Meuleman
  (?)
@ 2014-12-05 14:47             ` Arend van Spriel
  -1 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-05 14:47 UTC (permalink / raw)
  To: Hante Meuleman
  Cc: Russell King - ARM Linux, Will Deacon, Marek Szyprowski,
	linux-arm-kernel, David Miller, linux-kernel, brcm80211-dev-list,
	linux-wireless

On 12/05/14 15:20, Hante Meuleman wrote:
> Ok, I'll add the necessary debug to get all the information out,
> but it will take some time to get it done, so I won't have anything
> before Monday.
>
> -----Original Message-----
> From: Russell King - ARM Linux [mailto:linux@arm.linux.org.uk]
> Sent: vrijdag 5 december 2014 14:24
> To: Hante Meuleman
> Cc: Will Deacon; Arend Van Spriel; Marek Szyprowski; linux-arm-kernel@lists.infradead.org; David Miller; linux-kernel@vger.kernel.org; brcm80211-dev-list; linux-wireless
> Subject: Re: using DMA-API on ARM
>
> Please wrap your message - replying to a message which looks like this in
> my editor is far from easy, and gives me much more work to /manually/
> reformat it before I can reply to it:

That's what happens with corporate IT forcing to use Outlook. We can 
workaround that using Thunderbird on Citrix. I will enlighten Hante 
about that option :-)

Regards,
Arend

> On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
>> The problem is with data coming from device, so DMA from device to host. The $
>>
>> However: this indicates that dma_alloc_coherent on an ARM target may result i$
>>
>> Regards,
>> Hante
>
> Thanks.
>
> On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
>> However: this indicates that dma_alloc_coherent on an ARM target may
>> result in a memory buffer which can be cached which conflicts with
>> the API of this function.
>
> If the memory has an alias which is cacheable, it is possible for cache
> lines to get allocated via that alias, even if the alias has no explicit
> accesses to it.
>
> This is something which I've been going on for quite literally /years/ -
> mismatched cache attributes can cause unpredictable behaviour.  I've had
> a lot of push back from people who are of the opinion that "if it works
> for me, then there isn't a problem" and I eventually gave up fighting
> the battle, especially as the ARM architecture people weakened my
> reasoning behind it by publishing a relaxation of the "no differing
> attributes" issue.  This was particularly true of those who wanted to
> use ioremap() on system memory - and cases such as
> dma_init_coherent_memory().
>
> So, I never fixed this problem in the original DMA allocator code; I
> basically gave up with it.  It's a latent bug which did need to be fixed,
> and is still present today in the non-CMA case.
>
> The symptoms which you are reporting sound very much like this kind of
> problem - the virtual address for the memory returned by
> dma_alloc_coherent() will not be cacheable memory - it will have been
> remapped using map_vm_area().  However, there could very well be a fully
> cacheable lowmem mapping of that memory, which if a read (speculative or
> otherwise) will bring a cache line in, and because the caches are VIPT
> or PIPT, that cache line can be hit via the non-cacheable mapping too.
>
> What I /really/ need is more evidence of this to tell those disbelievers
> where to stick their flawed arguments. :)
>


^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-05 14:47             ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-05 14:47 UTC (permalink / raw)
  To: Hante Meuleman
  Cc: Russell King - ARM Linux, Will Deacon, Marek Szyprowski,
	linux-arm-kernel, David Miller, linux-kernel, brcm80211-dev-list,
	linux-wireless

On 12/05/14 15:20, Hante Meuleman wrote:
> Ok, I'll add the necessary debug to get all the information out,
> but it will take some time to get it done, so I won't have anything
> before Monday.
>
> -----Original Message-----
> From: Russell King - ARM Linux [mailto:linux@arm.linux.org.uk]
> Sent: vrijdag 5 december 2014 14:24
> To: Hante Meuleman
> Cc: Will Deacon; Arend Van Spriel; Marek Szyprowski; linux-arm-kernel@lists.infradead.org; David Miller; linux-kernel@vger.kernel.org; brcm80211-dev-list; linux-wireless
> Subject: Re: using DMA-API on ARM
>
> Please wrap your message - replying to a message which looks like this in
> my editor is far from easy, and gives me much more work to /manually/
> reformat it before I can reply to it:

That's what happens with corporate IT forcing to use Outlook. We can 
workaround that using Thunderbird on Citrix. I will enlighten Hante 
about that option :-)

Regards,
Arend

> On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
>> The problem is with data coming from device, so DMA from device to host. The $
>>
>> However: this indicates that dma_alloc_coherent on an ARM target may result i$
>>
>> Regards,
>> Hante
>
> Thanks.
>
> On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
>> However: this indicates that dma_alloc_coherent on an ARM target may
>> result in a memory buffer which can be cached which conflicts with
>> the API of this function.
>
> If the memory has an alias which is cacheable, it is possible for cache
> lines to get allocated via that alias, even if the alias has no explicit
> accesses to it.
>
> This is something which I've been going on for quite literally /years/ -
> mismatched cache attributes can cause unpredictable behaviour.  I've had
> a lot of push back from people who are of the opinion that "if it works
> for me, then there isn't a problem" and I eventually gave up fighting
> the battle, especially as the ARM architecture people weakened my
> reasoning behind it by publishing a relaxation of the "no differing
> attributes" issue.  This was particularly true of those who wanted to
> use ioremap() on system memory - and cases such as
> dma_init_coherent_memory().
>
> So, I never fixed this problem in the original DMA allocator code; I
> basically gave up with it.  It's a latent bug which did need to be fixed,
> and is still present today in the non-CMA case.
>
> The symptoms which you are reporting sound very much like this kind of
> problem - the virtual address for the memory returned by
> dma_alloc_coherent() will not be cacheable memory - it will have been
> remapped using map_vm_area().  However, there could very well be a fully
> cacheable lowmem mapping of that memory, which if a read (speculative or
> otherwise) will bring a cache line in, and because the caches are VIPT
> or PIPT, that cache line can be hit via the non-cacheable mapping too.
>
> What I /really/ need is more evidence of this to tell those disbelievers
> where to stick their flawed arguments. :)
>


^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 14:47             ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-05 14:47 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/05/14 15:20, Hante Meuleman wrote:
> Ok, I'll add the necessary debug to get all the information out,
> but it will take some time to get it done, so I won't have anything
> before Monday.
>
> -----Original Message-----
> From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
> Sent: vrijdag 5 december 2014 14:24
> To: Hante Meuleman
> Cc: Will Deacon; Arend Van Spriel; Marek Szyprowski; linux-arm-kernel at lists.infradead.org; David Miller; linux-kernel at vger.kernel.org; brcm80211-dev-list; linux-wireless
> Subject: Re: using DMA-API on ARM
>
> Please wrap your message - replying to a message which looks like this in
> my editor is far from easy, and gives me much more work to /manually/
> reformat it before I can reply to it:

That's what happens with corporate IT forcing to use Outlook. We can 
workaround that using Thunderbird on Citrix. I will enlighten Hante 
about that option :-)

Regards,
Arend

> On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
>> The problem is with data coming from device, so DMA from device to host. The $
>>
>> However: this indicates that dma_alloc_coherent on an ARM target may result i$
>>
>> Regards,
>> Hante
>
> Thanks.
>
> On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
>> However: this indicates that dma_alloc_coherent on an ARM target may
>> result in a memory buffer which can be cached which conflicts with
>> the API of this function.
>
> If the memory has an alias which is cacheable, it is possible for cache
> lines to get allocated via that alias, even if the alias has no explicit
> accesses to it.
>
> This is something which I've been going on for quite literally /years/ -
> mismatched cache attributes can cause unpredictable behaviour.  I've had
> a lot of push back from people who are of the opinion that "if it works
> for me, then there isn't a problem" and I eventually gave up fighting
> the battle, especially as the ARM architecture people weakened my
> reasoning behind it by publishing a relaxation of the "no differing
> attributes" issue.  This was particularly true of those who wanted to
> use ioremap() on system memory - and cases such as
> dma_init_coherent_memory().
>
> So, I never fixed this problem in the original DMA allocator code; I
> basically gave up with it.  It's a latent bug which did need to be fixed,
> and is still present today in the non-CMA case.
>
> The symptoms which you are reporting sound very much like this kind of
> problem - the virtual address for the memory returned by
> dma_alloc_coherent() will not be cacheable memory - it will have been
> remapped using map_vm_area().  However, there could very well be a fully
> cacheable lowmem mapping of that memory, which if a read (speculative or
> otherwise) will bring a cache line in, and because the caches are VIPT
> or PIPT, that cache line can be hit via the non-cacheable mapping too.
>
> What I /really/ need is more evidence of this to tell those disbelievers
> where to stick their flawed arguments. :)
>

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05 13:23         ` Russell King - ARM Linux
  (?)
@ 2014-12-05 15:06           ` Russell King - ARM Linux
  -1 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 15:06 UTC (permalink / raw)
  To: Hante Meuleman
  Cc: linux-wireless, brcm80211-dev-list, Will Deacon, linux-kernel,
	Arend Van Spriel, David Miller, linux-arm-kernel,
	Marek Szyprowski

I've been doing more digging into the current DMA code, and I'm dismayed
to see that there's new bugs in it...

commit 513510ddba9650fc7da456eefeb0ead7632324f6
Author: Laura Abbott <lauraa@codeaurora.org>
Date:   Thu Oct 9 15:26:40 2014 -0700

    common: dma-mapping: introduce common remapping functions

This uses map_vm_area() to achieve the remapping of pages allocated inside
dma_alloc_coherent().  dma_alloc_coherent() is documented in a rather
round-about way in Documentation/DMA-API.txt:

| Part Ia - Using large DMA-coherent buffers
| ------------------------------------------
| 
| void *
| dma_alloc_coherent(struct device *dev, size_t size,
|                              dma_addr_t *dma_handle, gfp_t flag)
| 
| void
| dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
|                            dma_addr_t dma_handle)
| 
| Free a region of consistent memory you previously allocated.  dev,
| size and dma_handle must all be the same as those passed into
| dma_alloc_coherent().  cpu_addr must be the virtual address returned by
| the dma_alloc_coherent().
| 
| Note that unlike their sibling allocation calls, these routines
| may only be called with IRQs enabled.

Note that very last paragraph.  What this says is that it is explicitly
permitted to call dma_alloc_coherent() with IRQs disabled.

Now, the question is: is it safe to call map_vm_area() with IRQs disabled?
Well, map_vm_area() calls pud_alloc(), pmd_alloc(), and pte_alloc_kernel().
These functions all call into the kernel memory allocator *without*
GFP_ATOMIC - in other words, these allocations are permitted to sleep.
Except, IRQs are off, so it's a bug to call these functions from
dma_alloc_coherent().

Now, if we look at the previous code, it used ioremap_page_range().  This
has the same problem: it needs to allocate page tables, and it can only
do it via functions which may sleep.

If we go back even further, we find that the use of ioremap_page_range()
in dma_alloc_coherent() was introduced by:

commit e9da6e9905e639b0f842a244bc770b48ad0523e9
Author: Marek Szyprowski <m.szyprowski@samsung.com>
Date:   Mon Jul 30 09:11:33 2012 +0200

    ARM: dma-mapping: remove custom consistent dma region

which is the commit which removed my pre-allocated page tables for the
DMA re-mapping region - code which I explicitly had to specifically
avoid this issue.

Obviously, this isn't a big problem, because people haven't reported
that they've hit any of the might_sleep() checks in the memory
allocators, which I think is our only saving grace - but it's still
wrong to the specified calling conditions of the DMA API.

If the problem which you (Broadcom) are suffering from is down to the
issue I suspect (that being having mappings with different cache
attributes) then I'm not sure that there's anything we can realistically
do about that.  There's a number of issues which make it hard to see a
way forward.

One example is that if we allocate memory, we need to be able to change
(or remove) the cacheable mappings associated with that memory.  We'd
need to touch the L1 page table, either to change the attributes of the
section mapping, or to convert the section mapping to a L2 page table
pointer.  We need to change the attributes in a break-flush-make sequence
to avoid TLB conflicts.

However, those mappings may be shared between other CPUs in a SMP system.
So, we would need to flush the TLBs on other CPUs before we could proceed
to create replacement mappings.  That means something like stop_machine()
or sending (and waiting for completion) of an IPI to the other CPUs.  That
is totally impractical due to dma_alloc_coherent() being allowed to be
called with IRQs off.

I'll continue to think about it, but I don't see many possibilities to
satisfy dma_alloc_coherent()'s documented requirements other than by
pre-allocating a chunk of memory at boot time to be served out as
DMA-able memory for these horrid cases.

I don't see much point in keeping the map_vm_area() approach on ARM
even if we did fallback - if we're re-establishing mappings for
the surrounding pages in lowmem, we might as well insert appropriately
attributed mappings for the DMA memory as well.

On the face of it, it would be better to allocate one section at a
time, but my unfortunate experience is that 3.x kernels are a /lot/
more trigger happy with the OOM killer, and the chances of being able
to allocate 1MB of memory at a go after the system has been running
for a while is near-on impossible.  So I don't think that's a reality.

Even if we did break up section mappings in this way, it would also
mean that over time, we'd end up with much of lowmem mapped using 4K
page table entries, which would place significant pressure on the MMU
TLBs.

So, we might just be far better off pre-allocating enough "DMA
coherent" memory at boot time and be done with it.  Those who want
it dynamic can use CMA instead.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-05 15:06           ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 15:06 UTC (permalink / raw)
  To: Hante Meuleman
  Cc: linux-wireless, brcm80211-dev-list, Will Deacon, linux-kernel,
	Arend Van Spriel, David Miller, linux-arm-kernel,
	Marek Szyprowski

I've been doing more digging into the current DMA code, and I'm dismayed
to see that there's new bugs in it...

commit 513510ddba9650fc7da456eefeb0ead7632324f6
Author: Laura Abbott <lauraa@codeaurora.org>
Date:   Thu Oct 9 15:26:40 2014 -0700

    common: dma-mapping: introduce common remapping functions

This uses map_vm_area() to achieve the remapping of pages allocated inside
dma_alloc_coherent().  dma_alloc_coherent() is documented in a rather
round-about way in Documentation/DMA-API.txt:

| Part Ia - Using large DMA-coherent buffers
| ------------------------------------------
| 
| void *
| dma_alloc_coherent(struct device *dev, size_t size,
|                              dma_addr_t *dma_handle, gfp_t flag)
| 
| void
| dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
|                            dma_addr_t dma_handle)
| 
| Free a region of consistent memory you previously allocated.  dev,
| size and dma_handle must all be the same as those passed into
| dma_alloc_coherent().  cpu_addr must be the virtual address returned by
| the dma_alloc_coherent().
| 
| Note that unlike their sibling allocation calls, these routines
| may only be called with IRQs enabled.

Note that very last paragraph.  What this says is that it is explicitly
permitted to call dma_alloc_coherent() with IRQs disabled.

Now, the question is: is it safe to call map_vm_area() with IRQs disabled?
Well, map_vm_area() calls pud_alloc(), pmd_alloc(), and pte_alloc_kernel().
These functions all call into the kernel memory allocator *without*
GFP_ATOMIC - in other words, these allocations are permitted to sleep.
Except, IRQs are off, so it's a bug to call these functions from
dma_alloc_coherent().

Now, if we look at the previous code, it used ioremap_page_range().  This
has the same problem: it needs to allocate page tables, and it can only
do it via functions which may sleep.

If we go back even further, we find that the use of ioremap_page_range()
in dma_alloc_coherent() was introduced by:

commit e9da6e9905e639b0f842a244bc770b48ad0523e9
Author: Marek Szyprowski <m.szyprowski@samsung.com>
Date:   Mon Jul 30 09:11:33 2012 +0200

    ARM: dma-mapping: remove custom consistent dma region

which is the commit which removed my pre-allocated page tables for the
DMA re-mapping region - code which I explicitly had to specifically
avoid this issue.

Obviously, this isn't a big problem, because people haven't reported
that they've hit any of the might_sleep() checks in the memory
allocators, which I think is our only saving grace - but it's still
wrong to the specified calling conditions of the DMA API.

If the problem which you (Broadcom) are suffering from is down to the
issue I suspect (that being having mappings with different cache
attributes) then I'm not sure that there's anything we can realistically
do about that.  There's a number of issues which make it hard to see a
way forward.

One example is that if we allocate memory, we need to be able to change
(or remove) the cacheable mappings associated with that memory.  We'd
need to touch the L1 page table, either to change the attributes of the
section mapping, or to convert the section mapping to a L2 page table
pointer.  We need to change the attributes in a break-flush-make sequence
to avoid TLB conflicts.

However, those mappings may be shared between other CPUs in a SMP system.
So, we would need to flush the TLBs on other CPUs before we could proceed
to create replacement mappings.  That means something like stop_machine()
or sending (and waiting for completion) of an IPI to the other CPUs.  That
is totally impractical due to dma_alloc_coherent() being allowed to be
called with IRQs off.

I'll continue to think about it, but I don't see many possibilities to
satisfy dma_alloc_coherent()'s documented requirements other than by
pre-allocating a chunk of memory at boot time to be served out as
DMA-able memory for these horrid cases.

I don't see much point in keeping the map_vm_area() approach on ARM
even if we did fallback - if we're re-establishing mappings for
the surrounding pages in lowmem, we might as well insert appropriately
attributed mappings for the DMA memory as well.

On the face of it, it would be better to allocate one section at a
time, but my unfortunate experience is that 3.x kernels are a /lot/
more trigger happy with the OOM killer, and the chances of being able
to allocate 1MB of memory at a go after the system has been running
for a while is near-on impossible.  So I don't think that's a reality.

Even if we did break up section mappings in this way, it would also
mean that over time, we'd end up with much of lowmem mapped using 4K
page table entries, which would place significant pressure on the MMU
TLBs.

So, we might just be far better off pre-allocating enough "DMA
coherent" memory at boot time and be done with it.  Those who want
it dynamic can use CMA instead.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 15:06           ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 15:06 UTC (permalink / raw)
  To: linux-arm-kernel

I've been doing more digging into the current DMA code, and I'm dismayed
to see that there's new bugs in it...

commit 513510ddba9650fc7da456eefeb0ead7632324f6
Author: Laura Abbott <lauraa@codeaurora.org>
Date:   Thu Oct 9 15:26:40 2014 -0700

    common: dma-mapping: introduce common remapping functions

This uses map_vm_area() to achieve the remapping of pages allocated inside
dma_alloc_coherent().  dma_alloc_coherent() is documented in a rather
round-about way in Documentation/DMA-API.txt:

| Part Ia - Using large DMA-coherent buffers
| ------------------------------------------
| 
| void *
| dma_alloc_coherent(struct device *dev, size_t size,
|                              dma_addr_t *dma_handle, gfp_t flag)
| 
| void
| dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
|                            dma_addr_t dma_handle)
| 
| Free a region of consistent memory you previously allocated.  dev,
| size and dma_handle must all be the same as those passed into
| dma_alloc_coherent().  cpu_addr must be the virtual address returned by
| the dma_alloc_coherent().
| 
| Note that unlike their sibling allocation calls, these routines
| may only be called with IRQs enabled.

Note that very last paragraph.  What this says is that it is explicitly
permitted to call dma_alloc_coherent() with IRQs disabled.

Now, the question is: is it safe to call map_vm_area() with IRQs disabled?
Well, map_vm_area() calls pud_alloc(), pmd_alloc(), and pte_alloc_kernel().
These functions all call into the kernel memory allocator *without*
GFP_ATOMIC - in other words, these allocations are permitted to sleep.
Except, IRQs are off, so it's a bug to call these functions from
dma_alloc_coherent().

Now, if we look at the previous code, it used ioremap_page_range().  This
has the same problem: it needs to allocate page tables, and it can only
do it via functions which may sleep.

If we go back even further, we find that the use of ioremap_page_range()
in dma_alloc_coherent() was introduced by:

commit e9da6e9905e639b0f842a244bc770b48ad0523e9
Author: Marek Szyprowski <m.szyprowski@samsung.com>
Date:   Mon Jul 30 09:11:33 2012 +0200

    ARM: dma-mapping: remove custom consistent dma region

which is the commit which removed my pre-allocated page tables for the
DMA re-mapping region - code which I explicitly had to specifically
avoid this issue.

Obviously, this isn't a big problem, because people haven't reported
that they've hit any of the might_sleep() checks in the memory
allocators, which I think is our only saving grace - but it's still
wrong to the specified calling conditions of the DMA API.

If the problem which you (Broadcom) are suffering from is down to the
issue I suspect (that being having mappings with different cache
attributes) then I'm not sure that there's anything we can realistically
do about that.  There's a number of issues which make it hard to see a
way forward.

One example is that if we allocate memory, we need to be able to change
(or remove) the cacheable mappings associated with that memory.  We'd
need to touch the L1 page table, either to change the attributes of the
section mapping, or to convert the section mapping to a L2 page table
pointer.  We need to change the attributes in a break-flush-make sequence
to avoid TLB conflicts.

However, those mappings may be shared between other CPUs in a SMP system.
So, we would need to flush the TLBs on other CPUs before we could proceed
to create replacement mappings.  That means something like stop_machine()
or sending (and waiting for completion) of an IPI to the other CPUs.  That
is totally impractical due to dma_alloc_coherent() being allowed to be
called with IRQs off.

I'll continue to think about it, but I don't see many possibilities to
satisfy dma_alloc_coherent()'s documented requirements other than by
pre-allocating a chunk of memory at boot time to be served out as
DMA-able memory for these horrid cases.

I don't see much point in keeping the map_vm_area() approach on ARM
even if we did fallback - if we're re-establishing mappings for
the surrounding pages in lowmem, we might as well insert appropriately
attributed mappings for the DMA memory as well.

On the face of it, it would be better to allocate one section at a
time, but my unfortunate experience is that 3.x kernels are a /lot/
more trigger happy with the OOM killer, and the chances of being able
to allocate 1MB of memory at a go after the system has been running
for a while is near-on impossible.  So I don't think that's a reality.

Even if we did break up section mappings in this way, it would also
mean that over time, we'd end up with much of lowmem mapped using 4K
page table entries, which would place significant pressure on the MMU
TLBs.

So, we might just be far better off pre-allocating enough "DMA
coherent" memory at boot time and be done with it.  Those who want
it dynamic can use CMA instead.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05 11:11     ` Russell King - ARM Linux
  (?)
@ 2014-12-05 17:38       ` Catalin Marinas
  -1 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-05 17:38 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Arnd Bergmann, linux-wireless, brcm80211-dev-list, linux-kernel,
	Arend van Spriel, David Miller, linux-arm-kernel

On Fri, Dec 05, 2014 at 11:11:14AM +0000, Russell King - ARM Linux wrote:
> In any case, wouldn't using a u64 type for "address" be better - isn't
> "long long" 128-bit on 64-bit architectures?

No, it's still 64-bit. There is no 128-bit integer in the C standard.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-05 17:38       ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-05 17:38 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Arnd Bergmann, linux-wireless, brcm80211-dev-list, linux-kernel,
	Arend van Spriel, David Miller, linux-arm-kernel

On Fri, Dec 05, 2014 at 11:11:14AM +0000, Russell King - ARM Linux wrote:
> In any case, wouldn't using a u64 type for "address" be better - isn't
> "long long" 128-bit on 64-bit architectures?

No, it's still 64-bit. There is no 128-bit integer in the C standard.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 17:38       ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-05 17:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 05, 2014 at 11:11:14AM +0000, Russell King - ARM Linux wrote:
> In any case, wouldn't using a u64 type for "address" be better - isn't
> "long long" 128-bit on 64-bit architectures?

No, it's still 64-bit. There is no 128-bit integer in the C standard.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05 17:38       ` Catalin Marinas
  (?)
@ 2014-12-05 18:24         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 18:24 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Arnd Bergmann, linux-wireless, brcm80211-dev-list, linux-kernel,
	Arend van Spriel, David Miller, linux-arm-kernel

On Fri, Dec 05, 2014 at 05:38:39PM +0000, Catalin Marinas wrote:
> On Fri, Dec 05, 2014 at 11:11:14AM +0000, Russell King - ARM Linux wrote:
> > In any case, wouldn't using a u64 type for "address" be better - isn't
> > "long long" 128-bit on 64-bit architectures?
> 
> No, it's still 64-bit. There is no 128-bit integer in the C standard.

Actually, that's a fallicy.

The C99 standard (like previous versions) does not define exactly the
number of bits in each type.  It defines ranks of type, and says that
lower ranks are a subrange of integers with higher ranks (for the same
signed-ness.)  See section 6.2.5.

So, it merely states that:

range(char) <= range(short) <= range(int) <= range(long) <= range(long long)

So, an implementation could have:

char: 8  short: 16 int: 16 long: 32 long long: 64
char: 8  short: 16 int: 32 long: 32 long long: 64
char: 8  short: 16 int: 32 long: 64 long long: 64
char: 8  short: 16 int: 64 long: 64 long long: 64

or even:

char: 8  short: 16 int: 32 long: 64 long long: 128

and that would still be compliant with C99, since it continues to meet
the criteria about the required data types specified in the standard.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-05 18:24         ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 18:24 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Arnd Bergmann, linux-wireless, brcm80211-dev-list, linux-kernel,
	Arend van Spriel, David Miller, linux-arm-kernel

On Fri, Dec 05, 2014 at 05:38:39PM +0000, Catalin Marinas wrote:
> On Fri, Dec 05, 2014 at 11:11:14AM +0000, Russell King - ARM Linux wrote:
> > In any case, wouldn't using a u64 type for "address" be better - isn't
> > "long long" 128-bit on 64-bit architectures?
> 
> No, it's still 64-bit. There is no 128-bit integer in the C standard.

Actually, that's a fallicy.

The C99 standard (like previous versions) does not define exactly the
number of bits in each type.  It defines ranks of type, and says that
lower ranks are a subrange of integers with higher ranks (for the same
signed-ness.)  See section 6.2.5.

So, it merely states that:

range(char) <= range(short) <= range(int) <= range(long) <= range(long long)

So, an implementation could have:

char: 8  short: 16 int: 16 long: 32 long long: 64
char: 8  short: 16 int: 32 long: 32 long long: 64
char: 8  short: 16 int: 32 long: 64 long long: 64
char: 8  short: 16 int: 64 long: 64 long long: 64

or even:

char: 8  short: 16 int: 32 long: 64 long long: 128

and that would still be compliant with C99, since it continues to meet
the criteria about the required data types specified in the standard.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 18:24         ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 18:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 05, 2014 at 05:38:39PM +0000, Catalin Marinas wrote:
> On Fri, Dec 05, 2014 at 11:11:14AM +0000, Russell King - ARM Linux wrote:
> > In any case, wouldn't using a u64 type for "address" be better - isn't
> > "long long" 128-bit on 64-bit architectures?
> 
> No, it's still 64-bit. There is no 128-bit integer in the C standard.

Actually, that's a fallicy.

The C99 standard (like previous versions) does not define exactly the
number of bits in each type.  It defines ranks of type, and says that
lower ranks are a subrange of integers with higher ranks (for the same
signed-ness.)  See section 6.2.5.

So, it merely states that:

range(char) <= range(short) <= range(int) <= range(long) <= range(long long)

So, an implementation could have:

char: 8  short: 16 int: 16 long: 32 long long: 64
char: 8  short: 16 int: 32 long: 32 long long: 64
char: 8  short: 16 int: 32 long: 64 long long: 64
char: 8  short: 16 int: 64 long: 64 long long: 64

or even:

char: 8  short: 16 int: 32 long: 64 long long: 128

and that would still be compliant with C99, since it continues to meet
the criteria about the required data types specified in the standard.

-- 
FTTC broadband for 0.8mile line: currently@9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05 15:06           ` Russell King - ARM Linux
  (?)
@ 2014-12-05 18:28             ` Catalin Marinas
  -1 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-05 18:28 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Hante Meuleman, linux-wireless, brcm80211-dev-list, linux-kernel,
	Will Deacon, Arend Van Spriel, David Miller, linux-arm-kernel,
	Marek Szyprowski

On Fri, Dec 05, 2014 at 03:06:48PM +0000, Russell King - ARM Linux wrote:
> I've been doing more digging into the current DMA code, and I'm dismayed
> to see that there's new bugs in it...
> 
> commit 513510ddba9650fc7da456eefeb0ead7632324f6
> Author: Laura Abbott <lauraa@codeaurora.org>
> Date:   Thu Oct 9 15:26:40 2014 -0700
> 
>     common: dma-mapping: introduce common remapping functions
> 
> This uses map_vm_area() to achieve the remapping of pages allocated inside
> dma_alloc_coherent().  dma_alloc_coherent() is documented in a rather
> round-about way in Documentation/DMA-API.txt:
> 
> | Part Ia - Using large DMA-coherent buffers
> | ------------------------------------------
> | 
> | void *
> | dma_alloc_coherent(struct device *dev, size_t size,
> |                              dma_addr_t *dma_handle, gfp_t flag)
> | 
> | void
> | dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
> |                            dma_addr_t dma_handle)
> | 
> | Free a region of consistent memory you previously allocated.  dev,
> | size and dma_handle must all be the same as those passed into
> | dma_alloc_coherent().  cpu_addr must be the virtual address returned by
> | the dma_alloc_coherent().
> | 
> | Note that unlike their sibling allocation calls, these routines
> | may only be called with IRQs enabled.
> 
> Note that very last paragraph.  What this says is that it is explicitly
> permitted to call dma_alloc_coherent() with IRQs disabled.

This is solved by using a pre-allocated, pre-mapped atomic_pool which
avoids any further mapping. __dma_alloc() calls __alloc_from_pool() when
!__GFP_WAIT.

This code got pretty complex and we may find bugs. It can be simplified
by a pre-allocated non-cacheable region that is safe in atomic context
(how big you allocate this is hard to say).

> If the problem which you (Broadcom) are suffering from is down to the
> issue I suspect (that being having mappings with different cache
> attributes) then I'm not sure that there's anything we can realistically
> do about that.  There's a number of issues which make it hard to see a
> way forward.

I'm still puzzled by this problem, so I don't have any suggestion yet. I
wouldn't blame the mismatched attributes yet as I haven't seen such
problem in practice (but you never know).

How does the DT describe this device? Could it have some dma-coherent
property in there that causes dma_alloc_coherent() to create a cacheable
memory?

The reverse could also cause problems: the device is coherent but the
CPU creates a non-cacheable mapping.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-05 18:28             ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-05 18:28 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Hante Meuleman, linux-wireless, brcm80211-dev-list, linux-kernel,
	Will Deacon, Arend Van Spriel, David Miller, linux-arm-kernel,
	Marek Szyprowski

On Fri, Dec 05, 2014 at 03:06:48PM +0000, Russell King - ARM Linux wrote:
> I've been doing more digging into the current DMA code, and I'm dismayed
> to see that there's new bugs in it...
> 
> commit 513510ddba9650fc7da456eefeb0ead7632324f6
> Author: Laura Abbott <lauraa@codeaurora.org>
> Date:   Thu Oct 9 15:26:40 2014 -0700
> 
>     common: dma-mapping: introduce common remapping functions
> 
> This uses map_vm_area() to achieve the remapping of pages allocated inside
> dma_alloc_coherent().  dma_alloc_coherent() is documented in a rather
> round-about way in Documentation/DMA-API.txt:
> 
> | Part Ia - Using large DMA-coherent buffers
> | ------------------------------------------
> | 
> | void *
> | dma_alloc_coherent(struct device *dev, size_t size,
> |                              dma_addr_t *dma_handle, gfp_t flag)
> | 
> | void
> | dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
> |                            dma_addr_t dma_handle)
> | 
> | Free a region of consistent memory you previously allocated.  dev,
> | size and dma_handle must all be the same as those passed into
> | dma_alloc_coherent().  cpu_addr must be the virtual address returned by
> | the dma_alloc_coherent().
> | 
> | Note that unlike their sibling allocation calls, these routines
> | may only be called with IRQs enabled.
> 
> Note that very last paragraph.  What this says is that it is explicitly
> permitted to call dma_alloc_coherent() with IRQs disabled.

This is solved by using a pre-allocated, pre-mapped atomic_pool which
avoids any further mapping. __dma_alloc() calls __alloc_from_pool() when
!__GFP_WAIT.

This code got pretty complex and we may find bugs. It can be simplified
by a pre-allocated non-cacheable region that is safe in atomic context
(how big you allocate this is hard to say).

> If the problem which you (Broadcom) are suffering from is down to the
> issue I suspect (that being having mappings with different cache
> attributes) then I'm not sure that there's anything we can realistically
> do about that.  There's a number of issues which make it hard to see a
> way forward.

I'm still puzzled by this problem, so I don't have any suggestion yet. I
wouldn't blame the mismatched attributes yet as I haven't seen such
problem in practice (but you never know).

How does the DT describe this device? Could it have some dma-coherent
property in there that causes dma_alloc_coherent() to create a cacheable
memory?

The reverse could also cause problems: the device is coherent but the
CPU creates a non-cacheable mapping.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 18:28             ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-05 18:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 05, 2014 at 03:06:48PM +0000, Russell King - ARM Linux wrote:
> I've been doing more digging into the current DMA code, and I'm dismayed
> to see that there's new bugs in it...
> 
> commit 513510ddba9650fc7da456eefeb0ead7632324f6
> Author: Laura Abbott <lauraa@codeaurora.org>
> Date:   Thu Oct 9 15:26:40 2014 -0700
> 
>     common: dma-mapping: introduce common remapping functions
> 
> This uses map_vm_area() to achieve the remapping of pages allocated inside
> dma_alloc_coherent().  dma_alloc_coherent() is documented in a rather
> round-about way in Documentation/DMA-API.txt:
> 
> | Part Ia - Using large DMA-coherent buffers
> | ------------------------------------------
> | 
> | void *
> | dma_alloc_coherent(struct device *dev, size_t size,
> |                              dma_addr_t *dma_handle, gfp_t flag)
> | 
> | void
> | dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
> |                            dma_addr_t dma_handle)
> | 
> | Free a region of consistent memory you previously allocated.  dev,
> | size and dma_handle must all be the same as those passed into
> | dma_alloc_coherent().  cpu_addr must be the virtual address returned by
> | the dma_alloc_coherent().
> | 
> | Note that unlike their sibling allocation calls, these routines
> | may only be called with IRQs enabled.
> 
> Note that very last paragraph.  What this says is that it is explicitly
> permitted to call dma_alloc_coherent() with IRQs disabled.

This is solved by using a pre-allocated, pre-mapped atomic_pool which
avoids any further mapping. __dma_alloc() calls __alloc_from_pool() when
!__GFP_WAIT.

This code got pretty complex and we may find bugs. It can be simplified
by a pre-allocated non-cacheable region that is safe in atomic context
(how big you allocate this is hard to say).

> If the problem which you (Broadcom) are suffering from is down to the
> issue I suspect (that being having mappings with different cache
> attributes) then I'm not sure that there's anything we can realistically
> do about that.  There's a number of issues which make it hard to see a
> way forward.

I'm still puzzled by this problem, so I don't have any suggestion yet. I
wouldn't blame the mismatched attributes yet as I haven't seen such
problem in practice (but you never know).

How does the DT describe this device? Could it have some dma-coherent
property in there that causes dma_alloc_coherent() to create a cacheable
memory?

The reverse could also cause problems: the device is coherent but the
CPU creates a non-cacheable mapping.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05 18:24         ` Russell King - ARM Linux
  (?)
@ 2014-12-05 18:31           ` Catalin Marinas
  -1 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-05 18:31 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Arnd Bergmann, linux-wireless, brcm80211-dev-list, linux-kernel,
	Arend van Spriel, David Miller, linux-arm-kernel

On Fri, Dec 05, 2014 at 06:24:43PM +0000, Russell King - ARM Linux wrote:
> On Fri, Dec 05, 2014 at 05:38:39PM +0000, Catalin Marinas wrote:
> > On Fri, Dec 05, 2014 at 11:11:14AM +0000, Russell King - ARM Linux wrote:
> > > In any case, wouldn't using a u64 type for "address" be better - isn't
> > > "long long" 128-bit on 64-bit architectures?
> > 
> > No, it's still 64-bit. There is no 128-bit integer in the C standard.
> 
> Actually, that's a fallicy.
> 
> The C99 standard (like previous versions) does not define exactly the
> number of bits in each type.  It defines ranks of type, and says that
> lower ranks are a subrange of integers with higher ranks (for the same
> signed-ness.)  See section 6.2.5.
> 
> So, it merely states that:
> 
> range(char) <= range(short) <= range(int) <= range(long) <= range(long long)

You are probably right, I haven't checked. But the ABI we use in Linux
for 64-bit, LP64, defines long long as 64-bit. Gcc has a int128_t type
but it's specific to this toolchain.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-05 18:31           ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-05 18:31 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Arnd Bergmann, linux-wireless, brcm80211-dev-list, linux-kernel,
	Arend van Spriel, David Miller, linux-arm-kernel

On Fri, Dec 05, 2014 at 06:24:43PM +0000, Russell King - ARM Linux wrote:
> On Fri, Dec 05, 2014 at 05:38:39PM +0000, Catalin Marinas wrote:
> > On Fri, Dec 05, 2014 at 11:11:14AM +0000, Russell King - ARM Linux wrote:
> > > In any case, wouldn't using a u64 type for "address" be better - isn't
> > > "long long" 128-bit on 64-bit architectures?
> > 
> > No, it's still 64-bit. There is no 128-bit integer in the C standard.
> 
> Actually, that's a fallicy.
> 
> The C99 standard (like previous versions) does not define exactly the
> number of bits in each type.  It defines ranks of type, and says that
> lower ranks are a subrange of integers with higher ranks (for the same
> signed-ness.)  See section 6.2.5.
> 
> So, it merely states that:
> 
> range(char) <= range(short) <= range(int) <= range(long) <= range(long long)

You are probably right, I haven't checked. But the ABI we use in Linux
for 64-bit, LP64, defines long long as 64-bit. Gcc has a int128_t type
but it's specific to this toolchain.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 18:31           ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-05 18:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 05, 2014 at 06:24:43PM +0000, Russell King - ARM Linux wrote:
> On Fri, Dec 05, 2014 at 05:38:39PM +0000, Catalin Marinas wrote:
> > On Fri, Dec 05, 2014 at 11:11:14AM +0000, Russell King - ARM Linux wrote:
> > > In any case, wouldn't using a u64 type for "address" be better - isn't
> > > "long long" 128-bit on 64-bit architectures?
> > 
> > No, it's still 64-bit. There is no 128-bit integer in the C standard.
> 
> Actually, that's a fallicy.
> 
> The C99 standard (like previous versions) does not define exactly the
> number of bits in each type.  It defines ranks of type, and says that
> lower ranks are a subrange of integers with higher ranks (for the same
> signed-ness.)  See section 6.2.5.
> 
> So, it merely states that:
> 
> range(char) <= range(short) <= range(int) <= range(long) <= range(long long)

You are probably right, I haven't checked. But the ABI we use in Linux
for 64-bit, LP64, defines long long as 64-bit. Gcc has a int128_t type
but it's specific to this toolchain.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05  9:22 ` Arend van Spriel
  (?)
@ 2014-12-05 18:39   ` Catalin Marinas
  -1 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-05 18:39 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Russell King, linux-wireless, brcm80211-dev-list, David Miller,
	linux-arm-kernel, linux-kernel

On Fri, Dec 05, 2014 at 09:22:22AM +0000, Arend van Spriel wrote:
> For our brcm80211 development we are working on getting brcmfmac driver
> up and running on a Broadcom ARM-based platform. The wireless device is
> a PCIe device, which is hooked up to the system behind a PCIe host
> bridge, and we transfer information between host and device using a
> descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> tested on x86 and seen no issue. However, on this ARM platform
> (single-core A9) we detect occasionally that the descriptor content is
> invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> retried a number of times if the problem persists. Actually, found out
> that someone made a mistake by using virt_to_dma(va) to get the
> dma_handle parameter. So probably we only provided a delay in the retry
> loop. After fixing that a single call to dma_sync_single_for_cpu() is
> sufficient. The DMA-API-HOWTO clearly states that:

Does your system have an L2 cache? What's the SoC topology, can PCIe see
such L2 cache (or snoop the L1 caches)?

Also, are you certain that dma_alloc_coherent() ends up creating a
non-cacheable mapping in Linux (this call translates to a function
pointer call which may or may not create non-cacheable memory, depending
on the "dma-coherent" property passed via DT).

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-05 18:39   ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-05 18:39 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Russell King, linux-wireless, brcm80211-dev-list, David Miller,
	linux-arm-kernel, linux-kernel

On Fri, Dec 05, 2014 at 09:22:22AM +0000, Arend van Spriel wrote:
> For our brcm80211 development we are working on getting brcmfmac driver
> up and running on a Broadcom ARM-based platform. The wireless device is
> a PCIe device, which is hooked up to the system behind a PCIe host
> bridge, and we transfer information between host and device using a
> descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> tested on x86 and seen no issue. However, on this ARM platform
> (single-core A9) we detect occasionally that the descriptor content is
> invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> retried a number of times if the problem persists. Actually, found out
> that someone made a mistake by using virt_to_dma(va) to get the
> dma_handle parameter. So probably we only provided a delay in the retry
> loop. After fixing that a single call to dma_sync_single_for_cpu() is
> sufficient. The DMA-API-HOWTO clearly states that:

Does your system have an L2 cache? What's the SoC topology, can PCIe see
such L2 cache (or snoop the L1 caches)?

Also, are you certain that dma_alloc_coherent() ends up creating a
non-cacheable mapping in Linux (this call translates to a function
pointer call which may or may not create non-cacheable memory, depending
on the "dma-coherent" property passed via DT).

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 18:39   ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-05 18:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 05, 2014 at 09:22:22AM +0000, Arend van Spriel wrote:
> For our brcm80211 development we are working on getting brcmfmac driver
> up and running on a Broadcom ARM-based platform. The wireless device is
> a PCIe device, which is hooked up to the system behind a PCIe host
> bridge, and we transfer information between host and device using a
> descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> tested on x86 and seen no issue. However, on this ARM platform
> (single-core A9) we detect occasionally that the descriptor content is
> invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> retried a number of times if the problem persists. Actually, found out
> that someone made a mistake by using virt_to_dma(va) to get the
> dma_handle parameter. So probably we only provided a delay in the retry
> loop. After fixing that a single call to dma_sync_single_for_cpu() is
> sufficient. The DMA-API-HOWTO clearly states that:

Does your system have an L2 cache? What's the SoC topology, can PCIe see
such L2 cache (or snoop the L1 caches)?

Also, are you certain that dma_alloc_coherent() ends up creating a
non-cacheable mapping in Linux (this call translates to a function
pointer call which may or may not create non-cacheable memory, depending
on the "dma-coherent" property passed via DT).

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05 18:39   ` Catalin Marinas
  (?)
@ 2014-12-05 18:53     ` Catalin Marinas
  -1 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-05 18:53 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Russell King, linux-wireless, brcm80211-dev-list, David Miller,
	linux-arm-kernel, linux-kernel

On Fri, Dec 05, 2014 at 06:39:45PM +0000, Catalin Marinas wrote:
> On Fri, Dec 05, 2014 at 09:22:22AM +0000, Arend van Spriel wrote:
> > For our brcm80211 development we are working on getting brcmfmac driver
> > up and running on a Broadcom ARM-based platform. The wireless device is
> > a PCIe device, which is hooked up to the system behind a PCIe host
> > bridge, and we transfer information between host and device using a
> > descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> > tested on x86 and seen no issue. However, on this ARM platform
> > (single-core A9) we detect occasionally that the descriptor content is
> > invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> > retried a number of times if the problem persists. Actually, found out
> > that someone made a mistake by using virt_to_dma(va) to get the
> > dma_handle parameter. So probably we only provided a delay in the retry
> > loop. After fixing that a single call to dma_sync_single_for_cpu() is
> > sufficient. The DMA-API-HOWTO clearly states that:
> 
> Does your system have an L2 cache? What's the SoC topology, can PCIe see
> such L2 cache (or snoop the L1 caches)?

BTW, if you really have a PL310-like L2 cache, have a look at some
patches (I've seen similar symptoms) and make sure your configuration is
correct:

http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6395/1

http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1

The first one is vexpress specific. The second one was eventually
discarded by Russell (I don't remember the reason, I guess it's because
SoC code is supposed to set the right bits in there anyway). In your
case, such bits may be set up by firmware, so Linux cannot fix anything
up.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-05 18:53     ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-05 18:53 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Russell King, linux-wireless, brcm80211-dev-list, David Miller,
	linux-arm-kernel, linux-kernel

On Fri, Dec 05, 2014 at 06:39:45PM +0000, Catalin Marinas wrote:
> On Fri, Dec 05, 2014 at 09:22:22AM +0000, Arend van Spriel wrote:
> > For our brcm80211 development we are working on getting brcmfmac driver
> > up and running on a Broadcom ARM-based platform. The wireless device is
> > a PCIe device, which is hooked up to the system behind a PCIe host
> > bridge, and we transfer information between host and device using a
> > descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> > tested on x86 and seen no issue. However, on this ARM platform
> > (single-core A9) we detect occasionally that the descriptor content is
> > invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> > retried a number of times if the problem persists. Actually, found out
> > that someone made a mistake by using virt_to_dma(va) to get the
> > dma_handle parameter. So probably we only provided a delay in the retry
> > loop. After fixing that a single call to dma_sync_single_for_cpu() is
> > sufficient. The DMA-API-HOWTO clearly states that:
> 
> Does your system have an L2 cache? What's the SoC topology, can PCIe see
> such L2 cache (or snoop the L1 caches)?

BTW, if you really have a PL310-like L2 cache, have a look at some
patches (I've seen similar symptoms) and make sure your configuration is
correct:

http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6395/1

http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1

The first one is vexpress specific. The second one was eventually
discarded by Russell (I don't remember the reason, I guess it's because
SoC code is supposed to set the right bits in there anyway). In your
case, such bits may be set up by firmware, so Linux cannot fix anything
up.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 18:53     ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-05 18:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 05, 2014 at 06:39:45PM +0000, Catalin Marinas wrote:
> On Fri, Dec 05, 2014 at 09:22:22AM +0000, Arend van Spriel wrote:
> > For our brcm80211 development we are working on getting brcmfmac driver
> > up and running on a Broadcom ARM-based platform. The wireless device is
> > a PCIe device, which is hooked up to the system behind a PCIe host
> > bridge, and we transfer information between host and device using a
> > descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
> > tested on x86 and seen no issue. However, on this ARM platform
> > (single-core A9) we detect occasionally that the descriptor content is
> > invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
> > retried a number of times if the problem persists. Actually, found out
> > that someone made a mistake by using virt_to_dma(va) to get the
> > dma_handle parameter. So probably we only provided a delay in the retry
> > loop. After fixing that a single call to dma_sync_single_for_cpu() is
> > sufficient. The DMA-API-HOWTO clearly states that:
> 
> Does your system have an L2 cache? What's the SoC topology, can PCIe see
> such L2 cache (or snoop the L1 caches)?

BTW, if you really have a PL310-like L2 cache, have a look at some
patches (I've seen similar symptoms) and make sure your configuration is
correct:

http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6395/1

http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1

The first one is vexpress specific. The second one was eventually
discarded by Russell (I don't remember the reason, I guess it's because
SoC code is supposed to set the right bits in there anyway). In your
case, such bits may be set up by firmware, so Linux cannot fix anything
up.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05 18:28             ` Catalin Marinas
  (?)
@ 2014-12-05 19:22               ` Arend van Spriel
  -1 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-05 19:22 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Russell King - ARM Linux, Hante Meuleman, linux-wireless,
	brcm80211-dev-list, linux-kernel, Will Deacon, David Miller,
	linux-arm-kernel, Marek Szyprowski

On 12/05/14 19:28, Catalin Marinas wrote:
> On Fri, Dec 05, 2014 at 03:06:48PM +0000, Russell King - ARM Linux wrote:
>> I've been doing more digging into the current DMA code, and I'm dismayed
>> to see that there's new bugs in it...
>>
>> commit 513510ddba9650fc7da456eefeb0ead7632324f6
>> Author: Laura Abbott<lauraa@codeaurora.org>
>> Date:   Thu Oct 9 15:26:40 2014 -0700
>>
>>      common: dma-mapping: introduce common remapping functions
>>
>> This uses map_vm_area() to achieve the remapping of pages allocated inside
>> dma_alloc_coherent().  dma_alloc_coherent() is documented in a rather
>> round-about way in Documentation/DMA-API.txt:
>>
>> | Part Ia - Using large DMA-coherent buffers
>> | ------------------------------------------
>> |
>> | void *
>> | dma_alloc_coherent(struct device *dev, size_t size,
>> |                              dma_addr_t *dma_handle, gfp_t flag)
>> |
>> | void
>> | dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
>> |                            dma_addr_t dma_handle)
>> |
>> | Free a region of consistent memory you previously allocated.  dev,
>> | size and dma_handle must all be the same as those passed into
>> | dma_alloc_coherent().  cpu_addr must be the virtual address returned by
>> | the dma_alloc_coherent().
>> |
>> | Note that unlike their sibling allocation calls, these routines
>> | may only be called with IRQs enabled.
>>
>> Note that very last paragraph.  What this says is that it is explicitly
>> permitted to call dma_alloc_coherent() with IRQs disabled.
>
> This is solved by using a pre-allocated, pre-mapped atomic_pool which
> avoids any further mapping. __dma_alloc() calls __alloc_from_pool() when
> !__GFP_WAIT.

So we are actually calling dma_alloc_coherent() with GFP_KERNEL during 
device probe. That last paragraph Russell pointed out seems to suggest 
this is not allowed.

> This code got pretty complex and we may find bugs. It can be simplified
> by a pre-allocated non-cacheable region that is safe in atomic context
> (how big you allocate this is hard to say).
>
>> If the problem which you (Broadcom) are suffering from is down to the
>> issue I suspect (that being having mappings with different cache
>> attributes) then I'm not sure that there's anything we can realistically
>> do about that.  There's a number of issues which make it hard to see a
>> way forward.
>
> I'm still puzzled by this problem, so I don't have any suggestion yet. I
> wouldn't blame the mismatched attributes yet as I haven't seen such
> problem in practice (but you never know).
>
> How does the DT describe this device? Could it have some dma-coherent
> property in there that causes dma_alloc_coherent() to create a cacheable
> memory?

Ok. Will add it to our todo list: check DTS files for dma-coherent property.

Thanks,
Arend

> The reverse could also cause problems: the device is coherent but the
> CPU creates a non-cacheable mapping.
>


^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-05 19:22               ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-05 19:22 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Russell King - ARM Linux, Hante Meuleman, linux-wireless,
	brcm80211-dev-list, linux-kernel, Will Deacon, David Miller,
	linux-arm-kernel, Marek Szyprowski

On 12/05/14 19:28, Catalin Marinas wrote:
> On Fri, Dec 05, 2014 at 03:06:48PM +0000, Russell King - ARM Linux wrote:
>> I've been doing more digging into the current DMA code, and I'm dismayed
>> to see that there's new bugs in it...
>>
>> commit 513510ddba9650fc7da456eefeb0ead7632324f6
>> Author: Laura Abbott<lauraa@codeaurora.org>
>> Date:   Thu Oct 9 15:26:40 2014 -0700
>>
>>      common: dma-mapping: introduce common remapping functions
>>
>> This uses map_vm_area() to achieve the remapping of pages allocated inside
>> dma_alloc_coherent().  dma_alloc_coherent() is documented in a rather
>> round-about way in Documentation/DMA-API.txt:
>>
>> | Part Ia - Using large DMA-coherent buffers
>> | ------------------------------------------
>> |
>> | void *
>> | dma_alloc_coherent(struct device *dev, size_t size,
>> |                              dma_addr_t *dma_handle, gfp_t flag)
>> |
>> | void
>> | dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
>> |                            dma_addr_t dma_handle)
>> |
>> | Free a region of consistent memory you previously allocated.  dev,
>> | size and dma_handle must all be the same as those passed into
>> | dma_alloc_coherent().  cpu_addr must be the virtual address returned by
>> | the dma_alloc_coherent().
>> |
>> | Note that unlike their sibling allocation calls, these routines
>> | may only be called with IRQs enabled.
>>
>> Note that very last paragraph.  What this says is that it is explicitly
>> permitted to call dma_alloc_coherent() with IRQs disabled.
>
> This is solved by using a pre-allocated, pre-mapped atomic_pool which
> avoids any further mapping. __dma_alloc() calls __alloc_from_pool() when
> !__GFP_WAIT.

So we are actually calling dma_alloc_coherent() with GFP_KERNEL during 
device probe. That last paragraph Russell pointed out seems to suggest 
this is not allowed.

> This code got pretty complex and we may find bugs. It can be simplified
> by a pre-allocated non-cacheable region that is safe in atomic context
> (how big you allocate this is hard to say).
>
>> If the problem which you (Broadcom) are suffering from is down to the
>> issue I suspect (that being having mappings with different cache
>> attributes) then I'm not sure that there's anything we can realistically
>> do about that.  There's a number of issues which make it hard to see a
>> way forward.
>
> I'm still puzzled by this problem, so I don't have any suggestion yet. I
> wouldn't blame the mismatched attributes yet as I haven't seen such
> problem in practice (but you never know).
>
> How does the DT describe this device? Could it have some dma-coherent
> property in there that causes dma_alloc_coherent() to create a cacheable
> memory?

Ok. Will add it to our todo list: check DTS files for dma-coherent property.

Thanks,
Arend

> The reverse could also cause problems: the device is coherent but the
> CPU creates a non-cacheable mapping.
>


^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 19:22               ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-05 19:22 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/05/14 19:28, Catalin Marinas wrote:
> On Fri, Dec 05, 2014 at 03:06:48PM +0000, Russell King - ARM Linux wrote:
>> I've been doing more digging into the current DMA code, and I'm dismayed
>> to see that there's new bugs in it...
>>
>> commit 513510ddba9650fc7da456eefeb0ead7632324f6
>> Author: Laura Abbott<lauraa@codeaurora.org>
>> Date:   Thu Oct 9 15:26:40 2014 -0700
>>
>>      common: dma-mapping: introduce common remapping functions
>>
>> This uses map_vm_area() to achieve the remapping of pages allocated inside
>> dma_alloc_coherent().  dma_alloc_coherent() is documented in a rather
>> round-about way in Documentation/DMA-API.txt:
>>
>> | Part Ia - Using large DMA-coherent buffers
>> | ------------------------------------------
>> |
>> | void *
>> | dma_alloc_coherent(struct device *dev, size_t size,
>> |                              dma_addr_t *dma_handle, gfp_t flag)
>> |
>> | void
>> | dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
>> |                            dma_addr_t dma_handle)
>> |
>> | Free a region of consistent memory you previously allocated.  dev,
>> | size and dma_handle must all be the same as those passed into
>> | dma_alloc_coherent().  cpu_addr must be the virtual address returned by
>> | the dma_alloc_coherent().
>> |
>> | Note that unlike their sibling allocation calls, these routines
>> | may only be called with IRQs enabled.
>>
>> Note that very last paragraph.  What this says is that it is explicitly
>> permitted to call dma_alloc_coherent() with IRQs disabled.
>
> This is solved by using a pre-allocated, pre-mapped atomic_pool which
> avoids any further mapping. __dma_alloc() calls __alloc_from_pool() when
> !__GFP_WAIT.

So we are actually calling dma_alloc_coherent() with GFP_KERNEL during 
device probe. That last paragraph Russell pointed out seems to suggest 
this is not allowed.

> This code got pretty complex and we may find bugs. It can be simplified
> by a pre-allocated non-cacheable region that is safe in atomic context
> (how big you allocate this is hard to say).
>
>> If the problem which you (Broadcom) are suffering from is down to the
>> issue I suspect (that being having mappings with different cache
>> attributes) then I'm not sure that there's anything we can realistically
>> do about that.  There's a number of issues which make it hard to see a
>> way forward.
>
> I'm still puzzled by this problem, so I don't have any suggestion yet. I
> wouldn't blame the mismatched attributes yet as I haven't seen such
> problem in practice (but you never know).
>
> How does the DT describe this device? Could it have some dma-coherent
> property in there that causes dma_alloc_coherent() to create a cacheable
> memory?

Ok. Will add it to our todo list: check DTS files for dma-coherent property.

Thanks,
Arend

> The reverse could also cause problems: the device is coherent but the
> CPU creates a non-cacheable mapping.
>

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05 19:22               ` Arend van Spriel
  (?)
@ 2014-12-05 19:25                 ` Russell King - ARM Linux
  -1 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 19:25 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Catalin Marinas, Hante Meuleman, linux-wireless,
	brcm80211-dev-list, linux-kernel, Will Deacon, David Miller,
	linux-arm-kernel, Marek Szyprowski

On Fri, Dec 05, 2014 at 08:22:05PM +0100, Arend van Spriel wrote:
> On 12/05/14 19:28, Catalin Marinas wrote:
> >This is solved by using a pre-allocated, pre-mapped atomic_pool which
> >avoids any further mapping. __dma_alloc() calls __alloc_from_pool() when
> >!__GFP_WAIT.
> 
> So we are actually calling dma_alloc_coherent() with GFP_KERNEL during
> device probe. That last paragraph Russell pointed out seems to suggest this
> is not allowed.

device probe is a schedulable, sleepable context, so dma_alloc_coherent()
is fine there.  As Catalin points out, and as I realised after sending
them ail, it does check for __GFP_WAIT and uses a smaller atomic pool
for those allocations.  This explains why no one has hit any warnings in
map_vm_area.

So, it's safe from atomic contexts after all.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-05 19:25                 ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 19:25 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Catalin Marinas, Hante Meuleman, linux-wireless,
	brcm80211-dev-list, linux-kernel, Will Deacon, David Miller,
	linux-arm-kernel, Marek Szyprowski

On Fri, Dec 05, 2014 at 08:22:05PM +0100, Arend van Spriel wrote:
> On 12/05/14 19:28, Catalin Marinas wrote:
> >This is solved by using a pre-allocated, pre-mapped atomic_pool which
> >avoids any further mapping. __dma_alloc() calls __alloc_from_pool() when
> >!__GFP_WAIT.
> 
> So we are actually calling dma_alloc_coherent() with GFP_KERNEL during
> device probe. That last paragraph Russell pointed out seems to suggest this
> is not allowed.

device probe is a schedulable, sleepable context, so dma_alloc_coherent()
is fine there.  As Catalin points out, and as I realised after sending
them ail, it does check for __GFP_WAIT and uses a smaller atomic pool
for those allocations.  This explains why no one has hit any warnings in
map_vm_area.

So, it's safe from atomic contexts after all.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 19:25                 ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-05 19:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 05, 2014 at 08:22:05PM +0100, Arend van Spriel wrote:
> On 12/05/14 19:28, Catalin Marinas wrote:
> >This is solved by using a pre-allocated, pre-mapped atomic_pool which
> >avoids any further mapping. __dma_alloc() calls __alloc_from_pool() when
> >!__GFP_WAIT.
> 
> So we are actually calling dma_alloc_coherent() with GFP_KERNEL during
> device probe. That last paragraph Russell pointed out seems to suggest this
> is not allowed.

device probe is a schedulable, sleepable context, so dma_alloc_coherent()
is fine there.  As Catalin points out, and as I realised after sending
them ail, it does check for __GFP_WAIT and uses a smaller atomic pool
for those allocations.  This explains why no one has hit any warnings in
map_vm_area.

So, it's safe from atomic contexts after all.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05 18:53     ` Catalin Marinas
  (?)
@ 2014-12-05 19:50       ` Arend van Spriel
  -1 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-05 19:50 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Russell King, linux-wireless, brcm80211-dev-list, David Miller,
	linux-arm-kernel, linux-kernel

On 12/05/14 19:53, Catalin Marinas wrote:
> On Fri, Dec 05, 2014 at 06:39:45PM +0000, Catalin Marinas wrote:
>> On Fri, Dec 05, 2014 at 09:22:22AM +0000, Arend van Spriel wrote:
>>> For our brcm80211 development we are working on getting brcmfmac driver
>>> up and running on a Broadcom ARM-based platform. The wireless device is
>>> a PCIe device, which is hooked up to the system behind a PCIe host
>>> bridge, and we transfer information between host and device using a
>>> descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
>>> tested on x86 and seen no issue. However, on this ARM platform
>>> (single-core A9) we detect occasionally that the descriptor content is
>>> invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
>>> retried a number of times if the problem persists. Actually, found out
>>> that someone made a mistake by using virt_to_dma(va) to get the
>>> dma_handle parameter. So probably we only provided a delay in the retry
>>> loop. After fixing that a single call to dma_sync_single_for_cpu() is
>>> sufficient. The DMA-API-HOWTO clearly states that:
>>
>> Does your system have an L2 cache? What's the SoC topology, can PCIe see
>> such L2 cache (or snoop the L1 caches)?
>
> BTW, if you really have a PL310-like L2 cache, have a look at some
> patches (I've seen similar symptoms) and make sure your configuration is
> correct:
>
> http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6395/1
>
> http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1
>
> The first one is vexpress specific. The second one was eventually
> discarded by Russell (I don't remember the reason, I guess it's because
> SoC code is supposed to set the right bits in there anyway). In your
> case, such bits may be set up by firmware, so Linux cannot fix anything
> up.

I guess by firmware you mean to bootloader. This one boots with CFE 
bootloader which Broadcom maintains itself so could look into that.

Regards,
Arend


^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-05 19:50       ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-05 19:50 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Russell King, linux-wireless, brcm80211-dev-list, David Miller,
	linux-arm-kernel, linux-kernel

On 12/05/14 19:53, Catalin Marinas wrote:
> On Fri, Dec 05, 2014 at 06:39:45PM +0000, Catalin Marinas wrote:
>> On Fri, Dec 05, 2014 at 09:22:22AM +0000, Arend van Spriel wrote:
>>> For our brcm80211 development we are working on getting brcmfmac driver
>>> up and running on a Broadcom ARM-based platform. The wireless device is
>>> a PCIe device, which is hooked up to the system behind a PCIe host
>>> bridge, and we transfer information between host and device using a
>>> descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
>>> tested on x86 and seen no issue. However, on this ARM platform
>>> (single-core A9) we detect occasionally that the descriptor content is
>>> invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
>>> retried a number of times if the problem persists. Actually, found out
>>> that someone made a mistake by using virt_to_dma(va) to get the
>>> dma_handle parameter. So probably we only provided a delay in the retry
>>> loop. After fixing that a single call to dma_sync_single_for_cpu() is
>>> sufficient. The DMA-API-HOWTO clearly states that:
>>
>> Does your system have an L2 cache? What's the SoC topology, can PCIe see
>> such L2 cache (or snoop the L1 caches)?
>
> BTW, if you really have a PL310-like L2 cache, have a look at some
> patches (I've seen similar symptoms) and make sure your configuration is
> correct:
>
> http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6395/1
>
> http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1
>
> The first one is vexpress specific. The second one was eventually
> discarded by Russell (I don't remember the reason, I guess it's because
> SoC code is supposed to set the right bits in there anyway). In your
> case, such bits may be set up by firmware, so Linux cannot fix anything
> up.

I guess by firmware you mean to bootloader. This one boots with CFE 
bootloader which Broadcom maintains itself so could look into that.

Regards,
Arend


^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-05 19:50       ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-05 19:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/05/14 19:53, Catalin Marinas wrote:
> On Fri, Dec 05, 2014 at 06:39:45PM +0000, Catalin Marinas wrote:
>> On Fri, Dec 05, 2014 at 09:22:22AM +0000, Arend van Spriel wrote:
>>> For our brcm80211 development we are working on getting brcmfmac driver
>>> up and running on a Broadcom ARM-based platform. The wireless device is
>>> a PCIe device, which is hooked up to the system behind a PCIe host
>>> bridge, and we transfer information between host and device using a
>>> descriptor ring buffer allocated using dma_alloc_coherent(). We mostly
>>> tested on x86 and seen no issue. However, on this ARM platform
>>> (single-core A9) we detect occasionally that the descriptor content is
>>> invalid. When this occurs we do a dma_sync_single_for_cpu() and this is
>>> retried a number of times if the problem persists. Actually, found out
>>> that someone made a mistake by using virt_to_dma(va) to get the
>>> dma_handle parameter. So probably we only provided a delay in the retry
>>> loop. After fixing that a single call to dma_sync_single_for_cpu() is
>>> sufficient. The DMA-API-HOWTO clearly states that:
>>
>> Does your system have an L2 cache? What's the SoC topology, can PCIe see
>> such L2 cache (or snoop the L1 caches)?
>
> BTW, if you really have a PL310-like L2 cache, have a look at some
> patches (I've seen similar symptoms) and make sure your configuration is
> correct:
>
> http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6395/1
>
> http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1
>
> The first one is vexpress specific. The second one was eventually
> discarded by Russell (I don't remember the reason, I guess it's because
> SoC code is supposed to set the right bits in there anyway). In your
> case, such bits may be set up by firmware, so Linux cannot fix anything
> up.

I guess by firmware you mean to bootloader. This one boots with CFE 
bootloader which Broadcom maintains itself so could look into that.

Regards,
Arend

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-05 18:53     ` Catalin Marinas
  (?)
@ 2014-12-08 12:55       ` Johannes Stezenbach
  -1 siblings, 0 replies; 115+ messages in thread
From: Johannes Stezenbach @ 2014-12-08 12:55 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Arend van Spriel, Russell King, linux-wireless,
	brcm80211-dev-list, David Miller, linux-arm-kernel, linux-kernel

On Fri, Dec 05, 2014 at 06:53:03PM +0000, Catalin Marinas wrote:
> On Fri, Dec 05, 2014 at 06:39:45PM +0000, Catalin Marinas wrote:
> > 
> > Does your system have an L2 cache? What's the SoC topology, can PCIe see
> > such L2 cache (or snoop the L1 caches)?
> 
> BTW, if you really have a PL310-like L2 cache, have a look at some
> patches (I've seen similar symptoms) and make sure your configuration is
> correct:
> 
> http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6395/1
> 
> http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1
> 
> The first one is vexpress specific. The second one was eventually
> discarded by Russell (I don't remember the reason, I guess it's because
> SoC code is supposed to set the right bits in there anyway). In your
> case, such bits may be set up by firmware, so Linux cannot fix anything
> up.

How do you avoid the unpredictable behavior mentioned in the
PL310 TRM when the Shared Attribute Invalidate Enable bit is set?
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0246h/Ceggcfcj.html

I think this bit does not do what you seem to think it does, it only
changes behaviour for "writes targeting a full cache line, for example
4x64-bit bursts with all strobes active", which then cause the
cacheline to be invalidated.  "Other cases are identical to the default
shared behavior", which is "cacheable no allocate for reads"
and "write through no write allocate for writes".

If the problem is really speculative reads via the cachable
alias mapping, it seems this bit cannot solve the problem, right?


Johannes

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-08 12:55       ` Johannes Stezenbach
  0 siblings, 0 replies; 115+ messages in thread
From: Johannes Stezenbach @ 2014-12-08 12:55 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Arend van Spriel, Russell King, linux-wireless,
	brcm80211-dev-list, David Miller, linux-arm-kernel, linux-kernel

On Fri, Dec 05, 2014 at 06:53:03PM +0000, Catalin Marinas wrote:
> On Fri, Dec 05, 2014 at 06:39:45PM +0000, Catalin Marinas wrote:
> > 
> > Does your system have an L2 cache? What's the SoC topology, can PCIe see
> > such L2 cache (or snoop the L1 caches)?
> 
> BTW, if you really have a PL310-like L2 cache, have a look at some
> patches (I've seen similar symptoms) and make sure your configuration is
> correct:
> 
> http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6395/1
> 
> http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1
> 
> The first one is vexpress specific. The second one was eventually
> discarded by Russell (I don't remember the reason, I guess it's because
> SoC code is supposed to set the right bits in there anyway). In your
> case, such bits may be set up by firmware, so Linux cannot fix anything
> up.

How do you avoid the unpredictable behavior mentioned in the
PL310 TRM when the Shared Attribute Invalidate Enable bit is set?
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0246h/Ceggcfcj.html

I think this bit does not do what you seem to think it does, it only
changes behaviour for "writes targeting a full cache line, for example
4x64-bit bursts with all strobes active", which then cause the
cacheline to be invalidated.  "Other cases are identical to the default
shared behavior", which is "cacheable no allocate for reads"
and "write through no write allocate for writes".

If the problem is really speculative reads via the cachable
alias mapping, it seems this bit cannot solve the problem, right?


Johannes

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-08 12:55       ` Johannes Stezenbach
  0 siblings, 0 replies; 115+ messages in thread
From: Johannes Stezenbach @ 2014-12-08 12:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 05, 2014 at 06:53:03PM +0000, Catalin Marinas wrote:
> On Fri, Dec 05, 2014 at 06:39:45PM +0000, Catalin Marinas wrote:
> > 
> > Does your system have an L2 cache? What's the SoC topology, can PCIe see
> > such L2 cache (or snoop the L1 caches)?
> 
> BTW, if you really have a PL310-like L2 cache, have a look at some
> patches (I've seen similar symptoms) and make sure your configuration is
> correct:
> 
> http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6395/1
> 
> http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1
> 
> The first one is vexpress specific. The second one was eventually
> discarded by Russell (I don't remember the reason, I guess it's because
> SoC code is supposed to set the right bits in there anyway). In your
> case, such bits may be set up by firmware, so Linux cannot fix anything
> up.

How do you avoid the unpredictable behavior mentioned in the
PL310 TRM when the Shared Attribute Invalidate Enable bit is set?
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0246h/Ceggcfcj.html

I think this bit does not do what you seem to think it does, it only
changes behaviour for "writes targeting a full cache line, for example
4x64-bit bursts with all strobes active", which then cause the
cacheline to be invalidated.  "Other cases are identical to the default
shared behavior", which is "cacheable no allocate for reads"
and "write through no write allocate for writes".

If the problem is really speculative reads via the cachable
alias mapping, it seems this bit cannot solve the problem, right?


Johannes

^ permalink raw reply	[flat|nested] 115+ messages in thread

* RE: using DMA-API on ARM
  2014-12-05 14:20           ` Hante Meuleman
  (?)
@ 2014-12-08 13:47             ` Hante Meuleman
  -1 siblings, 0 replies; 115+ messages in thread
From: Hante Meuleman @ 2014-12-08 13:47 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Will Deacon, Arend Van Spriel, Marek Szyprowski,
	linux-arm-kernel, David Miller, linux-kernel, brcm80211-dev-list,
	linux-wireless

[-- Attachment #1: Type: text/plain, Size: 4257 bytes --]

Still using outlook, but will limit the line length, I hope that works for the
moment. Attached is a log with the requested information, it is a little
bit non-standard though. The dump code from the mm was copied in
the driver and called from there, mapping the prints back to our local
printf, but it should produce the same. I did this because I didn't realize
the table is static.

Some background on the test setup: I'm using a Broadcom reference 
design AP platform with an BRCM 4708 host SOC. For the AP router 
platform the opensource packet OpenWRT was used. Some small
modifications were made to get it to work on our HW. Only one core
is enabled for the moment (no time to figure out how to enable the
other one). Openwrt was configured to use kernel 3.18-rc2 and 
the brcmfmac of the compat-wireless code was updated with our 
latest code (minor patches, which have been submitted already). 
The device used is 43602 pcie device. Some modifications to the build
system were made to enable PCIE. The test is to connect with a 
client to the AP and run iperf (TCP). The test can run for many hours
without a problem, but sometimes fails very quickly.

The log: first the ring allocation info is printed. Starting at
16.124847, ring 2, 3 and 4 are rings used for device to host. In this
log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
16 bytes. The next thing printed is the kernel page tables. Then some 
OpenWRT info and the logging of part of the connection setup. Then at 
1780.130752 the logging of the failure starts. The sequence number is 
modulo 253 with ring size of 1024 matches an "old" entry (read 40, 
expected 52). Then the different pointers are printed followed by 
the kernel page table. The code does then a cache invalidate on the 
dma_handle and the next read the sequence number is correct.

Regards,
Hante



Please wrap your message - replying to a message which looks like this in
my editor is far from easy, and gives me much more work to /manually/
reformat it before I can reply to it:

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> The problem is with data coming from device, so DMA from device to host. The $
>
> However: this indicates that dma_alloc_coherent on an ARM target may result i$
>
> Regards,
> Hante

Thanks.

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> However: this indicates that dma_alloc_coherent on an ARM target may
> result in a memory buffer which can be cached which conflicts with
> the API of this function.

If the memory has an alias which is cacheable, it is possible for cache
lines to get allocated via that alias, even if the alias has no explicit
accesses to it.

This is something which I've been going on for quite literally /years/ -
mismatched cache attributes can cause unpredictable behaviour.  I've had
a lot of push back from people who are of the opinion that "if it works
for me, then there isn't a problem" and I eventually gave up fighting
the battle, especially as the ARM architecture people weakened my
reasoning behind it by publishing a relaxation of the "no differing
attributes" issue.  This was particularly true of those who wanted to
use ioremap() on system memory - and cases such as
dma_init_coherent_memory().

So, I never fixed this problem in the original DMA allocator code; I
basically gave up with it.  It's a latent bug which did need to be fixed,
and is still present today in the non-CMA case.

The symptoms which you are reporting sound very much like this kind of
problem - the virtual address for the memory returned by
dma_alloc_coherent() will not be cacheable memory - it will have been
remapped using map_vm_area().  However, there could very well be a fully
cacheable lowmem mapping of that memory, which if a read (speculative or
otherwise) will bring a cache line in, and because the caches are VIPT
or PIPT, that cache line can be hit via the non-cacheable mapping too.

What I /really/ need is more evidence of this to tell those disbelievers
where to stick their flawed arguments. :)

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

[-- Attachment #2: cache_fail_dmesg.txt --]
[-- Type: text/plain, Size: 35592 bytes --]

root@OpenWrt:/# dmesg
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 3.18.0-rc2 (developer@meuleman-test) (gcc version 4.8.3 (OpenWrt/Linaro GCC 4.8-2014.04 r43121) ) #66 SMP Mon Dec 8 12:38:39 CET 2014
[    0.000000] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7),c5387d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] Machine model: Buffalo WZR-1750DHP (BCM4708)
[    0.000000] Memory policy: Data cache writealloc
[    0.000000] On node 0 totalpages: 32768
[    0.000000] free_area_init_node: node 0, pgdat c038ee00, node_mem_map c7efb000
[    0.000000]   Normal zone: 256 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 32768 pages, LIFO batch:7
[    0.000000] PERCPU: Embedded 9 pages/cpu @c7ee3000 s6528 r8192 d22144 u36864
[    0.000000] pcpu-alloc: s6528 r8192 d22144 u36864 alloc=9*4096
[    0.000000] pcpu-alloc: [0] 0 [0] 1
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 32512
[    0.000000] Kernel command line: console=ttyS0,115200
[    0.000000] PID hash table entries: 512 (order: -1, 2048 bytes)
[    0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
[    0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Memory: 125936K/131072K available (2682K kernel code, 103K rwdata, 744K rodata, 164K init, 188K bss, 5136K reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xffe00000   (2048 kB)
[    0.000000]     vmalloc : 0xc8800000 - 0xff000000   ( 872 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xc8000000   ( 128 MB)
[    0.000000]     modules : 0xbf000000 - 0xc0000000   (  16 MB)
[    0.000000]       .text : 0xc0008000 - 0xc0360dc4   (3428 kB)
[    0.000000]       .init : 0xc0361000 - 0xc038a000   ( 164 kB)
[    0.000000]       .data : 0xc038a000 - 0xc03a3eb8   ( 104 kB)
[    0.000000]        .bss : 0xc03a3eb8 - 0xc03d2ebc   ( 189 kB)
[    0.000000] Hierarchical RCU implementation.
[    0.000000]  RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2.
[    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=2
[    0.000000] NR_IRQS:16 nr_irqs:16 16
[    0.000000] PL310 OF: cache setting yield illegal associativity
[    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
[    0.000000] L2C-310 enabling early BRESP for Cortex-A9
[    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
[    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
[    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
[    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001
[    0.000017] sched_clock: 64 bits at 400MHz, resolution 2ns, wraps every 2748779069440ns
[    0.000315] Calibrating delay loop... 1594.16 BogoMIPS (lpj=7970816)
[    0.090133] pid_max: default: 32768 minimum: 301
[    0.090299] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.090312] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.090822] CPU: Testing write buffer coherency: ok
[    0.091084] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
[    0.091152] Setting up static identity map for 0x11728 - 0x1175c
[    0.092455] Brought up 1 CPUs
[    0.092471] SMP: Total of 1 processors activated.
[    0.092481] CPU: All CPU(s) started in SVC mode.
[    0.099682] NET: Registered protocol family 16
[    0.100425] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.106341] usbcore: registered new interface driver usbfs
[    0.106422] usbcore: registered new interface driver hub
[    0.106500] usbcore: registered new device driver usb
[    0.107259] Switched to clocksource arm_global_timer
[    0.108567] NET: Registered protocol family 2
[    0.109224] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    0.109251] TCP bind hash table entries: 1024 (order: 1, 8192 bytes)
[    0.109278] TCP: Hash tables configured (established 1024 bind 1024)
[    0.109350] TCP: reno registered
[    0.109368] UDP hash table entries: 256 (order: 1, 8192 bytes)
[    0.109404] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes)
[    0.109669] NET: Registered protocol family 1
[    0.109737] PCI: CLS 0 bytes, default 64
[    0.110768] futex hash table entries: 512 (order: 3, 32768 bytes)
[    0.111905] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.111932] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[    0.112155] msgmni has been set to 245
[    0.113050] io scheduler noop registered
[    0.113073] io scheduler deadline registered (default)
[    0.113329] Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
[    0.113952] console [ttyS0] disabled
[    0.114026] of_serial 18000300.serial: ttyS0 at MMIO 0x18000300 (irq = 117, base_baud = 6250000) is a 16550
[    0.514919] console [ttyS0] enabled
[    0.518713] of_serial 18000400.serial: ttyS1 at MMIO 0x18000400 (irq = 117, base_baud = 6250000) is a 16550
[    0.603994] no nvram found
[    0.606975] Unsupported SPROM revision 0 detected. Will extract v1
[    0.613693] bcmnand: Broadcom NAND Controller driver loaded
[    0.620439] bgmac: Broadcom 47xx GBit MAC driver loaded
[    0.625723] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    0.632256] ehci-pci: EHCI PCI platform driver
[    0.636742] ehci-platform: EHCI generic platform driver
[    0.642218] bcma: bus0: Found chip with id 53010, rev 0x00 and package 0x02
[    0.649209] bcma: bus0: Core 0 found: ChipCommon (manuf 0x4BF, id 0x800, rev 0x2A, class 0x0)
[    0.657791] bcma: bus0: Core 1 found: Chipcommon B (manuf 0x4BF, id 0x50B, rev 0x01, class 0x0)
[    0.666522] bcma: bus0: Core 2 found: DMA (manuf 0x4BF, id 0x502, rev 0x01, class 0x0)
[    0.674477] bcma: bus0: Core 3 found: GBit MAC (manuf 0x4BF, id 0x82D, rev 0x05, class 0x0)
[    0.682858] bcma: bus0: Core 4 found: GBit MAC (manuf 0x4BF, id 0x82D, rev 0x05, class 0x0)
[    0.691249] bcma: bus0: Core 5 found: GBit MAC (manuf 0x4BF, id 0x82D, rev 0x05, class 0x0)
[    0.699635] bcma: bus0: Core 6 found: GBit MAC (manuf 0x4BF, id 0x82D, rev 0x05, class 0x0)
[    0.707993] bcma: bus0: Core 7 found: PCIe Gen 2 (manuf 0x4BF, id 0x501, rev 0x01, class 0x0)
[    0.716528] bcma: bus0: Core 8 found: PCIe Gen 2 (manuf 0x4BF, id 0x501, rev 0x01, class 0x0)
[    0.725074] bcma: bus0: Core 9 found: PCIe Gen 2 (manuf 0x4BF, id 0x501, rev 0x01, class 0x0)
[    0.733641] bcma: bus0: Core 10 found: ARM Cortex A9 core (ihost) (manuf 0x4BF, id 0x510, rev 0x01, class 0x0)
[    0.743658] bcma: bus0: Core 11 found: USB 2.0 (manuf 0x4BF, id 0x504, rev 0x01, class 0x0)
[    0.752036] bcma: bus0: Core 12 found: USB 3.0 (manuf 0x4BF, id 0x505, rev 0x01, class 0x0)
[    0.760426] bcma: bus0: Core 13 found: SDIO3 (manuf 0x4BF, id 0x503, rev 0x01, class 0x0)
[    0.768626] bcma: bus0: Core 14 found: ARM Cortex A9 JTAG (manuf 0x4BF, id 0x506, rev 0x01, class 0x0)
[    0.777962] bcma: bus0: Core 15 found: Denali DDR2/DDR3 memory controller (manuf 0x4BF, id 0x507, rev 0x01, class 0x0)
[    0.788681] bcma: bus0: Core 16 found: ROM (manuf 0x4BF, id 0x508, rev 0x01, class 0x0)
[    0.796726] bcma: bus0: Core 17 found: NAND flash controller (manuf 0x4BF, id 0x509, rev 0x01, class 0x0)
[    0.806325] bcma: bus0: Core 18 found: SPI flash controller (manuf 0x4BF, id 0x50A, rev 0x01, class 0x0)
[    0.820252] bcmnand: NAND Controller rev 6.1
[    0.840228] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xdc
[    0.846565] nand: Micron NAND 512MiB 3,3V 8-bit
[    0.851094] nand: 512MiB, SLC, page size: 2048, OOB size: 64
[    1.220976] bcm53xxspiflash spi32766.0: mx25l25635e (32768 Kbytes)
[    2.585498] next_part_offset limited to 1000000
[    2.590014] 5 bcm47xxpart partitions found on MTD device spi32766.0
[    2.596260] Creating 5 MTD partitions on "spi32766.0":
[    2.601389] 0x000000000000-0x000000040000 : "boot"
[    2.606848] 0x000000040000-0x000000ff0000 : "firmware"
[    2.612569] 0x00000004001c-0x000000184c00 : "linux"
[    2.617429] mtd: partition "linux" must either start or end on erase block boundary or be smaller than an erase block -- forcing read-only
[    2.630415] 0x000000184c00-0x000000ff0000 : "rootfs"
[    2.635364] mtd: partition "rootfs" must either start or end on erase block boundary or be smaller than an erase block -- forcing read-only
[    2.648435] mtd: device 4 (rootfs) set to be root filesystem
[    2.654360] 1 squashfs-split partitions found on MTD device rootfs
[    2.660542] 0x000000450000-0x000000ff0000 : "rootfs_data"
[    2.666561] 0x000000ff0000-0x000001000000 : "nvram"
[    2.672108] bcma: bus0: Found sprom from device tree provider
[    2.678032] bgmac bcma0:3: Invalid MAC addr: 00:00:00:00:00:00
[    2.683900] bgmac bcma0:3: Using random MAC: a2:68:1a:ca:99:26
[    2.689770] bgmac bcma0:3: Found PHY addr: 0
[    2.698590] libphy: bgmac mii bus: probed
[    2.781466] b53_common: found switch: BCM53011, rev 3
[    2.787094] netif_napi_add() called with weight 128 on device eth0
[    2.793422] bgmac bcma0:4: Invalid MAC addr: 00:00:00:00:00:00
[    2.799255] bgmac bcma0:4: Using random MAC: 6a:b7:e9:ad:58:4c
[    2.805138] bgmac bcma0:4: Found PHY addr: 0
[    2.812607] libphy: bgmac mii bus: probed
[    2.890939] bgmac: Unsupported core_unit 2
[    2.895033] bgmac: probe of bcma0:5 failed with error -524
[    2.900619] bgmac: Unsupported core_unit 3
[    2.904704] bgmac: probe of bcma0:6 failed with error -524
[    2.910271] pcie2_bcma bcma0:7: scanning bus
[    3.164199] pcie2_bcma bcma0:7: switching to GEN2
[    3.418495] pcie2_bcma bcma0:7: PCI host bridge to bus 0000:00
[    3.424332] pci_bus 0000:00: root bus resource [mem 0x08000000-0x0fffffff]
[    3.431189] pci_bus 0000:00: root bus resource [io  0x8000000-0xfffffff]
[    3.437859] pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff]
[    3.445774] pci 0000:00:00.0: [14e4:8011] type 01 class 0x060400
[    3.445842] pci 0000:00:00.0: PME# supported from D0 D3hot D3cold
[    3.446051] PCI: bus0: Fast back to back transfers disabled
[    3.451757] pci 0000:01:00.0: [14e4:43bc] type 00 class 0x028000
[    3.451792] pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x00007fff 64bit]
[    3.451815] pci 0000:01:00.0: reg 0x18: [mem 0x00000000-0x003fffff 64bit]
[    3.451908] pci 0000:01:00.0: supports D1 D2
[    3.451920] pci 0000:01:00.0: PME# supported from D0 D1 D2 D3hot D3cold
[    3.452102] PCI: bus1: Fast back to back transfers disabled
[    3.457657] pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
[    3.457675] pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 01
[    3.457724] pci 0000:00:00.0: BAR 8: assigned [mem 0x08000000-0x085fffff]
[    3.464514] pci 0000:01:00.0: BAR 2: assigned [mem 0x08000000-0x083fffff 64bit]
[    3.471808] pci 0000:01:00.0: BAR 0: assigned [mem 0x08400000-0x08407fff 64bit]
[    3.479098] pci 0000:00:00.0: PCI bridge to [bus 01]
[    3.484050] pci 0000:00:00.0:   bridge window [mem 0x08000000-0x085fffff]
[    3.490879] pci 0000:01:00.0: Max Payload Size 128, but upstream 0000:00:00.0 set to 512; if necessary, use "pci=pcie_bus_safe" and report a bug
[    3.503894] pcie2_bcma bcma0:8: scanning bus
[    3.757879] pcie2_bcma bcma0:9: scanning bus
[    4.012438] bcma: bus0: Bus registered
[    4.016517] TCP: cubic registered
[    4.019832] NET: Registered protocol family 17
[    4.024381] bridge: automatic filtering via arp/ip/ip6tables has been deprecated. Update your scripts to load br_netfilter if you need this.
[    4.036954] 8021q: 802.1Q VLAN Support v1.8
[    4.041208] Registering SWP/SWPB emulation handler
[    4.064654] VFS: Mounted root (squashfs filesystem) readonly on device 31:4.
[   926] Freeing unused kernel memory: 164K (c0361000 - c038a000)
[    6.136424] gpio-keys gpio-keys: failed to request irq:-6 for gpio:11
[    6.142919] gpio-keys gpio-keys: failed to request irq:-6 for gpio:12
[    6.149333] gpio-keys gpio-keys: failed to request irq:-6 for gpio:13
[    6.155756] gpio-keys gpio-keys: failed to request irq:-6 for gpio:14
[    6.162180] gpio-keys gpio-keys: failed to request irq:-6 for gpio:15
[    6.234566] random: mktemp urandom read with 41 bits of entropy available
[    9.650068] jffs2: notice: (288) jffs2_build_xattr_subsystem: complete building xattr subsystem, 0 of xdatum (0 unchecked, 0 orphan) and 0 of xref (0 dead, 0 orphan) found.
[    9.666442] overlayfs: missing upperdir or lowerdir or workdir
[   14.159733] Loading modules backported from Linux version master-2014-10-08-0-g0275925
[   14.167681] Backport generated by backports.git backports-20140905-1-gde42785
[   14.180633] cfg80211: Calling CRDA to update world regulatory domain
[   14.192280] cfg80211: World regulatory domain updated:
[   14.197413] cfg80211:  DFS Master region: unset
[   14.201802] cfg80211:   (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)
[   14.211517] cfg80211:   (2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[   14.219481] cfg80211:   (2457000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[   14.227454] cfg80211:   (2474000 KHz - 2494000 KHz @ 20000 KHz), (N/A, 2000 mBm), (N/A)
[   14.235427] cfg80211:   (5170000 KHz - 5250000 KHz @ 160000 KHz), (N/A, 2000 mBm), (N/A)
[   14.243489] cfg80211:   (5250000 KHz - 5330000 KHz @ 160000 KHz), (N/A, 2000 mBm), (0 s)
[   14.251551] cfg80211:   (5490000 KHz - 5730000 KHz @ 160000 KHz), (N/A, 2000 mBm), (0 s)
[   14.259604] cfg80211:   (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A)
[   14.267577] cfg80211:   (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 0 mBm), (N/A)
[   14.289862] usbcore: registered new interface driver brcmfmac
[   14.295733] brcmfmac 0000:01:00.0: enabling device (0140 -> 0142)
[   15.325236] brcmfmac 0000:01:00.0: Direct firmware load for brcm/brcmfmac43602-pcie.txt failed with error -2
[   16.124847] brcmfmac: brcmf_pcie_alloc_dma_and_ring: RING 0: virtual address: c8ccf000, physical address:   (null):06c06000
[   16.136056] brcmfmac: brcmf_pcie_alloc_dma_and_ring: RING 1: virtual address: c8cd1000, physical address:   (null):06c12000
[   16.147179] brcmfmac: brcmf_pcie_alloc_dma_and_ring: RING 2: virtual address: c8cd4000, physical address:   (null):06c07000
[   16.158377] brcmfmac: brcmf_pcie_alloc_dma_and_ring: RING 3: virtual address: c8cd6000, physical address:   (null):073bc000
[   16.169526] brcmfmac: brcmf_pcie_alloc_dma_and_ring: RING 4: virtual address: c8cdb000, physical address:   (null):06c14000
[   16.301412] brcmfmac: brcmf_msgbuf_rxbuf_data_post: Failed to reserve space in commonring
[   16.321273] brcmfmac: localseq_vprintf: ---[ Modules ]---
[   16.326768] brcmfmac: localseq_vprintf: 0xbf000000-0xbf002000           8K     RW x  SHD MEM/CACHED/WBWA
[   16.336242] brcmfmac: localseq_vprintf: 0xbf005000-0xbf007000           8K     RW x  SHD MEM/CACHED/WBWA
[   16.345696] brcmfmac: localseq_vprintf: 0xbf00a000-0xbf00b000           4K     RW x  SHD MEM/CACHED/WBWA
[   16.355147] brcmfmac: localseq_vprintf: 0xbf00e000-0xbf03d000         188K     RW x  SHD MEM/CACHED/WBWA
[   16.364599] brcmfmac: localseq_vprintf: 0xbf046000-0xbf06f000         164K     RW x  SHD MEM/CACHED/WBWA
[   16.374064] brcmfmac: localseq_vprintf: ---[ Kernel Mapping ]---
[   16.380045] brcmfmac: localseq_vprintf: 0xc0000000-0xc0400000           4M     RW x  SHD
[   16.388113] brcmfmac: localseq_vprintf: 0xc0400000-0xc8000000         124M     RW NX SHD
[   16.396168] brcmfmac: localseq_vprintf: ---[ vmalloc() Area ]---
[   16.402163] brcmfmac: localseq_vprintf: 0xc8800000-0xc8801000           4K     RW NX SHD DEV/SHARED
[   16.411173] brcmfmac: localseq_vprintf: 0xc8802000-0xc8803000           4K     RW NX SHD DEV/SHARED
[   16.420184] brcmfmac: localseq_vprintf: 0xc8804000-0xc8805000           4K     RW NX SHD DEV/SHARED
[   16.429188] brcmfmac: localseq_vprintf: 0xc8806000-0xc8807000           4K     RW NX SHD DEV/SHARED
[   16.438200] brcmfmac: localseq_vprintf: 0xc8808000-0xc8809000           4K     RW NX SHD DEV/SHARED
[   16.447215] brcmfmac: localseq_vprintf: 0xc880e000-0xc884e000         256K     RW NX SHD MEM/BUFFERABLE/WC
[   16.456840] brcmfmac: localseq_vprintf: 0xc884f000-0xc8895000         280K     RW NX SHD MEM/CACHED/WBWA
[   16.466287] brcmfmac: localseq_vprintf: 0xc8896000-0xc8897000           4K     RW NX SHD DEV/SHARED
[   16.475299] brcmfmac: localseq_vprintf: 0xc8898000-0xc8899000           4K     RW NX SHD DEV/SHARED
[   16.484310] brcmfmac: localseq_vprintf: 0xc889a000-0xc889b000           4K     RW NX SHD DEV/SHARED
[   16.493322] brcmfmac: localseq_vprintf: 0xc889e000-0xc889f000           4K     RW NX SHD DEV/SHARED
[   16.502335] brcmfmac: localseq_vprintf: 0xc88a0000-0xc88a1000           4K     RW NX SHD DEV/SHARED
[   16.511345] brcmfmac: localseq_vprintf: 0xc88a2000-0xc88a3000           4K     RW NX SHD DEV/SHARED
[   16.520357] brcmfmac: localseq_vprintf: 0xc88a4000-0xc88a5000           4K     RW NX SHD DEV/SHARED
[   16.529361] brcmfmac: localseq_vprintf: 0xc88a6000-0xc88a7000           4K     RW NX SHD DEV/SHARED
[   16.538372] brcmfmac: localseq_vprintf: 0xc88a8000-0xc88a9000           4K     RW NX SHD DEV/SHARED
[   16.547382] brcmfmac: localseq_vprintf: 0xc88aa000-0xc88ab000           4K     RW NX SHD DEV/SHARED
[   16.556394] brcmfmac: localseq_vprintf: 0xc88ac000-0xc88ad000           4K     RW NX SHD DEV/SHARED
[   16.565404] brcmfmac: localseq_vprintf: 0xc88ae000-0xc88af000           4K     RW NX SHD DEV/SHARED
[   16.574417] brcmfmac: localseq_vprintf: 0xc88b0000-0xc88b1000           4K     RW NX SHD DEV/SHARED
[   16.583428] brcmfmac: localseq_vprintf: 0xc88b2000-0xc88b3000           4K     RW NX SHD DEV/SHARED
[   16.592441] brcmfmac: localseq_vprintf: 0xc88b4000-0xc88b5000           4K     RW NX SHD DEV/SHARED
[   16.601451] brcmfmac: localseq_vprintf: 0xc88b6000-0xc88b7000           4K     RW NX SHD DEV/SHARED
[   16.610464] brcmfmac: localseq_vprintf: 0xc88b8000-0xc88b9000           4K     RW NX SHD DEV/SHARED
[   16.619467] brcmfmac: localseq_vprintf: 0xc88ba000-0xc88bb000           4K     RW NX SHD DEV/SHARED
[   16.628478] brcmfmac: localseq_vprintf: 0xc88bc000-0xc88bd000           4K     RW NX SHD DEV/SHARED
[   16.637490] brcmfmac: localseq_vprintf: 0xc88be000-0xc88bf000           4K     RW NX SHD DEV/SHARED
[   16.646503] brcmfmac: localseq_vprintf: 0xc88c0000-0xc88c1000           4K     RW NX SHD DEV/SHARED
[   16.655512] brcmfmac: localseq_vprintf: 0xc88c2000-0xc88c3000           4K     RW NX SHD DEV/SHARED
[   16.664524] brcmfmac: localseq_vprintf: 0xc88c4000-0xc88c5000           4K     RW NX SHD DEV/SHARED
[   16.673535] brcmfmac: localseq_vprintf: 0xc88c6000-0xc88c7000           4K     RW NX SHD DEV/SHARED
[   16.682547] brcmfmac: localseq_vprintf: 0xc88c8000-0xc88c9000           4K     RW NX SHD DEV/SHARED
[   16.691558] brcmfmac: localseq_vprintf: 0xc88ca000-0xc88cb000           4K     RW NX SHD DEV/SHARED
[   16.700569] brcmfmac: localseq_vprintf: 0xc88cc000-0xc88cd000           4K     RW NX SHD DEV/SHARED
[   16.709573] brcmfmac: localseq_vprintf: 0xc88ce000-0xc88cf000           4K     RW NX SHD DEV/SHARED
[   16.718585] brcmfmac: localseq_vprintf: 0xc88d0000-0xc88d1000           4K     RW NX SHD DEV/SHARED
[   16.727596] brcmfmac: localseq_vprintf: 0xc88d2000-0xc88d3000           4K     RW NX SHD DEV/SHARED
[   16.736608] brcmfmac: localseq_vprintf: 0xc88d4000-0xc88d5000           4K     RW NX SHD DEV/SHARED
[   16.745618] brcmfmac: localseq_vprintf: 0xc88d6000-0xc88d7000           4K     RW NX SHD DEV/SHARED
[   16.754631] brcmfmac: localseq_vprintf: 0xc88d8000-0xc88d9000           4K     RW NX SHD DEV/SHARED
[   16.763642] brcmfmac: localseq_vprintf: 0xc88da000-0xc88db000           4K     RW NX SHD DEV/SHARED
[   16.772654] brcmfmac: localseq_vprintf: 0xc88dc000-0xc88dd000           4K     RW NX SHD DEV/SHARED
[   16.781665] brcmfmac: localseq_vprintf: 0xc88de000-0xc88df000           4K     RW NX SHD DEV/SHARED
[   16.790677] brcmfmac: localseq_vprintf: 0xc88e0000-0xc88e1000           4K     RW NX SHD DEV/SHARED
[   16.799680] brcmfmac: localseq_vprintf: 0xc88e2000-0xc88e3000           4K     RW NX SHD DEV/SHARED
[   16.808691] brcmfmac: localseq_vprintf: 0xc88e4000-0xc88e5000           4K     RW NX SHD DEV/SHARED
[   16.817703] brcmfmac: localseq_vprintf: 0xc88e6000-0xc88e7000           4K     RW NX SHD DEV/SHARED
[   16.826714] brcmfmac: localseq_vprintf: 0xc88e8000-0xc88e9000           4K     RW NX SHD DEV/SHARED
[   16.835725] brcmfmac: localseq_vprintf: 0xc88ea000-0xc88ec000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.845343] brcmfmac: localseq_vprintf: 0xc88ed000-0xc88ef000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.854959] brcmfmac: localseq_vprintf: 0xc88f0000-0xc88f2000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.864575] brcmfmac: localseq_vprintf: 0xc88f3000-0xc88f5000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.874191] brcmfmac: localseq_vprintf: 0xc88f6000-0xc88f8000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.883807] brcmfmac: localseq_vprintf: 0xc88fa000-0xc88fb000           4K     RW NX SHD DEV/SHARED
[   16.892819] brcmfmac: localseq_vprintf: 0xc88fc000-0xc88fe000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.902435] brcmfmac: localseq_vprintf: 0xc88ff000-0xc8901000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.912051] brcmfmac: localseq_vprintf: 0xc8902000-0xc8904000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.921667] brcmfmac: localseq_vprintf: 0xc8905000-0xc8907000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.931285] brcmfmac: localseq_vprintf: 0xc8908000-0xc890a000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.940901] brcmfmac: localseq_vprintf: 0xc890b000-0xc890e000          12K     RW NX SHD MEM/CACHED/WBWA
[   16.950347] brcmfmac: localseq_vprintf: 0xc890f000-0xc894f000         256K     RW NX SHD MEM/CACHED/WBWA
[   16.959792] brcmfmac: localseq_vprintf: 0xc8950000-0xc8990000         256K     RW NX SHD MEM/CACHED/WBWA
[   16.969256] brcmfmac: localseq_vprintf: 0xc8aa0000-0xc8aa8000          32K     RW NX SHD DEV/SHARED
[   16.978298] brcmfmac: localseq_vprintf: 0xc8ccf000-0xc8cd0000           4K     RW NX SHD MEM/BUFFERABLE/WC
[   16.987920] brcmfmac: localseq_vprintf: 0xc8cd1000-0xc8cd3000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.997536] brcmfmac: localseq_vprintf: 0xc8cd4000-0xc8cd5000           4K     RW NX SHD MEM/BUFFERABLE/WC
[   17.007152] brcmfmac: localseq_vprintf: 0xc8cd6000-0xc8cda000          16K     RW NX SHD MEM/BUFFERABLE/WC
[   17.016778] brcmfmac: localseq_vprintf: 0xc8cdb000-0xc8cdd000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   17.026394] brcmfmac: localseq_vprintf: 0xc8cde000-0xc8cdf000           4K     RW NX SHD MEM/BUFFERABLE/WC
[   17.036009] brcmfmac: localseq_vprintf: 0xc8ce0000-0xc8ce1000           4K     RW NX SHD MFERABLE/WC
[   17.045626] brcmfmac: localseq_vprintf: 0xc8ce5000-0xc8ce6000           4K     RW NX SHD MEM/BUFFERABLE/WC
[   17.055524] brcmfmac: localseq_vprintf: 0xca800000-0xcac00000           4M     RW NX SHD DEV/SHARED
[   17.064597] brcmfmac: localseq_vprintf: 0xfedee000-0xfedf1000          12K     RW NX SHD MEM/CACHED/WBWA
[   17.074046] brcmfmac: localseq_vprintf: 0xfedf7000-0xfedfa000          12K     RW NX SHD MEM/CACHED/WBWA
[   17.083499] brcmfmac: localseq_vprintf: ---[ vmalloc() End ]---
[   17.089392] brcmfmac: localseq_vprintf: ---[ Fixmap Area ]---
[   17.095145] brcmfmac: localseq_vprintf: ---[ Vectors ]---
[   17.100534] brcmfmac: localseq_vprintf: 0xffff0000-0xffff1000           4K USR ro x  SHD MEM/CACHED/WBWA
[   17.109969] brcmfmac: localseq_vprintf: 0xffff1000-0xffff2000           4K     ro x  SHD MEM/CACHED/WBWA
[   17.119406] brcmfmac: localseq_vprintf: ---[ Vectors End ]---
[   20.683755] device eth0.1 entered promiscuous mode
[   20.688542] device eth0 entered promiscuous mode
[   20.714866] br-lan: port 1(eth0.1) entered forwarding state
[   20.720475] br-lan: port 1(eth0.1) entered forwarding state
[   22.720161] br-lan: port 1(eth0.1) entered forwarding state
[   22.829502] brcmfmac: brcmf_add_if: ERROR: netdev:wlan0 already exists
[   22.836043] brcmfmac: brcmf_add_if: ignore IF event
[   22.851645] device wlan0 entered promiscuous mode
[   22.856391] br-lan: port 2(wlan0) entered forwarding state
[   22.861913] br-lan: port 2(wlan0) entered forwarding state
[   23.060471] brcmfmac: brcmf_add_if: ERROR: netdev:wlan0 already exists
[   23.066977] brcmfmac: brcmf_add_if: ignore IF event
[   24.870181] br-lan: port 2(wlan0) entered forwarding state
[   35.830824] brcmfmac: brcmf_cfg80211_change_station: Change station, MAC 00:90:4c:0c:c1:54
[   35.839157] brcmfmac: brcmf_cfg80211_change_station: Change station, mask 0x001c set 0x0000
[   48.582775] random: nonblocking pool is initialized
[ 1780.130752] brcmfmac: brcmf_sync_seqnum: Sequence number failure (expected 52, read 40)
[ 1780.138733] brcmfmac: brcmf_sync_seqnum: Sequence number pointer c8cd600c, as part of struct at address c8cd6000
[ 1780.148891] brcmfmac: brcmf_sync_seqnum: Struct size 16
[ 1780.154102] brcmfmac: brcmf_sync_seqnum: dma_handle of ring:   (null):073bc000, dma_to_pfn(dma_handle): 0x000073bc
[ 1780.164321] brcmfmac: brcmf_sync_seqnum: PHYS_PFN_OFFSET: 0x00000000
[ 1780.171601] brcmfmac: brcmf_sync_seqnum: ========= walk_pgd(): ==========
[ 1780.178361] brcmfmac: localseq_vprintf: ---[ Modules ]---
[ 1780.183851] brcmfmac: localseq_vprintf: 0xbf000000-0xbf002000           8K     RW x  SHD MEM/CACHED/WBWA
[ 1780.193308] brcmfmac: localseq_vprintf: 0xbf005000-0xbf007000           8K     RW x  SHD MEM/CACHED/WBWA
[ 1780.202756] brcmfmac: localseq_vprintf: 0xbf00a000-0xbf00b000           4K     RW x  SHD MEM/CACHED/WBWA
[ 1780.212210] brcmfmac: localseq_vprintf: 0xbf00e000-0xbf03d000         188K     RW x  SHD MEM/CACHED/WBWA
[ 1780.221663] brcmfmac: localseq_vprintf: 0xbf046000-0xbf06f000         164K     RW x  SHD MEM/CACHED/WBWA
[ 1780.231128] brcmfmac: localseq_vprintf: ---[ Kernel Mapping ]---
[ 1780.237109] brcmfmac: localseq_vprintf: 0xc0000000-0xc0400000           4M     RW x  SHD
[ 1780.245176] brcmfmac: localseq_vprintf: 0xc0400000-0xc8000000         124M     RW NX SHD
[ 1780.253234] brcmfmac: localseq_vprintf: ---[ vmalloc() Area ]---
[ 1780.259217] brcmfmac: localseq_vprintf: 0xc8800000-0xc8801000           4K     RW NX SHD DEV/SHARED
[ 1780.268228] brcmfmac: localseq_vprintf: 0xc8802000-0xc8803000           4K     RW NX SHD DEV/SHARED
[ 1780.277240] brcmfmac: localseq_vprintf: 0xc8804000-0xc8805000           4K     RW NX SHD DEV/SHARED
[ 1780.286250] brcmfmac: localseq_vprintf: 0xc8806000-0xc8807000           4K     RW NX SHD DEV/SHARED
[ 1780.295263] brcmfmac: localseq_vprintf: 0xc8808000-0xc8809000           4K     RW NX SHD DEV/SHARED
[ 1780.304278] brcmfmac: localseq_vprintf: 0xc880e000-0xc884e000         256K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.313903] brcmfmac: localseq_vprintf: 0xc884f000-0xc8895000         280K     RW NX SHD MEM/CACHED/WBWA
[ 1780.323351] brcmfmac: localseq_vprintf: 0xc8896000-0xc8897000           4K     RW NX SHD DEV/SHARED
[ 1780.332362] brcmfmac: localseq_vprintf: 0xc8898000-0xc8899000           4K     RW NX SHD DEV/SHARED
[ 1780.341375] brcmfmac: localseq_vprintf: 0xc889a000-0xc889b000           4K     RW NX SHD DEV/SHARED
[ 1780.350378] brcmfmac: localseq_vprintf: 0xc889e000-0xc889f000           4K     RW NX SHD DEV/SHARED
[ 1780.359389] brcmfmac: localseq_vprintf: 0xc88a0000-0xc88a1000           4K     RW NX SHD DEV/SHARED
[ 1780.368400] brcmfmac: localseq_vprintf: 0xc88a2000-0xc88a3000           4K     RW NX SHD DEV/SHARED
[ 1780.377411] brcmfmac: localseq_vprintf: 0xc88a4000-0xc88a5000           4K     RW NX SHD DEV/SHARED
[ 1780.386423] brcmfmac: localseq_vprintf: 0xc88a6000-0xc88a7000           4K     RW NX SHD DEV/SHARED
[ 1780.395434] brcmfmac: localseq_vprintf: 0xc88a8000-0xc88a9000           4K     RW NX SHD DEV/SHARED
[ 1780.404459] brcmfmac: localseq_vprintf: 0xc88aa000-0xc88ab000           4K     RW NX SHD DEV/SHARED
[ 1780.413477] brcmfmac: localseq_vprintf: 0xc88ac000-0xc88ad000           4K     RW NX SHD DEV/SHARED
[ 1780.422495] brcmfmac: localseq_vprintf: 0xc88ae000-0xc88af000           4K     RW NX SHD DEV/SHARED
[ 1780.431507] brcmfmac: localseq_vprintf: 0xc88b0000-0xc88b1000           4K     RW NX SHD DEV/SHARED
[ 1780.440510] brcmfmac: localseq_vprintf: 0xc88b2000-0xc88b3000           4K     RW NX SHD DEV/SHARED
[ 1780.449522] brcmfmac: localseq_vprintf: 0xc88b4000-0xc88b5000           4K     RW NX SHD DEV/SHARED
[ 1780.458533] brcmfmac: localseq_vprintf: 0xc88b6000-0xc88b7000           4K     RW NX SHD DEV/SHARED
[ 1780.467544] brcmfmac: localseq_vprintf: 0xc88b8000-0xc88b9000           4K     RW NX SHD DEV/SHARED
[ 1780.476556] brcmfmac: localseq_vprintf: 0xc88ba000-0xc88bb000           4K     RW NX SHD DEV/SHARED
[ 1780.485566] brcmfmac: localseq_vprintf: 0xc88bc000-0xc88bd000           4K     RW NX SHD DEV/SHARED
[ 1780.494579] brcmfmac: localseq_vprintf: 0xc88be000-0xc88bf000           4K     RW NX SHD DEV/SHARED
[ 1780.503590] brcmfmac: localseq_vprintf: 0xc88c0000-0xc88c1000           4K     RW NX SHD DEV/SHARED
[ 1780.512601] brcmfmac: localseq_vprintf: 0xc88c2000-0xc88c3000           4K     RW NX SHD DEV/SHARED
[ 1780.521613] brcmfmac: localseq_vprintf: 0xc88c4000-0xc88c5000           4K     RW NX SHD DEV/SHARED
[ 1780.530624] brcmfmac: localseq_vprintf: 0xc88c6000-0xc88c7000           4K     RW NX SHD DEV/SHARED
[ 1780.539629] brcmfmac: localseq_vprintf: 0xc88c8000-0xc88c9000           4K     RW NX SHD DEV/SHARED
[ 1780.548639] brcmfmac: localseq_vprintf: 0xc88ca000-0xc88cb000           4K     RW NX SHD DEV/SHARED
[ 1780.557651] brcmfmac: localseq_vprintf: 0xc88cc000-0xc88cd000           4K     RW NX SHD DEV/SHARED
[ 1780.566662] brcmfmac: localseq_vprintf: 0xc88ce000-0xc88cf000           4K     RW NX SHD DEV/SHARED
[ 1780.575673] brcmfmac: localseq_vprintf: 0xc88d0000-0xc88d1000           4K     RW NX SHD DEV/SHARED
[ 1780.584686] brcmfmac: localseq_vprintf: 0xc88d2000-0xc88d3000           4K     RW NX SHD DEV/SHARED
[ 1780.593697] brcmfmac: localseq_vprintf: 0xc88d4000-0xc88d5000           4K     RW NX SHD DEV/SHARED
[ 1780.602708] brcmfmac: localseq_vprintf: 0xc88d6000-0xc88d7000           4K     RW NX SHD DEV/SHARED
[ 1780.611720] brcmfmac: localseq_vprintf: 0xc88d8000-0xc88d9000           4K     RW NX SHD DEV/SHARED
[ 1780.620731] brcmfmac: localseq_vprintf: 0xc88da000-0xc88db000           4K     RW NX SHD DEV/SHARED
[ 1780.629734] brcmfmac: localseq_vprintf: 0xc88dc000-0xc88dd000           4K     RW NX SHD DEV/SHARED
[ 1780.638746] brcmfmac: localseq_vprintf: 0xc88de000-0xc88df000           4K     RW NX SHD DEV/SHARED
[ 1780.647759] brcmfmac: localseq_vprintf: 0xc88e0000-0xc88e1000           4K     RW NX SHD DEV/SHARED
[ 1780.656768] brcmfmac: localseq_vprintf: 0xc88e2000-0xc88e3000           4K     RW NX SHD DEV/SHARED
[ 1780.665779] brcmfmac: localseq_vprintf: 0xc88e4000-0xc88e5000           4K     RW NX SHD DEV/SHARED
[ 1780.674792] brcmfmac: localseq_vprintf: 0xc88e6000-0xc88e7000           4K     RW NX SHD DEV/SHARED
[ 1780.683805] brcmfmac: localseq_vprintf: 0xc88e8000-0xc88e9000           4K     RW NX SHD DEV/SHARED
[ 1780.692815] brcmfmac: localseq_vprintf: 0xc88ea000-0xc88ec000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.702432] brcmfmac: localseq_vprintf: 0xc88ed000-0xc88ef000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.712048] brcmfmac: localseq_vprintf: 0xc88f0000-0xc88f2000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.721664] brcmfmac: localseq_vprintf: 0xc88f3000-0xc88f5000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.731281] brcmfmac: localseq_vprintf: 0xc88f6000-0xc88f8000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.740896] brcmfmac: localseq_vprintf: 0xc88fa000-0xc88fb000           4K     RW NX SHD DEV/SHARED
[ 1780.749901] brcmfmac: localseq_vprintf: 0xc88fc000-0xc88fe000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.759516] brcmfmac: localseq_vprintf: 0xc88ff000-0xc8901000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.769132] brcmfmac: localseq_vprintf: 0xc8902000-0xc8904000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.778748] brcmfmac: localseq_vprintf: 0xc8905000-0xc8907000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.788365] brcmfmac: localseq_vprintf: 0xc8908000-0xc890a000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.797rcmfmac: localseq_vprintf: 0xc890b000-0xc890e000          12K     RW NX SHD MEM/CACHED/WBWA
[ 1780.807428] brcmfmac: localseq_vprintf: 0xc890f000-0xc894f000         256K     RW NX SHD MEM/CACHED/WBWA
[ 1780.816894] brcmfmac: localseq_vprintf: 0xc8950000-0xc8990000         256K     RW NX SHD MEM/CACHED/WBWA
[ 1780.826354] brcmfmac: localseq_vprintf: 0xc8aa0000-0xc8aa8000          32K     RW NX SHD DEV/SHARED
[ 1780.835398] brcmfmac: localseq_vprintf: 0xc8ccf000-0xc8cd0000           4K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.845019] brcmfmac: localseq_vprintf: 0xc8cd1000-0xc8cd3000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.854633] brcmfmac: localseq_vprintf: 0xc8cd4000-0xc8cd5000           4K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.864251] brcmfmac: localseq_vprintf: 0xc8cd6000-0xc8cda000          16K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.873866] brcmfmac: localseq_vprintf: 0xc8cdb000-0xc8cdd000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.883483] brcmfmac: localseq_vprintf: 0xc8cde000-0xc8cdf000           4K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.893098] brcmfmac: localseq_vprintf: 0xc8ce0000-0xc8ce1000           4K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.902715] brcmfmac: localseq_vprintf: 0xc8ce5000-0xc8ce6000           4K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.912334] brcmfmac: localseq_vprintf: 0xc8d05000-0xc8d06000           4K     RW NX SHD MEM/CACHED/WBWA
[ 1780.921785] brcmfmac: localseq_vprintf: 0xc8d09000-0xc8d0f000          24K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.931401] brcmfmac: localseq_vprintf: 0xc8d10000-0xc8d16000          24K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.941300] brcmfmac: localseq_vprintf: 0xca800000-0xcac00000           4M     RW NX SHD DEV/SHARED
[ 1780.950358] brcmfmac: localseq_vprintf: 0xfedee000-0xfedf1000          12K     RW NX SHD MEM/CACHED/WBWA
[ 1780.959817] brcmfmac: localseq_vprintf: 0xfedf7000-0xfedfa000          12K     RW NX SHD MEM/CACHED/WBWA
[ 1780.969257] brcmfmac: localseq_vprintf: ---[ vmalloc() End ]---
[ 1780.975156] brcmfmac: localseq_vprintf: ---[ Fixmap Area ]---
[ 1780.980909] brcmfmac: localseq_vprintf: ---[ Vectors ]---
[ 1780.986291] brcmfmac: localseq_vprintf: 0xffff0000-0xffff1000           4K USR ro x  SHD MEM/CACHED/WBWA
[ 1780.995737] sched: RT throttling activated
[ 1780.999822] brcmfmac: localseq_vprintf: 0xffff1000-0xffff2000           4K     ro x  SHD MEM/CACHED/WBWA
[ 1781.009262] brcmfmac: localseq_vprintf: ---[ Vectors End ]---
[ 1781.014991] brcmfmac: brcmf_sync_seqnum: Loopcnt 1 (expected 52, read 52)
root@OpenWrt:/#


^ permalink raw reply	[flat|nested] 115+ messages in thread

* RE: using DMA-API on ARM
@ 2014-12-08 13:47             ` Hante Meuleman
  0 siblings, 0 replies; 115+ messages in thread
From: Hante Meuleman @ 2014-12-08 13:47 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Will Deacon, Arend Van Spriel, Marek Szyprowski,
	linux-arm-kernel, David Miller, linux-kernel, brcm80211-dev-list,
	linux-wireless

[-- Attachment #1: Type: text/plain, Size: 4257 bytes --]

Still using outlook, but will limit the line length, I hope that works for the
moment. Attached is a log with the requested information, it is a little
bit non-standard though. The dump code from the mm was copied in
the driver and called from there, mapping the prints back to our local
printf, but it should produce the same. I did this because I didn't realize
the table is static.

Some background on the test setup: I'm using a Broadcom reference 
design AP platform with an BRCM 4708 host SOC. For the AP router 
platform the opensource packet OpenWRT was used. Some small
modifications were made to get it to work on our HW. Only one core
is enabled for the moment (no time to figure out how to enable the
other one). Openwrt was configured to use kernel 3.18-rc2 and 
the brcmfmac of the compat-wireless code was updated with our 
latest code (minor patches, which have been submitted already). 
The device used is 43602 pcie device. Some modifications to the build
system were made to enable PCIE. The test is to connect with a 
client to the AP and run iperf (TCP). The test can run for many hours
without a problem, but sometimes fails very quickly.

The log: first the ring allocation info is printed. Starting at
16.124847, ring 2, 3 and 4 are rings used for device to host. In this
log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
16 bytes. The next thing printed is the kernel page tables. Then some 
OpenWRT info and the logging of part of the connection setup. Then at 
1780.130752 the logging of the failure starts. The sequence number is 
modulo 253 with ring size of 1024 matches an "old" entry (read 40, 
expected 52). Then the different pointers are printed followed by 
the kernel page table. The code does then a cache invalidate on the 
dma_handle and the next read the sequence number is correct.

Regards,
Hante



Please wrap your message - replying to a message which looks like this in
my editor is far from easy, and gives me much more work to /manually/
reformat it before I can reply to it:

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> The problem is with data coming from device, so DMA from device to host. The $
>
> However: this indicates that dma_alloc_coherent on an ARM target may result i$
>
> Regards,
> Hante

Thanks.

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> However: this indicates that dma_alloc_coherent on an ARM target may
> result in a memory buffer which can be cached which conflicts with
> the API of this function.

If the memory has an alias which is cacheable, it is possible for cache
lines to get allocated via that alias, even if the alias has no explicit
accesses to it.

This is something which I've been going on for quite literally /years/ -
mismatched cache attributes can cause unpredictable behaviour.  I've had
a lot of push back from people who are of the opinion that "if it works
for me, then there isn't a problem" and I eventually gave up fighting
the battle, especially as the ARM architecture people weakened my
reasoning behind it by publishing a relaxation of the "no differing
attributes" issue.  This was particularly true of those who wanted to
use ioremap() on system memory - and cases such as
dma_init_coherent_memory().

So, I never fixed this problem in the original DMA allocator code; I
basically gave up with it.  It's a latent bug which did need to be fixed,
and is still present today in the non-CMA case.

The symptoms which you are reporting sound very much like this kind of
problem - the virtual address for the memory returned by
dma_alloc_coherent() will not be cacheable memory - it will have been
remapped using map_vm_area().  However, there could very well be a fully
cacheable lowmem mapping of that memory, which if a read (speculative or
otherwise) will bring a cache line in, and because the caches are VIPT
or PIPT, that cache line can be hit via the non-cacheable mapping too.

What I /really/ need is more evidence of this to tell those disbelievers
where to stick their flawed arguments. :)

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

[-- Attachment #2: cache_fail_dmesg.txt --]
[-- Type: text/plain, Size: 35592 bytes --]

root@OpenWrt:/# dmesg
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 3.18.0-rc2 (developer@meuleman-test) (gcc version 4.8.3 (OpenWrt/Linaro GCC 4.8-2014.04 r43121) ) #66 SMP Mon Dec 8 12:38:39 CET 2014
[    0.000000] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7),c5387d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] Machine model: Buffalo WZR-1750DHP (BCM4708)
[    0.000000] Memory policy: Data cache writealloc
[    0.000000] On node 0 totalpages: 32768
[    0.000000] free_area_init_node: node 0, pgdat c038ee00, node_mem_map c7efb000
[    0.000000]   Normal zone: 256 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 32768 pages, LIFO batch:7
[    0.000000] PERCPU: Embedded 9 pages/cpu @c7ee3000 s6528 r8192 d22144 u36864
[    0.000000] pcpu-alloc: s6528 r8192 d22144 u36864 alloc=9*4096
[    0.000000] pcpu-alloc: [0] 0 [0] 1
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 32512
[    0.000000] Kernel command line: console=ttyS0,115200
[    0.000000] PID hash table entries: 512 (order: -1, 2048 bytes)
[    0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
[    0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Memory: 125936K/131072K available (2682K kernel code, 103K rwdata, 744K rodata, 164K init, 188K bss, 5136K reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xffe00000   (2048 kB)
[    0.000000]     vmalloc : 0xc8800000 - 0xff000000   ( 872 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xc8000000   ( 128 MB)
[    0.000000]     modules : 0xbf000000 - 0xc0000000   (  16 MB)
[    0.000000]       .text : 0xc0008000 - 0xc0360dc4   (3428 kB)
[    0.000000]       .init : 0xc0361000 - 0xc038a000   ( 164 kB)
[    0.000000]       .data : 0xc038a000 - 0xc03a3eb8   ( 104 kB)
[    0.000000]        .bss : 0xc03a3eb8 - 0xc03d2ebc   ( 189 kB)
[    0.000000] Hierarchical RCU implementation.
[    0.000000]  RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2.
[    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=2
[    0.000000] NR_IRQS:16 nr_irqs:16 16
[    0.000000] PL310 OF: cache setting yield illegal associativity
[    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
[    0.000000] L2C-310 enabling early BRESP for Cortex-A9
[    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
[    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
[    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
[    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001
[    0.000017] sched_clock: 64 bits at 400MHz, resolution 2ns, wraps every 2748779069440ns
[    0.000315] Calibrating delay loop... 1594.16 BogoMIPS (lpj=7970816)
[    0.090133] pid_max: default: 32768 minimum: 301
[    0.090299] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.090312] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.090822] CPU: Testing write buffer coherency: ok
[    0.091084] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
[    0.091152] Setting up static identity map for 0x11728 - 0x1175c
[    0.092455] Brought up 1 CPUs
[    0.092471] SMP: Total of 1 processors activated.
[    0.092481] CPU: All CPU(s) started in SVC mode.
[    0.099682] NET: Registered protocol family 16
[    0.100425] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.106341] usbcore: registered new interface driver usbfs
[    0.106422] usbcore: registered new interface driver hub
[    0.106500] usbcore: registered new device driver usb
[    0.107259] Switched to clocksource arm_global_timer
[    0.108567] NET: Registered protocol family 2
[    0.109224] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    0.109251] TCP bind hash table entries: 1024 (order: 1, 8192 bytes)
[    0.109278] TCP: Hash tables configured (established 1024 bind 1024)
[    0.109350] TCP: reno registered
[    0.109368] UDP hash table entries: 256 (order: 1, 8192 bytes)
[    0.109404] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes)
[    0.109669] NET: Registered protocol family 1
[    0.109737] PCI: CLS 0 bytes, default 64
[    0.110768] futex hash table entries: 512 (order: 3, 32768 bytes)
[    0.111905] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.111932] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[    0.112155] msgmni has been set to 245
[    0.113050] io scheduler noop registered
[    0.113073] io scheduler deadline registered (default)
[    0.113329] Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
[    0.113952] console [ttyS0] disabled
[    0.114026] of_serial 18000300.serial: ttyS0 at MMIO 0x18000300 (irq = 117, base_baud = 6250000) is a 16550
[    0.514919] console [ttyS0] enabled
[    0.518713] of_serial 18000400.serial: ttyS1 at MMIO 0x18000400 (irq = 117, base_baud = 6250000) is a 16550
[    0.603994] no nvram found
[    0.606975] Unsupported SPROM revision 0 detected. Will extract v1
[    0.613693] bcmnand: Broadcom NAND Controller driver loaded
[    0.620439] bgmac: Broadcom 47xx GBit MAC driver loaded
[    0.625723] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    0.632256] ehci-pci: EHCI PCI platform driver
[    0.636742] ehci-platform: EHCI generic platform driver
[    0.642218] bcma: bus0: Found chip with id 53010, rev 0x00 and package 0x02
[    0.649209] bcma: bus0: Core 0 found: ChipCommon (manuf 0x4BF, id 0x800, rev 0x2A, class 0x0)
[    0.657791] bcma: bus0: Core 1 found: Chipcommon B (manuf 0x4BF, id 0x50B, rev 0x01, class 0x0)
[    0.666522] bcma: bus0: Core 2 found: DMA (manuf 0x4BF, id 0x502, rev 0x01, class 0x0)
[    0.674477] bcma: bus0: Core 3 found: GBit MAC (manuf 0x4BF, id 0x82D, rev 0x05, class 0x0)
[    0.682858] bcma: bus0: Core 4 found: GBit MAC (manuf 0x4BF, id 0x82D, rev 0x05, class 0x0)
[    0.691249] bcma: bus0: Core 5 found: GBit MAC (manuf 0x4BF, id 0x82D, rev 0x05, class 0x0)
[    0.699635] bcma: bus0: Core 6 found: GBit MAC (manuf 0x4BF, id 0x82D, rev 0x05, class 0x0)
[    0.707993] bcma: bus0: Core 7 found: PCIe Gen 2 (manuf 0x4BF, id 0x501, rev 0x01, class 0x0)
[    0.716528] bcma: bus0: Core 8 found: PCIe Gen 2 (manuf 0x4BF, id 0x501, rev 0x01, class 0x0)
[    0.725074] bcma: bus0: Core 9 found: PCIe Gen 2 (manuf 0x4BF, id 0x501, rev 0x01, class 0x0)
[    0.733641] bcma: bus0: Core 10 found: ARM Cortex A9 core (ihost) (manuf 0x4BF, id 0x510, rev 0x01, class 0x0)
[    0.743658] bcma: bus0: Core 11 found: USB 2.0 (manuf 0x4BF, id 0x504, rev 0x01, class 0x0)
[    0.752036] bcma: bus0: Core 12 found: USB 3.0 (manuf 0x4BF, id 0x505, rev 0x01, class 0x0)
[    0.760426] bcma: bus0: Core 13 found: SDIO3 (manuf 0x4BF, id 0x503, rev 0x01, class 0x0)
[    0.768626] bcma: bus0: Core 14 found: ARM Cortex A9 JTAG (manuf 0x4BF, id 0x506, rev 0x01, class 0x0)
[    0.777962] bcma: bus0: Core 15 found: Denali DDR2/DDR3 memory controller (manuf 0x4BF, id 0x507, rev 0x01, class 0x0)
[    0.788681] bcma: bus0: Core 16 found: ROM (manuf 0x4BF, id 0x508, rev 0x01, class 0x0)
[    0.796726] bcma: bus0: Core 17 found: NAND flash controller (manuf 0x4BF, id 0x509, rev 0x01, class 0x0)
[    0.806325] bcma: bus0: Core 18 found: SPI flash controller (manuf 0x4BF, id 0x50A, rev 0x01, class 0x0)
[    0.820252] bcmnand: NAND Controller rev 6.1
[    0.840228] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xdc
[    0.846565] nand: Micron NAND 512MiB 3,3V 8-bit
[    0.851094] nand: 512MiB, SLC, page size: 2048, OOB size: 64
[    1.220976] bcm53xxspiflash spi32766.0: mx25l25635e (32768 Kbytes)
[    2.585498] next_part_offset limited to 1000000
[    2.590014] 5 bcm47xxpart partitions found on MTD device spi32766.0
[    2.596260] Creating 5 MTD partitions on "spi32766.0":
[    2.601389] 0x000000000000-0x000000040000 : "boot"
[    2.606848] 0x000000040000-0x000000ff0000 : "firmware"
[    2.612569] 0x00000004001c-0x000000184c00 : "linux"
[    2.617429] mtd: partition "linux" must either start or end on erase block boundary or be smaller than an erase block -- forcing read-only
[    2.630415] 0x000000184c00-0x000000ff0000 : "rootfs"
[    2.635364] mtd: partition "rootfs" must either start or end on erase block boundary or be smaller than an erase block -- forcing read-only
[    2.648435] mtd: device 4 (rootfs) set to be root filesystem
[    2.654360] 1 squashfs-split partitions found on MTD device rootfs
[    2.660542] 0x000000450000-0x000000ff0000 : "rootfs_data"
[    2.666561] 0x000000ff0000-0x000001000000 : "nvram"
[    2.672108] bcma: bus0: Found sprom from device tree provider
[    2.678032] bgmac bcma0:3: Invalid MAC addr: 00:00:00:00:00:00
[    2.683900] bgmac bcma0:3: Using random MAC: a2:68:1a:ca:99:26
[    2.689770] bgmac bcma0:3: Found PHY addr: 0
[    2.698590] libphy: bgmac mii bus: probed
[    2.781466] b53_common: found switch: BCM53011, rev 3
[    2.787094] netif_napi_add() called with weight 128 on device eth0
[    2.793422] bgmac bcma0:4: Invalid MAC addr: 00:00:00:00:00:00
[    2.799255] bgmac bcma0:4: Using random MAC: 6a:b7:e9:ad:58:4c
[    2.805138] bgmac bcma0:4: Found PHY addr: 0
[    2.812607] libphy: bgmac mii bus: probed
[    2.890939] bgmac: Unsupported core_unit 2
[    2.895033] bgmac: probe of bcma0:5 failed with error -524
[    2.900619] bgmac: Unsupported core_unit 3
[    2.904704] bgmac: probe of bcma0:6 failed with error -524
[    2.910271] pcie2_bcma bcma0:7: scanning bus
[    3.164199] pcie2_bcma bcma0:7: switching to GEN2
[    3.418495] pcie2_bcma bcma0:7: PCI host bridge to bus 0000:00
[    3.424332] pci_bus 0000:00: root bus resource [mem 0x08000000-0x0fffffff]
[    3.431189] pci_bus 0000:00: root bus resource [io  0x8000000-0xfffffff]
[    3.437859] pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff]
[    3.445774] pci 0000:00:00.0: [14e4:8011] type 01 class 0x060400
[    3.445842] pci 0000:00:00.0: PME# supported from D0 D3hot D3cold
[    3.446051] PCI: bus0: Fast back to back transfers disabled
[    3.451757] pci 0000:01:00.0: [14e4:43bc] type 00 class 0x028000
[    3.451792] pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x00007fff 64bit]
[    3.451815] pci 0000:01:00.0: reg 0x18: [mem 0x00000000-0x003fffff 64bit]
[    3.451908] pci 0000:01:00.0: supports D1 D2
[    3.451920] pci 0000:01:00.0: PME# supported from D0 D1 D2 D3hot D3cold
[    3.452102] PCI: bus1: Fast back to back transfers disabled
[    3.457657] pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
[    3.457675] pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 01
[    3.457724] pci 0000:00:00.0: BAR 8: assigned [mem 0x08000000-0x085fffff]
[    3.464514] pci 0000:01:00.0: BAR 2: assigned [mem 0x08000000-0x083fffff 64bit]
[    3.471808] pci 0000:01:00.0: BAR 0: assigned [mem 0x08400000-0x08407fff 64bit]
[    3.479098] pci 0000:00:00.0: PCI bridge to [bus 01]
[    3.484050] pci 0000:00:00.0:   bridge window [mem 0x08000000-0x085fffff]
[    3.490879] pci 0000:01:00.0: Max Payload Size 128, but upstream 0000:00:00.0 set to 512; if necessary, use "pci=pcie_bus_safe" and report a bug
[    3.503894] pcie2_bcma bcma0:8: scanning bus
[    3.757879] pcie2_bcma bcma0:9: scanning bus
[    4.012438] bcma: bus0: Bus registered
[    4.016517] TCP: cubic registered
[    4.019832] NET: Registered protocol family 17
[    4.024381] bridge: automatic filtering via arp/ip/ip6tables has been deprecated. Update your scripts to load br_netfilter if you need this.
[    4.036954] 8021q: 802.1Q VLAN Support v1.8
[    4.041208] Registering SWP/SWPB emulation handler
[    4.064654] VFS: Mounted root (squashfs filesystem) readonly on device 31:4.
[   926] Freeing unused kernel memory: 164K (c0361000 - c038a000)
[    6.136424] gpio-keys gpio-keys: failed to request irq:-6 for gpio:11
[    6.142919] gpio-keys gpio-keys: failed to request irq:-6 for gpio:12
[    6.149333] gpio-keys gpio-keys: failed to request irq:-6 for gpio:13
[    6.155756] gpio-keys gpio-keys: failed to request irq:-6 for gpio:14
[    6.162180] gpio-keys gpio-keys: failed to request irq:-6 for gpio:15
[    6.234566] random: mktemp urandom read with 41 bits of entropy available
[    9.650068] jffs2: notice: (288) jffs2_build_xattr_subsystem: complete building xattr subsystem, 0 of xdatum (0 unchecked, 0 orphan) and 0 of xref (0 dead, 0 orphan) found.
[    9.666442] overlayfs: missing upperdir or lowerdir or workdir
[   14.159733] Loading modules backported from Linux version master-2014-10-08-0-g0275925
[   14.167681] Backport generated by backports.git backports-20140905-1-gde42785
[   14.180633] cfg80211: Calling CRDA to update world regulatory domain
[   14.192280] cfg80211: World regulatory domain updated:
[   14.197413] cfg80211:  DFS Master region: unset
[   14.201802] cfg80211:   (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)
[   14.211517] cfg80211:   (2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[   14.219481] cfg80211:   (2457000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[   14.227454] cfg80211:   (2474000 KHz - 2494000 KHz @ 20000 KHz), (N/A, 2000 mBm), (N/A)
[   14.235427] cfg80211:   (5170000 KHz - 5250000 KHz @ 160000 KHz), (N/A, 2000 mBm), (N/A)
[   14.243489] cfg80211:   (5250000 KHz - 5330000 KHz @ 160000 KHz), (N/A, 2000 mBm), (0 s)
[   14.251551] cfg80211:   (5490000 KHz - 5730000 KHz @ 160000 KHz), (N/A, 2000 mBm), (0 s)
[   14.259604] cfg80211:   (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A)
[   14.267577] cfg80211:   (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 0 mBm), (N/A)
[   14.289862] usbcore: registered new interface driver brcmfmac
[   14.295733] brcmfmac 0000:01:00.0: enabling device (0140 -> 0142)
[   15.325236] brcmfmac 0000:01:00.0: Direct firmware load for brcm/brcmfmac43602-pcie.txt failed with error -2
[   16.124847] brcmfmac: brcmf_pcie_alloc_dma_and_ring: RING 0: virtual address: c8ccf000, physical address:   (null):06c06000
[   16.136056] brcmfmac: brcmf_pcie_alloc_dma_and_ring: RING 1: virtual address: c8cd1000, physical address:   (null):06c12000
[   16.147179] brcmfmac: brcmf_pcie_alloc_dma_and_ring: RING 2: virtual address: c8cd4000, physical address:   (null):06c07000
[   16.158377] brcmfmac: brcmf_pcie_alloc_dma_and_ring: RING 3: virtual address: c8cd6000, physical address:   (null):073bc000
[   16.169526] brcmfmac: brcmf_pcie_alloc_dma_and_ring: RING 4: virtual address: c8cdb000, physical address:   (null):06c14000
[   16.301412] brcmfmac: brcmf_msgbuf_rxbuf_data_post: Failed to reserve space in commonring
[   16.321273] brcmfmac: localseq_vprintf: ---[ Modules ]---
[   16.326768] brcmfmac: localseq_vprintf: 0xbf000000-0xbf002000           8K     RW x  SHD MEM/CACHED/WBWA
[   16.336242] brcmfmac: localseq_vprintf: 0xbf005000-0xbf007000           8K     RW x  SHD MEM/CACHED/WBWA
[   16.345696] brcmfmac: localseq_vprintf: 0xbf00a000-0xbf00b000           4K     RW x  SHD MEM/CACHED/WBWA
[   16.355147] brcmfmac: localseq_vprintf: 0xbf00e000-0xbf03d000         188K     RW x  SHD MEM/CACHED/WBWA
[   16.364599] brcmfmac: localseq_vprintf: 0xbf046000-0xbf06f000         164K     RW x  SHD MEM/CACHED/WBWA
[   16.374064] brcmfmac: localseq_vprintf: ---[ Kernel Mapping ]---
[   16.380045] brcmfmac: localseq_vprintf: 0xc0000000-0xc0400000           4M     RW x  SHD
[   16.388113] brcmfmac: localseq_vprintf: 0xc0400000-0xc8000000         124M     RW NX SHD
[   16.396168] brcmfmac: localseq_vprintf: ---[ vmalloc() Area ]---
[   16.402163] brcmfmac: localseq_vprintf: 0xc8800000-0xc8801000           4K     RW NX SHD DEV/SHARED
[   16.411173] brcmfmac: localseq_vprintf: 0xc8802000-0xc8803000           4K     RW NX SHD DEV/SHARED
[   16.420184] brcmfmac: localseq_vprintf: 0xc8804000-0xc8805000           4K     RW NX SHD DEV/SHARED
[   16.429188] brcmfmac: localseq_vprintf: 0xc8806000-0xc8807000           4K     RW NX SHD DEV/SHARED
[   16.438200] brcmfmac: localseq_vprintf: 0xc8808000-0xc8809000           4K     RW NX SHD DEV/SHARED
[   16.447215] brcmfmac: localseq_vprintf: 0xc880e000-0xc884e000         256K     RW NX SHD MEM/BUFFERABLE/WC
[   16.456840] brcmfmac: localseq_vprintf: 0xc884f000-0xc8895000         280K     RW NX SHD MEM/CACHED/WBWA
[   16.466287] brcmfmac: localseq_vprintf: 0xc8896000-0xc8897000           4K     RW NX SHD DEV/SHARED
[   16.475299] brcmfmac: localseq_vprintf: 0xc8898000-0xc8899000           4K     RW NX SHD DEV/SHARED
[   16.484310] brcmfmac: localseq_vprintf: 0xc889a000-0xc889b000           4K     RW NX SHD DEV/SHARED
[   16.493322] brcmfmac: localseq_vprintf: 0xc889e000-0xc889f000           4K     RW NX SHD DEV/SHARED
[   16.502335] brcmfmac: localseq_vprintf: 0xc88a0000-0xc88a1000           4K     RW NX SHD DEV/SHARED
[   16.511345] brcmfmac: localseq_vprintf: 0xc88a2000-0xc88a3000           4K     RW NX SHD DEV/SHARED
[   16.520357] brcmfmac: localseq_vprintf: 0xc88a4000-0xc88a5000           4K     RW NX SHD DEV/SHARED
[   16.529361] brcmfmac: localseq_vprintf: 0xc88a6000-0xc88a7000           4K     RW NX SHD DEV/SHARED
[   16.538372] brcmfmac: localseq_vprintf: 0xc88a8000-0xc88a9000           4K     RW NX SHD DEV/SHARED
[   16.547382] brcmfmac: localseq_vprintf: 0xc88aa000-0xc88ab000           4K     RW NX SHD DEV/SHARED
[   16.556394] brcmfmac: localseq_vprintf: 0xc88ac000-0xc88ad000           4K     RW NX SHD DEV/SHARED
[   16.565404] brcmfmac: localseq_vprintf: 0xc88ae000-0xc88af000           4K     RW NX SHD DEV/SHARED
[   16.574417] brcmfmac: localseq_vprintf: 0xc88b0000-0xc88b1000           4K     RW NX SHD DEV/SHARED
[   16.583428] brcmfmac: localseq_vprintf: 0xc88b2000-0xc88b3000           4K     RW NX SHD DEV/SHARED
[   16.592441] brcmfmac: localseq_vprintf: 0xc88b4000-0xc88b5000           4K     RW NX SHD DEV/SHARED
[   16.601451] brcmfmac: localseq_vprintf: 0xc88b6000-0xc88b7000           4K     RW NX SHD DEV/SHARED
[   16.610464] brcmfmac: localseq_vprintf: 0xc88b8000-0xc88b9000           4K     RW NX SHD DEV/SHARED
[   16.619467] brcmfmac: localseq_vprintf: 0xc88ba000-0xc88bb000           4K     RW NX SHD DEV/SHARED
[   16.628478] brcmfmac: localseq_vprintf: 0xc88bc000-0xc88bd000           4K     RW NX SHD DEV/SHARED
[   16.637490] brcmfmac: localseq_vprintf: 0xc88be000-0xc88bf000           4K     RW NX SHD DEV/SHARED
[   16.646503] brcmfmac: localseq_vprintf: 0xc88c0000-0xc88c1000           4K     RW NX SHD DEV/SHARED
[   16.655512] brcmfmac: localseq_vprintf: 0xc88c2000-0xc88c3000           4K     RW NX SHD DEV/SHARED
[   16.664524] brcmfmac: localseq_vprintf: 0xc88c4000-0xc88c5000           4K     RW NX SHD DEV/SHARED
[   16.673535] brcmfmac: localseq_vprintf: 0xc88c6000-0xc88c7000           4K     RW NX SHD DEV/SHARED
[   16.682547] brcmfmac: localseq_vprintf: 0xc88c8000-0xc88c9000           4K     RW NX SHD DEV/SHARED
[   16.691558] brcmfmac: localseq_vprintf: 0xc88ca000-0xc88cb000           4K     RW NX SHD DEV/SHARED
[   16.700569] brcmfmac: localseq_vprintf: 0xc88cc000-0xc88cd000           4K     RW NX SHD DEV/SHARED
[   16.709573] brcmfmac: localseq_vprintf: 0xc88ce000-0xc88cf000           4K     RW NX SHD DEV/SHARED
[   16.718585] brcmfmac: localseq_vprintf: 0xc88d0000-0xc88d1000           4K     RW NX SHD DEV/SHARED
[   16.727596] brcmfmac: localseq_vprintf: 0xc88d2000-0xc88d3000           4K     RW NX SHD DEV/SHARED
[   16.736608] brcmfmac: localseq_vprintf: 0xc88d4000-0xc88d5000           4K     RW NX SHD DEV/SHARED
[   16.745618] brcmfmac: localseq_vprintf: 0xc88d6000-0xc88d7000           4K     RW NX SHD DEV/SHARED
[   16.754631] brcmfmac: localseq_vprintf: 0xc88d8000-0xc88d9000           4K     RW NX SHD DEV/SHARED
[   16.763642] brcmfmac: localseq_vprintf: 0xc88da000-0xc88db000           4K     RW NX SHD DEV/SHARED
[   16.772654] brcmfmac: localseq_vprintf: 0xc88dc000-0xc88dd000           4K     RW NX SHD DEV/SHARED
[   16.781665] brcmfmac: localseq_vprintf: 0xc88de000-0xc88df000           4K     RW NX SHD DEV/SHARED
[   16.790677] brcmfmac: localseq_vprintf: 0xc88e0000-0xc88e1000           4K     RW NX SHD DEV/SHARED
[   16.799680] brcmfmac: localseq_vprintf: 0xc88e2000-0xc88e3000           4K     RW NX SHD DEV/SHARED
[   16.808691] brcmfmac: localseq_vprintf: 0xc88e4000-0xc88e5000           4K     RW NX SHD DEV/SHARED
[   16.817703] brcmfmac: localseq_vprintf: 0xc88e6000-0xc88e7000           4K     RW NX SHD DEV/SHARED
[   16.826714] brcmfmac: localseq_vprintf: 0xc88e8000-0xc88e9000           4K     RW NX SHD DEV/SHARED
[   16.835725] brcmfmac: localseq_vprintf: 0xc88ea000-0xc88ec000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.845343] brcmfmac: localseq_vprintf: 0xc88ed000-0xc88ef000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.854959] brcmfmac: localseq_vprintf: 0xc88f0000-0xc88f2000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.864575] brcmfmac: localseq_vprintf: 0xc88f3000-0xc88f5000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.874191] brcmfmac: localseq_vprintf: 0xc88f6000-0xc88f8000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.883807] brcmfmac: localseq_vprintf: 0xc88fa000-0xc88fb000           4K     RW NX SHD DEV/SHARED
[   16.892819] brcmfmac: localseq_vprintf: 0xc88fc000-0xc88fe000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.902435] brcmfmac: localseq_vprintf: 0xc88ff000-0xc8901000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.912051] brcmfmac: localseq_vprintf: 0xc8902000-0xc8904000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.921667] brcmfmac: localseq_vprintf: 0xc8905000-0xc8907000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.931285] brcmfmac: localseq_vprintf: 0xc8908000-0xc890a000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.940901] brcmfmac: localseq_vprintf: 0xc890b000-0xc890e000          12K     RW NX SHD MEM/CACHED/WBWA
[   16.950347] brcmfmac: localseq_vprintf: 0xc890f000-0xc894f000         256K     RW NX SHD MEM/CACHED/WBWA
[   16.959792] brcmfmac: localseq_vprintf: 0xc8950000-0xc8990000         256K     RW NX SHD MEM/CACHED/WBWA
[   16.969256] brcmfmac: localseq_vprintf: 0xc8aa0000-0xc8aa8000          32K     RW NX SHD DEV/SHARED
[   16.978298] brcmfmac: localseq_vprintf: 0xc8ccf000-0xc8cd0000           4K     RW NX SHD MEM/BUFFERABLE/WC
[   16.987920] brcmfmac: localseq_vprintf: 0xc8cd1000-0xc8cd3000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   16.997536] brcmfmac: localseq_vprintf: 0xc8cd4000-0xc8cd5000           4K     RW NX SHD MEM/BUFFERABLE/WC
[   17.007152] brcmfmac: localseq_vprintf: 0xc8cd6000-0xc8cda000          16K     RW NX SHD MEM/BUFFERABLE/WC
[   17.016778] brcmfmac: localseq_vprintf: 0xc8cdb000-0xc8cdd000           8K     RW NX SHD MEM/BUFFERABLE/WC
[   17.026394] brcmfmac: localseq_vprintf: 0xc8cde000-0xc8cdf000           4K     RW NX SHD MEM/BUFFERABLE/WC
[   17.036009] brcmfmac: localseq_vprintf: 0xc8ce0000-0xc8ce1000           4K     RW NX SHD MFERABLE/WC
[   17.045626] brcmfmac: localseq_vprintf: 0xc8ce5000-0xc8ce6000           4K     RW NX SHD MEM/BUFFERABLE/WC
[   17.055524] brcmfmac: localseq_vprintf: 0xca800000-0xcac00000           4M     RW NX SHD DEV/SHARED
[   17.064597] brcmfmac: localseq_vprintf: 0xfedee000-0xfedf1000          12K     RW NX SHD MEM/CACHED/WBWA
[   17.074046] brcmfmac: localseq_vprintf: 0xfedf7000-0xfedfa000          12K     RW NX SHD MEM/CACHED/WBWA
[   17.083499] brcmfmac: localseq_vprintf: ---[ vmalloc() End ]---
[   17.089392] brcmfmac: localseq_vprintf: ---[ Fixmap Area ]---
[   17.095145] brcmfmac: localseq_vprintf: ---[ Vectors ]---
[   17.100534] brcmfmac: localseq_vprintf: 0xffff0000-0xffff1000           4K USR ro x  SHD MEM/CACHED/WBWA
[   17.109969] brcmfmac: localseq_vprintf: 0xffff1000-0xffff2000           4K     ro x  SHD MEM/CACHED/WBWA
[   17.119406] brcmfmac: localseq_vprintf: ---[ Vectors End ]---
[   20.683755] device eth0.1 entered promiscuous mode
[   20.688542] device eth0 entered promiscuous mode
[   20.714866] br-lan: port 1(eth0.1) entered forwarding state
[   20.720475] br-lan: port 1(eth0.1) entered forwarding state
[   22.720161] br-lan: port 1(eth0.1) entered forwarding state
[   22.829502] brcmfmac: brcmf_add_if: ERROR: netdev:wlan0 already exists
[   22.836043] brcmfmac: brcmf_add_if: ignore IF event
[   22.851645] device wlan0 entered promiscuous mode
[   22.856391] br-lan: port 2(wlan0) entered forwarding state
[   22.861913] br-lan: port 2(wlan0) entered forwarding state
[   23.060471] brcmfmac: brcmf_add_if: ERROR: netdev:wlan0 already exists
[   23.066977] brcmfmac: brcmf_add_if: ignore IF event
[   24.870181] br-lan: port 2(wlan0) entered forwarding state
[   35.830824] brcmfmac: brcmf_cfg80211_change_station: Change station, MAC 00:90:4c:0c:c1:54
[   35.839157] brcmfmac: brcmf_cfg80211_change_station: Change station, mask 0x001c set 0x0000
[   48.582775] random: nonblocking pool is initialized
[ 1780.130752] brcmfmac: brcmf_sync_seqnum: Sequence number failure (expected 52, read 40)
[ 1780.138733] brcmfmac: brcmf_sync_seqnum: Sequence number pointer c8cd600c, as part of struct at address c8cd6000
[ 1780.148891] brcmfmac: brcmf_sync_seqnum: Struct size 16
[ 1780.154102] brcmfmac: brcmf_sync_seqnum: dma_handle of ring:   (null):073bc000, dma_to_pfn(dma_handle): 0x000073bc
[ 1780.164321] brcmfmac: brcmf_sync_seqnum: PHYS_PFN_OFFSET: 0x00000000
[ 1780.171601] brcmfmac: brcmf_sync_seqnum: ========= walk_pgd(): ==========
[ 1780.178361] brcmfmac: localseq_vprintf: ---[ Modules ]---
[ 1780.183851] brcmfmac: localseq_vprintf: 0xbf000000-0xbf002000           8K     RW x  SHD MEM/CACHED/WBWA
[ 1780.193308] brcmfmac: localseq_vprintf: 0xbf005000-0xbf007000           8K     RW x  SHD MEM/CACHED/WBWA
[ 1780.202756] brcmfmac: localseq_vprintf: 0xbf00a000-0xbf00b000           4K     RW x  SHD MEM/CACHED/WBWA
[ 1780.212210] brcmfmac: localseq_vprintf: 0xbf00e000-0xbf03d000         188K     RW x  SHD MEM/CACHED/WBWA
[ 1780.221663] brcmfmac: localseq_vprintf: 0xbf046000-0xbf06f000         164K     RW x  SHD MEM/CACHED/WBWA
[ 1780.231128] brcmfmac: localseq_vprintf: ---[ Kernel Mapping ]---
[ 1780.237109] brcmfmac: localseq_vprintf: 0xc0000000-0xc0400000           4M     RW x  SHD
[ 1780.245176] brcmfmac: localseq_vprintf: 0xc0400000-0xc8000000         124M     RW NX SHD
[ 1780.253234] brcmfmac: localseq_vprintf: ---[ vmalloc() Area ]---
[ 1780.259217] brcmfmac: localseq_vprintf: 0xc8800000-0xc8801000           4K     RW NX SHD DEV/SHARED
[ 1780.268228] brcmfmac: localseq_vprintf: 0xc8802000-0xc8803000           4K     RW NX SHD DEV/SHARED
[ 1780.277240] brcmfmac: localseq_vprintf: 0xc8804000-0xc8805000           4K     RW NX SHD DEV/SHARED
[ 1780.286250] brcmfmac: localseq_vprintf: 0xc8806000-0xc8807000           4K     RW NX SHD DEV/SHARED
[ 1780.295263] brcmfmac: localseq_vprintf: 0xc8808000-0xc8809000           4K     RW NX SHD DEV/SHARED
[ 1780.304278] brcmfmac: localseq_vprintf: 0xc880e000-0xc884e000         256K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.313903] brcmfmac: localseq_vprintf: 0xc884f000-0xc8895000         280K     RW NX SHD MEM/CACHED/WBWA
[ 1780.323351] brcmfmac: localseq_vprintf: 0xc8896000-0xc8897000           4K     RW NX SHD DEV/SHARED
[ 1780.332362] brcmfmac: localseq_vprintf: 0xc8898000-0xc8899000           4K     RW NX SHD DEV/SHARED
[ 1780.341375] brcmfmac: localseq_vprintf: 0xc889a000-0xc889b000           4K     RW NX SHD DEV/SHARED
[ 1780.350378] brcmfmac: localseq_vprintf: 0xc889e000-0xc889f000           4K     RW NX SHD DEV/SHARED
[ 1780.359389] brcmfmac: localseq_vprintf: 0xc88a0000-0xc88a1000           4K     RW NX SHD DEV/SHARED
[ 1780.368400] brcmfmac: localseq_vprintf: 0xc88a2000-0xc88a3000           4K     RW NX SHD DEV/SHARED
[ 1780.377411] brcmfmac: localseq_vprintf: 0xc88a4000-0xc88a5000           4K     RW NX SHD DEV/SHARED
[ 1780.386423] brcmfmac: localseq_vprintf: 0xc88a6000-0xc88a7000           4K     RW NX SHD DEV/SHARED
[ 1780.395434] brcmfmac: localseq_vprintf: 0xc88a8000-0xc88a9000           4K     RW NX SHD DEV/SHARED
[ 1780.404459] brcmfmac: localseq_vprintf: 0xc88aa000-0xc88ab000           4K     RW NX SHD DEV/SHARED
[ 1780.413477] brcmfmac: localseq_vprintf: 0xc88ac000-0xc88ad000           4K     RW NX SHD DEV/SHARED
[ 1780.422495] brcmfmac: localseq_vprintf: 0xc88ae000-0xc88af000           4K     RW NX SHD DEV/SHARED
[ 1780.431507] brcmfmac: localseq_vprintf: 0xc88b0000-0xc88b1000           4K     RW NX SHD DEV/SHARED
[ 1780.440510] brcmfmac: localseq_vprintf: 0xc88b2000-0xc88b3000           4K     RW NX SHD DEV/SHARED
[ 1780.449522] brcmfmac: localseq_vprintf: 0xc88b4000-0xc88b5000           4K     RW NX SHD DEV/SHARED
[ 1780.458533] brcmfmac: localseq_vprintf: 0xc88b6000-0xc88b7000           4K     RW NX SHD DEV/SHARED
[ 1780.467544] brcmfmac: localseq_vprintf: 0xc88b8000-0xc88b9000           4K     RW NX SHD DEV/SHARED
[ 1780.476556] brcmfmac: localseq_vprintf: 0xc88ba000-0xc88bb000           4K     RW NX SHD DEV/SHARED
[ 1780.485566] brcmfmac: localseq_vprintf: 0xc88bc000-0xc88bd000           4K     RW NX SHD DEV/SHARED
[ 1780.494579] brcmfmac: localseq_vprintf: 0xc88be000-0xc88bf000           4K     RW NX SHD DEV/SHARED
[ 1780.503590] brcmfmac: localseq_vprintf: 0xc88c0000-0xc88c1000           4K     RW NX SHD DEV/SHARED
[ 1780.512601] brcmfmac: localseq_vprintf: 0xc88c2000-0xc88c3000           4K     RW NX SHD DEV/SHARED
[ 1780.521613] brcmfmac: localseq_vprintf: 0xc88c4000-0xc88c5000           4K     RW NX SHD DEV/SHARED
[ 1780.530624] brcmfmac: localseq_vprintf: 0xc88c6000-0xc88c7000           4K     RW NX SHD DEV/SHARED
[ 1780.539629] brcmfmac: localseq_vprintf: 0xc88c8000-0xc88c9000           4K     RW NX SHD DEV/SHARED
[ 1780.548639] brcmfmac: localseq_vprintf: 0xc88ca000-0xc88cb000           4K     RW NX SHD DEV/SHARED
[ 1780.557651] brcmfmac: localseq_vprintf: 0xc88cc000-0xc88cd000           4K     RW NX SHD DEV/SHARED
[ 1780.566662] brcmfmac: localseq_vprintf: 0xc88ce000-0xc88cf000           4K     RW NX SHD DEV/SHARED
[ 1780.575673] brcmfmac: localseq_vprintf: 0xc88d0000-0xc88d1000           4K     RW NX SHD DEV/SHARED
[ 1780.584686] brcmfmac: localseq_vprintf: 0xc88d2000-0xc88d3000           4K     RW NX SHD DEV/SHARED
[ 1780.593697] brcmfmac: localseq_vprintf: 0xc88d4000-0xc88d5000           4K     RW NX SHD DEV/SHARED
[ 1780.602708] brcmfmac: localseq_vprintf: 0xc88d6000-0xc88d7000           4K     RW NX SHD DEV/SHARED
[ 1780.611720] brcmfmac: localseq_vprintf: 0xc88d8000-0xc88d9000           4K     RW NX SHD DEV/SHARED
[ 1780.620731] brcmfmac: localseq_vprintf: 0xc88da000-0xc88db000           4K     RW NX SHD DEV/SHARED
[ 1780.629734] brcmfmac: localseq_vprintf: 0xc88dc000-0xc88dd000           4K     RW NX SHD DEV/SHARED
[ 1780.638746] brcmfmac: localseq_vprintf: 0xc88de000-0xc88df000           4K     RW NX SHD DEV/SHARED
[ 1780.647759] brcmfmac: localseq_vprintf: 0xc88e0000-0xc88e1000           4K     RW NX SHD DEV/SHARED
[ 1780.656768] brcmfmac: localseq_vprintf: 0xc88e2000-0xc88e3000           4K     RW NX SHD DEV/SHARED
[ 1780.665779] brcmfmac: localseq_vprintf: 0xc88e4000-0xc88e5000           4K     RW NX SHD DEV/SHARED
[ 1780.674792] brcmfmac: localseq_vprintf: 0xc88e6000-0xc88e7000           4K     RW NX SHD DEV/SHARED
[ 1780.683805] brcmfmac: localseq_vprintf: 0xc88e8000-0xc88e9000           4K     RW NX SHD DEV/SHARED
[ 1780.692815] brcmfmac: localseq_vprintf: 0xc88ea000-0xc88ec000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.702432] brcmfmac: localseq_vprintf: 0xc88ed000-0xc88ef000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.712048] brcmfmac: localseq_vprintf: 0xc88f0000-0xc88f2000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.721664] brcmfmac: localseq_vprintf: 0xc88f3000-0xc88f5000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.731281] brcmfmac: localseq_vprintf: 0xc88f6000-0xc88f8000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.740896] brcmfmac: localseq_vprintf: 0xc88fa000-0xc88fb000           4K     RW NX SHD DEV/SHARED
[ 1780.749901] brcmfmac: localseq_vprintf: 0xc88fc000-0xc88fe000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.759516] brcmfmac: localseq_vprintf: 0xc88ff000-0xc8901000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.769132] brcmfmac: localseq_vprintf: 0xc8902000-0xc8904000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.778748] brcmfmac: localseq_vprintf: 0xc8905000-0xc8907000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.788365] brcmfmac: localseq_vprintf: 0xc8908000-0xc890a000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.797rcmfmac: localseq_vprintf: 0xc890b000-0xc890e000          12K     RW NX SHD MEM/CACHED/WBWA
[ 1780.807428] brcmfmac: localseq_vprintf: 0xc890f000-0xc894f000         256K     RW NX SHD MEM/CACHED/WBWA
[ 1780.816894] brcmfmac: localseq_vprintf: 0xc8950000-0xc8990000         256K     RW NX SHD MEM/CACHED/WBWA
[ 1780.826354] brcmfmac: localseq_vprintf: 0xc8aa0000-0xc8aa8000          32K     RW NX SHD DEV/SHARED
[ 1780.835398] brcmfmac: localseq_vprintf: 0xc8ccf000-0xc8cd0000           4K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.845019] brcmfmac: localseq_vprintf: 0xc8cd1000-0xc8cd3000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.854633] brcmfmac: localseq_vprintf: 0xc8cd4000-0xc8cd5000           4K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.864251] brcmfmac: localseq_vprintf: 0xc8cd6000-0xc8cda000          16K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.873866] brcmfmac: localseq_vprintf: 0xc8cdb000-0xc8cdd000           8K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.883483] brcmfmac: localseq_vprintf: 0xc8cde000-0xc8cdf000           4K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.893098] brcmfmac: localseq_vprintf: 0xc8ce0000-0xc8ce1000           4K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.902715] brcmfmac: localseq_vprintf: 0xc8ce5000-0xc8ce6000           4K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.912334] brcmfmac: localseq_vprintf: 0xc8d05000-0xc8d06000           4K     RW NX SHD MEM/CACHED/WBWA
[ 1780.921785] brcmfmac: localseq_vprintf: 0xc8d09000-0xc8d0f000          24K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.931401] brcmfmac: localseq_vprintf: 0xc8d10000-0xc8d16000          24K     RW NX SHD MEM/BUFFERABLE/WC
[ 1780.941300] brcmfmac: localseq_vprintf: 0xca800000-0xcac00000           4M     RW NX SHD DEV/SHARED
[ 1780.950358] brcmfmac: localseq_vprintf: 0xfedee000-0xfedf1000          12K     RW NX SHD MEM/CACHED/WBWA
[ 1780.959817] brcmfmac: localseq_vprintf: 0xfedf7000-0xfedfa000          12K     RW NX SHD MEM/CACHED/WBWA
[ 1780.969257] brcmfmac: localseq_vprintf: ---[ vmalloc() End ]---
[ 1780.975156] brcmfmac: localseq_vprintf: ---[ Fixmap Area ]---
[ 1780.980909] brcmfmac: localseq_vprintf: ---[ Vectors ]---
[ 1780.986291] brcmfmac: localseq_vprintf: 0xffff0000-0xffff1000           4K USR ro x  SHD MEM/CACHED/WBWA
[ 1780.995737] sched: RT throttling activated
[ 1780.999822] brcmfmac: localseq_vprintf: 0xffff1000-0xffff2000           4K     ro x  SHD MEM/CACHED/WBWA
[ 1781.009262] brcmfmac: localseq_vprintf: ---[ Vectors End ]---
[ 1781.014991] brcmfmac: brcmf_sync_seqnum: Loopcnt 1 (expected 52, read 52)
root@OpenWrt:/#


^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-08 13:47             ` Hante Meuleman
  0 siblings, 0 replies; 115+ messages in thread
From: Hante Meuleman @ 2014-12-08 13:47 UTC (permalink / raw)
  To: linux-arm-kernel

Still using outlook, but will limit the line length, I hope that works for the
moment. Attached is a log with the requested information, it is a little
bit non-standard though. The dump code from the mm was copied in
the driver and called from there, mapping the prints back to our local
printf, but it should produce the same. I did this because I didn't realize
the table is static.

Some background on the test setup: I'm using a Broadcom reference 
design AP platform with an BRCM 4708 host SOC. For the AP router 
platform the opensource packet OpenWRT was used. Some small
modifications were made to get it to work on our HW. Only one core
is enabled for the moment (no time to figure out how to enable the
other one). Openwrt was configured to use kernel 3.18-rc2 and 
the brcmfmac of the compat-wireless code was updated with our 
latest code (minor patches, which have been submitted already). 
The device used is 43602 pcie device. Some modifications to the build
system were made to enable PCIE. The test is to connect with a 
client to the AP and run iperf (TCP). The test can run for many hours
without a problem, but sometimes fails very quickly.

The log: first the ring allocation info is printed. Starting at
16.124847, ring 2, 3 and 4 are rings used for device to host. In this
log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
16 bytes. The next thing printed is the kernel page tables. Then some 
OpenWRT info and the logging of part of the connection setup. Then at 
1780.130752 the logging of the failure starts. The sequence number is 
modulo 253 with ring size of 1024 matches an "old" entry (read 40, 
expected 52). Then the different pointers are printed followed by 
the kernel page table. The code does then a cache invalidate on the 
dma_handle and the next read the sequence number is correct.

Regards,
Hante



Please wrap your message - replying to a message which looks like this in
my editor is far from easy, and gives me much more work to /manually/
reformat it before I can reply to it:

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> The problem is with data coming from device, so DMA from device to host. The $
>
> However: this indicates that dma_alloc_coherent on an ARM target may result i$
>
> Regards,
> Hante

Thanks.

On Fri, Dec 05, 2014 at 12:56:45PM +0000, Hante Meuleman wrote:
> However: this indicates that dma_alloc_coherent on an ARM target may
> result in a memory buffer which can be cached which conflicts with
> the API of this function.

If the memory has an alias which is cacheable, it is possible for cache
lines to get allocated via that alias, even if the alias has no explicit
accesses to it.

This is something which I've been going on for quite literally /years/ -
mismatched cache attributes can cause unpredictable behaviour.  I've had
a lot of push back from people who are of the opinion that "if it works
for me, then there isn't a problem" and I eventually gave up fighting
the battle, especially as the ARM architecture people weakened my
reasoning behind it by publishing a relaxation of the "no differing
attributes" issue.  This was particularly true of those who wanted to
use ioremap() on system memory - and cases such as
dma_init_coherent_memory().

So, I never fixed this problem in the original DMA allocator code; I
basically gave up with it.  It's a latent bug which did need to be fixed,
and is still present today in the non-CMA case.

The symptoms which you are reporting sound very much like this kind of
problem - the virtual address for the memory returned by
dma_alloc_coherent() will not be cacheable memory - it will have been
remapped using map_vm_area().  However, there could very well be a fully
cacheable lowmem mapping of that memory, which if a read (speculative or
otherwise) will bring a cache line in, and because the caches are VIPT
or PIPT, that cache line can be hit via the non-cacheable mapping too.

What I /really/ need is more evidence of this to tell those disbelievers
where to stick their flawed arguments. :)

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: cache_fail_dmesg.txt
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141208/b16580d5/attachment-0001.txt>

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-08 13:47             ` Hante Meuleman
@ 2014-12-08 15:01               ` Arnd Bergmann
  -1 siblings, 0 replies; 115+ messages in thread
From: Arnd Bergmann @ 2014-12-08 15:01 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Hante Meuleman, Russell King - ARM Linux, linux-wireless,
	brcm80211-dev-list, Will Deacon, linux-kernel, Arend Van Spriel,
	David Miller, Marek Szyprowski, hauke

On Monday 08 December 2014 13:47:38 Hante Meuleman wrote:
> Still using outlook, but will limit the line length, I hope that works for the
> moment. Attached is a log with the requested information, it is a little
> bit non-standard though. The dump code from the mm was copied in
> the driver and called from there, mapping the prints back to our local
> printf, but it should produce the same. I did this because I didn't realize
> the table is static.
> 
> Some background on the test setup: I'm using a Broadcom reference 
> design AP platform with an BRCM 4708 host SOC.

I think you are using the wrong dtb file, the log says this is
a "Buffalo WZR-1750DHP", not the reference design.

> For the AP router 
> platform the opensource packet OpenWRT was used. Some small
> modifications were made to get it to work on our HW. Only one core
> is enabled for the moment (no time to figure out how to enable the
> other one). Openwrt was configured to use kernel 3.18-rc2 and 
> the brcmfmac of the compat-wireless code was updated with our 
> latest code (minor patches, which have been submitted already). 
> The device used is 43602 pcie device. Some modifications to the build
> system were made to enable PCIE. The test is to connect with a 
> client to the AP and run iperf (TCP). The test can run for many hours
> without a problem, but sometimes fails very quickly.

The bcm4708 platform is maintained by Hauke Mehrtens, adding him to Cc.

In your log, I see this message:

[    0.000000] PL310 OF: cache setting yield illegal associativity
[    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
[    0.000000] L2C-310 enabling early BRESP for Cortex-A9
[    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
[    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
[    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
[    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001

Evidently the cache controller information in DT is incorrect and
the setup may be wrong as a consequence, which may explain cache
coherency problems.

Can you verify that the AUX_CTRL value is the same one you see
in a working kernel?

> The log: first the ring allocation info is printed. Starting at
> 16.124847, ring 2, 3 and 4 are rings used for device to host. In this
> log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
> 16 bytes. The next thing printed is the kernel page tables. Then some 
> OpenWRT info and the logging of part of the connection setup. Then at 
> 1780.130752 the logging of the failure starts. The sequence number is 
> modulo 253 with ring size of 1024 matches an "old" entry (read 40, 
> expected 52). Then the different pointers are printed followed by 
> the kernel page table. The code does then a cache invalidate on the 
> dma_handle and the next read the sequence number is correct.

How do you invalidate the cache? A dma_handle is of type dma_addr_t
and we don't define an operation for that, nor does it make sense
on an allocation from dma_alloc_coherent(). What happens if you
take out the invalidate?

Can you post the patch that you use (both platform and driver) relative
to the snapshot of the the mainline kernel you are basing on?

	Arnd


^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-08 15:01               ` Arnd Bergmann
  0 siblings, 0 replies; 115+ messages in thread
From: Arnd Bergmann @ 2014-12-08 15:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 08 December 2014 13:47:38 Hante Meuleman wrote:
> Still using outlook, but will limit the line length, I hope that works for the
> moment. Attached is a log with the requested information, it is a little
> bit non-standard though. The dump code from the mm was copied in
> the driver and called from there, mapping the prints back to our local
> printf, but it should produce the same. I did this because I didn't realize
> the table is static.
> 
> Some background on the test setup: I'm using a Broadcom reference 
> design AP platform with an BRCM 4708 host SOC.

I think you are using the wrong dtb file, the log says this is
a "Buffalo WZR-1750DHP", not the reference design.

> For the AP router 
> platform the opensource packet OpenWRT was used. Some small
> modifications were made to get it to work on our HW. Only one core
> is enabled for the moment (no time to figure out how to enable the
> other one). Openwrt was configured to use kernel 3.18-rc2 and 
> the brcmfmac of the compat-wireless code was updated with our 
> latest code (minor patches, which have been submitted already). 
> The device used is 43602 pcie device. Some modifications to the build
> system were made to enable PCIE. The test is to connect with a 
> client to the AP and run iperf (TCP). The test can run for many hours
> without a problem, but sometimes fails very quickly.

The bcm4708 platform is maintained by Hauke Mehrtens, adding him to Cc.

In your log, I see this message:

[    0.000000] PL310 OF: cache setting yield illegal associativity
[    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
[    0.000000] L2C-310 enabling early BRESP for Cortex-A9
[    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
[    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
[    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
[    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001

Evidently the cache controller information in DT is incorrect and
the setup may be wrong as a consequence, which may explain cache
coherency problems.

Can you verify that the AUX_CTRL value is the same one you see
in a working kernel?

> The log: first the ring allocation info is printed. Starting at
> 16.124847, ring 2, 3 and 4 are rings used for device to host. In this
> log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
> 16 bytes. The next thing printed is the kernel page tables. Then some 
> OpenWRT info and the logging of part of the connection setup. Then at 
> 1780.130752 the logging of the failure starts. The sequence number is 
> modulo 253 with ring size of 1024 matches an "old" entry (read 40, 
> expected 52). Then the different pointers are printed followed by 
> the kernel page table. The code does then a cache invalidate on the 
> dma_handle and the next read the sequence number is correct.

How do you invalidate the cache? A dma_handle is of type dma_addr_t
and we don't define an operation for that, nor does it make sense
on an allocation from dma_alloc_coherent(). What happens if you
take out the invalidate?

Can you post the patch that you use (both platform and driver) relative
to the snapshot of the the mainline kernel you are basing on?

	Arnd

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-08 15:01               ` Arnd Bergmann
@ 2014-12-08 15:17                 ` Russell King - ARM Linux
  -1 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-08 15:17 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Hante Meuleman, linux-wireless,
	brcm80211-dev-list, Will Deacon, linux-kernel, Arend Van Spriel,
	David Miller, Marek Szyprowski, hauke

On Mon, Dec 08, 2014 at 04:01:32PM +0100, Arnd Bergmann wrote:
> In your log, I see this message:
> 
> [    0.000000] PL310 OF: cache setting yield illegal associativity
> [    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
> [    0.000000] L2C-310 enabling early BRESP for Cortex-A9
> [    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
> [    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
> [    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
> [    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001
> 
> Evidently the cache controller information in DT is incorrect and
> the setup may be wrong as a consequence, which may explain cache
> coherency problems.

No.  See d0b92845e54 (ARM: 8182/1: l2c: Make l2x0_cache_size_of_parse() return 'int')
which was merged in rc3, post-dating this kernel.  The original commit
was buggy, and produces those harmless "illegal associativity" messages.
They occur if DT *doesn't* specify the cache parameters, in which case
we use the hardware-set value (which /should/ be correct.)

We made these optional in DT as hardware really should set these
correctly in the first place.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-08 15:17                 ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-08 15:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 08, 2014 at 04:01:32PM +0100, Arnd Bergmann wrote:
> In your log, I see this message:
> 
> [    0.000000] PL310 OF: cache setting yield illegal associativity
> [    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
> [    0.000000] L2C-310 enabling early BRESP for Cortex-A9
> [    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
> [    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
> [    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
> [    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001
> 
> Evidently the cache controller information in DT is incorrect and
> the setup may be wrong as a consequence, which may explain cache
> coherency problems.

No.  See d0b92845e54 (ARM: 8182/1: l2c: Make l2x0_cache_size_of_parse() return 'int')
which was merged in rc3, post-dating this kernel.  The original commit
was buggy, and produces those harmless "illegal associativity" messages.
They occur if DT *doesn't* specify the cache parameters, in which case
we use the hardware-set value (which /should/ be correct.)

We made these optional in DT as hardware really should set these
correctly in the first place.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-08 15:17                 ` Russell King - ARM Linux
@ 2014-12-08 15:22                   ` Arnd Bergmann
  -1 siblings, 0 replies; 115+ messages in thread
From: Arnd Bergmann @ 2014-12-08 15:22 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: linux-arm-kernel, Hante Meuleman, linux-wireless,
	brcm80211-dev-list, Will Deacon, linux-kernel, Arend Van Spriel,
	David Miller, Marek Szyprowski, hauke

On Monday 08 December 2014 15:17:33 Russell King - ARM Linux wrote:
> On Mon, Dec 08, 2014 at 04:01:32PM +0100, Arnd Bergmann wrote:
> > In your log, I see this message:
> > 
> > [    0.000000] PL310 OF: cache setting yield illegal associativity
> > [    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
> > [    0.000000] L2C-310 enabling early BRESP for Cortex-A9
> > [    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
> > [    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
> > [    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
> > [    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001
> > 
> > Evidently the cache controller information in DT is incorrect and
> > the setup may be wrong as a consequence, which may explain cache
> > coherency problems.
> 
> No.  See d0b92845e54 (ARM: 8182/1: l2c: Make l2x0_cache_size_of_parse() return 'int')
> which was merged in rc3, post-dating this kernel.  The original commit
> was buggy, and produces those harmless "illegal associativity" messages.
> They occur if DT *doesn't* specify the cache parameters, in which case
> we use the hardware-set value (which /should/ be correct.)
> 
> We made these optional in DT as hardware really should set these
> correctly in the first place.

Ok, good.

	Arnd

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-08 15:22                   ` Arnd Bergmann
  0 siblings, 0 replies; 115+ messages in thread
From: Arnd Bergmann @ 2014-12-08 15:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 08 December 2014 15:17:33 Russell King - ARM Linux wrote:
> On Mon, Dec 08, 2014 at 04:01:32PM +0100, Arnd Bergmann wrote:
> > In your log, I see this message:
> > 
> > [    0.000000] PL310 OF: cache setting yield illegal associativity
> > [    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
> > [    0.000000] L2C-310 enabling early BRESP for Cortex-A9
> > [    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
> > [    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
> > [    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
> > [    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001
> > 
> > Evidently the cache controller information in DT is incorrect and
> > the setup may be wrong as a consequence, which may explain cache
> > coherency problems.
> 
> No.  See d0b92845e54 (ARM: 8182/1: l2c: Make l2x0_cache_size_of_parse() return 'int')
> which was merged in rc3, post-dating this kernel.  The original commit
> was buggy, and produces those harmless "illegal associativity" messages.
> They occur if DT *doesn't* specify the cache parameters, in which case
> we use the hardware-set value (which /should/ be correct.)
> 
> We made these optional in DT as hardware really should set these
> correctly in the first place.

Ok, good.

	Arnd

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-08 12:55       ` Johannes Stezenbach
  (?)
@ 2014-12-08 15:55         ` Catalin Marinas
  -1 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-08 15:55 UTC (permalink / raw)
  To: Johannes Stezenbach
  Cc: Russell King, brcm80211-dev-list, linux-wireless, linux-kernel,
	Arend van Spriel, David Miller, linux-arm-kernel

On Mon, Dec 08, 2014 at 12:55:38PM +0000, Johannes Stezenbach wrote:
> On Fri, Dec 05, 2014 at 06:53:03PM +0000, Catalin Marinas wrote:
> > On Fri, Dec 05, 2014 at 06:39:45PM +0000, Catalin Marinas wrote:
> > > 
> > > Does your system have an L2 cache? What's the SoC topology, can PCIe see
> > > such L2 cache (or snoop the L1 caches)?
> > 
> > BTW, if you really have a PL310-like L2 cache, have a look at some
> > patches (I've seen similar symptoms) and make sure your configuration is
> > correct:
> > 
> > http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6395/1
> > 
> > http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1
> > 
> > The first one is vexpress specific. The second one was eventually
> > discarded by Russell (I don't remember the reason, I guess it's because
> > SoC code is supposed to set the right bits in there anyway). In your
> > case, such bits may be set up by firmware, so Linux cannot fix anything
> > up.
> 
> How do you avoid the unpredictable behavior mentioned in the
> PL310 TRM when the Shared Attribute Invalidate Enable bit is set?
> http://infocenter.arm.com/help/topic/com.arm.doc.ddi0246h/Ceggcfcj.html

So you talk about "Shared Attribute _Invalidate_ Enable" (bit 13) while
I talk about "Shared Attribute _Override_ Enable" (bit 22).

In addition, Shared _Invalidate_ behaviour can only be enabled if Shared
Attribute _Override_ Enable bit is not set.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-08 15:55         ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-08 15:55 UTC (permalink / raw)
  To: Johannes Stezenbach
  Cc: Russell King, brcm80211-dev-list, linux-wireless, linux-kernel,
	Arend van Spriel, David Miller, linux-arm-kernel

On Mon, Dec 08, 2014 at 12:55:38PM +0000, Johannes Stezenbach wrote:
> On Fri, Dec 05, 2014 at 06:53:03PM +0000, Catalin Marinas wrote:
> > On Fri, Dec 05, 2014 at 06:39:45PM +0000, Catalin Marinas wrote:
> > > 
> > > Does your system have an L2 cache? What's the SoC topology, can PCIe see
> > > such L2 cache (or snoop the L1 caches)?
> > 
> > BTW, if you really have a PL310-like L2 cache, have a look at some
> > patches (I've seen similar symptoms) and make sure your configuration is
> > correct:
> > 
> > http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6395/1
> > 
> > http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1
> > 
> > The first one is vexpress specific. The second one was eventually
> > discarded by Russell (I don't remember the reason, I guess it's because
> > SoC code is supposed to set the right bits in there anyway). In your
> > case, such bits may be set up by firmware, so Linux cannot fix anything
> > up.
> 
> How do you avoid the unpredictable behavior mentioned in the
> PL310 TRM when the Shared Attribute Invalidate Enable bit is set?
> http://infocenter.arm.com/help/topic/com.arm.doc.ddi0246h/Ceggcfcj.html

So you talk about "Shared Attribute _Invalidate_ Enable" (bit 13) while
I talk about "Shared Attribute _Override_ Enable" (bit 22).

In addition, Shared _Invalidate_ behaviour can only be enabled if Shared
Attribute _Override_ Enable bit is not set.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-08 15:55         ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-08 15:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 08, 2014 at 12:55:38PM +0000, Johannes Stezenbach wrote:
> On Fri, Dec 05, 2014 at 06:53:03PM +0000, Catalin Marinas wrote:
> > On Fri, Dec 05, 2014 at 06:39:45PM +0000, Catalin Marinas wrote:
> > > 
> > > Does your system have an L2 cache? What's the SoC topology, can PCIe see
> > > such L2 cache (or snoop the L1 caches)?
> > 
> > BTW, if you really have a PL310-like L2 cache, have a look at some
> > patches (I've seen similar symptoms) and make sure your configuration is
> > correct:
> > 
> > http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6395/1
> > 
> > http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1
> > 
> > The first one is vexpress specific. The second one was eventually
> > discarded by Russell (I don't remember the reason, I guess it's because
> > SoC code is supposed to set the right bits in there anyway). In your
> > case, such bits may be set up by firmware, so Linux cannot fix anything
> > up.
> 
> How do you avoid the unpredictable behavior mentioned in the
> PL310 TRM when the Shared Attribute Invalidate Enable bit is set?
> http://infocenter.arm.com/help/topic/com.arm.doc.ddi0246h/Ceggcfcj.html

So you talk about "Shared Attribute _Invalidate_ Enable" (bit 13) while
I talk about "Shared Attribute _Override_ Enable" (bit 22).

In addition, Shared _Invalidate_ behaviour can only be enabled if Shared
Attribute _Override_ Enable bit is not set.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-08 15:01               ` Arnd Bergmann
  (?)
@ 2014-12-08 16:03                 ` Catalin Marinas
  -1 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-08 16:03 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Russell King - ARM Linux, brcm80211-dev-list,
	linux-wireless, linux-kernel, Will Deacon, Hante Meuleman, hauke,
	Arend Van Spriel, David Miller, Marek Szyprowski

On Mon, Dec 08, 2014 at 03:01:32PM +0000, Arnd Bergmann wrote:
> [    0.000000] PL310 OF: cache setting yield illegal associativity
> [    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
> [    0.000000] L2C-310 enabling early BRESP for Cortex-A9
> [    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
> [    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
> [    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
> [    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001

If the above value is correct, they should make sure bit 22 is set in
AUX_CTRL.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-08 16:03                 ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-08 16:03 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Russell King - ARM Linux, brcm80211-dev-list,
	linux-wireless, linux-kernel, Will Deacon, Hante Meuleman, hauke,
	Arend Van Spriel, David Miller, Marek Szyprowski

On Mon, Dec 08, 2014 at 03:01:32PM +0000, Arnd Bergmann wrote:
> [    0.000000] PL310 OF: cache setting yield illegal associativity
> [    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
> [    0.000000] L2C-310 enabling early BRESP for Cortex-A9
> [    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
> [    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
> [    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
> [    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001

If the above value is correct, they should make sure bit 22 is set in
AUX_CTRL.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-08 16:03                 ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-08 16:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 08, 2014 at 03:01:32PM +0000, Arnd Bergmann wrote:
> [    0.000000] PL310 OF: cache setting yield illegal associativity
> [    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
> [    0.000000] L2C-310 enabling early BRESP for Cortex-A9
> [    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
> [    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
> [    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
> [    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001

If the above value is correct, they should make sure bit 22 is set in
AUX_CTRL.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-08 15:01               ` Arnd Bergmann
@ 2014-12-08 16:22                 ` Arend van Spriel
  -1 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-08 16:22 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Hante Meuleman, Russell King - ARM Linux,
	linux-wireless, brcm80211-dev-list, Will Deacon, linux-kernel,
	David Miller, Marek Szyprowski, hauke

[-- Attachment #1: Type: text/plain, Size: 3893 bytes --]

On 12/08/14 16:01, Arnd Bergmann wrote:
> On Monday 08 December 2014 13:47:38 Hante Meuleman wrote:
>> Still using outlook, but will limit the line length, I hope that works for the
>> moment. Attached is a log with the requested information, it is a little
>> bit non-standard though. The dump code from the mm was copied in
>> the driver and called from there, mapping the prints back to our local
>> printf, but it should produce the same. I did this because I didn't realize
>> the table is static.
>>
>> Some background on the test setup: I'm using a Broadcom reference
>> design AP platform with an BRCM 4708 host SOC.
>
> I think you are using the wrong dtb file, the log says this is
> a "Buffalo WZR-1750DHP", not the reference design.

That router is close enough to the reference design.

>> For the AP router
>> platform the opensource packet OpenWRT was used. Some small
>> modifications were made to get it to work on our HW. Only one core
>> is enabled for the moment (no time to figure out how to enable the
>> other one). Openwrt was configured to use kernel 3.18-rc2 and
>> the brcmfmac of the compat-wireless code was updated with our
>> latest code (minor patches, which have been submitted already).
>> The device used is 43602 pcie device. Some modifications to the build
>> system were made to enable PCIE. The test is to connect with a
>> client to the AP and run iperf (TCP). The test can run for many hours
>> without a problem, but sometimes fails very quickly.
>
> The bcm4708 platform is maintained by Hauke Mehrtens, adding him to Cc.

Thanks. While going through the DTS files I intended to add him as well ;-)

> In your log, I see this message:
>
> [    0.000000] PL310 OF: cache setting yield illegal associativity
> [    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
> [    0.000000] L2C-310 enabling early BRESP for Cortex-A9
> [    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
> [    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
> [    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
> [    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001
>
> Evidently the cache controller information in DT is incorrect and
> the setup may be wrong as a consequence, which may explain cache
> coherency problems.

While staring at the DTS files I suspect there are some parts still 
missing. I have attached them for reference. Catalin pointed us to a 
patch in the l2 cache [1]. We have not tried that yet.

> Can you verify that the AUX_CTRL value is the same one you see
> in a working kernel?
>
>> The log: first the ring allocation info is printed. Starting at
>> 16.124847, ring 2, 3 and 4 are rings used for device to host. In this
>> log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
>> 16 bytes. The next thing printed is the kernel page tables. Then some
>> OpenWRT info and the logging of part of the connection setup. Then at
>> 1780.130752 the logging of the failure starts. The sequence number is
>> modulo 253 with ring size of 1024 matches an "old" entry (read 40,
>> expected 52). Then the different pointers are printed followed by
>> the kernel page table. The code does then a cache invalidate on the
>> dma_handle and the next read the sequence number is correct.
>
> How do you invalidate the cache? A dma_handle is of type dma_addr_t
> and we don't define an operation for that, nor does it make sense
> on an allocation from dma_alloc_coherent(). What happens if you
> take out the invalidate?

dma_sync_single_for_cpu(, DMA_FROM_DEVICE) which ends up invalidating 
the cache (or that is our suspicion).

> Can you post the patch that you use (both platform and driver) relative
> to the snapshot of the the mainline kernel you are basing on?
>
> 	Arnd
>

Regards,
Arend

[1] http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1

[-- Attachment #2: bcm-dt-files.tar.bz2 --]
[-- Type: application/x-bzip2, Size: 2139 bytes --]

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-08 16:22                 ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-08 16:22 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/08/14 16:01, Arnd Bergmann wrote:
> On Monday 08 December 2014 13:47:38 Hante Meuleman wrote:
>> Still using outlook, but will limit the line length, I hope that works for the
>> moment. Attached is a log with the requested information, it is a little
>> bit non-standard though. The dump code from the mm was copied in
>> the driver and called from there, mapping the prints back to our local
>> printf, but it should produce the same. I did this because I didn't realize
>> the table is static.
>>
>> Some background on the test setup: I'm using a Broadcom reference
>> design AP platform with an BRCM 4708 host SOC.
>
> I think you are using the wrong dtb file, the log says this is
> a "Buffalo WZR-1750DHP", not the reference design.

That router is close enough to the reference design.

>> For the AP router
>> platform the opensource packet OpenWRT was used. Some small
>> modifications were made to get it to work on our HW. Only one core
>> is enabled for the moment (no time to figure out how to enable the
>> other one). Openwrt was configured to use kernel 3.18-rc2 and
>> the brcmfmac of the compat-wireless code was updated with our
>> latest code (minor patches, which have been submitted already).
>> The device used is 43602 pcie device. Some modifications to the build
>> system were made to enable PCIE. The test is to connect with a
>> client to the AP and run iperf (TCP). The test can run for many hours
>> without a problem, but sometimes fails very quickly.
>
> The bcm4708 platform is maintained by Hauke Mehrtens, adding him to Cc.

Thanks. While going through the DTS files I intended to add him as well ;-)

> In your log, I see this message:
>
> [    0.000000] PL310 OF: cache setting yield illegal associativity
> [    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
> [    0.000000] L2C-310 enabling early BRESP for Cortex-A9
> [    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
> [    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
> [    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
> [    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001
>
> Evidently the cache controller information in DT is incorrect and
> the setup may be wrong as a consequence, which may explain cache
> coherency problems.

While staring at the DTS files I suspect there are some parts still 
missing. I have attached them for reference. Catalin pointed us to a 
patch in the l2 cache [1]. We have not tried that yet.

> Can you verify that the AUX_CTRL value is the same one you see
> in a working kernel?
>
>> The log: first the ring allocation info is printed. Starting at
>> 16.124847, ring 2, 3 and 4 are rings used for device to host. In this
>> log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
>> 16 bytes. The next thing printed is the kernel page tables. Then some
>> OpenWRT info and the logging of part of the connection setup. Then at
>> 1780.130752 the logging of the failure starts. The sequence number is
>> modulo 253 with ring size of 1024 matches an "old" entry (read 40,
>> expected 52). Then the different pointers are printed followed by
>> the kernel page table. The code does then a cache invalidate on the
>> dma_handle and the next read the sequence number is correct.
>
> How do you invalidate the cache? A dma_handle is of type dma_addr_t
> and we don't define an operation for that, nor does it make sense
> on an allocation from dma_alloc_coherent(). What happens if you
> take out the invalidate?

dma_sync_single_for_cpu(, DMA_FROM_DEVICE) which ends up invalidating 
the cache (or that is our suspicion).

> Can you post the patch that you use (both platform and driver) relative
> to the snapshot of the the mainline kernel you are basing on?
>
> 	Arnd
>

Regards,
Arend

[1] http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bcm-dt-files.tar.bz2
Type: application/x-bzip2
Size: 2139 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141208/43560d5e/attachment.bz2>

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-08 16:22                 ` Arend van Spriel
@ 2014-12-08 16:38                   ` Arnd Bergmann
  -1 siblings, 0 replies; 115+ messages in thread
From: Arnd Bergmann @ 2014-12-08 16:38 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: linux-arm-kernel, Hante Meuleman, Russell King - ARM Linux,
	linux-wireless, brcm80211-dev-list, Will Deacon, linux-kernel,
	David Miller, Marek Szyprowski, hauke

On Monday 08 December 2014 17:22:44 Arend van Spriel wrote:
> >> The log: first the ring allocation info is printed. Starting at
> >> 16.124847, ring 2, 3 and 4 are rings used for device to host. In this
> >> log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
> >> 16 bytes. The next thing printed is the kernel page tables. Then some
> >> OpenWRT info and the logging of part of the connection setup. Then at
> >> 1780.130752 the logging of the failure starts. The sequence number is
> >> modulo 253 with ring size of 1024 matches an "old" entry (read 40,
> >> expected 52). Then the different pointers are printed followed by
> >> the kernel page table. The code does then a cache invalidate on the
> >> dma_handle and the next read the sequence number is correct.
> >
> > How do you invalidate the cache? A dma_handle is of type dma_addr_t
> > and we don't define an operation for that, nor does it make sense
> > on an allocation from dma_alloc_coherent(). What happens if you
> > take out the invalidate?
> 
> dma_sync_single_for_cpu(, DMA_FROM_DEVICE) which ends up invalidating 
> the cache (or that is our suspicion).

I'm not sure about that:

static void arm_dma_sync_single_for_cpu(struct device *dev,
                dma_addr_t handle, size_t size, enum dma_data_direction dir)
{
        unsigned int offset = handle & (PAGE_SIZE - 1);
        struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
        __dma_page_dev_to_cpu(page, offset, size, dir);
}

Assuming a noncoherent linear (no IOMMU, no swiotlb, no dmabounce) mapping,
dma_to_pfn will return the correct pfn here, but pfn_to_page will return a
page pointer into the kernel linear mapping, which is not the same
as the pointer you get from __alloc_remap_buffer(). The pointer that
was returned from dma_alloc_coherent is a) non-cachable, and b) not the
same that you flush here.

	Arnd

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-08 16:38                   ` Arnd Bergmann
  0 siblings, 0 replies; 115+ messages in thread
From: Arnd Bergmann @ 2014-12-08 16:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 08 December 2014 17:22:44 Arend van Spriel wrote:
> >> The log: first the ring allocation info is printed. Starting at
> >> 16.124847, ring 2, 3 and 4 are rings used for device to host. In this
> >> log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
> >> 16 bytes. The next thing printed is the kernel page tables. Then some
> >> OpenWRT info and the logging of part of the connection setup. Then at
> >> 1780.130752 the logging of the failure starts. The sequence number is
> >> modulo 253 with ring size of 1024 matches an "old" entry (read 40,
> >> expected 52). Then the different pointers are printed followed by
> >> the kernel page table. The code does then a cache invalidate on the
> >> dma_handle and the next read the sequence number is correct.
> >
> > How do you invalidate the cache? A dma_handle is of type dma_addr_t
> > and we don't define an operation for that, nor does it make sense
> > on an allocation from dma_alloc_coherent(). What happens if you
> > take out the invalidate?
> 
> dma_sync_single_for_cpu(, DMA_FROM_DEVICE) which ends up invalidating 
> the cache (or that is our suspicion).

I'm not sure about that:

static void arm_dma_sync_single_for_cpu(struct device *dev,
                dma_addr_t handle, size_t size, enum dma_data_direction dir)
{
        unsigned int offset = handle & (PAGE_SIZE - 1);
        struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
        __dma_page_dev_to_cpu(page, offset, size, dir);
}

Assuming a noncoherent linear (no IOMMU, no swiotlb, no dmabounce) mapping,
dma_to_pfn will return the correct pfn here, but pfn_to_page will return a
page pointer into the kernel linear mapping, which is not the same
as the pointer you get from __alloc_remap_buffer(). The pointer that
was returned from dma_alloc_coherent is a) non-cachable, and b) not the
same that you flush here.

	Arnd

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-08 16:38                   ` Arnd Bergmann
@ 2014-12-08 16:47                     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-08 16:47 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Arend van Spriel, linux-arm-kernel, Hante Meuleman,
	linux-wireless, brcm80211-dev-list, Will Deacon, linux-kernel,
	David Miller, Marek Szyprowski, hauke

On Mon, Dec 08, 2014 at 05:38:57PM +0100, Arnd Bergmann wrote:
> On Monday 08 December 2014 17:22:44 Arend van Spriel wrote:
> > >> The log: first the ring allocation info is printed. Starting at
> > >> 16.124847, ring 2, 3 and 4 are rings used for device to host. In this
> > >> log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
> > >> 16 bytes. The next thing printed is the kernel page tables. Then some
> > >> OpenWRT info and the logging of part of the connection setup. Then at
> > >> 1780.130752 the logging of the failure starts. The sequence number is
> > >> modulo 253 with ring size of 1024 matches an "old" entry (read 40,
> > >> expected 52). Then the different pointers are printed followed by
> > >> the kernel page table. The code does then a cache invalidate on the
> > >> dma_handle and the next read the sequence number is correct.
> > >
> > > How do you invalidate the cache? A dma_handle is of type dma_addr_t
> > > and we don't define an operation for that, nor does it make sense
> > > on an allocation from dma_alloc_coherent(). What happens if you
> > > take out the invalidate?
> > 
> > dma_sync_single_for_cpu(, DMA_FROM_DEVICE) which ends up invalidating 
> > the cache (or that is our suspicion).
> 
> I'm not sure about that:
> 
> static void arm_dma_sync_single_for_cpu(struct device *dev,
>                 dma_addr_t handle, size_t size, enum dma_data_direction dir)
> {
>         unsigned int offset = handle & (PAGE_SIZE - 1);
>         struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
>         __dma_page_dev_to_cpu(page, offset, size, dir);
> }
> 
> Assuming a noncoherent linear (no IOMMU, no swiotlb, no dmabounce) mapping,
> dma_to_pfn will return the correct pfn here, but pfn_to_page will return a
> page pointer into the kernel linear mapping, which is not the same
> as the pointer you get from __alloc_remap_buffer(). The pointer that
> was returned from dma_alloc_coherent is a) non-cachable, and b) not the
> same that you flush here.

Having looked up the details of the Cortex CPU TRMs:

1. The caches are PIPT.
2. A non-cacheable mapping will not hit L1 cache lines which may be
   allocated against the same physical address.  (This is implementation
   specific.)

So, the problem can't be the L1 cache, it has to be the L2 cache.

The L2 cache only deals with physical addresses, so it doesn't really
matter which mapping gets flushed - the result will be the same as far
as the L2 cache is concerned.

If bit 22 is not set in the auxcr, then a non-cacheable access can hit
a cache line which may be allocated in the L2 cache (which may have
been allocated via a speculative prefetch via the cacheable mapping.)

In the case which has been supplied, the physical address does indeed
have two mappings: it has a lowmem mapping which is cacheable, and it
has the DMA mapping which is marked as non-cacheable.  Accesses via
the non-cacheable mapping will not hit L1 (that's an implementation
specific behaviour.)  However, they may hit L2 if bit 22 is clear.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-08 16:47                     ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-08 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 08, 2014 at 05:38:57PM +0100, Arnd Bergmann wrote:
> On Monday 08 December 2014 17:22:44 Arend van Spriel wrote:
> > >> The log: first the ring allocation info is printed. Starting at
> > >> 16.124847, ring 2, 3 and 4 are rings used for device to host. In this
> > >> log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
> > >> 16 bytes. The next thing printed is the kernel page tables. Then some
> > >> OpenWRT info and the logging of part of the connection setup. Then at
> > >> 1780.130752 the logging of the failure starts. The sequence number is
> > >> modulo 253 with ring size of 1024 matches an "old" entry (read 40,
> > >> expected 52). Then the different pointers are printed followed by
> > >> the kernel page table. The code does then a cache invalidate on the
> > >> dma_handle and the next read the sequence number is correct.
> > >
> > > How do you invalidate the cache? A dma_handle is of type dma_addr_t
> > > and we don't define an operation for that, nor does it make sense
> > > on an allocation from dma_alloc_coherent(). What happens if you
> > > take out the invalidate?
> > 
> > dma_sync_single_for_cpu(, DMA_FROM_DEVICE) which ends up invalidating 
> > the cache (or that is our suspicion).
> 
> I'm not sure about that:
> 
> static void arm_dma_sync_single_for_cpu(struct device *dev,
>                 dma_addr_t handle, size_t size, enum dma_data_direction dir)
> {
>         unsigned int offset = handle & (PAGE_SIZE - 1);
>         struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
>         __dma_page_dev_to_cpu(page, offset, size, dir);
> }
> 
> Assuming a noncoherent linear (no IOMMU, no swiotlb, no dmabounce) mapping,
> dma_to_pfn will return the correct pfn here, but pfn_to_page will return a
> page pointer into the kernel linear mapping, which is not the same
> as the pointer you get from __alloc_remap_buffer(). The pointer that
> was returned from dma_alloc_coherent is a) non-cachable, and b) not the
> same that you flush here.

Having looked up the details of the Cortex CPU TRMs:

1. The caches are PIPT.
2. A non-cacheable mapping will not hit L1 cache lines which may be
   allocated against the same physical address.  (This is implementation
   specific.)

So, the problem can't be the L1 cache, it has to be the L2 cache.

The L2 cache only deals with physical addresses, so it doesn't really
matter which mapping gets flushed - the result will be the same as far
as the L2 cache is concerned.

If bit 22 is not set in the auxcr, then a non-cacheable access can hit
a cache line which may be allocated in the L2 cache (which may have
been allocated via a speculative prefetch via the cacheable mapping.)

In the case which has been supplied, the physical address does indeed
have two mappings: it has a lowmem mapping which is cacheable, and it
has the DMA mapping which is marked as non-cacheable.  Accesses via
the non-cacheable mapping will not hit L1 (that's an implementation
specific behaviour.)  However, they may hit L2 if bit 22 is clear.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-08 15:55         ` Catalin Marinas
  (?)
@ 2014-12-08 16:50           ` Johannes Stezenbach
  -1 siblings, 0 replies; 115+ messages in thread
From: Johannes Stezenbach @ 2014-12-08 16:50 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Russell King, brcm80211-dev-list, linux-wireless, linux-kernel,
	Arend van Spriel, David Miller, linux-arm-kernel

On Mon, Dec 08, 2014 at 03:55:57PM +0000, Catalin Marinas wrote:
> On Mon, Dec 08, 2014 at 12:55:38PM +0000, Johannes Stezenbach wrote:
> > On Fri, Dec 05, 2014 at 06:53:03PM +0000, Catalin Marinas wrote:
> > > 
> > > BTW, if you really have a PL310-like L2 cache, have a look at some
> > > patches (I've seen similar symptoms) and make sure your configuration is
> > > correct:
> > > 
> > > http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6395/1
> > > 
> > > http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1
> > > 
> > > The first one is vexpress specific. The second one was eventually
> > > discarded by Russell (I don't remember the reason, I guess it's because
> > > SoC code is supposed to set the right bits in there anyway). In your
> > > case, such bits may be set up by firmware, so Linux cannot fix anything
> > > up.
> > 
> > How do you avoid the unpredictable behavior mentioned in the
> > PL310 TRM when the Shared Attribute Invalidate Enable bit is set?
> > http://infocenter.arm.com/help/topic/com.arm.doc.ddi0246h/Ceggcfcj.html
> 
> So you talk about "Shared Attribute _Invalidate_ Enable" (bit 13) while
> I talk about "Shared Attribute _Override_ Enable" (bit 22).
> 
> In addition, Shared _Invalidate_ behaviour can only be enabled if Shared
> Attribute _Override_ Enable bit is not set.

Yeah, I got confused, sorry for the noise.

Thanks,
Johannes

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-08 16:50           ` Johannes Stezenbach
  0 siblings, 0 replies; 115+ messages in thread
From: Johannes Stezenbach @ 2014-12-08 16:50 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Russell King, brcm80211-dev-list, linux-wireless, linux-kernel,
	Arend van Spriel, David Miller, linux-arm-kernel

On Mon, Dec 08, 2014 at 03:55:57PM +0000, Catalin Marinas wrote:
> On Mon, Dec 08, 2014 at 12:55:38PM +0000, Johannes Stezenbach wrote:
> > On Fri, Dec 05, 2014 at 06:53:03PM +0000, Catalin Marinas wrote:
> > > 
> > > BTW, if you really have a PL310-like L2 cache, have a look at some
> > > patches (I've seen similar symptoms) and make sure your configuration is
> > > correct:
> > > 
> > > http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6395/1
> > > 
> > > http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1
> > > 
> > > The first one is vexpress specific. The second one was eventually
> > > discarded by Russell (I don't remember the reason, I guess it's because
> > > SoC code is supposed to set the right bits in there anyway). In your
> > > case, such bits may be set up by firmware, so Linux cannot fix anything
> > > up.
> > 
> > How do you avoid the unpredictable behavior mentioned in the
> > PL310 TRM when the Shared Attribute Invalidate Enable bit is set?
> > http://infocenter.arm.com/help/topic/com.arm.doc.ddi0246h/Ceggcfcj.html
> 
> So you talk about "Shared Attribute _Invalidate_ Enable" (bit 13) while
> I talk about "Shared Attribute _Override_ Enable" (bit 22).
> 
> In addition, Shared _Invalidate_ behaviour can only be enabled if Shared
> Attribute _Override_ Enable bit is not set.

Yeah, I got confused, sorry for the noise.

Thanks,
Johannes

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-08 16:50           ` Johannes Stezenbach
  0 siblings, 0 replies; 115+ messages in thread
From: Johannes Stezenbach @ 2014-12-08 16:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 08, 2014 at 03:55:57PM +0000, Catalin Marinas wrote:
> On Mon, Dec 08, 2014 at 12:55:38PM +0000, Johannes Stezenbach wrote:
> > On Fri, Dec 05, 2014 at 06:53:03PM +0000, Catalin Marinas wrote:
> > > 
> > > BTW, if you really have a PL310-like L2 cache, have a look at some
> > > patches (I've seen similar symptoms) and make sure your configuration is
> > > correct:
> > > 
> > > http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6395/1
> > > 
> > > http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=6529/1
> > > 
> > > The first one is vexpress specific. The second one was eventually
> > > discarded by Russell (I don't remember the reason, I guess it's because
> > > SoC code is supposed to set the right bits in there anyway). In your
> > > case, such bits may be set up by firmware, so Linux cannot fix anything
> > > up.
> > 
> > How do you avoid the unpredictable behavior mentioned in the
> > PL310 TRM when the Shared Attribute Invalidate Enable bit is set?
> > http://infocenter.arm.com/help/topic/com.arm.doc.ddi0246h/Ceggcfcj.html
> 
> So you talk about "Shared Attribute _Invalidate_ Enable" (bit 13) while
> I talk about "Shared Attribute _Override_ Enable" (bit 22).
> 
> In addition, Shared _Invalidate_ behaviour can only be enabled if Shared
> Attribute _Override_ Enable bit is not set.

Yeah, I got confused, sorry for the noise.

Thanks,
Johannes

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-08 16:38                   ` Arnd Bergmann
  (?)
@ 2014-12-08 16:50                     ` Catalin Marinas
  -1 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-08 16:50 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Arend van Spriel, Russell King - ARM Linux, brcm80211-dev-list,
	linux-wireless, linux-kernel, Will Deacon, Hante Meuleman, hauke,
	David Miller, linux-arm-kernel, Marek Szyprowski

On Mon, Dec 08, 2014 at 04:38:57PM +0000, Arnd Bergmann wrote:
> On Monday 08 December 2014 17:22:44 Arend van Spriel wrote:
> > >> The log: first the ring allocation info is printed. Starting at
> > >> 16.124847, ring 2, 3 and 4 are rings used for device to host. In this
> > >> log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
> > >> 16 bytes. The next thing printed is the kernel page tables. Then some
> > >> OpenWRT info and the logging of part of the connection setup. Then at
> > >> 1780.130752 the logging of the failure starts. The sequence number is
> > >> modulo 253 with ring size of 1024 matches an "old" entry (read 40,
> > >> expected 52). Then the different pointers are printed followed by
> > >> the kernel page table. The code does then a cache invalidate on the
> > >> dma_handle and the next read the sequence number is correct.
> > >
> > > How do you invalidate the cache? A dma_handle is of type dma_addr_t
> > > and we don't define an operation for that, nor does it make sense
> > > on an allocation from dma_alloc_coherent(). What happens if you
> > > take out the invalidate?
> > 
> > dma_sync_single_for_cpu(, DMA_FROM_DEVICE) which ends up invalidating 
> > the cache (or that is our suspicion).
> 
> I'm not sure about that:
> 
> static void arm_dma_sync_single_for_cpu(struct device *dev,
>                 dma_addr_t handle, size_t size, enum dma_data_direction dir)
> {
>         unsigned int offset = handle & (PAGE_SIZE - 1);
>         struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
>         __dma_page_dev_to_cpu(page, offset, size, dir);
> }
> 
> Assuming a noncoherent linear (no IOMMU, no swiotlb, no dmabounce) mapping,
> dma_to_pfn will return the correct pfn here, but pfn_to_page will return a
> page pointer into the kernel linear mapping,

Or a highmem page, both should be handled by dma_cache_maint_page().

> which is not the same
> as the pointer you get from __alloc_remap_buffer(). The pointer that
> was returned from dma_alloc_coherent is a) non-cachable, and b) not the
> same that you flush here.

Correct. But apart from the fact that you don't need to flush buffers
allocated with dma_alloc_coherent(), the above sync_single would work on
ARMv7 where the D-cache is PIPT, so the virtual address doesn't matter
much as long as it maps the same physical address.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-08 16:50                     ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-08 16:50 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Arend van Spriel, Russell King - ARM Linux, brcm80211-dev-list,
	linux-wireless, linux-kernel, Will Deacon, Hante Meuleman, hauke,
	David Miller, linux-arm-kernel, Marek Szyprowski

On Mon, Dec 08, 2014 at 04:38:57PM +0000, Arnd Bergmann wrote:
> On Monday 08 December 2014 17:22:44 Arend van Spriel wrote:
> > >> The log: first the ring allocation info is printed. Starting at
> > >> 16.124847, ring 2, 3 and 4 are rings used for device to host. In this
> > >> log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
> > >> 16 bytes. The next thing printed is the kernel page tables. Then some
> > >> OpenWRT info and the logging of part of the connection setup. Then at
> > >> 1780.130752 the logging of the failure starts. The sequence number is
> > >> modulo 253 with ring size of 1024 matches an "old" entry (read 40,
> > >> expected 52). Then the different pointers are printed followed by
> > >> the kernel page table. The code does then a cache invalidate on the
> > >> dma_handle and the next read the sequence number is correct.
> > >
> > > How do you invalidate the cache? A dma_handle is of type dma_addr_t
> > > and we don't define an operation for that, nor does it make sense
> > > on an allocation from dma_alloc_coherent(). What happens if you
> > > take out the invalidate?
> > 
> > dma_sync_single_for_cpu(, DMA_FROM_DEVICE) which ends up invalidating 
> > the cache (or that is our suspicion).
> 
> I'm not sure about that:
> 
> static void arm_dma_sync_single_for_cpu(struct device *dev,
>                 dma_addr_t handle, size_t size, enum dma_data_direction dir)
> {
>         unsigned int offset = handle & (PAGE_SIZE - 1);
>         struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
>         __dma_page_dev_to_cpu(page, offset, size, dir);
> }
> 
> Assuming a noncoherent linear (no IOMMU, no swiotlb, no dmabounce) mapping,
> dma_to_pfn will return the correct pfn here, but pfn_to_page will return a
> page pointer into the kernel linear mapping,

Or a highmem page, both should be handled by dma_cache_maint_page().

> which is not the same
> as the pointer you get from __alloc_remap_buffer(). The pointer that
> was returned from dma_alloc_coherent is a) non-cachable, and b) not the
> same that you flush here.

Correct. But apart from the fact that you don't need to flush buffers
allocated with dma_alloc_coherent(), the above sync_single would work on
ARMv7 where the D-cache is PIPT, so the virtual address doesn't matter
much as long as it maps the same physical address.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-08 16:50                     ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-08 16:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 08, 2014 at 04:38:57PM +0000, Arnd Bergmann wrote:
> On Monday 08 December 2014 17:22:44 Arend van Spriel wrote:
> > >> The log: first the ring allocation info is printed. Starting at
> > >> 16.124847, ring 2, 3 and 4 are rings used for device to host. In this
> > >> log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
> > >> 16 bytes. The next thing printed is the kernel page tables. Then some
> > >> OpenWRT info and the logging of part of the connection setup. Then at
> > >> 1780.130752 the logging of the failure starts. The sequence number is
> > >> modulo 253 with ring size of 1024 matches an "old" entry (read 40,
> > >> expected 52). Then the different pointers are printed followed by
> > >> the kernel page table. The code does then a cache invalidate on the
> > >> dma_handle and the next read the sequence number is correct.
> > >
> > > How do you invalidate the cache? A dma_handle is of type dma_addr_t
> > > and we don't define an operation for that, nor does it make sense
> > > on an allocation from dma_alloc_coherent(). What happens if you
> > > take out the invalidate?
> > 
> > dma_sync_single_for_cpu(, DMA_FROM_DEVICE) which ends up invalidating 
> > the cache (or that is our suspicion).
> 
> I'm not sure about that:
> 
> static void arm_dma_sync_single_for_cpu(struct device *dev,
>                 dma_addr_t handle, size_t size, enum dma_data_direction dir)
> {
>         unsigned int offset = handle & (PAGE_SIZE - 1);
>         struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
>         __dma_page_dev_to_cpu(page, offset, size, dir);
> }
> 
> Assuming a noncoherent linear (no IOMMU, no swiotlb, no dmabounce) mapping,
> dma_to_pfn will return the correct pfn here, but pfn_to_page will return a
> page pointer into the kernel linear mapping,

Or a highmem page, both should be handled by dma_cache_maint_page().

> which is not the same
> as the pointer you get from __alloc_remap_buffer(). The pointer that
> was returned from dma_alloc_coherent is a) non-cachable, and b) not the
> same that you flush here.

Correct. But apart from the fact that you don't need to flush buffers
allocated with dma_alloc_coherent(), the above sync_single would work on
ARMv7 where the D-cache is PIPT, so the virtual address doesn't matter
much as long as it maps the same physical address.

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-08 16:50                     ` Catalin Marinas
  (?)
@ 2014-12-08 16:54                       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-08 16:54 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Arnd Bergmann, Arend van Spriel, brcm80211-dev-list,
	linux-wireless, linux-kernel, Will Deacon, Hante Meuleman, hauke,
	David Miller, linux-arm-kernel, Marek Szyprowski

On Mon, Dec 08, 2014 at 04:50:43PM +0000, Catalin Marinas wrote:
> On Mon, Dec 08, 2014 at 04:38:57PM +0000, Arnd Bergmann wrote:
> > On Monday 08 December 2014 17:22:44 Arend van Spriel wrote:
> > > >> The log: first the ring allocation info is printed. Starting at
> > > >> 16.124847, ring 2, 3 and 4 are rings used for device to host. In this
> > > >> log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
> > > >> 16 bytes. The next thing printed is the kernel page tables. Then some
> > > >> OpenWRT info and the logging of part of the connection setup. Then at
> > > >> 1780.130752 the logging of the failure starts. The sequence number is
> > > >> modulo 253 with ring size of 1024 matches an "old" entry (read 40,
> > > >> expected 52). Then the different pointers are printed followed by
> > > >> the kernel page table. The code does then a cache invalidate on the
> > > >> dma_handle and the next read the sequence number is correct.
> > > >
> > > > How do you invalidate the cache? A dma_handle is of type dma_addr_t
> > > > and we don't define an operation for that, nor does it make sense
> > > > on an allocation from dma_alloc_coherent(). What happens if you
> > > > take out the invalidate?
> > > 
> > > dma_sync_single_for_cpu(, DMA_FROM_DEVICE) which ends up invalidating 
> > > the cache (or that is our suspicion).
> > 
> > I'm not sure about that:
> > 
> > static void arm_dma_sync_single_for_cpu(struct device *dev,
> >                 dma_addr_t handle, size_t size, enum dma_data_direction dir)
> > {
> >         unsigned int offset = handle & (PAGE_SIZE - 1);
> >         struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
> >         __dma_page_dev_to_cpu(page, offset, size, dir);
> > }
> > 
> > Assuming a noncoherent linear (no IOMMU, no swiotlb, no dmabounce) mapping,
> > dma_to_pfn will return the correct pfn here, but pfn_to_page will return a
> > page pointer into the kernel linear mapping,
> 
> Or a highmem page, both should be handled by dma_cache_maint_page().

A valid point, but one which is irrelevant to this thread, because we're
talking about a platform with only 128MB, and a PAGE_OFFSET of 2GB (hence
no highmem):

Memory: 125936K/131072K available (2682K kernel code, 103K rwdata,
 744K rodata, 164K init, 188K bss, 5136K reserved)

Can we stay on-point to getting this problem solved, rather than drifting
off topic please?

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-08 16:54                       ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-08 16:54 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Arnd Bergmann, Arend van Spriel, brcm80211-dev-list,
	linux-wireless, linux-kernel, Will Deacon, Hante Meuleman, hauke,
	David Miller, linux-arm-kernel, Marek Szyprowski

On Mon, Dec 08, 2014 at 04:50:43PM +0000, Catalin Marinas wrote:
> On Mon, Dec 08, 2014 at 04:38:57PM +0000, Arnd Bergmann wrote:
> > On Monday 08 December 2014 17:22:44 Arend van Spriel wrote:
> > > >> The log: first the ring allocation info is printed. Starting at
> > > >> 16.124847, ring 2, 3 and 4 are rings used for device to host. In this
> > > >> log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
> > > >> 16 bytes. The next thing printed is the kernel page tables. Then some
> > > >> OpenWRT info and the logging of part of the connection setup. Then at
> > > >> 1780.130752 the logging of the failure starts. The sequence number is
> > > >> modulo 253 with ring size of 1024 matches an "old" entry (read 40,
> > > >> expected 52). Then the different pointers are printed followed by
> > > >> the kernel page table. The code does then a cache invalidate on the
> > > >> dma_handle and the next read the sequence number is correct.
> > > >
> > > > How do you invalidate the cache? A dma_handle is of type dma_addr_t
> > > > and we don't define an operation for that, nor does it make sense
> > > > on an allocation from dma_alloc_coherent(). What happens if you
> > > > take out the invalidate?
> > > 
> > > dma_sync_single_for_cpu(, DMA_FROM_DEVICE) which ends up invalidating 
> > > the cache (or that is our suspicion).
> > 
> > I'm not sure about that:
> > 
> > static void arm_dma_sync_single_for_cpu(struct device *dev,
> >                 dma_addr_t handle, size_t size, enum dma_data_direction dir)
> > {
> >         unsigned int offset = handle & (PAGE_SIZE - 1);
> >         struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
> >         __dma_page_dev_to_cpu(page, offset, size, dir);
> > }
> > 
> > Assuming a noncoherent linear (no IOMMU, no swiotlb, no dmabounce) mapping,
> > dma_to_pfn will return the correct pfn here, but pfn_to_page will return a
> > page pointer into the kernel linear mapping,
> 
> Or a highmem page, both should be handled by dma_cache_maint_page().

A valid point, but one which is irrelevant to this thread, because we're
talking about a platform with only 128MB, and a PAGE_OFFSET of 2GB (hence
no highmem):

Memory: 125936K/131072K available (2682K kernel code, 103K rwdata,
 744K rodata, 164K init, 188K bss, 5136K reserved)

Can we stay on-point to getting this problem solved, rather than drifting
off topic please?

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-08 16:54                       ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-08 16:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 08, 2014 at 04:50:43PM +0000, Catalin Marinas wrote:
> On Mon, Dec 08, 2014 at 04:38:57PM +0000, Arnd Bergmann wrote:
> > On Monday 08 December 2014 17:22:44 Arend van Spriel wrote:
> > > >> The log: first the ring allocation info is printed. Starting at
> > > >> 16.124847, ring 2, 3 and 4 are rings used for device to host. In this
> > > >> log the failure is on a read of ring 3. Ring 3 is 1024 entries of each
> > > >> 16 bytes. The next thing printed is the kernel page tables. Then some
> > > >> OpenWRT info and the logging of part of the connection setup. Then at
> > > >> 1780.130752 the logging of the failure starts. The sequence number is
> > > >> modulo 253 with ring size of 1024 matches an "old" entry (read 40,
> > > >> expected 52). Then the different pointers are printed followed by
> > > >> the kernel page table. The code does then a cache invalidate on the
> > > >> dma_handle and the next read the sequence number is correct.
> > > >
> > > > How do you invalidate the cache? A dma_handle is of type dma_addr_t
> > > > and we don't define an operation for that, nor does it make sense
> > > > on an allocation from dma_alloc_coherent(). What happens if you
> > > > take out the invalidate?
> > > 
> > > dma_sync_single_for_cpu(, DMA_FROM_DEVICE) which ends up invalidating 
> > > the cache (or that is our suspicion).
> > 
> > I'm not sure about that:
> > 
> > static void arm_dma_sync_single_for_cpu(struct device *dev,
> >                 dma_addr_t handle, size_t size, enum dma_data_direction dir)
> > {
> >         unsigned int offset = handle & (PAGE_SIZE - 1);
> >         struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
> >         __dma_page_dev_to_cpu(page, offset, size, dir);
> > }
> > 
> > Assuming a noncoherent linear (no IOMMU, no swiotlb, no dmabounce) mapping,
> > dma_to_pfn will return the correct pfn here, but pfn_to_page will return a
> > page pointer into the kernel linear mapping,
> 
> Or a highmem page, both should be handled by dma_cache_maint_page().

A valid point, but one which is irrelevant to this thread, because we're
talking about a platform with only 128MB, and a PAGE_OFFSET of 2GB (hence
no highmem):

Memory: 125936K/131072K available (2682K kernel code, 103K rwdata,
 744K rodata, 164K init, 188K bss, 5136K reserved)

Can we stay on-point to getting this problem solved, rather than drifting
off topic please?

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-08 16:03                 ` Catalin Marinas
  (?)
@ 2014-12-08 17:01                   ` Arend van Spriel
  -1 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-08 17:01 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Arnd Bergmann, linux-arm-kernel, Russell King - ARM Linux,
	brcm80211-dev-list, linux-wireless, linux-kernel, Will Deacon,
	Hante Meuleman, hauke, David Miller, Marek Szyprowski

On 12/08/14 17:03, Catalin Marinas wrote:
> On Mon, Dec 08, 2014 at 03:01:32PM +0000, Arnd Bergmann wrote:
>> [    0.000000] PL310 OF: cache setting yield illegal associativity
>> [    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
>> [    0.000000] L2C-310 enabling early BRESP for Cortex-A9
>> [    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
>> [    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
>> [    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
>> [    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001
>
> If the above value is correct, they should make sure bit 22 is set in
> AUX_CTRL.

Hante applied the patch and it now says:

[    0.000000] PL310 OF: cache setting yield illegal associativity
[    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
[    0.000000] L2C-310 enabling early BRESP for Cortex-A9
[    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
[    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
[    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
[    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e530001

He started running a test overnight. So will see if it hits the failure 
with this L2 cache configuration.

Regards,
Arend

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-08 17:01                   ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-08 17:01 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Arnd Bergmann, linux-arm-kernel, Russell King - ARM Linux,
	brcm80211-dev-list, linux-wireless, linux-kernel, Will Deacon,
	Hante Meuleman, hauke, David Miller, Marek Szyprowski

On 12/08/14 17:03, Catalin Marinas wrote:
> On Mon, Dec 08, 2014 at 03:01:32PM +0000, Arnd Bergmann wrote:
>> [    0.000000] PL310 OF: cache setting yield illegal associativity
>> [    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
>> [    0.000000] L2C-310 enabling early BRESP for Cortex-A9
>> [    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
>> [    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
>> [    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
>> [    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001
>
> If the above value is correct, they should make sure bit 22 is set in
> AUX_CTRL.

Hante applied the patch and it now says:

[    0.000000] PL310 OF: cache setting yield illegal associativity
[    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
[    0.000000] L2C-310 enabling early BRESP for Cortex-A9
[    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
[    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
[    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
[    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e530001

He started running a test overnight. So will see if it hits the failure 
with this L2 cache configuration.

Regards,
Arend

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-08 17:01                   ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-08 17:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/08/14 17:03, Catalin Marinas wrote:
> On Mon, Dec 08, 2014 at 03:01:32PM +0000, Arnd Bergmann wrote:
>> [    0.000000] PL310 OF: cache setting yield illegal associativity
>> [    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
>> [    0.000000] L2C-310 enabling early BRESP for Cortex-A9
>> [    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
>> [    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
>> [    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
>> [    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001
>
> If the above value is correct, they should make sure bit 22 is set in
> AUX_CTRL.

Hante applied the patch and it now says:

[    0.000000] PL310 OF: cache setting yield illegal associativity
[    0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
[    0.000000] L2C-310 enabling early BRESP for Cortex-A9
[    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
[    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
[    0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
[    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e530001

He started running a test overnight. So will see if it hits the failure 
with this L2 cache configuration.

Regards,
Arend

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-08 17:01                   ` Arend van Spriel
  (?)
@ 2014-12-09 10:19                     ` Arend van Spriel
  -1 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-09 10:19 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Catalin Marinas, Arnd Bergmann, linux-arm-kernel,
	brcm80211-dev-list, linux-wireless, linux-kernel, Will Deacon,
	Hante Meuleman, hauke, David Miller, Marek Szyprowski

On 12/08/14 18:01, Arend van Spriel wrote:
> On 12/08/14 17:03, Catalin Marinas wrote:
>> On Mon, Dec 08, 2014 at 03:01:32PM +0000, Arnd Bergmann wrote:
>>> [ 0.000000] PL310 OF: cache setting yield illegal associativity
>>> [ 0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
>>> [ 0.000000] L2C-310 enabling early BRESP for Cortex-A9
>>> [ 0.000000] L2C-310 full line of zeros enabled for Cortex-A9
>>> [ 0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
>>> [ 0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
>>> [ 0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001
>>
>> If the above value is correct, they should make sure bit 22 is set in
>> AUX_CTRL.
>
> Hante applied the patch and it now says:
>
> [ 0.000000] PL310 OF: cache setting yield illegal associativity
> [ 0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
> [ 0.000000] L2C-310 enabling early BRESP for Cortex-A9
> [ 0.000000] L2C-310 full line of zeros enabled for Cortex-A9
> [ 0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
> [ 0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
> [ 0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e530001
>
> He started running a test overnight. So will see if it hits the failure
> with this L2 cache configuration.

The issue did not trigger overnight so it seems setting bit 22 <Shared 
Attribute _Override_ Enable> solves the issue over here. Now the 
question is how to move forward with this. As I understood from Catalin 
this patch was not included as it was not considered responsibility of 
the linux kernel.

Regards,
Arend

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-09 10:19                     ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-09 10:19 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Catalin Marinas, Arnd Bergmann, linux-arm-kernel,
	brcm80211-dev-list, linux-wireless, linux-kernel, Will Deacon,
	Hante Meuleman, hauke, David Miller, Marek Szyprowski

On 12/08/14 18:01, Arend van Spriel wrote:
> On 12/08/14 17:03, Catalin Marinas wrote:
>> On Mon, Dec 08, 2014 at 03:01:32PM +0000, Arnd Bergmann wrote:
>>> [ 0.000000] PL310 OF: cache setting yield illegal associativity
>>> [ 0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
>>> [ 0.000000] L2C-310 enabling early BRESP for Cortex-A9
>>> [ 0.000000] L2C-310 full line of zeros enabled for Cortex-A9
>>> [ 0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
>>> [ 0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
>>> [ 0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001
>>
>> If the above value is correct, they should make sure bit 22 is set in
>> AUX_CTRL.
>
> Hante applied the patch and it now says:
>
> [ 0.000000] PL310 OF: cache setting yield illegal associativity
> [ 0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
> [ 0.000000] L2C-310 enabling early BRESP for Cortex-A9
> [ 0.000000] L2C-310 full line of zeros enabled for Cortex-A9
> [ 0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
> [ 0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
> [ 0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e530001
>
> He started running a test overnight. So will see if it hits the failure
> with this L2 cache configuration.

The issue did not trigger overnight so it seems setting bit 22 <Shared 
Attribute _Override_ Enable> solves the issue over here. Now the 
question is how to move forward with this. As I understood from Catalin 
this patch was not included as it was not considered responsibility of 
the linux kernel.

Regards,
Arend

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-09 10:19                     ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-09 10:19 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/08/14 18:01, Arend van Spriel wrote:
> On 12/08/14 17:03, Catalin Marinas wrote:
>> On Mon, Dec 08, 2014 at 03:01:32PM +0000, Arnd Bergmann wrote:
>>> [ 0.000000] PL310 OF: cache setting yield illegal associativity
>>> [ 0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
>>> [ 0.000000] L2C-310 enabling early BRESP for Cortex-A9
>>> [ 0.000000] L2C-310 full line of zeros enabled for Cortex-A9
>>> [ 0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
>>> [ 0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
>>> [ 0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e130001
>>
>> If the above value is correct, they should make sure bit 22 is set in
>> AUX_CTRL.
>
> Hante applied the patch and it now says:
>
> [ 0.000000] PL310 OF: cache setting yield illegal associativity
> [ 0.000000] PL310 OF: -1069781724 calculated, only 8 and 16 legal
> [ 0.000000] L2C-310 enabling early BRESP for Cortex-A9
> [ 0.000000] L2C-310 full line of zeros enabled for Cortex-A9
> [ 0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
> [ 0.000000] L2C-310 cache controller enabled, 16 ways, 256 kB
> [ 0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x4e530001
>
> He started running a test overnight. So will see if it hits the failure
> with this L2 cache configuration.

The issue did not trigger overnight so it seems setting bit 22 <Shared 
Attribute _Override_ Enable> solves the issue over here. Now the 
question is how to move forward with this. As I understood from Catalin 
this patch was not included as it was not considered responsibility of 
the linux kernel.

Regards,
Arend

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-09 10:19                     ` Arend van Spriel
  (?)
@ 2014-12-09 10:29                       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-09 10:29 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Catalin Marinas, Arnd Bergmann, linux-arm-kernel,
	brcm80211-dev-list, linux-wireless, linux-kernel, Will Deacon,
	Hante Meuleman, hauke, David Miller, Marek Szyprowski

On Tue, Dec 09, 2014 at 11:19:40AM +0100, Arend van Spriel wrote:
> The issue did not trigger overnight so it seems setting bit 22 <Shared
> Attribute _Override_ Enable> solves the issue over here. Now the question is
> how to move forward with this. As I understood from Catalin this patch was
> not included as it was not considered responsibility of the linux kernel.

It is preferable for firmware to configure the L2 cache appropriately,
which includes things like the prefetch offsets as well as feature bits
like bit 22.

I think what I'll do is queue up a patch which adds a warning if bit 22
is not set, suggesting that firmware is updated to set this bit.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-09 10:29                       ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-09 10:29 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Catalin Marinas, Arnd Bergmann, linux-arm-kernel,
	brcm80211-dev-list, linux-wireless, linux-kernel, Will Deacon,
	Hante Meuleman, hauke, David Miller, Marek Szyprowski

On Tue, Dec 09, 2014 at 11:19:40AM +0100, Arend van Spriel wrote:
> The issue did not trigger overnight so it seems setting bit 22 <Shared
> Attribute _Override_ Enable> solves the issue over here. Now the question is
> how to move forward with this. As I understood from Catalin this patch was
> not included as it was not considered responsibility of the linux kernel.

It is preferable for firmware to configure the L2 cache appropriately,
which includes things like the prefetch offsets as well as feature bits
like bit 22.

I think what I'll do is queue up a patch which adds a warning if bit 22
is not set, suggesting that firmware is updated to set this bit.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-09 10:29                       ` Russell King - ARM Linux
  0 siblings, 0 replies; 115+ messages in thread
From: Russell King - ARM Linux @ 2014-12-09 10:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Dec 09, 2014 at 11:19:40AM +0100, Arend van Spriel wrote:
> The issue did not trigger overnight so it seems setting bit 22 <Shared
> Attribute _Override_ Enable> solves the issue over here. Now the question is
> how to move forward with this. As I understood from Catalin this patch was
> not included as it was not considered responsibility of the linux kernel.

It is preferable for firmware to configure the L2 cache appropriately,
which includes things like the prefetch offsets as well as feature bits
like bit 22.

I think what I'll do is queue up a patch which adds a warning if bit 22
is not set, suggesting that firmware is updated to set this bit.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-09 10:29                       ` Russell King - ARM Linux
  (?)
@ 2014-12-09 11:07                         ` Arend van Spriel
  -1 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-09 11:07 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Catalin Marinas, Arnd Bergmann, linux-arm-kernel,
	brcm80211-dev-list, linux-wireless, linux-kernel, Will Deacon,
	Hante Meuleman, hauke, David Miller, Marek Szyprowski

On 12/09/14 11:29, Russell King - ARM Linux wrote:
> On Tue, Dec 09, 2014 at 11:19:40AM +0100, Arend van Spriel wrote:
>> The issue did not trigger overnight so it seems setting bit 22<Shared
>> Attribute _Override_ Enable>  solves the issue over here. Now the question is
>> how to move forward with this. As I understood from Catalin this patch was
>> not included as it was not considered responsibility of the linux kernel.
>
> It is preferable for firmware to configure the L2 cache appropriately,
> which includes things like the prefetch offsets as well as feature bits
> like bit 22.
>
> I think what I'll do is queue up a patch which adds a warning if bit 22
> is not set, suggesting that firmware is updated to set this bit.

I was thinking in the same direction. Thanks to you all for looking into 
this. It did not feel right to use the dma_sync_single_for_cpu() for 
memory allocated with dma_alloc_coherent() and I am glad this got 
cleared up.

Regards,
Arend


^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-09 11:07                         ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-09 11:07 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Catalin Marinas, Arnd Bergmann, linux-arm-kernel,
	brcm80211-dev-list, linux-wireless, linux-kernel, Will Deacon,
	Hante Meuleman, hauke, David Miller, Marek Szyprowski

On 12/09/14 11:29, Russell King - ARM Linux wrote:
> On Tue, Dec 09, 2014 at 11:19:40AM +0100, Arend van Spriel wrote:
>> The issue did not trigger overnight so it seems setting bit 22<Shared
>> Attribute _Override_ Enable>  solves the issue over here. Now the question is
>> how to move forward with this. As I understood from Catalin this patch was
>> not included as it was not considered responsibility of the linux kernel.
>
> It is preferable for firmware to configure the L2 cache appropriately,
> which includes things like the prefetch offsets as well as feature bits
> like bit 22.
>
> I think what I'll do is queue up a patch which adds a warning if bit 22
> is not set, suggesting that firmware is updated to set this bit.

I was thinking in the same direction. Thanks to you all for looking into 
this. It did not feel right to use the dma_sync_single_for_cpu() for 
memory allocated with dma_alloc_coherent() and I am glad this got 
cleared up.

Regards,
Arend


^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-09 11:07                         ` Arend van Spriel
  0 siblings, 0 replies; 115+ messages in thread
From: Arend van Spriel @ 2014-12-09 11:07 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/09/14 11:29, Russell King - ARM Linux wrote:
> On Tue, Dec 09, 2014 at 11:19:40AM +0100, Arend van Spriel wrote:
>> The issue did not trigger overnight so it seems setting bit 22<Shared
>> Attribute _Override_ Enable>  solves the issue over here. Now the question is
>> how to move forward with this. As I understood from Catalin this patch was
>> not included as it was not considered responsibility of the linux kernel.
>
> It is preferable for firmware to configure the L2 cache appropriately,
> which includes things like the prefetch offsets as well as feature bits
> like bit 22.
>
> I think what I'll do is queue up a patch which adds a warning if bit 22
> is not set, suggesting that firmware is updated to set this bit.

I was thinking in the same direction. Thanks to you all for looking into 
this. It did not feel right to use the dma_sync_single_for_cpu() for 
memory allocated with dma_alloc_coherent() and I am glad this got 
cleared up.

Regards,
Arend

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-09 10:29                       ` Russell King - ARM Linux
  (?)
@ 2014-12-09 11:54                         ` Catalin Marinas
  -1 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-09 11:54 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Arend van Spriel, Arnd Bergmann, linux-arm-kernel,
	brcm80211-dev-list, linux-wireless, linux-kernel, Will Deacon,
	Hante Meuleman, hauke, David Miller, Marek Szyprowski

On Tue, Dec 09, 2014 at 10:29:05AM +0000, Russell King - ARM Linux wrote:
> On Tue, Dec 09, 2014 at 11:19:40AM +0100, Arend van Spriel wrote:
> > The issue did not trigger overnight so it seems setting bit 22 <Shared
> > Attribute _Override_ Enable> solves the issue over here. Now the question is
> > how to move forward with this. As I understood from Catalin this patch was
> > not included as it was not considered responsibility of the linux kernel.
> 
> It is preferable for firmware to configure the L2 cache appropriately,
> which includes things like the prefetch offsets as well as feature bits
> like bit 22.
> 
> I think what I'll do is queue up a patch which adds a warning if bit 22
> is not set, suggesting that firmware is updated to set this bit.

I'm fine with a (big) warning on this bit. But when you boot in secure
mode on 32-bit, do we still have a read/modify/write sequence for
L2X0_AUX_CTRL? A quick look at l2c310_enable() didn't reveal this (the
code has changed since I proposed the bit 22 setting patch).

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2014-12-09 11:54                         ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-09 11:54 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Arend van Spriel, Arnd Bergmann, linux-arm-kernel,
	brcm80211-dev-list, linux-wireless, linux-kernel, Will Deacon,
	Hante Meuleman, hauke, David Miller, Marek Szyprowski

On Tue, Dec 09, 2014 at 10:29:05AM +0000, Russell King - ARM Linux wrote:
> On Tue, Dec 09, 2014 at 11:19:40AM +0100, Arend van Spriel wrote:
> > The issue did not trigger overnight so it seems setting bit 22 <Shared
> > Attribute _Override_ Enable> solves the issue over here. Now the question is
> > how to move forward with this. As I understood from Catalin this patch was
> > not included as it was not considered responsibility of the linux kernel.
> 
> It is preferable for firmware to configure the L2 cache appropriately,
> which includes things like the prefetch offsets as well as feature bits
> like bit 22.
> 
> I think what I'll do is queue up a patch which adds a warning if bit 22
> is not set, suggesting that firmware is updated to set this bit.

I'm fine with a (big) warning on this bit. But when you boot in secure
mode on 32-bit, do we still have a read/modify/write sequence for
L2X0_AUX_CTRL? A quick look at l2c310_enable() didn't reveal this (the
code has changed since I proposed the bit 22 setting patch).

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2014-12-09 11:54                         ` Catalin Marinas
  0 siblings, 0 replies; 115+ messages in thread
From: Catalin Marinas @ 2014-12-09 11:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Dec 09, 2014 at 10:29:05AM +0000, Russell King - ARM Linux wrote:
> On Tue, Dec 09, 2014 at 11:19:40AM +0100, Arend van Spriel wrote:
> > The issue did not trigger overnight so it seems setting bit 22 <Shared
> > Attribute _Override_ Enable> solves the issue over here. Now the question is
> > how to move forward with this. As I understood from Catalin this patch was
> > not included as it was not considered responsibility of the linux kernel.
> 
> It is preferable for firmware to configure the L2 cache appropriately,
> which includes things like the prefetch offsets as well as feature bits
> like bit 22.
> 
> I think what I'll do is queue up a patch which adds a warning if bit 22
> is not set, suggesting that firmware is updated to set this bit.

I'm fine with a (big) warning on this bit. But when you boot in secure
mode on 32-bit, do we still have a read/modify/write sequence for
L2X0_AUX_CTRL? A quick look at l2c310_enable() didn't reveal this (the
code has changed since I proposed the bit 22 setting patch).

-- 
Catalin

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
  2014-12-09 10:29                       ` Russell King - ARM Linux
  (?)
@ 2015-01-20 15:22                         ` Fabio Estevam
  -1 siblings, 0 replies; 115+ messages in thread
From: Fabio Estevam @ 2015-01-20 15:22 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Arend van Spriel, brcm80211-dev-list, Arnd Bergmann,
	Catalin Marinas, linux-wireless, linux-kernel, Will Deacon,
	Hante Meuleman, hauke, David Miller, linux-arm-kernel,
	Marek Szyprowski

Hi Russell,

On Tue, Dec 9, 2014 at 8:29 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Tue, Dec 09, 2014 at 11:19:40AM +0100, Arend van Spriel wrote:
>> The issue did not trigger overnight so it seems setting bit 22 <Shared
>> Attribute _Override_ Enable> solves the issue over here. Now the question is
>> how to move forward with this. As I understood from Catalin this patch was
>> not included as it was not considered responsibility of the linux kernel.
>
> It is preferable for firmware to configure the L2 cache appropriately,
> which includes things like the prefetch offsets as well as feature bits
> like bit 22.
>
> I think what I'll do is queue up a patch which adds a warning if bit 22
> is not set, suggesting that firmware is updated to set this bit.

Do you mean something like this?

--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -943,6 +943,10 @@ static int __init __l2c_init(const struct
l2c_init_data *data,
     pr_info("%s: CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
         data->type, cache_id, aux);

+    if (!(aux & L2C_AUX_CTRL_SHARED_OVERRIDE))
+        pr_warn("%s: L2C_AUX_CTRL_SHARED_OVERRIDE needs to be set by
the bootloader\n",
+            data->type);
+
     return 0;
 }

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: using DMA-API on ARM
@ 2015-01-20 15:22                         ` Fabio Estevam
  0 siblings, 0 replies; 115+ messages in thread
From: Fabio Estevam @ 2015-01-20 15:22 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Arend van Spriel, brcm80211-dev-list, Arnd Bergmann,
	Catalin Marinas, linux-wireless, linux-kernel, Will Deacon,
	Hante Meuleman, hauke, David Miller, linux-arm-kernel,
	Marek Szyprowski

Hi Russell,

On Tue, Dec 9, 2014 at 8:29 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Tue, Dec 09, 2014 at 11:19:40AM +0100, Arend van Spriel wrote:
>> The issue did not trigger overnight so it seems setting bit 22 <Shared
>> Attribute _Override_ Enable> solves the issue over here. Now the question is
>> how to move forward with this. As I understood from Catalin this patch was
>> not included as it was not considered responsibility of the linux kernel.
>
> It is preferable for firmware to configure the L2 cache appropriately,
> which includes things like the prefetch offsets as well as feature bits
> like bit 22.
>
> I think what I'll do is queue up a patch which adds a warning if bit 22
> is not set, suggesting that firmware is updated to set this bit.

Do you mean something like this?

--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -943,6 +943,10 @@ static int __init __l2c_init(const struct
l2c_init_data *data,
     pr_info("%s: CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
         data->type, cache_id, aux);

+    if (!(aux & L2C_AUX_CTRL_SHARED_OVERRIDE))
+        pr_warn("%s: L2C_AUX_CTRL_SHARED_OVERRIDE needs to be set by
the bootloader\n",
+            data->type);
+
     return 0;
 }

^ permalink raw reply	[flat|nested] 115+ messages in thread

* using DMA-API on ARM
@ 2015-01-20 15:22                         ` Fabio Estevam
  0 siblings, 0 replies; 115+ messages in thread
From: Fabio Estevam @ 2015-01-20 15:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

On Tue, Dec 9, 2014 at 8:29 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Tue, Dec 09, 2014 at 11:19:40AM +0100, Arend van Spriel wrote:
>> The issue did not trigger overnight so it seems setting bit 22 <Shared
>> Attribute _Override_ Enable> solves the issue over here. Now the question is
>> how to move forward with this. As I understood from Catalin this patch was
>> not included as it was not considered responsibility of the linux kernel.
>
> It is preferable for firmware to configure the L2 cache appropriately,
> which includes things like the prefetch offsets as well as feature bits
> like bit 22.
>
> I think what I'll do is queue up a patch which adds a warning if bit 22
> is not set, suggesting that firmware is updated to set this bit.

Do you mean something like this?

--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -943,6 +943,10 @@ static int __init __l2c_init(const struct
l2c_init_data *data,
     pr_info("%s: CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
         data->type, cache_id, aux);

+    if (!(aux & L2C_AUX_CTRL_SHARED_OVERRIDE))
+        pr_warn("%s: L2C_AUX_CTRL_SHARED_OVERRIDE needs to be set by
the bootloader\n",
+            data->type);
+
     return 0;
 }

^ permalink raw reply	[flat|nested] 115+ messages in thread

end of thread, other threads:[~2015-01-20 15:23 UTC | newest]

Thread overview: 115+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-05  9:22 using DMA-API on ARM Arend van Spriel
2014-12-05  9:22 ` Arend van Spriel
2014-12-05  9:22 ` Arend van Spriel
2014-12-05  9:45 ` Russell King - ARM Linux
2014-12-05  9:45   ` Russell King - ARM Linux
2014-12-05  9:45   ` Russell King - ARM Linux
2014-12-05 12:24   ` Will Deacon
2014-12-05 12:24     ` Will Deacon
2014-12-05 12:24     ` Will Deacon
2014-12-05 12:56     ` Hante Meuleman
2014-12-05 12:56       ` Hante Meuleman
2014-12-05 12:56       ` Hante Meuleman
2014-12-05 13:23       ` Russell King - ARM Linux
2014-12-05 13:23         ` Russell King - ARM Linux
2014-12-05 13:23         ` Russell King - ARM Linux
2014-12-05 14:20         ` Hante Meuleman
2014-12-05 14:20           ` Hante Meuleman
2014-12-05 14:20           ` Hante Meuleman
2014-12-05 14:47           ` Arend van Spriel
2014-12-05 14:47             ` Arend van Spriel
2014-12-05 14:47             ` Arend van Spriel
2014-12-08 13:47           ` Hante Meuleman
2014-12-08 13:47             ` Hante Meuleman
2014-12-08 13:47             ` Hante Meuleman
2014-12-08 15:01             ` Arnd Bergmann
2014-12-08 15:01               ` Arnd Bergmann
2014-12-08 15:17               ` Russell King - ARM Linux
2014-12-08 15:17                 ` Russell King - ARM Linux
2014-12-08 15:22                 ` Arnd Bergmann
2014-12-08 15:22                   ` Arnd Bergmann
2014-12-08 16:03               ` Catalin Marinas
2014-12-08 16:03                 ` Catalin Marinas
2014-12-08 16:03                 ` Catalin Marinas
2014-12-08 17:01                 ` Arend van Spriel
2014-12-08 17:01                   ` Arend van Spriel
2014-12-08 17:01                   ` Arend van Spriel
2014-12-09 10:19                   ` Arend van Spriel
2014-12-09 10:19                     ` Arend van Spriel
2014-12-09 10:19                     ` Arend van Spriel
2014-12-09 10:29                     ` Russell King - ARM Linux
2014-12-09 10:29                       ` Russell King - ARM Linux
2014-12-09 10:29                       ` Russell King - ARM Linux
2014-12-09 11:07                       ` Arend van Spriel
2014-12-09 11:07                         ` Arend van Spriel
2014-12-09 11:07                         ` Arend van Spriel
2014-12-09 11:54                       ` Catalin Marinas
2014-12-09 11:54                         ` Catalin Marinas
2014-12-09 11:54                         ` Catalin Marinas
2015-01-20 15:22                       ` Fabio Estevam
2015-01-20 15:22                         ` Fabio Estevam
2015-01-20 15:22                         ` Fabio Estevam
2014-12-08 16:22               ` Arend van Spriel
2014-12-08 16:22                 ` Arend van Spriel
2014-12-08 16:38                 ` Arnd Bergmann
2014-12-08 16:38                   ` Arnd Bergmann
2014-12-08 16:47                   ` Russell King - ARM Linux
2014-12-08 16:47                     ` Russell King - ARM Linux
2014-12-08 16:50                   ` Catalin Marinas
2014-12-08 16:50                     ` Catalin Marinas
2014-12-08 16:50                     ` Catalin Marinas
2014-12-08 16:54                     ` Russell King - ARM Linux
2014-12-08 16:54                       ` Russell King - ARM Linux
2014-12-08 16:54                       ` Russell King - ARM Linux
2014-12-05 15:06         ` Russell King - ARM Linux
2014-12-05 15:06           ` Russell King - ARM Linux
2014-12-05 15:06           ` Russell King - ARM Linux
2014-12-05 18:28           ` Catalin Marinas
2014-12-05 18:28             ` Catalin Marinas
2014-12-05 18:28             ` Catalin Marinas
2014-12-05 19:22             ` Arend van Spriel
2014-12-05 19:22               ` Arend van Spriel
2014-12-05 19:22               ` Arend van Spriel
2014-12-05 19:25               ` Russell King - ARM Linux
2014-12-05 19:25                 ` Russell King - ARM Linux
2014-12-05 19:25                 ` Russell King - ARM Linux
2014-12-05 12:43   ` Arend van Spriel
2014-12-05 12:43     ` Arend van Spriel
2014-12-05 12:43     ` Arend van Spriel
2014-12-05 12:59     ` Russell King - ARM Linux
2014-12-05 12:59       ` Russell King - ARM Linux
2014-12-05 12:59       ` Russell King - ARM Linux
2014-12-05  9:52 ` Arnd Bergmann
2014-12-05  9:52   ` Arnd Bergmann
2014-12-05 11:11   ` Russell King - ARM Linux
2014-12-05 11:11     ` Russell King - ARM Linux
2014-12-05 11:49     ` Hante Meuleman
2014-12-05 11:49       ` Hante Meuleman
2014-12-05 11:49       ` Hante Meuleman
2014-12-05 17:38     ` Catalin Marinas
2014-12-05 17:38       ` Catalin Marinas
2014-12-05 17:38       ` Catalin Marinas
2014-12-05 18:24       ` Russell King - ARM Linux
2014-12-05 18:24         ` Russell King - ARM Linux
2014-12-05 18:24         ` Russell King - ARM Linux
2014-12-05 18:31         ` Catalin Marinas
2014-12-05 18:31           ` Catalin Marinas
2014-12-05 18:31           ` Catalin Marinas
2014-12-05 18:39 ` Catalin Marinas
2014-12-05 18:39   ` Catalin Marinas
2014-12-05 18:39   ` Catalin Marinas
2014-12-05 18:53   ` Catalin Marinas
2014-12-05 18:53     ` Catalin Marinas
2014-12-05 18:53     ` Catalin Marinas
2014-12-05 19:50     ` Arend van Spriel
2014-12-05 19:50       ` Arend van Spriel
2014-12-05 19:50       ` Arend van Spriel
2014-12-08 12:55     ` Johannes Stezenbach
2014-12-08 12:55       ` Johannes Stezenbach
2014-12-08 12:55       ` Johannes Stezenbach
2014-12-08 15:55       ` Catalin Marinas
2014-12-08 15:55         ` Catalin Marinas
2014-12-08 15:55         ` Catalin Marinas
2014-12-08 16:50         ` Johannes Stezenbach
2014-12-08 16:50           ` Johannes Stezenbach
2014-12-08 16:50           ` Johannes Stezenbach

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.