UnalignedMmap

Unaligned Map

Large majority of PE executables have sections that are page-aligned in memory but not in the PE file image. Linux's mmap() doesn't support mappings that are not aligned to page boundries with regard to file offsets. Currently it forces wineserver to fake mmap() by allocating anonymous pages and using read() to load the sections.

In dlls/ntdll/virtual.c, comment above map_file_into_view() says: "Linux kernels before 2.4.x can support non page-aligned offsets, as long as the offset is aligned to the filesystem block size. This is a big performance gain so we want to take advantage of it."

These days are long gone, we are now using Linux 2.6, and it doesn't support unaligned mmap().

Enter upmfs. This simple kernel module exports this function to userspace using '/proc':

  • int mmap_offset(int fd, unsigned long offset);

Given an fd and an offset, a new fd is returned. Using mmap() on that new fd, the mapping will be aligned with the given offset, which can be smaller than PAGE_SIZE.

A wineserver implementation can check the existance of that module in the kernel (i.e "/proc/upmfs/interface" exists) and use its functionality.

I already have a working prototype of that module. Experiments show %10 reduction in memory usage of Winamp.


I think the right way to do this is to fix the files on disk. There is a Windows tool to do that, and writing a Unix one would be trivial. Not as much fun as writing a kernel module I admit... --- AJ

This would probably work for most cases, but for some cases it might be really inconvenient or not feasible. The most noticeable are big files, e.g. a 500MB one file installer, possibly even on a read only medium like a CD. This would be a really inconvenient thing for users. In some cases like copy-prevention and the like it might not be feasible to modify the executable without circumventing the copy-prevention. -- JanZerebecki 2007-10-05 13:04:47

UnalignedMmap (last edited 2008-05-03 04:06:08 by nathan.n)