[lkml]   [2002]   [Feb]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
Subject[patch] simpler 'highpte' design.

We'd like to propose the following, simpler 'highpte' design:

(the highpte-2.5.5-A0 patch is the 'interesting' patch.)

the underlying issue is the following: on 32-bit x86 systems with lots of
RAM and lots of processes, the total size of process pagetables can be
very high. Until now, the VM allocated pagetables in the so-called lowmem
pool, which has a maximum size of 1 GB. So on 32 GB systems it can happen
that the system becomes limited by this 1 GB pool. This problem has been
seen in practice on enterprise-size Linux systems. Hence these patches
that allow the pagetables to reside in the 'highmem' area as well.

why did we write a new patch? There are a number of fundamental
differences between Andrea's patch and our highpte patch:

- we never kmap() deep within the VM, accessing pte's.

In this design it's not allowed to kmap() ptes. No blocking, no

kmap() is deadlock land for any serious load, and it also creates
nasty dependencies - who wants to squeeze 32GB of RAM into a tiny kmap
window. kmap() was implemented by me and i never wanted it to have any
bigger role. The global spinlock, the seldom tested 'out of kmap
entries' case all point in the direction of unrobustness. kmap() is
unavoidable in a few places, but we do not want to depend on it too

- we do not put kernel-VM ptes into highmem.

the 'upper 1 GB' (default VM split) kernel pagetables are shared by
every process in the system, thus there is just no point in complicating
(and slowing down) the directly mapped portion of the VM. Look at how
low impact our patch has on the arch/i386 tree.

kernel-space VM and user-space VM access can be separated very cleanly
in 99% of the cases. But the user-space pte mapping functions work for
the kernel-space pagetables as well - since the kernel-space TLBs are in
lowmem, they will work automatically, this covers the remaining 1%.

- safe interface migration.

this patch removes pte_offset() which becomes pte_offset_map(). Patches
and modules that are not updated to the new mechanizm will fail
safely at compile-time. This also makes it easier to identify the places
that need fixing.

also, due to the fact that the mapping of ptes cannot block in this
design, all the pmd_page_under_lock() and pmd_page2_under_lock()
complexity visible in Andrea's patch becomes unnecessery.

- no 'kmap series' complexity.

since the patch does not depend on the kmap series stuff for
performance, that portion can be omitted. I'd like to have persistent
kmaps be used very carefully, and only in clear, highlevel cases such as
read(). kmap() bugs have a track record of being found very slowly,
this is mostly due to the relative rarity of truly big highmem systems.

[ - configurability.

minor nit: Andrea's latest patch ties highmem-ptes to CONFIG_HIGHMEM.
This is no big issue. Our patch defines 5 highmem variants:


which is more correct IMO - people who eg. use their RAM to fill the
pagecache should have the option to disable pte-mapping.

(if anyone is wondering why 4G_HIGHPTE exists, we have seen
production 4G_HIGH systems hitting the 1 GB pagetable size
limit as well ...) ]

[ - the removal of pte/pmd/pgd quicklists.

While not directly connected to highpte's, i think a per-CPU page-pool
will solve most of the needs here. The pgd quicklist was disabled in the
base kernel because it showed weird problems. It always looked a bit
fragile that we had all these special pools for ptes, pmds and pgds. But
this issue is clearly separate and should be addressed in a separate
patch. ]

please take a look at our patch, and see the fundamental simplicity of it.
The patch in essence makes 'pte access' a slightly more expensive
instruction on CONFIG_HIGHPTE systems - no locking and no blocking is
involved. I very strongly believe that we want to have this kind of
simplicity on the lowest level of our VM: when accessing the pte's.

testing status: i iterated through the following test-matrix:

nohighmem 4GB 4GB-highpte 64GB 64GB-highpte
UP-preempt on x x x x x
UP-preempt off x x x x x
SMP-preempt on x x x x x
SMP-preempt off x x x x x

all 20 kernels compile & boot just fine kernel 2.5.5-pre1 + the 3 patches.
I've done VM stresstesting as well, on 64GB-highpte-preempt-SMP and
nohighmem-nopreempt-UP (the two opposite points in the complexity
spectrum). I've also tested some kernels inbetween. (4GB-highpte-SMP for
example.) The Rik-VM based variant of the patch has seen a few hours of
Cerberus testing as well, and has proven to be robust. The patch is
absolutely preemption-safe.

(note that the debugging helpers so far caught all the bugs one can make
while converting non-mapped pte code to mapped pte code.)




[ I'd like to specify the directions in which blame can go: the
uvirt-to-kva-2.5.5-A0 cleanup patch was written by Arjan (merged to
2.5.5-pre1 by me), the setup-highmem-2.5.5-A0 patch was written by me, and
the highpte-2.5.5-A0 patch was designed by Arjan and myself and
implemented mostly by myself. Testing and cleanup was done by both of us.]

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
More majordomo info at
Please read the FAQ at

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