In the current pc/mmu.c, vmapalloc() contains this comment: /* * could span page directory entries, but not worth the trouble. * not going to be very much contention. */ Traditionally not many callers use vmap(), and vunmap() is even rarer: at boot time, a few drivers vmap() some space which will be used for the lifetime of the kernel; some callers invoke vunmap() in error cases, and others occasionally unmap temporarily-mapped small areas. Some students here are working on a driver that puts more pressure on vmap()/vunmap(). In particular, this driver uses vmap() to get multiple megabytes (4, 8, ...), uses the space for some minutes, and then releases it. In some situations this runs into trouble: for "large" allocations, vmapalloc() looks for empty page-directory entries and fails if there aren't any. This can fail even if there is enough space in the vmap, if previously most of the vmap page-directory entries were set to point to page tables: even if all the PTEs in those page tables are blank, the tables aren't removed, so the PDEs aren't empty, so vmapalloc() thinks there is no large space. This problem hasn't shown up before because nobody (that I know of) frequently calls vunmap() on large areas. This patch modifies vmapalloc() as follows: 1. It still tries to satisfy "large" requests by looking for blank PDEs. This is the same code as the old mmu.c, but if a "large" request cannot be satisified this way, instead of returning failure we press on. 2. The middle part of vmapalloc() has been rewritten so it can satisfy requests with regions that span page tables. This is tried for both "large" and non-"large" requests. 3. Finally, if a request is non-"large" and wasn't satisfied by a region mapped by an existing page table (step 2), a new page table is begun (this is the same as code in the original mmu.c). In addition to the patch I am including: 1. devtest.c - a driver that, when poked, will vmap() and then immediately vunmap() 32M. 2. old_result, new_result - transcripts of using the devtest.c driver to exercise the old and new vmapalloc() versions. I realize messing with mmu.c merits some care. Hopefully the risk is acceptable here because most existing callers of vmap()/vunmap() won't run any of the new code, e.g., callers who allocate a large range and never free it. The patch and the test driver were prepared by my students (Ashish Kaila, Rohan Patil, Pratik Shah, and Maneet Singh) but edited for clarity and then tested by me before submission.