Currently the 32 bit x86 architecture is the most popular type of computer. In this architecture, traditionally the Linux kernel has split the 4GB of virtual memory address space into 3GB for user programs and 1GB for the kernel.
Use pointers from kernel object to another. The alternative would be to track physical addresses, mapping in a physical address and calculating the virtual address of the structure before accessing it, and unmapping the physical address after use.
On other architectures, such as that of the MIPS processor, the hardware itself is only capable of directly accessing a portion of physical memory. A 32-bit MIPS processor normally runs its operating system in a 512 MiB portion of memory that has a direct mapping between the virtual and physical address. All other memory must be accessed through a translation lookaside buffer (TLB) and it is not capable of mapping all of the 4 GiB of physical memory into its address at the same time. Thus, its need for high memory support can be even more dire than that of the x86 architecture
Coping with highmem
The function kmap() gives you a persistant mapping, ie. one that will still be there after you schedule and/or move to another CPU. However, this kind of mapping is allocated under a global lock, which can be a bottleneck on SMP systems. The kmap() function is discouraged.
Good SMP scalability can be obtained by using kmap_atomic(), which is lockless. The reason kmap_atomic() can run without any locks is that the page is mapped to a fixed address which is private to the CPU on which you run. Of course, this means that you can not schedule between setting up such a mapping and using it, since another process running on the same CPU might also need the same address! This is the highmem mapping type used most in the 2.6 kernel.
On a system with 2GB memory, a little more than half of the memory will be in high memory (ZONE_HIGHMEM) and a little less than half of memory will be in so-called low memory (ZONE_NORMAL and ZONE_DMA). It is important that the kernel allocates process and page cache memory from both zones and that the pageout code recycles pages from both zones, in proportion to each zone's size.
The reason for this is that applications might want to use all 2GB of memory. If the system ended up allocating and reclaiming high memory much faster than low memory, then the application would have part of its data swapped out from high memory, instead of resident in low memory. However, the better the system balances allocations and recycling between high and low memory, the closer the application's effective available memory size approaches the full 2GB.
The main danger of running on a 32 bit system with lots of highmem (more than 8GB) is that the kernel could end up needing to allocate more data than what fits in ZONE_NORMAL. This means the machine can effectively run out of memory, even if there were still lots of high memory free.
The third issue is that, on a 32 bit system, no process will be able to effectively use more than 3GB of memory. This means that buying more than 4GB of memory is only useful if none of the processes on your system need all of the memory.
For these reasons it is recommended that if you buy a system with more than 4GB of memory, you should consider getting a 64 bit CPU and installing a 64 bit operating system. The price difference between 32 and 64 bit systems is practically nonexistant in 2005, and 64 bit x86-64 systems can still run 32 bit applications, so there is no real need to experience the pains of highmem any more...