public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Does kmalloc always return address below 4GB?
@ 2002-03-05 11:12 Adam J. Richter
  2002-03-05 11:16 ` David S. Miller
  0 siblings, 1 reply; 20+ messages in thread
From: Adam J. Richter @ 2002-03-05 11:12 UTC (permalink / raw)
  To: linux-kernel

	I am trying to convert linux-2.5.6-pre2/drivers/scsi/advansys.c
to the DMA mapping system described in Documenation/DMA-mapping.txt
in an effort to try to help to make all of the drivers compile again.
I have a question that would help me with this process, and probably
others who has occasion to fiddle with any of the many devices covered
by this question.

	According to DMA-mapping.txt, I am allowed to use use
an address returned from kmalloc as a DMA address, without
need to convert by pci_map_single or allocate space with
pci_alloc_consistent.  The advansys.c hardware (and probably
many PCI devices) asssumes 32-bit addresses.  Can I rely on
on all architectures that support PCI or ISA that kmalloc
will always return an address below 2**32 if GFP_HIGHMEM
is not specified?  If not, then I guess I can use
pci_alloc_consistent and pci_map_single as necessary, since they
should can potentially know that I am using a device that
only understands 32-bit addresses, from my earlier call to
pci_set_dma_mask.  However, I assume that it is considered
simpler and therefore better to avoid these routines when possible.

Adam J. Richter     __     ______________   4880 Stevens Creek Blvd, Suite 104
adam@yggdrasil.com     \ /                  San Jose, California 95129-1034
+1 408 261-6630         | g g d r a s i l   United States of America
fax +1 408 261-6631      "Free Software For The Rest Of Us."

^ permalink raw reply	[flat|nested] 20+ messages in thread
* Re: Does kmalloc always return address below 4GB?
@ 2002-03-05 11:52 Adam J. Richter
  2002-03-05 11:59 ` David S. Miller
  0 siblings, 1 reply; 20+ messages in thread
From: Adam J. Richter @ 2002-03-05 11:52 UTC (permalink / raw)
  To: davem; +Cc: linux-kernel

>Just use pci_alloc_consistent, it never gives you
>anything larger than 32-bit addresses, please read the
>documentation :-)

	I see the smiley, but let me point out that I have
read Documentation/DMA-mapping.txt and I was misled by this
sentence:

| If you acquired your memory via the page allocator
| (i.e. __get_free_page*()) or the generic memory allocators
| (i.e. kmalloc() or kmem_cache_alloc()) then you may DMA to/from
| that memory using the addresses returned from those routines.

	It might be a good idea to rephrase it.  If I knew what that
sentence I would propose a patch to the DMA-mapping.txt file, but I
honestly don't know what proposition that sentence is supposed
to convey.  If there really is no guarantee that this sentence is
conveying, then I guess the sentence should be deleted.

	Anyhow, thanks for your quick clarification.  The driver
breaking on 64-bit architectures was exactly what I was worried about.

Adam J. Richter     __     ______________   4880 Stevens Creek Blvd, Suite 104
adam@yggdrasil.com     \ /                  San Jose, California 95129-1034
+1 408 261-6630         | g g d r a s i l   United States of America
fax +1 408 261-6631      "Free Software For The Rest Of Us."

