Out of pure stupidity and curiosity, how hard would it
be to abstract-out the VM layer and modularize it (like
the network fair-scheduling algos...)?
I would guess such a interface might look like the
following off-the cuff code, and could be selected at
compile-time or (Holy Deadlocks, Batman!) runtime via
modules.
(A module VM replacement would be: (old=old VM, new=new VM)
a) release all swap areas
b) lock kernel, block all interrupts.
c) new->init(1)
d) old->stop()
e) start interrupts, unblock kernel.
f) (user-land can re-add the swap areas)
g) user-land can rmmod() old VM.
)
--------------------- off-the-cuff code ----------------------------
typedef unsigned long phys_off_t;
typedef unsigned long virt_off_t;
typedef void *vmmu_swap_h;
#define PAGE_BITS 12 /* 4 K Pages */
#define PAGE_SIZE (1<<PAGE_BITS)
typedef enum vmmu_page_t={
VMMU_RESERVED=0, /* Unusable pages (initial default) */
VMMU_DMA, /* DMAable pages */
VMMU_IO, /* IO (non-memory) pages (readl(), etc) */
VMMU_RAM, /* Standard ram */
VMMU_RAM_NOSWAP, /* Locked ram (ie, kernel code) */
VMMU_SWAP, /* Returned when asking the phys addr of a
* swapped-out page */
};
struct vmmu_struct {
/* init: Set up any structures/kernel treads that may be needed.
* If migrate is true, walk the kernel task_list, SHM
* segments, io ranges, etc, and build the private VMMU info.
* Otherwise, assume that the arch will send the appropriate
* set_page_range() calls.
* stop: Kill any kernel threads, drop any self-allocated memory
*/
int (*init)(int migrate);
int (*stop);
/* on_idle: Optional function. If not null, this is called
* before the kernel idle loop.
*/
void (*on_idle)(void);
/* Set a range of pages to a type. Used in initial arch setup.
*/
int (*set_page_range)(phys_off_t start,unsigned pages,vmmu_page_t type);
/* Allocate and deallocate page ranges
*/
virt_off_t (*get_dma_pages)(unsigned pages,int is_contiguous);
virt_off_t (*get_io_pages)(phys_off_t start,unsigned pages,int rw);
virt_off_t (*get_pages)(struct task_struct *task,unsigned pages);
int (*free_pages)(virt_off_t addr,unsigned pages);
/* get_page_info: Given a virtual address, get the type and physical
* page address (if valid for that page type)
*/
int (*get_page_info)(virt_off_t page,vmmu_page_t *type,phys_off_t *addr);
/* add_swap: Using an open file or device, looks for a swap signatue,
* and adds to the VM pool. Returns a opaque handle
* to the allocated swap.
* remove_swap: Given a handle from add_swap, maps in all swap from
* the swap area (if possible), and closes the associated file.
*/
vmmu_swap_h (*add_swap)(struct file *file,int priority);
int (*remove_swap)(vmmu_swap_h area);
/* lock_pages: lock pages into ram (if possible)
* unlock_pages: Allow pages to be swappable.
*/
int (*lock_pages)(virt_off_t addr,unsigned pages);
int (*unlock_pages)(virt_off_t add,unsigned pages);
};
-- Jason McMullan, Senior Linux Consultant, Linuxcare, Inc. 412.422.8077 tel, 412.656.3519 cell, 415.701.0792 fax jmcmullan@linuxcare.com, http://www.linuxcare.com/ Linuxcare. Support for the revolution.- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Mon Aug 07 2000 - 21:00:12 EST