linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: linux@arm.linux.org.uk (Russell King - ARM Linux)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 RESEND 08/17] ARM: LPAE: use phys_addr_t in free_memmap()
Date: Tue, 25 Sep 2012 14:30:13 +0100	[thread overview]
Message-ID: <20120925133013.GP15609@n2100.arm.linux.org.uk> (raw)
In-Reply-To: <20120925112256.GC14924@arm.com>

On Tue, Sep 25, 2012 at 02:08:04PM +0100, Catalin Marinas wrote:
> On Mon, Sep 24, 2012 at 06:14:25PM +0100, Russell King - ARM Linux wrote:
> > On Mon, Sep 24, 2012 at 05:51:46PM +0100, Catalin Marinas wrote:
> > > I don't think that's needed. free_all_bootmem() in mm/nobootmem.c takes
> > > care of freeing lowmem but it has a different notion of max_low_pfn. So
> > > this hunk did the trick:
> > > 
> > > @@ -420,8 +366,8 @@ void __init bootmem_init(void)
> > >  	 * Note: max_low_pfn and max_pfn reflect the number of _pages_ in
> > >  	 * the system, not the maximum PFN.
> > >  	 */
> > > -	max_low_pfn = max_low - PHYS_PFN_OFFSET;
> > > -	max_pfn = max_high - PHYS_PFN_OFFSET;
> > > +	max_low_pfn = max_low;
> > > +	max_pfn = max_high;
> > >  }
> > 
> > Did you actually look to see where that's used before you made the change.
> > I don't think you did.
> > 
> > The reason we have that there is that much of the kernel assumes memory
> > always starts at physical zero, so the max*pfn variables can be used to
> > generate bitmasks to cover the range of system memory addresses - iow,
> > (1 << max_low_pfn) - 1.
> > 
> > Eg, in the block code:
> > 
> >         blk_max_low_pfn = max_low_pfn - 1;
> >         blk_max_pfn = max_pfn - 1;
> > ...
> >         unsigned long b_pfn = dma_mask >> PAGE_SHIFT;
> > 
> >         if (b_pfn < blk_max_low_pfn)
> >                 dma = 1;
> > 
> > Having a DMA mask for a peripheral which only has 24 bits wired (so
> > 0x00ffffff) with a system memory offset of 0xc0000000 results in
> > apparantly _all_ system memory being DMA-able according to this test
> > unless max_low_pfn is defined as the _number_ of bits in the RAM
> > address.
> > 
> > In dma_get_required_mask():
> > 
> >         u32 low_totalram = ((max_pfn - 1) << PAGE_SHIFT);
> > 
> >                 low_totalram = (1 << (fls(low_totalram) - 1));
> >                 low_totalram += low_totalram - 1;
> > 
> > which results in (for a phys offset of 0xc0000000) low_totalram being
> > 0xffffffff unconditionally no matter how much RAM you actually have.
> 
> And for those platforms the phys and bus (dma) addresses are different.

That doesn't have anything to do with it actually.  If you look at the
above analysis, where the DMA addresses are has nothing to do with it.

> So it's not about whether the physical RAM starts at 0 but whether the
> device has a different view of the RAM address space.

Yes it is.  Much of the kernel assumes PFN0 equals physical address 0.
That's a pretty sane assumption.

max_pfn/max_low_pfn are PFNs, so the theoretical correct value for these
should be max_physical_address_of_ram >> PAGE_SHIFT.  But, as I say, that
breaks _anything_ that has an offset of RAM _and_ a device which can't
address all RAM.  The reason for that is that DMA _masks_ are _masks_ and
are not the upper limit of addressible RAM.

Taking my example above, the DMA mask for a device with only 24-bits of
addressing is 0x00ffffff.  That may be connected to a system bridge which
maps the low order bus space to system RAM, and system RAM may start at
0xc0000000, and end at 0xcfffffff.

In that situation:

	blk_max_low_pfn = max_low_pfn - 1;

	unsigned long b_pfn = dma_mask >> PAGE_SHIFT;
	if (b_pfn < blk_max_low_pfn)
		dma = 1;

_breaks_ if we define max_low_pfn to be 0xcfffffff >> PAGE_SHIFT,
because now the above calculation says the whole of system memory is
DMA-able.

This isn't a question of setting a different DMA mask for the device.
The DMA mask for the device is correct.  What's wrong is that there's
a mis-interpretation between different parts of the kernel caused by
the assumption that system RAM always starts at PFN0, physical address
zero.

> The reverse could
> also be problematic if phys == bus and max_low_pfn corresponds to an
> address that's not actually accessible for the device (though in
> practice I don't expect this).

"In practice I don't expect this" - history has shown, for at least the
last 12 years, that this isn't a problem because this has been how things
have been done on ARM.

