lkml.org 
[lkml]   [2000]   [Mar]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
SubjectRe: DMA mapping
From
Hello again.

On Tue, Mar 07, 2000 at 10:11:00AM +0100, Jakub Jelinek wrote:
> The discussion was held mostly privately among Linux port maintainers, but
> parts of it went to lkml, just do a search.

I found a tiny amount of info (various searches), but never mind.

> > In particular, I'm curious as to why there isn't a
> >
> > void * pci_map_invert (pci_dev * device, dma_addr_t bus_addr)
>
> It can be fairly slow, its the same as why there is no virt_to_phys for
> vmalloced area (both may require looking up some page tables, in
> pci_map_invert IO page tables particularly on some machines).

I have been ill at home for a few days, I took the opportunity to look
at the feasibility of either changing unmap_single to return a void *
or producing a separate invert_single for the architectures that
define non-trivial mapping functions. It was not hard and no search
through tables is necessary (2.3.50).

I sketch the code here for alpha and sparc64:

alpha pci_unmap_single changes:

// inv_iommu_pte(x) = (x & ~1) << (PAGE_SHIFT-1)
direct-map case: return phys_to_virt (dma - some_constant)
... as before
paddr = inv_iommu_pte (arena->ptes[dma_ofs]) | dma & ~PAGEMASK
return phys_to_virt (phys)

sparc64 changes:

base_phys = iopte_val(*base) & PAGE_MASK
cpu = __va (base_phys) | dma & ~PAGE_MASK
lock...unlock as before
return cpu

phys_to_virt and __va are very short inline functions in both cases,
how expensive are the arena and iopte_val lookups?

It really is trivial. Whether the code would be better off in a
separate invert function can be argued. cons: adds another function,
adds some code repetition with unmap; pros: no hit for other users of
unmap, no need for caller to know size to get at the inverse (though
how likely is it that the caller does not know the type of the
pointer?), no change to unmap's type (though void to void * is pretty
innocuous), most likely to be important: the caller may not want to
unmap the buffer at the same time.

Calling the (hypothetical) pci_invert_single with some value not
returned by pci_map_single is, naturally, undefined.

Minor things:

inverted address will be bogus if the caller originally asks for a
mapping of zero pages (page-aligned start address, zero bytes long).

there may be an off-by-1 buglet in arch/alpha/kernel/pci_iommu.c:

one test reads: paddr + size + __direct_map_base - 1 <= max_dma
another reads: arena->dma_base + arena->size > max_dma

The first one does not allow foo == max_dma but the second does.

If anyone would like to see a patch for either void * unmap () or
which adds a separate invert function, let me know and I'll put one
together for all architectures.

Giuliano.
--
mail: gprocida@madge.com / myxie@debian.org | public PGP key ID: 93898735
home: +44 181 351 1172 / Flat 5, 135 Palmerston Road, London N22 8RW, UK
work: +44 1753 661 305 / Madge Networks, Wexham Springs, Slough SL3 6PJ, UK

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:57    [W:0.522 / U:1.840 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site