Skip to content

Day94 - vmalloc() and vmap() Internals

Today's Goal

Today I extended the virtual memory subsystem by introducing vmap() and vunmap().

Unlike vmalloc(), which allocates backing pages internally, vmap() creates a virtually contiguous mapping from an existing array of physical pages. This separation highlights the difference between virtual address mapping and physical page ownership.

To better model the Linux kernel implementation, I refactored the virtual mapping subsystem into an independent mapping manager shared by both vmalloc() and vmap().


What I Learned

Virtual Mapping Manager

Implemented a reusable virtual mapping manager responsible for:

  • Managing virtual address allocation
  • Maintaining virtual mapping information
  • Translating virtual addresses back to struct page
  • Supporting different page ownership models

The mapping manager is now shared by both vmalloc() and vmap().


vmalloc()

Implemented:

  • vmalloc()
  • vfree()

vmalloc() allocates backing pages from the Buddy Allocator before creating a virtual mapping.

vmalloc()


alloc_pages()



Virtual Mapping



Return Virtual Address

vfree() removes the mapping and releases the backing pages.


vmap()

Implemented:

  • vmap()
  • vunmap()

Unlike vmalloc(), vmap() maps pages supplied by the caller without allocating additional physical memory.

Caller

alloc_pages()



     vmap()



Virtual Mapping



Return Virtual Address

vunmap() removes only the virtual mapping. The caller remains responsible for releasing the backing pages.


Labs

Lab 1 — Virtual Mapping Manager

Implemented:

  • vm_mapping_create()
  • vm_mapping_destroy()
  • vm_mapping_destroy_all()
  • vm_mapping_to_page()

Verified:

  • Mapping creation
  • Mapping destruction
  • Address translation
  • Ownership handling

Lab 2 — vmalloc()

Verified:

  • Virtual address allocation
  • Backing page allocation
  • Mapping removal
  • Automatic page release

Lab 3 — Physically Non-contiguous Pages

Created fragmented physical memory and demonstrated that:

  • Virtual addresses remain contiguous.
  • Physical pages can be completely scattered.

Lab 4 — vmap()

Verified:

  • Mapping existing pages
  • Virtual-to-physical translation
  • vunmap() removes only the mapping
  • Backing pages remain allocated

Lab 5 — Mixed vmalloc() and vmap()

Verified that the virtual mapping manager can manage both:

  • owned mappings (vmalloc())
  • external mappings (vmap())

at the same time.

Confirmed that:

  • vfree() only releases owned pages.
  • vunmap() only removes mappings.
  • Caller-owned pages remain valid until explicitly released.

Key Takeaways

  • vmalloc() allocates backing pages and creates a virtual mapping.
  • vmap() creates a virtual mapping for existing pages.
  • Both APIs share the same virtual mapping subsystem.
  • The main difference is ownership of the backing pages.
  • Separating mapping management from page allocation better reflects the Linux kernel architecture.