The chunk, bnode, and broot structures are of a common size: 256 bytes on narrow systems or 512 bytes for wide systems. As a region is initialized, the total number of pages it will map (or at least the number it will start with) is used to calculate the depth of its b-tree. Once this is known, space for the chunks, bnodes, and the broot will need to be allocated. As we noted, all three structures are sized the same. This allows room for a 29th-order bnode. Each chunk will hold either 32 or 64 vfd|dbd structure pairs, depending on the architecture. These uniformly sized structures may be conveniently packed into whole memory pages. Once the total space requirements are determined, the kernel allocates enough pages to hold them (see Figure 6-11). This group of allocated page frames is reffered to as a page list. In most instances not all the space in the page list is filled with chunks or bnodes; if the tree grows, these unused fragments are utilized. If we run out of page fragments, the system simply allocates another page and adds it to the region's page list. Figure 6-11. Growing the Tree
An interesting feature of this model is that pages for the b-trees are allocated from the system's free memory pools the same as pages allocated to a user process. These page allocations do not impact the kernel's memory arenas, and as some b-trees must be very large, this is a good thing. Another feature is that if a process is deactivated, its page list may be moved to swap. As process deactivation occurs only in cases of extreme memory pressure, being able to reclaim these extra pages helps vhand perform its task. If a process has been deactivated and its b-tree has been paged out, we must be able to find these pages and restore them to memory when the process is reactivated. As these pages are not defined by a disk block descriptor entry, the back-store location needs to be stored in the region structure. Since the region structure has a static size, and the number of pages in the page list may vary according to the overall region page count, an interesting method was implemented to find the swapped page list pages. The region r_dbd contains a disk block descriptor to locate the first page of the page list in swap, the disk block descriptor of the second page is stored at the end of the first page, and so on. This presents a bit of an anomaly. It is said that HP-UX kernel pages are never swapped out, that the kernel is always in-core. Now we see that a region's b-tree may be paged out if its process is deactivated. As a page list is allocated to hold a region b-tree and the region is a kernel structure these pages are kernel pages. So, is the HP-UX kernel ever paged out? The answer is still no, but with the following clarification. Pages initially assigned to the kernel at boot time are considered static kernel pages; those allocated by the kernel later are considered dynamic kernel pages. The kernel never swaps its static pages, but under certain circumstances, such as deactivation, some dynamic pages may be paged out. Another benefit of this design is that when a process terminates its page list, pages are returned to the system memory pools. |