linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mikko Perttunen <cyndis@kapsi.fi>
To: Arnd Bergmann <arnd@arndb.de>
Cc: Thierry Reding <thierry.reding@gmail.com>,
	Linux ARM <linux-arm-kernel@lists.infradead.org>,
	Mikko Perttunen <mperttunen@nvidia.com>,
	dri-devel <dri-devel@lists.freedesktop.org>,
	linux-tegra@vger.kernel.org,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] [RFC] gpu: host1x: shut up warning about DMA API misuse
Date: Thu, 20 Apr 2017 12:44:42 +0300	[thread overview]
Message-ID: <46945c47-2e4e-270d-b551-b207c538e5cb@kapsi.fi> (raw)
In-Reply-To: <CAK8P3a3JJrA_4Zur47ngWmR7VeKBopJLNZCaqOPzzmnFoV3=Ew@mail.gmail.com>

On 20.04.2017 11:25, Arnd Bergmann wrote:
> On Thu, Apr 20, 2017 at 9:02 AM, Mikko Perttunen <cyndis@kapsi.fi> wrote:
>> On 19.04.2017 21:24, Arnd Bergmann wrote:
>>>
>>> When dma_addr_t and phys_addr_t are not the same size, we get a warning
>>> from the dma_alloc_wc function:
>>>
>>> drivers/gpu/host1x/cdma.c: In function 'host1x_pushbuffer_init':
>>> drivers/gpu/host1x/cdma.c:94:48: error: passing argument 3 of
>>> 'dma_alloc_wc' from incompatible pointer type
>>> [-Werror=incompatible-pointer-types]
>>>    pb->mapped = dma_alloc_wc(host1x->dev, size, &pb->phys,
>>>                                                 ^
>>> In file included from drivers/gpu/host1x/cdma.c:22:0:
>>> include/linux/dma-mapping.h:761:37: note: expected 'dma_addr_t * {aka long
>>> long unsigned int *}' but argument is of type 'phys_addr_t * {aka unsigned
>>> int *}'
>>>  static noinline_if_stackbloat void *dma_alloc_wc(struct device *dev,
>>> size_t size,
>>>                                      ^~~~~~~~~~~~
>>> drivers/gpu/host1x/cdma.c:113:48: error: passing argument 3 of
>>> 'dma_alloc_wc' from incompatible pointer type
>>> [-Werror=incompatible-pointer-types]
>>>    pb->mapped = dma_alloc_wc(host1x->dev, size, &pb->phys,
>>>                                                 ^
>>> In file included from drivers/gpu/host1x/cdma.c:22:0:
>>> include/linux/dma-mapping.h:761:37: note: expected 'dma_addr_t * {aka long
>>> long unsigned int *}' but argument is of type 'phys_addr_t * {aka unsigned
>>> int *}'
>>>  static noinline_if_stackbloat void *dma_alloc_wc(struct device *dev,
>>> size_t size,
>>>                                      ^~~~~~~~~~~~
>>>
>>> The problem here is that dma_alloc_wc() returns a pointer to a dma_addr_t
>>> that may already be translated by an IOMMU, but the driver passes this
>>> into iommu_map() as a physical address. This works by accident only when
>>> the IOMMU does not get registered with the DMA API and there is a 1:1
>>> mapping between physical addresses as seen by the CPU and the device.
>>>
>>> The fundamental problem here is the lack of a generic API to do what the
>>> driver wants: allocating CPU-visible memory for use by a device through
>>> user-defined IOMMU settings. Neither the dma-mapping API nor the IOMMU
>>> API can do this by itself, and combining the two is not well-defined.
>>>
>>> This patch addresses the type mismatch by adding a third pointer into the
>>> push_buffer structure: in addition to the address as seen from the CPU
>>> and the address inside of the local IOMMU domain, the pb->alloc pointer
>>> is the token returned by dma_alloc_wc(), and this is what we later need
>>> to pass into dma_free_wc().
>>>
>>> The address we pass into iommu_map() however is the physical address
>>> computed from virt_to_phys(), assuming that the pointer we have here
>>> is part of the linear mapping (which is also questionable, e.g. when we
>>> have a non-coherent device on ARM32 this may be false). Also, when
>>> the DMA API uses the IOMMU to allocate the pointer for the default
>>> domain, we end up with two IOMMU mappings for the same physical address.
>>>
>>
>> I think we have a "policy" on Tegra that the DMA API will never allocate
>> using the IOMMU (Thierry can elaborate on this), which is why I wrote the
>> code with that assumption. Essentially, we have made the DMA API into the
>> API that allocates CPU-visible memory.
>
> I don't think this can be a per-platform policy.

Yeah, now that we are using the ARM SMMU on T186 onwards it's more 
difficult than when we were using the Tegra SMMU, so we'll probably have 
to change that.

The goal of the current code is to allocate memory from the CMA, so one 
option would be to change it to use dma_alloc_from_contiguous. That way 
we wouldn't get the double IOMMU mapping, which would be nice.

>
>> Considering that, I'm wondering if we can just have a temporary local
>> dma_addr_t and then cast that to phys_addr_t, combined with a good comment?
>
> That was my first approach, and it does address the warning, but
> I did not send it because it still felt too wrong.
>
>      Arnd
> --
> To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

  reply	other threads:[~2017-04-20  9:45 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-19 18:24 [PATCH] [RFC] gpu: host1x: shut up warning about DMA API misuse Arnd Bergmann
2017-04-20  7:02 ` Mikko Perttunen
2017-04-20  8:25   ` Arnd Bergmann
2017-04-20  9:44     ` Mikko Perttunen [this message]
2017-04-20 10:02       ` Arnd Bergmann
2017-04-20 10:14         ` Mikko Perttunen
2017-04-20  9:49     ` Russell King - ARM Linux
2017-04-20 10:05       ` Arnd Bergmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=46945c47-2e4e-270d-b551-b207c538e5cb@kapsi.fi \
    --to=cyndis@kapsi.fi \
    --cc=arnd@arndb.de \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=mperttunen@nvidia.com \
    --cc=thierry.reding@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).