* Prefixed memset_physical() and memcpy_to_physical() with "vm_",

added vm_memcpy_from_physical() and vm_memcpy_physical_page(), and
  added respective functions to the vm_translation_map operations. The
  architecture specific implementation can now decide how to implement
  them most efficiently. Added generic implementations that can be used,
  though.
* Changed vm_{get,put}_physical_page(). The former no longer accepts
  flags (the only flag PHYSICAL_PAGE_DONT_WAIT wasn't needed anymore).
  Instead it returns an implementation-specific handle that has to be
  passed to the latter. Added vm_{get,put}_physical_page_current_cpu()
  and *_debug() variants, that work only for the current CPU,
  respectively when in the kernel debugger. Also adjusted the
  vm_translation_map operations accordingly.
* Made consequent use of the physical memory operations in the source
  tree.
* Also adjusted the m68k and ppc implementations with respect to the
  vm_translation_map operation changes, but they are probably broken,
  nevertheless.
* For x86 the generic physical page mapper isn't used anymore. It is
  suboptimal in any case. For systems with small memory it is too much
  overhead, since one can just map the complete physical memory (that's
  not done yet, though). For systems with large memory it counteracts
  the VM strategy to reuse the least recently used pages. Since those
  pages will most likely not be mapped by the page mapper anymore, it
  will keep remapping chunks. This was also the reason why building
  Haiku in Haiku was significantly faster with only 256 MB RAM (since
  that much could be kept mapped all the time).
  Now we're using a different strategy: We have small pools of virtual
  page slots per CPU that are used for the physical page operations
  (memset_physical(), memcpy_*_physical()) with CPU-pinned thread.
  Furthermore we have four slots per translation map, which are used to
  map page tables.

These changes speed up the Haiku image build in Haiku significantly. On
my Core2 Duo 2.2 GHz 2 GB machine about 40% to 20 min 40 s (KDEBUG
disabled, block cache debug disabled). Still more than factor 3 slower
than FreeBSD and Linux, though.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28244 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-10-20 00:06:09 +00:00
parent ef8a9c3074
commit 47c40a10a1
33 changed files with 1756 additions and 596 deletions
@@ -5,24 +5,9 @@
#ifndef _KERNEL_ARCH_x86_VM_TRANSLATION_MAP_H
#define _KERNEL_ARCH_x86_VM_TRANSLATION_MAP_H
#include <arch/vm_translation_map.h>
#define PAGE_INVALIDATE_CACHE_SIZE 64
struct page_directory_entry;
typedef struct vm_translation_map_arch_info {
struct page_directory_entry *pgdir_virt;
struct page_directory_entry *pgdir_phys;
vint32 active_on_cpus;
// mask indicating on which CPUs the map is currently used
int num_invalidate_pages;
addr_t pages_to_invalidate[PAGE_INVALIDATE_CACHE_SIZE];
} vm_translation_map_arch_info;
// quick function to return the physical pgdir of a mapping, needed for a context switch
#ifdef __cplusplus
extern "C"
+15 -5
View File
@@ -91,17 +91,27 @@ status_t vm_unmap_pages(struct vm_area *area, addr_t base, size_t length,
bool preserveModified);
status_t vm_map_page(struct vm_area *area, struct vm_page *page, addr_t address,
uint32 protection);
status_t vm_get_physical_page(addr_t paddr, addr_t *vaddr, uint32 flags);
status_t vm_put_physical_page(addr_t vaddr);
status_t vm_get_physical_page(addr_t paddr, addr_t* vaddr, void** _handle);
status_t vm_put_physical_page(addr_t vaddr, void* handle);
status_t vm_get_physical_page_current_cpu(addr_t paddr, addr_t* vaddr,
void** _handle);
status_t vm_put_physical_page_current_cpu(addr_t vaddr, void* handle);
status_t vm_get_physical_page_debug(addr_t paddr, addr_t* vaddr,
void** _handle);
status_t vm_put_physical_page_debug(addr_t vaddr, void* handle);
void vm_get_info(struct system_memory_info *info);
uint32 vm_num_page_faults(void);
off_t vm_available_memory(void);
off_t vm_available_not_needed_memory(void);
status_t memset_physical(addr_t address, int value, size_t length);
status_t memcpy_to_physical(addr_t to, const void* from, size_t length,
bool user);
status_t vm_memset_physical(addr_t address, int value, size_t length);
status_t vm_memcpy_from_physical(void* to, addr_t from, size_t length,
bool user);
status_t vm_memcpy_to_physical(addr_t to, const void* from, size_t length,
bool user);
void vm_memcpy_physical_page(addr_t to, addr_t from);
// user syscalls
area_id _user_create_area(const char *name, void **address, uint32 addressSpec,
+25 -2
View File
@@ -43,9 +43,32 @@ typedef struct vm_translation_map_ops {
uint32 attributes);
status_t (*clear_flags)(vm_translation_map *map, addr_t va, uint32 flags);
void (*flush)(vm_translation_map *map);
// get/put virtual address for physical page -- will be usuable on all CPUs
// (usually more expensive than the *_current_cpu() versions)
status_t (*get_physical_page)(addr_t physicalAddress,
addr_t *_virtualAddress, uint32 flags);
status_t (*put_physical_page)(addr_t virtualAddress);
addr_t *_virtualAddress, void **handle);
status_t (*put_physical_page)(addr_t virtualAddress, void *handle);
// get/put virtual address for physical page -- thread must be pinned the
// whole time
status_t (*get_physical_page_current_cpu)(addr_t physicalAddress,
addr_t *_virtualAddress, void **handle);
status_t (*put_physical_page_current_cpu)(addr_t virtualAddress,
void *handle);
// get/put virtual address for physical in KDL
status_t (*get_physical_page_debug)(addr_t physicalAddress,
addr_t *_virtualAddress, void **handle);
status_t (*put_physical_page_debug)(addr_t virtualAddress, void *handle);
// memory operations on pages
status_t (*memset_physical)(addr_t address, int value, size_t length);
status_t (*memcpy_from_physical)(void* to, addr_t from, size_t length,
bool user);
status_t (*memcpy_to_physical)(addr_t to, const void* from, size_t length,
bool user);
void (*memcpy_physical_page)(addr_t to, addr_t from);
} vm_translation_map_ops;
#include <arch/vm_translation_map.h>
-5
View File
@@ -47,11 +47,6 @@
(B_KERNEL_PROTECTION | B_USER_CLONEABLE_AREA | B_OVERCOMMITTING_AREA \
| B_SHARED_AREA)
// flags for vm_get_physical_page()
enum {
PHYSICAL_PAGE_DONT_WAIT = 0x01
};
// mapping argument for several internal VM functions
enum {
REGION_NO_PRIVATE_MAP = 0,