What I have shown above is that there _are_ problems, particularly in
the block layer, if we _don't_ do this.

  reply	other threads:[~2012-09-25 13:30 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-21 15:55 [PATCH v3 RESEND 00/17] LPAE fixes and extensions for Keystone Cyril Chemparathy
2012-09-21 15:55 ` [PATCH v3 RESEND 01/17] ARM: add mechanism for late code patching Cyril Chemparathy
2012-09-22 15:10   ` Nicolas Pitre
2012-09-22 21:41     ` Cyril Chemparathy
2012-09-24 12:06   ` Dave Martin
2012-09-24 14:49     ` Cyril Chemparathy
2012-09-24 15:54       ` Dave Martin
2012-09-21 15:56 ` [PATCH v3 RESEND 02/17] ARM: add self test for runtime patch mechanism Cyril Chemparathy
2012-09-21 15:56 ` [PATCH v3 RESEND 03/17] ARM: use late patch framework for phys-virt patching Cyril Chemparathy
2012-09-21 15:56 ` [PATCH v3 RESEND 04/17] ARM: LPAE: use phys_addr_t on virt <--> phys conversion Cyril Chemparathy
2012-09-24 13:09   ` Catalin Marinas
2012-09-24 13:57     ` Cyril Chemparathy
2012-09-21 15:56 ` [PATCH v3 RESEND 05/17] ARM: LPAE: support 64-bit virt_to_phys patching Cyril Chemparathy
2012-09-22 15:24   ` Nicolas Pitre
2012-09-24 15:13   ` Catalin Marinas
2012-09-24 15:56     ` Nicolas Pitre
2012-09-24 20:59       ` Cyril Chemparathy
2012-09-24 21:20         ` Nicolas Pitre
2012-09-24 21:52           ` Catalin Marinas
2012-09-24 22:32             ` Nicolas Pitre
2012-09-24 22:40               ` Russell King - ARM Linux
2012-09-24 22:53                 ` Cyril Chemparathy
2012-09-24 23:03                   ` Nicolas Pitre
2012-09-24 23:08                   ` Russell King - ARM Linux
2012-09-24 22:55                 ` Nicolas Pitre
2012-09-25 12:55                   ` Dave Martin
2012-09-25 13:53               ` Catalin Marinas
2012-09-24 21:53           ` Cyril Chemparathy
2012-09-24 22:06         ` Russell King - ARM Linux
2012-09-24 16:31   ` Dave Martin
2012-09-24 16:51     ` Nicolas Pitre
2012-09-21 15:56 ` [PATCH v3 RESEND 06/17] ARM: LPAE: use signed arithmetic for mask definitions Cyril Chemparathy
2012-09-24 13:09   ` Catalin Marinas
2012-09-24 13:54   ` Russell King - ARM Linux
2012-09-21 15:56 ` [PATCH v3 RESEND 07/17] ARM: LPAE: use phys_addr_t in alloc_init_pud() Cyril Chemparathy
2012-09-24 13:10   ` Catalin Marinas
2012-09-21 15:56 ` [PATCH v3 RESEND 08/17] ARM: LPAE: use phys_addr_t in free_memmap() Cyril Chemparathy
2012-09-24 13:29   ` Catalin Marinas
2012-09-24 13:41     ` Russell King - ARM Linux
2012-09-24 15:09       ` Cyril Chemparathy
2012-09-24 15:22         ` Russell King - ARM Linux
2012-09-24 16:41           ` Cyril Chemparathy
2012-09-24 16:51             ` Catalin Marinas
2012-09-24 17:06               ` Cyril Chemparathy
2012-09-24 17:14               ` Russell King - ARM Linux
2012-09-25 13:08                 ` Catalin Marinas
2012-09-25 13:30                   ` Russell King - ARM Linux [this message]
2012-09-24 16:55             ` Russell King - ARM Linux
2012-09-24 17:03               ` Catalin Marinas
2012-09-21 15:56 ` [PATCH v3 RESEND 09/17] ARM: LPAE: use phys_addr_t for initrd location and size Cyril Chemparathy
2012-09-24 13:30   ` Catalin Marinas
2012-09-24 13:38   ` Russell King - ARM Linux
2012-09-24 14:00     ` Cyril Chemparathy
2012-09-21 15:56 ` [PATCH v3 RESEND 10/17] ARM: LPAE: use phys_addr_t in switch_mm() Cyril Chemparathy
2012-09-24 14:05   ` Catalin Marinas
2012-09-24 14:32     ` Cyril Chemparathy
2012-09-21 15:56 ` [PATCH v3 RESEND 11/17] ARM: LPAE: use 64-bit accessors for TTBR registers Cyril Chemparathy
2012-09-24 14:10   ` Catalin Marinas
2012-09-21 15:56 ` [PATCH v3 RESEND 12/17] ARM: LPAE: define ARCH_LOW_ADDRESS_LIMIT for bootmem Cyril Chemparathy
2012-09-24 14:16   ` Catalin Marinas
2012-09-21 15:56 ` [PATCH v3 RESEND 13/17] ARM: LPAE: factor out T1SZ and TTBR1 computations Cyril Chemparathy
2012-09-24 14:45   ` Catalin Marinas
2012-09-24 14:58     ` Cyril Chemparathy
2012-09-21 15:56 ` [PATCH v3 RESEND 14/17] ARM: LPAE: accomodate >32-bit addresses for page table base Cyril Chemparathy
2012-09-24 15:17   ` Catalin Marinas
2012-09-21 15:56 ` [PATCH v3 RESEND 15/17] ARM: mm: use physical addresses in highmem sanity checks Cyril Chemparathy
2012-09-24 15:18   ` Catalin Marinas
2012-09-21 15:56 ` [PATCH v3 RESEND 16/17] ARM: mm: cleanup checks for membank overlap with vmalloc area Cyril Chemparathy
2012-09-21 15:56 ` [PATCH v3 RESEND 17/17] ARM: mm: clean up membank size limit checks Cyril Chemparathy

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=20120925133013.GP15609@n2100.arm.linux.org.uk \
    --to=linux@arm.linux.org.uk \
    --cc=linux-arm-kernel@lists.infradead.org \
    /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).