^ permalink raw reply	[flat|nested] 20+ messages in thread
* Re: Does kmalloc always return address below 4GB?
@ 2002-03-05 14:43 Adam J. Richter
  2002-03-05 15:15 ` David S. Miller
  0 siblings, 1 reply; 20+ messages in thread
From: Adam J. Richter @ 2002-03-05 14:43 UTC (permalink / raw)
  To: davem; +Cc: linux-kernel

>   | If you acquired your memory via the page allocator
>   | (i.e. __get_free_page*()) or the generic memory allocators
>   | (i.e. kmalloc() or kmem_cache_alloc()) then you may DMA to/from
>   | that memory using the addresses returned from those routines.
[...]
>Probably it should qualify what it means with "and you used
>GFP_KERNEL".  Because that was the intention.

	That change alone would result in a setence that
I still would not understand.  Does GFP_KERNEL guarantee address
below 4GB on all architectures?  The GFP_KERNEL mask that currently
includes __GFP_IO, but I'm not sure that that even means "below 4GB"
on all architectures.  If __GFP_IO really does guarantee "below 4GB
and physical = virtual" on all architectures, then it sounds like
I am back to not having to use pci_{,un}map_single in a number of
places in advansys.c, because the Scsi_Request structurs are allocated
with GFP_ATOMIC, which also includes __GFP_IO.

>I'll fix that.

>However, you can use GFP_HIGH memory with pci_map_page _iff_
>you set your DMA mask to allow 64-bits.

>The original impetus for that quoted bit of DMA-mapping.txt
>was to make sure nobody used vmalloc() or kmap() pointers.

	Just to be clear, I assume that you mean that you cannot
simply cast these virtual addresses to dma_addr_t and that the
underlying physical memory is not guaranteed to be below 4GB,
but that you can use that memory with pci_map_single if your
PCI device can handle 64 bit addresses.

	If I got it right, then here is some proposed replacement
text, to possibly save you a little effort:

| 	You cannot directly use an address in an area returned by
| vmalloc() or kmap(), because these routines are *not* guaranteed to
| return addresses where virtual == cpu memory bus == pci.  You
| cannot even use those addresses with PCI device that only have
| 32 bit addressing, because the underlying physical memory may be
| above 4GB.
|
| 	However, a PCI card that does 64-bit addressing can
| access memory returned by vmalloc or kmap via the dma_addr_t
| address returned by pci_map_single or pci_map_page.

Adam J. Richter     __     ______________   4880 Stevens Creek Blvd, Suite 104
adam@yggdrasil.com     \ /                  San Jose, California 95129-1034
+1 408 261-6630         | g g d r a s i l   United States of America
fax +1 408 261-6631      "Free Software For The Rest Of Us."

^ permalink raw reply	[flat|nested] 20+ messages in thread
* Re: Does kmalloc always return address below 4GB?
@ 2002-03-05 16:39 Adam J. Richter
  2002-03-05 17:00 ` Gerd Knorr
  2002-03-05 21:57 ` Steffen Persvold
  0 siblings, 2 replies; 20+ messages in thread
From: Adam J. Richter @ 2002-03-05 16:39 UTC (permalink / raw)
  To: davem; +Cc: linux-kernel

>   From: "Adam J. Richter" <adam@yggdrasil.com>
>   Date: Tue, 5 Mar 2002 06:43:35 -0800
>   
>   	Just to be clear, I assume that you mean that you cannot
>   simply cast these virtual addresses to dma_addr_t and that the
>   underlying physical memory is not guaranteed to be below 4GB,
>   but that you can use that memory with pci_map_single if your
>   PCI device can handle 64 bit addresses.
>   
>   	If I got it right, then here is some proposed replacement
>   text, to possibly save you a little effort:

>You haven't got it right.  Physical address > 4GB does not mean
>your 32-bit device cannot DMA to it.  Stop thinking about
>implementation, that's the whole point of the abstraction :-)

>On 64-bit platforms that don't set CONFIG_HIGHMEM, they have MMU's on
>the PCI bus that can map arbitrary 64-bit physical addresses to 32-bit
>PCI bus addresses.  So on these platforms you may pass any pointer
>from kmalloc()/alloc_page() whatsoever into the pci_map_foo()
>routines.

	I think you're confusing a "there exists one x" with "for every
x".  In your statement, you've reduced your universe to "platforms
that don't set CONFIG_HIGHMEM", but that is not all systems.

	While there exists one (or more) computers that have this
reverse mapping hardware, I believe that it is not true of *all*
platforms with >4GB of RAM.  I infer from your statement that
all 64-bit platforms that lack this hardware should define CONFIG_HIGHMEM.

>In order to handle highmem pages, you have to set your DMA mask
>appropriately (to indicate 64-bit addressing capability) and
>use pci_map_page() instead of pci_map_single().

	Let's say I have some random Pentium3 or Pentium4
machine with >4GB of memory, the PCI card in question only does 32 bit
addressing.  This is a CONFIG_HIGMEM platform and it lacks the
MMU that you discuss in the first paragraph of DMA-mapping.txt, right?

	Now imagine that a vmalloc in this driver returns a page
above 4GB (include/linux/vmalloc.h defines vmalloc() to pass __GFP_HIGHMEM).
What will pci_map_single return?   I think, under x86, pci_map_single
will call __pa, which will return the underlying physical address,
which, in this case, would be above 4GB, which would not be accessible
by the PCI card.

>Look at other drivers using the DMA interfaces like the two aic7xxx
>and all of the sym53c8xx drivers, they get it right.

	Grepping for vmalloc and kmap in them turns up no hits.

	I understand that your pci_alloc_consistent abstration allows
one to write a driver for a 32-bit PCI card that, on 64-bit systems
with the MMU that you describe, that will be able to use memory above 4GB
for IO transfers, like so:

		pci_set_dma_mask(pcidev, 0xffffffff);
		addr = pci_alloc_consistent(pcidev, nbytes, direction,
					    &dma_addr);
		/* __pa(addr) may be >4GB, but only on systems with
		   PCI address mapping hardware.  dma_address will
		   be <4GB on all systems. */
		TELL_DEVICE_TO_DO_TRANSFER(dma_addr, nbytes);
		pci_free_consistent(...);

	Maybe I need to rephrase my proposed text for greater
clarity.  The point of my proposed text was that, in the absense of
"#ifndef CONFIG_HIGMEM", the following code will not work on a 32-bit
computer with >4GB of RAM (CONFIG_HIGHEM) talking to a PCI card
that only does 32-bit addressing:

		pci_set_dma_mask(pcidev, 0xffffffff);
		addr = vmalloc(nbytes);
		/* On an x86 with >4GB of RAM, addr will be <4GB, but
	           __pa(addr) might be >4GB, and the system lacks
	           PCI address mapping harware. */

		dma_addr = pci_map_single(pcidev, addr, nbytes, direction);
		/* Uh oh!  dma_addr may be >4GB and I might not have	
		   PCI address mapping hardware! */
		TELL_DEVICE_TO_DO_TRANSFER(dma_addr, nbytes);
		pci_unmap_single(...);

	Was this unclear in my proposed text or do I still misunderstand
some fact that you're trying to convey (if so, sorry if for apparently
being so dense about it)?

Adam J. Richter     __     ______________   4880 Stevens Creek Blvd, Suite 104
adam@yggdrasil.com     \ /                  San Jose, California 95129-1034
+1 408 261-6630         | g g d r a s i l   United States of America
fax +1 408 261-6631      "Free Software For The Rest Of Us."

^ permalink raw reply	[flat|nested] 20+ messages in thread
* Re: Does kmalloc always return address below 4GB?
@ 2002-03-05 17:08 Adam J. Richter
  2002-03-06  1:13 ` David S. Miller
  0 siblings, 1 reply; 20+ messages in thread
