On Wed, Jun 16, 2004 at 06:48:48AM +0300, Shachar Shemesh wrote:

> Is it one of the options in himem support? I have there "off", "4GB", 
> and "64GB".

No, it's an external patch, by mingo of redhat. The RH kernels
probably have it as an option, and so do -mm. 

> Let's see what I understand. I get 3GB of virtual memory, no matter what 
> I compile in. If I want 4, I need a "4:4" patch, which is presumably not 
> there by default.

Right. 

> If I compiled himem support to "off", I get just 1GB (well, less) of 
> physical memory easily accessed. 

Not easily accesses - accessed at all!

> What's the difference? If I have a 
> machine with 4GB of physical memory, and himem support compiled "off", 
> and I ask for 2.5GB of heap memory, what is going to happen? 

Linux (and any other operating system) employs "memory
overcommit". That means that the OS will happily give you those 2.5GB
of *virtual memory*. If you try to actually use them, and there's only
896MB of physical memory... swapping (assuming you have swap),
potentially thrashing. Assuming no swap or not enough swap, if you try
to use more than 896MB of your allocated memory at once, your system
wil run out of memory, with the appropriate results. 

> Even more confused than before,

Ok, now that I'm awake, let me try again:

Linux's memory management divides physical memory into zones. ZONE_DMA
is irrelevant for our discussion, and is the first 16MB of
memory. ZONE_NORMAL is 16-896, and is always enabled. ZONE_HIGHMEM is
everything above 896MB of *physical memory*. 

Now for virtual memory. On 32bit architectures, each process has 4GB
of address space (32 bit pointers can point to addresses up to for
4GB). Off this 4GB of address space, the Linux kernel maps itself in
the address space of *every* process in the top 1GB (above
PAGE_OFFSET, 0xC0000000), which leaves 3GB of usable address space for
each process. 

Now for how physical and virtual tie together. In the kernel, the
first 896MB of physical memory (ZONE_DMA and ZONE_NORMAL) are always
mapped in in its virtual address space. That means that when you call
kmalloc() in the kernel, and get a void* (something which can be
directly accesses, which implies that it is mapped), you get a pointer
(i.e. virtual address) that maps physical memory in ZONE_DMA or
ZONE_NORMAL. So far so good, but what happens if the machine has 2GB
of physical memory? how does the kernel code get a pointer to memory
which is above 896MB? the answer is that most code in the kernel works
with "struct page*", which is a descriptor for physical memory. This
physical memory can live anywhere, in ZONE_NORMAL, or
ZONE_HIGHMEM. When you want to actually access its contents, you call
kmap(), which returns a void* which gives you a *temporary* mapping,
through which you can access the memory. When you're done with the
contents, you call kunmap(). 

I hope you're with me so far... to summarize, ZONE_NORMAL memory is
always mapped and accessed in the kernel through a void*, ZONE_HIGHMEM
needs to be mapped to be accesses. Those mappings are limited in
number and temporary. Without ZONE_HIGHMEM support (CONFIG_HIGHMEM),
there is no way to map physical memory above 896MB. 

This stuff is explained in copious details in Mel Gorman's
Undrestanding the Linux Virtual Memory Manager,
http://www.skynet.ie/~mel/projects/vm

Cheers, 
Muli 
-- 
Muli Ben-Yehuda
http://www.mulix.org | http://mulix.livejournal.com/

Attachment: signature.asc
Description: Digital signature

Reply via email to