memory-managementlinux-kernellinux-device-driverkernel-modulepage-fault

Prefetching in vm_fault(), Linux drivers


I'm implementing a simple device driver. The program that uses this driver takes in arguments from the user whether to use demand paging or prefetching(fetches next page only). But when the user requests for prefetching is should send this information to the driver. The problem is vm_fault has a standard structure as follows:

int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf);

So how to incorporate this additional information of prefetching into these, so that I can use it to write a different routine for prefetching? Or is there any other way to achieve this?

[EDIT]
To give a clearer picture:
This how a program takes input.

./user_prog [filename] --prefetch

The user_prog sets some flags in it, now how to send these flags information to dev.c(the driver file), as all the arguments to functions are fixed like above fault(). I hope this gives more clarification.


Solution

  • You can use the flags in mmap() to pass your custom flags too.

    void *mmap(void *addr, size_t length, int prot, int flags,
                      int fd, off_t offset);
    

    Make sure your custom flag values uses bits different from the flag values used by mmap(). From the manpage, the macros are defined in sys/mman.h. Find the exact values(may vary across systems) with echo '#include <sys/mman.h>' | gcc -E - -dM | grep MAP_*. My system has this:

    #define MAP_32BIT 0x40
    #define MAP_TYPE 0x0f
    #define MAP_EXECUTABLE 0x01000
    #define MAP_FAILED ((void *) -1)
    #define MAP_PRIVATE 0x02
    #define MAP_ANON MAP_ANONYMOUS
    #define MAP_LOCKED 0x02000
    #define MAP_STACK 0x20000
    #define MAP_NORESERVE 0x04000
    #define MAP_HUGE_SHIFT 26
    #define MAP_POPULATE 0x08000
    #define MAP_DENYWRITE 0x00800
    #define MAP_FILE 0
    #define MAP_SHARED 0x01
    #define MAP_GROWSDOWN 0x00100
    #define MAP_HUGE_MASK 0x3f
    #define MAP_HUGETLB 0x40000
    #define MAP_FIXED 0x10
    #define MAP_ANONYMOUS 0x20
    #define MAP_NONBLOCK 0x10000
    

    Some non-clashing flags would be 0x200 and 0x400.