From: Adam J. Richter @ 2002-03-05 17:08 UTC (permalink / raw)
  To: sp; +Cc: davem, linux-kernel

Steffen Persvold writes:
>I know pci_map_single (and _sg) will
>use bounce buffers on platforms without an IOMMU [...]

	For a moment I thought that must be the point that I
was missing, but I don't see any such bounce buffer support
in linux-2.5.6-pre2/include/asm-i386/pci.h or arch/i386/kernel/pci-dma.c.
I do not see how this is currently implemented on x86 systems with >4GB
of RAM.

	Or, by "will use" did you mean "will implement in the future?"

Adam J. Richter     __     ______________   4880 Stevens Creek Blvd, Suite 104
adam@yggdrasil.com     \ /                  San Jose, California 95129-1034
+1 408 261-6630         | g g d r a s i l   United States of America
fax +1 408 261-6631      "Free Software For The Rest Of Us."

^ permalink raw reply	[flat|nested] 20+ messages in thread
* Re: Does kmalloc always return address below 4GB?
@ 2002-03-06  2:28 Adam J. Richter
  0 siblings, 0 replies; 20+ messages in thread
From: Adam J. Richter @ 2002-03-06  2:28 UTC (permalink / raw)
  To: sp; +Cc: linux-kernel

>From: Steffen Persvold <sp@scali.com>
[...]
>This is sort of the same question I have, the only problem you will
>have here is that vmalloc() will
>return only _virtual_ contiguous pages [...]

	In my example, you can assume the amount of memory
being allocated fits into a single page.  I was not talking
about issues related to crossing page boundaries.

Adam J. Richter     __     ______________   4880 Stevens Creek Blvd, Suite 104
adam@yggdrasil.com     \ /                  San Jose, California 95129-1034
+1 408 261-6630         | g g d r a s i l   United States of America
fax +1 408 261-6631      "Free Software For The Rest Of Us."

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

end of thread, other threads:[~2002-03-06  7:25 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-03-05 11:12 Does kmalloc always return address below 4GB? Adam J. Richter
2002-03-05 11:16 ` David S. Miller
2002-03-05 15:43   ` Steffen Persvold
2002-03-05 15:47     ` David S. Miller
2002-03-05 16:44       ` David Mosberger
2002-03-06  1:09         ` David S. Miller
2002-03-06  1:31           ` David Mosberger
2002-03-06  1:52             ` David S. Miller
2002-03-06  2:04               ` David Mosberger
  -- strict thread matches above, loose matches on Subject: below --
2002-03-05 11:52 Adam J. Richter
2002-03-05 11:59 ` David S. Miller
2002-03-05 14:43 Adam J. Richter
2002-03-05 15:15 ` David S. Miller
2002-03-05 16:39 Adam J. Richter
2002-03-05 17:00 ` Gerd Knorr
2002-03-06  7:22   ` David S. Miller
2002-03-05 21:57 ` Steffen Persvold
2002-03-05 17:08 Adam J. Richter
2002-03-06  1:13 ` David S. Miller
2002-03-06  2:28 Adam J. Richter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox