[coyotos-dev] Fixing the kernel heap size

Jonathan S. Shapiro shap at eros-os.com
Wed Dec 19 19:12:18 EST 2007


The Coldfire port has brought an issue into sharp relief: it is highly
desirable to set a relatively HARD upper bound on the kernel heap.

Issue: on Coldfire, and possibly other embedded targets, we want to
direct-map the kernel to reduce TLB pressure. On other targets, we want
to use large page mappings for the kernel region. The underlying problem
is that the kernel heap is allocated simultaneously from two spaces:

  - The virtual address space of the kernel, which MUST be contiguous.
  - The physical memory space of the underlying memory, which MUST be
    contiguous on some platforms, and on others wants to be made up
    of large page mappings.

In order to do either direct mapping or large page mapping, it is
desirable to ensure that the majority of heap VAs are of the form

	VA = PA + constant.

For the most part, the kernel's heap requirements are known at boot
time. Given the size of physical memory, we can estimate the size
requirement on the heap exactly, with ONE exception: device memory. The
problem with device memory is that the drivers aren't in the kernel so
the kernel has no way to know what memory will appear from attached
cards.

For device memory, the requirement on the heap is that each page of
device memory requires an associated "struct Page" overhead structure in
the kernel heap. At present, these "struct Page" objects are dynamically
allocated by growing (but never shrinking) the kernel heap at run time.

The ultimate problem with this heap growth is that it relies on the MMU,
and for targets with soft-managed TLBs we really want to avoid pressure
from kernel mappings (thus the incentive to direct map the kernel).

A further issue is that post-boot heap growth shrinks the number of
available object frames that are allocatable by the space bank. This
inadvertently violates the kernel/spacebank contract.

There seem to be three classes of solution:

  1. Have a tunable number of "reserved" device page frames. Allocate
     the "struct page" structures for these early. If you run out,
     the attempt to map the device memory fails and it is necessary to
     re-tune and re-boot.

  2. Separate the kernel heap into two parts. One is fixed at boot time
     by pre-sizing. The second is dynamically growable but falls outside
     of the direct-mapped kernel heap. This is, in essence, a hybrid
     strategy.

  3. Conservatively reserve excess kernel heap space so that you
     always have enough, then provide a mechanism to "release" this
     space after the device config has been determined. This could be
     combined with [1].

I personally prefer strategies [1,3] The problem with it will mainly
arise when people stick modern gaming graphics cards into their PCI
slots and chew up some huge part of the memory map with them.  The
*minimum* requirement is that we be able to configure enough devices to
tell the user that we need to re-tune and reboot.

Do people have opinions about this?


shap



More information about the coyotos-dev mailing list