Messages in this thread | | | Subject | Re: [PATCH 1/2] dma-mapping: add a dma_ops_bypass flag to struct device | From | Alexey Kardashevskiy <> | Date | Tue, 24 Mar 2020 15:55:33 +1100 |
| |
On 24/03/2020 14:37, Alexey Kardashevskiy wrote: > > > On 24/03/2020 04:20, Christoph Hellwig wrote: >> On Mon, Mar 23, 2020 at 07:58:01PM +1100, Alexey Kardashevskiy wrote: >>>>> 0x100.0000.0000 .. 0x101.0000.0000 >>>>> >>>>> 2x4G, each is 1TB aligned. And we can map directly only the first 4GB >>>>> (because of the maximum IOMMU table size) but not the other. And 1:1 on >>>>> that "pseries" is done with offset=0x0800.0000.0000.0000. >>>>> >>>>> So we want to check every bus address against dev->bus_dma_limit, not >>>>> dev->coherent_dma_mask. In the example above I'd set bus_dma_limit to >>>>> 0x0800.0001.0000.0000 and 1:1 mapping for the second 4GB would not be >>>>> tried. Does this sound reasonable? Thanks, >>>> >>>> bus_dma_limit is just another limiting factor applied on top of >>>> coherent_dma_mask or dma_mask respectively. >>> >>> This is not enough for the task: in my example, I'd set bus limit to >>> 0x0800.0001.0000.0000 but this would disable bypass for all RAM >>> addresses - the first and the second 4GB blocks. >> >> So what about something like the version here: >> >> http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/dma-bypass.3 > > > dma_alloc_direct() and dma_map_direct() do the same thing now which is > good, did I miss anything else? > > This lets us disable bypass automatically if this weird memory appears > in the system but does not let us have 1:1 after that even for normal > RAM. Thanks,
Ah no, does not help much, simple setting dma_ops_bypass will though.
But eventually, in this function:
static inline bool dma_map_direct(struct device *dev, const struct dma_map_ops *ops) { if (likely(!ops)) return true; if (!dev->dma_ops_bypass) return false;
return min_not_zero(*dev->dma_mask, dev->bus_dma_limit) >= dma_direct_get_required_mask(dev); }
we rather want it to take a dma handle and a size, and add
if (dev->bus_dma_limit) return dev->bus_dma_limit > dma_handle + size;
where dma_handle=phys_to_dma(dev, phys) (I am not doing it here as unmap needs the same test and it does not receive phys as a parameter).
-- Alexey
| |