diff options
Diffstat (limited to 'debian/patches/mach-defpager-fix-receiver-lookups.patch')
-rw-r--r-- | debian/patches/mach-defpager-fix-receiver-lookups.patch | 941 |
1 files changed, 941 insertions, 0 deletions
diff --git a/debian/patches/mach-defpager-fix-receiver-lookups.patch b/debian/patches/mach-defpager-fix-receiver-lookups.patch new file mode 100644 index 00000000..2fe57a6c --- /dev/null +++ b/debian/patches/mach-defpager-fix-receiver-lookups.patch @@ -0,0 +1,941 @@ +diff --git a/hurd/default_pager.defs b/hurd/default_pager.defs +index 8ad82dc..4885503 100644 +--- a/hurd/default_pager.defs ++++ b/hurd/default_pager.defs +@@ -36,6 +36,10 @@ subsystem default_pager 2275; + + import <hurd/default_pager_types.h>; /* XXX */ + ++#ifdef DEFAULT_PAGER_IMPORTS ++DEFAULT_PAGER_IMPORTS ++#endif ++ + routine default_pager_object_create( + default_pager : mach_port_t; + out memory_object : memory_object_t = +@@ -90,6 +94,6 @@ routine default_pager_paging_storage( + to fix the object's maximum size. Any references to pages beyond the limit + will fail. */ + routine default_pager_object_set_size( +- memory_object : mach_port_t; ++ memory_object : memory_object_t; + msgseqno seqno : mach_port_seqno_t; + object_size_limit : vm_size_t); +diff --git a/mach-defpager/Makefile b/mach-defpager/Makefile +index e38a0be..09debed 100644 +--- a/mach-defpager/Makefile ++++ b/mach-defpager/Makefile +@@ -29,9 +29,10 @@ OBJS := $(SRCS:.c=.o) \ + memory_object default_pager memory_object_default exc) \ + default_pager_replyUser.o + ++HURDLIBS:= ihash + OTHERLIBS:= -lpthread + LDFLAGS += -static + + include ../Makeconf + +-MIGSFLAGS = -DSEQNOS ++MIGSFLAGS = -DSEQNOS -imacros $(srcdir)/mig-mutate.h +diff --git a/mach-defpager/default_pager.c b/mach-defpager/default_pager.c +index 8f8e13e..f514ea6 100644 +--- a/mach-defpager/default_pager.c ++++ b/mach-defpager/default_pager.c +@@ -38,14 +38,17 @@ + #include <mach/default_pager_types.h> + + #include <pthread.h> ++#include <stddef.h> + + #include <device/device_types.h> + #include <device/device.h> + +-#include <queue.h> +-#include <wiring.h> +-#include <kalloc.h> +-#include <default_pager.h> ++#include <hurd/ihash.h> ++ ++#include "queue.h" ++#include "wiring.h" ++#include "kalloc.h" ++#include "default_pager.h" + + #include <assert.h> + #include <errno.h> +@@ -60,6 +63,8 @@ + #include "default_pager_S.h" + #include "exc_S.h" + ++#include "priv.h" ++ + #define debug 0 + + static char my_name[] = "(default pager):"; +@@ -106,47 +111,6 @@ synchronized_printf (const char *fmt, ...) + #define ptoa(p) ((p)*vm_page_size) + #define atop(a) ((a)/vm_page_size) + +-/* +- * Bitmap allocation. +- */ +-typedef unsigned int bm_entry_t; +-#define NB_BM 32 +-#define BM_MASK 0xffffffff +- +-#define howmany(a,b) (((a) + (b) - 1)/(b)) +- +-/* +- * Value to indicate no block assigned +- */ +-#define NO_BLOCK ((vm_offset_t)-1) +- +-/* +- * 'Partition' structure for each paging area. +- * Controls allocation of blocks within paging area. +- */ +-struct part { +- pthread_mutex_t p_lock; /* for bitmap/free */ +- vm_size_t total_size; /* total number of blocks */ +- vm_size_t free; /* number of blocks free */ +- unsigned int id; /* named lookup */ +- bm_entry_t *bitmap; /* allocation map */ +- boolean_t going_away; /* destroy attempt in progress */ +- struct file_direct *file; /* file paged to */ +-}; +-typedef struct part *partition_t; +- +-struct { +- pthread_mutex_t lock; +- int n_partitions; +- partition_t *partition_list;/* array, for quick mapping */ +-} all_partitions; /* list of all such */ +- +-typedef unsigned char p_index_t; +- +-#define P_INDEX_INVALID ((p_index_t)-1) +- +-#define no_partition(x) ((x) == P_INDEX_INVALID) +- + partition_t partition_of(x) + int x; + { +@@ -632,81 +596,6 @@ ddprintf ("pager_dealloc_page(%d,%x,%d)\n",pindex,page,lock_it); + } + + /* +- * Allocation info for each paging object. +- * +- * Most operations, even pager_write_offset and pager_put_checksum, +- * just need a read lock. Higher-level considerations prevent +- * conflicting operations on a single page. The lock really protects +- * the underlying size and block map memory, so pager_extend needs a +- * write lock. +- * +- * An object can now span multiple paging partitions. The allocation +- * info we keep is a pair (offset,p_index) where the index is in the +- * array of all partition ptrs, and the offset is partition-relative. +- * Size wise we are doing ok fitting the pair into a single integer: +- * the offset really is in pages so we have vm_page_size bits available +- * for the partition index. +- */ +-#define DEBUG_READER_CONFLICTS 0 +- +-#if DEBUG_READER_CONFLICTS +-int default_pager_read_conflicts = 0; +-#endif +- +-union dp_map { +- +- struct { +- unsigned int p_offset : 24, +- p_index : 8; +- } block; +- +- union dp_map *indirect; +-}; +-typedef union dp_map *dp_map_t; +- +-/* quick check for part==block==invalid */ +-#define no_block(e) ((e).indirect == (dp_map_t)NO_BLOCK) +-#define invalidate_block(e) ((e).indirect = (dp_map_t)NO_BLOCK) +- +-struct dpager { +- pthread_mutex_t lock; /* lock for extending block map */ +- /* XXX should be read-write lock */ +-#if DEBUG_READER_CONFLICTS +- int readers; +- boolean_t writer; +-#endif +- dp_map_t map; /* block map */ +- vm_size_t size; /* size of paging object, in pages */ +- vm_size_t limit; /* limit (bytes) allowed to grow to */ +- vm_size_t byte_limit; /* limit, which wasn't +- rounded to page boundary */ +- p_index_t cur_partition; +-#ifdef CHECKSUM +- vm_offset_t *checksum; /* checksum - parallel to block map */ +-#define NO_CHECKSUM ((vm_offset_t)-1) +-#endif /* CHECKSUM */ +-}; +-typedef struct dpager *dpager_t; +- +-/* +- * A paging object uses either a one- or a two-level map of offsets +- * into a paging partition. +- */ +-#define PAGEMAP_ENTRIES 64 +- /* number of pages in a second-level map */ +-#define PAGEMAP_SIZE(npgs) ((npgs)*sizeof(vm_offset_t)) +- +-#define INDIRECT_PAGEMAP_ENTRIES(npgs) \ +- ((((npgs)-1)/PAGEMAP_ENTRIES) + 1) +-#define INDIRECT_PAGEMAP_SIZE(npgs) \ +- (INDIRECT_PAGEMAP_ENTRIES(npgs) * sizeof(vm_offset_t *)) +-#define INDIRECT_PAGEMAP(size) \ +- (size > PAGEMAP_ENTRIES) +- +-#define ROUNDUP_TO_PAGEMAP(npgs) \ +- (((npgs) + PAGEMAP_ENTRIES - 1) & ~(PAGEMAP_ENTRIES - 1)) +- +-/* + * Object sizes are rounded up to the next power of 2, + * unless they are bigger than a given maximum size. + */ +@@ -1885,40 +1774,6 @@ default_has_page(ds, offset) + return ( ! no_block(pager_read_offset(ds, offset)) ); + } + +-/* +- * Mapping between pager port and paging object. +- */ +-struct dstruct { +- queue_chain_t links; /* Link in pager-port list */ +- +- pthread_mutex_t lock; /* Lock for the structure */ +- pthread_cond_t +- waiting_seqno, /* someone waiting on seqno */ +- waiting_read, /* someone waiting on readers */ +- waiting_write, /* someone waiting on writers */ +- waiting_refs; /* someone waiting on refs */ +- +- memory_object_t pager; /* Pager port */ +- mach_port_seqno_t seqno; /* Pager port sequence number */ +- mach_port_t pager_request; /* Request port */ +- mach_port_urefs_t request_refs; /* Request port user-refs */ +- mach_port_t pager_name; /* Name port */ +- mach_port_urefs_t name_refs; /* Name port user-refs */ +- boolean_t external; /* Is an external object? */ +- +- unsigned int readers; /* Reads in progress */ +- unsigned int writers; /* Writes in progress */ +- +- /* This is the reply port of an outstanding +- default_pager_object_set_size call. */ +- mach_port_t lock_request; +- +- unsigned int errors; /* Pageout error count */ +- struct dpager dpager; /* Actual pager */ +-}; +-typedef struct dstruct * default_pager_t; +-#define DEFAULT_PAGER_NULL ((default_pager_t)0) +- + #if PARALLEL + #define dstruct_lock_init(ds) pthread_mutex_init(&ds->lock, NULL) + #define dstruct_lock(ds) pthread_mutex_lock(&ds->lock) +@@ -1929,25 +1784,14 @@ typedef struct dstruct * default_pager_t; + #define dstruct_unlock(ds) + #endif /* PARALLEL */ + +-/* +- * List of all pagers. A specific pager is +- * found directly via its port, this list is +- * only used for monitoring purposes by the +- * default_pager_object* calls +- */ +-struct pager_port { +- queue_head_t queue; +- pthread_mutex_t lock; +- int count; /* saves code */ +- queue_head_t leak_queue; +-} all_pagers; ++struct pager_port all_pagers; + + #define pager_port_list_init() \ + { \ + pthread_mutex_init(&all_pagers.lock, NULL); \ +- queue_init(&all_pagers.queue); \ ++ hurd_ihash_init (&all_pagers.htable, \ ++ offsetof (struct dstruct, htable_locp)); \ + queue_init(&all_pagers.leak_queue); \ +- all_pagers.count = 0; \ + } + + void pager_port_list_insert(port, ds) +@@ -1955,28 +1799,18 @@ void pager_port_list_insert(port, ds) + default_pager_t ds; + { + pthread_mutex_lock(&all_pagers.lock); +- queue_enter(&all_pagers.queue, ds, default_pager_t, links); +- all_pagers.count++; ++ hurd_ihash_add (&all_pagers.htable, ++ (hurd_ihash_key_t) port, ++ (hurd_ihash_value_t) ds); + pthread_mutex_unlock(&all_pagers.lock); + } + +-/* given a data structure return a good port-name to associate it to */ +-#define pnameof(_x_) (((vm_offset_t)(_x_))+1) +-/* reverse, assumes no-odd-pointers */ +-#define dnameof(_x_) (((vm_offset_t)(_x_))&~1) +- +-/* The magic typecast */ +-#define pager_port_lookup(_port_) \ +- ((! MACH_PORT_VALID(_port_) || \ +- ((default_pager_t)dnameof(_port_))->pager != (_port_)) ? \ +- DEFAULT_PAGER_NULL : (default_pager_t)dnameof(_port_)) +- + void pager_port_list_delete(ds) + default_pager_t ds; + { + pthread_mutex_lock(&all_pagers.lock); +- queue_remove(&all_pagers.queue, ds, default_pager_t, links); +- all_pagers.count--; ++ hurd_ihash_locp_remove (&all_pagers.htable, ++ ds->htable_locp); + pthread_mutex_unlock(&all_pagers.lock); + } + +@@ -2023,7 +1857,8 @@ dprintf("Partition x%x (id x%x) for %s, all_ok %d\n", part, id, name, all_ok); + pthread_mutex_lock(&part->p_lock); + + pthread_mutex_lock(&all_pagers.lock); +- queue_iterate(&all_pagers.queue, entry, default_pager_t, links) { ++ HURD_IHASH_ITERATE (&all_pagers.htable, val) { ++ entry = (default_pager_t) val; + + dstruct_lock(entry); + +@@ -2397,7 +2232,6 @@ seqnos_memory_object_create(old_pager, seqno, new_pager, new_size, + vm_size_t new_page_size; + { + default_pager_t ds; +- kern_return_t kr; + + assert(old_pager == default_pager_default_port); + assert(MACH_PORT_VALID(new_pager_request)); +@@ -2405,24 +2239,6 @@ seqnos_memory_object_create(old_pager, seqno, new_pager, new_size, + assert(new_page_size == vm_page_size); + + ds = pager_port_alloc(new_size); +-rename_it: +- kr = mach_port_rename( default_pager_self, +- new_pager, (mach_port_t)pnameof(ds)); +- if (kr != KERN_SUCCESS) { +- default_pager_t ds1; +- +- if (kr != KERN_NAME_EXISTS) +- panic("%s m_o_create", my_name); +- ds1 = (default_pager_t) kalloc(sizeof *ds1); +- *ds1 = *ds; +- pthread_mutex_lock(&all_pagers.lock); +- queue_enter(&all_pagers.leak_queue, ds, default_pager_t, links); +- pthread_mutex_unlock(&all_pagers.lock); +- ds = ds1; +- goto rename_it; +- } +- +- new_pager = (mach_port_t) pnameof(ds); + + /* + * Set up associations between these ports +@@ -2450,15 +2266,14 @@ memory_object_copy_strategy_t default_pager_copy_strategy = + MEMORY_OBJECT_COPY_DELAY; + + kern_return_t +-seqnos_memory_object_init(pager, seqno, pager_request, pager_name, ++seqnos_memory_object_init(ds, seqno, pager_request, pager_name, + pager_page_size) +- mach_port_t pager; ++ default_pager_t ds; + mach_port_seqno_t seqno; + mach_port_t pager_request; + mach_port_t pager_name; + vm_size_t pager_page_size; + { +- default_pager_t ds; + kern_return_t kr; + static char here[] = "%sinit"; + +@@ -2466,7 +2281,6 @@ seqnos_memory_object_init(pager, seqno, pager_request, pager_name, + assert(MACH_PORT_VALID(pager_name)); + assert(pager_page_size == vm_page_size); + +- ds = pager_port_lookup(pager); + if (ds == DEFAULT_PAGER_NULL) + panic(here, my_name); + pager_port_lock(ds, seqno); +@@ -2498,13 +2312,12 @@ seqnos_memory_object_init(pager, seqno, pager_request, pager_name, + } + + kern_return_t +-seqnos_memory_object_terminate(pager, seqno, pager_request, pager_name) +- mach_port_t pager; ++seqnos_memory_object_terminate(ds, seqno, pager_request, pager_name) ++ default_pager_t ds; + mach_port_seqno_t seqno; + mach_port_t pager_request; + mach_port_t pager_name; + { +- default_pager_t ds; + static char here[] = "%sterminate"; + + /* +@@ -2512,7 +2325,6 @@ seqnos_memory_object_terminate(pager, seqno, pager_request, pager_name) + * not send rights. + */ + +- ds = pager_port_lookup(pager); + if (ds == DEFAULT_PAGER_NULL) + panic(here, my_name); + ddprintf ("seqnos_memory_object_terminate <%p>: pager_port_lock: <%p>[s:%d,r:%d,w:%d,l:%d], %d\n", +@@ -2578,7 +2390,7 @@ void default_pager_no_senders(pager, seqno, mscount) + */ + + +- ds = pager_port_lookup(pager); ++ ds = begin_using_default_pager(pager); + if (ds == DEFAULT_PAGER_NULL) + panic(here,my_name); + pager_port_lock(ds, seqno); +@@ -2639,16 +2451,15 @@ int default_pager_pageout_count = 0; + static __thread default_pager_thread_t *dpt; + + kern_return_t +-seqnos_memory_object_data_request(pager, seqno, reply_to, offset, ++seqnos_memory_object_data_request(ds, seqno, reply_to, offset, + length, protection_required) +- memory_object_t pager; ++ default_pager_t ds; + mach_port_seqno_t seqno; + mach_port_t reply_to; + vm_offset_t offset; + vm_size_t length; + vm_prot_t protection_required; + { +- default_pager_t ds; + vm_offset_t addr; + unsigned int errors; + kern_return_t rc; +@@ -2657,7 +2468,6 @@ seqnos_memory_object_data_request(pager, seqno, reply_to, offset, + if (length != vm_page_size) + panic(here,my_name); + +- ds = pager_port_lookup(pager); + if (ds == DEFAULT_PAGER_NULL) + panic(here,my_name); + ddprintf ("seqnos_memory_object_data_request <%p>: pager_port_lock: <%p>[s:%d,r:%d,w:%d,l:%d], %d\n", +@@ -2742,9 +2552,9 @@ ddprintf ("seqnos_memory_object_data_request <%p>: pager_port_unlock: <%p>[s:%d, + * also assumes that the default_pager is single-threaded. + */ + kern_return_t +-seqnos_memory_object_data_initialize(pager, seqno, pager_request, ++seqnos_memory_object_data_initialize(ds, seqno, pager_request, + offset, addr, data_cnt) +- memory_object_t pager; ++ default_pager_t ds; + mach_port_seqno_t seqno; + mach_port_t pager_request; + register +@@ -2754,14 +2564,12 @@ seqnos_memory_object_data_initialize(pager, seqno, pager_request, + vm_size_t data_cnt; + { + vm_offset_t amount_sent; +- default_pager_t ds; + static char here[] = "%sdata_initialize"; + + #ifdef lint + pager_request++; + #endif /* lint */ + +- ds = pager_port_lookup(pager); + if (ds == DEFAULT_PAGER_NULL) + panic(here,my_name); + ddprintf ("seqnos_memory_object_data_initialize <%p>: pager_port_lock: <%p>[s:%d,r:%d,w:%d,l:%d], %d\n", +@@ -2804,9 +2612,9 @@ ddprintf ("seqnos_memory_object_data_initialize <%p>: pager_port_unlock: <%p>[s: + * into individual pages and pass them off to default_write. + */ + kern_return_t +-seqnos_memory_object_data_write(pager, seqno, pager_request, ++seqnos_memory_object_data_write(ds, seqno, pager_request, + offset, addr, data_cnt) +- memory_object_t pager; ++ default_pager_t ds; + mach_port_seqno_t seqno; + mach_port_t pager_request; + register +@@ -2817,7 +2625,6 @@ seqnos_memory_object_data_write(pager, seqno, pager_request, + { + register + vm_size_t amount_sent; +- default_pager_t ds; + static char here[] = "%sdata_write"; + int err; + +@@ -2828,7 +2635,6 @@ seqnos_memory_object_data_write(pager, seqno, pager_request, + if ((data_cnt % vm_page_size) != 0) + panic(here,my_name); + +- ds = pager_port_lookup(pager); + if (ds == DEFAULT_PAGER_NULL) + panic(here,my_name); + +@@ -2888,7 +2694,7 @@ seqnos_memory_object_data_write(pager, seqno, pager_request, + kern_return_t + seqnos_memory_object_copy(old_memory_object, seqno, old_memory_control, + offset, length, new_memory_object) +- memory_object_t old_memory_object; ++ default_pager_t old_memory_object; + mach_port_seqno_t seqno; + memory_object_control_t + old_memory_control; +@@ -2903,7 +2709,7 @@ seqnos_memory_object_copy(old_memory_object, seqno, old_memory_control, + /* We get this when our memory_object_lock_request has completed + after we truncated an object. */ + kern_return_t +-seqnos_memory_object_lock_completed (memory_object_t pager, ++seqnos_memory_object_lock_completed (default_pager_t ds, + mach_port_seqno_t seqno, + mach_port_t pager_request, + vm_offset_t offset, +@@ -2916,7 +2722,7 @@ seqnos_memory_object_lock_completed (memory_object_t pager, + kern_return_t + seqnos_memory_object_data_unlock(pager, seqno, pager_request, + offset, length, protection_required) +- memory_object_t pager; ++ default_pager_t pager; + mach_port_seqno_t seqno; + mach_port_t pager_request; + vm_offset_t offset; +@@ -2928,10 +2734,10 @@ seqnos_memory_object_data_unlock(pager, seqno, pager_request, + } + + kern_return_t +-seqnos_memory_object_supply_completed(pager, seqno, pager_request, ++seqnos_memory_object_supply_completed(ds, seqno, pager_request, + offset, length, + result, error_offset) +- memory_object_t pager; ++ default_pager_t ds; + mach_port_seqno_t seqno; + mach_port_t pager_request; + vm_offset_t offset; +@@ -2949,10 +2755,10 @@ seqnos_memory_object_supply_completed(pager, seqno, pager_request, + * into individual pages and pass them off to default_write. + */ + kern_return_t +-seqnos_memory_object_data_return(pager, seqno, pager_request, ++seqnos_memory_object_data_return(ds, seqno, pager_request, + offset, addr, data_cnt, + dirty, kernel_copy) +- memory_object_t pager; ++ default_pager_t ds; + mach_port_seqno_t seqno; + mach_port_t pager_request; + vm_offset_t offset; +@@ -2962,13 +2768,13 @@ seqnos_memory_object_data_return(pager, seqno, pager_request, + boolean_t kernel_copy; + { + +- return seqnos_memory_object_data_write (pager, seqno, pager_request, ++ return seqnos_memory_object_data_write (ds, seqno, pager_request, + offset, addr, data_cnt); + } + + kern_return_t +-seqnos_memory_object_change_completed(pager, seqno, may_cache, copy_strategy) +- memory_object_t pager; ++seqnos_memory_object_change_completed(ds, seqno, may_cache, copy_strategy) ++ default_pager_t ds; + mach_port_seqno_t seqno; + boolean_t may_cache; + memory_object_copy_strategy_t copy_strategy; +@@ -3364,23 +3170,14 @@ S_default_pager_object_create (mach_port_t pager, + return KERN_INVALID_ARGUMENT; + + ds = pager_port_alloc(size); +-rename_it: +- port = (mach_port_t) pnameof(ds); +- result = mach_port_allocate_name(default_pager_self, +- MACH_PORT_RIGHT_RECEIVE, port); +- if (result != KERN_SUCCESS) { +- default_pager_t ds1; +- +- if (result != KERN_NAME_EXISTS) return (result); +- +- ds1 = (default_pager_t) kalloc(sizeof *ds1); +- *ds1 = *ds; +- pthread_mutex_lock(&all_pagers.lock); +- queue_enter(&all_pagers.leak_queue, ds, default_pager_t, links); +- pthread_mutex_unlock(&all_pagers.lock); +- ds = ds1; +- goto rename_it; +- } ++ result = mach_port_allocate (default_pager_self, ++ MACH_PORT_RIGHT_RECEIVE, ++ &port); ++ if (result != KERN_SUCCESS) ++ { ++ kfree ((char *) ds, sizeof *ds); ++ return result; ++ } + + /* + * Set up associations between these ports +@@ -3454,7 +3251,7 @@ S_default_pager_objects (mach_port_t pager, + /* + * We will send no more than this many + */ +- actual = all_pagers.count; ++ actual = all_pagers.htable.nr_items; + pthread_mutex_unlock(&all_pagers.lock); + + if (opotential < actual) { +@@ -3496,7 +3293,8 @@ S_default_pager_objects (mach_port_t pager, + pthread_mutex_lock(&all_pagers.lock); + + num_pagers = 0; +- queue_iterate(&all_pagers.queue, entry, default_pager_t, links) { ++ HURD_IHASH_ITERATE (&all_pagers.htable, val) { ++ entry = (default_pager_t) val; + + mach_port_t port; + vm_size_t size; +@@ -3674,7 +3472,8 @@ S_default_pager_object_pages (mach_port_t pager, + default_pager_t entry; + + pthread_mutex_lock(&all_pagers.lock); +- queue_iterate(&all_pagers.queue, entry, default_pager_t, links) { ++ HURD_IHASH_ITERATE (&all_pagers.htable, val) { ++ entry = (default_pager_t) val; + dstruct_lock(entry); + if (entry->pager_name == object) { + pthread_mutex_unlock(&all_pagers.lock); +@@ -3756,14 +3555,12 @@ S_default_pager_object_pages (mach_port_t pager, + + + kern_return_t +-S_default_pager_object_set_size (mach_port_t pager, ++S_default_pager_object_set_size (default_pager_t ds, + mach_port_seqno_t seqno, + vm_size_t limit) + { + kern_return_t kr = KERN_SUCCESS; +- default_pager_t ds; + +- ds = pager_port_lookup(pager); + if (ds == DEFAULT_PAGER_NULL) + return KERN_INVALID_ARGUMENT; + +diff --git a/mach-defpager/main.c b/mach-defpager/main.c +index fe6f735..e33c2b3 100644 +--- a/mach-defpager/main.c ++++ b/mach-defpager/main.c +@@ -43,7 +43,7 @@ + #include <hurd/fd.h> + /* XXX */ + +-#include <default_pager.h> ++#include "default_pager.h" + + mach_port_t bootstrap_master_device_port; /* local name */ + mach_port_t bootstrap_master_host_port; /* local name */ +diff --git a/mach-defpager/mig-decls.h b/mach-defpager/mig-decls.h +new file mode 100644 +index 0000000..8118d61 +--- /dev/null ++++ b/mach-defpager/mig-decls.h +@@ -0,0 +1,34 @@ ++/* ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ Written by Justus Winter. ++ ++ This file is part of the GNU Hurd. ++ ++ The GNU Hurd is free software; you can redistribute it and/or ++ modify it under the terms of the GNU General Public License as ++ published by the Free Software Foundation; either version 2, or (at ++ your option) any later version. ++ ++ The GNU Hurd is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */ ++ ++#ifndef __MACH_DEFPAGER_MIG_DECLS_H__ ++#define __MACH_DEFPAGER_MIG_DECLS_H__ ++ ++#include "priv.h" ++ ++/* Called by server stub functions. */ ++ ++static inline struct dstruct * __attribute__ ((unused)) ++begin_using_default_pager (mach_port_t port) ++{ ++ return (default_pager_t) hurd_ihash_find (&all_pagers.htable, ++ (hurd_ihash_key_t) port); ++} ++ ++#endif /* __MACH_DEFPAGER_MIG_DECLS_H__ */ +diff --git a/mach-defpager/mig-mutate.h b/mach-defpager/mig-mutate.h +new file mode 100644 +index 0000000..54aeeba +--- /dev/null ++++ b/mach-defpager/mig-mutate.h +@@ -0,0 +1,22 @@ ++/* ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ Written by Justus Winter. ++ ++ This file is part of the GNU Hurd. ++ ++ The GNU Hurd is free software; you can redistribute it and/or ++ modify it under the terms of the GNU General Public License as ++ published by the Free Software Foundation; either version 2, or (at ++ your option) any later version. ++ ++ The GNU Hurd is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */ ++ ++#define MEMORY_OBJECT_INTRAN default_pager_t begin_using_default_pager (mach_port_t) ++#define MEMORY_OBJECT_IMPORTS import "mig-decls.h"; ++#define DEFAULT_PAGER_IMPORTS import "mig-decls.h"; +diff --git a/mach-defpager/priv.h b/mach-defpager/priv.h +new file mode 100644 +index 0000000..3684565 +--- /dev/null ++++ b/mach-defpager/priv.h +@@ -0,0 +1,200 @@ ++/* ++ * Mach Operating System ++ * Copyright (c) 1993-1989 Carnegie Mellon University ++ * All Rights Reserved. ++ * ++ * Permission to use, copy, modify and distribute this software and its ++ * documentation is hereby granted, provided that both the copyright ++ * notice and this permission notice appear in all copies of the ++ * software, derivative works or modified versions, and any portions ++ * thereof, and that both notices appear in supporting documentation. ++ * ++ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ++ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ++ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ++ * ++ * Carnegie Mellon requests users of this software to return to ++ * ++ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU ++ * School of Computer Science ++ * Carnegie Mellon University ++ * Pittsburgh PA 15213-3890 ++ * ++ * any improvements or extensions that they make and grant Carnegie Mellon ++ * the rights to redistribute these changes. ++ */ ++ ++#ifndef __MACH_DEFPAGER_PRIV_H__ ++#define __MACH_DEFPAGER_PRIV_H__ ++ ++#include <mach.h> ++#include <queue.h> ++#include <hurd/ihash.h> ++ ++/* ++ * Bitmap allocation. ++ */ ++typedef unsigned int bm_entry_t; ++#define NB_BM 32 ++#define BM_MASK 0xffffffff ++ ++#define howmany(a,b) (((a) + (b) - 1)/(b)) ++ ++/* ++ * Value to indicate no block assigned ++ */ ++#define NO_BLOCK ((vm_offset_t)-1) ++ ++/* ++ * 'Partition' structure for each paging area. ++ * Controls allocation of blocks within paging area. ++ */ ++struct part { ++ pthread_mutex_t p_lock; /* for bitmap/free */ ++ vm_size_t total_size; /* total number of blocks */ ++ vm_size_t free; /* number of blocks free */ ++ unsigned int id; /* named lookup */ ++ bm_entry_t *bitmap; /* allocation map */ ++ boolean_t going_away; /* destroy attempt in progress */ ++ struct file_direct *file; /* file paged to */ ++}; ++typedef struct part *partition_t; ++ ++struct { ++ pthread_mutex_t lock; ++ int n_partitions; ++ partition_t *partition_list;/* array, for quick mapping */ ++} all_partitions; /* list of all such */ ++ ++typedef unsigned char p_index_t; ++ ++#define P_INDEX_INVALID ((p_index_t)-1) ++ ++#define no_partition(x) ((x) == P_INDEX_INVALID) ++ ++/* ++ * Allocation info for each paging object. ++ * ++ * Most operations, even pager_write_offset and pager_put_checksum, ++ * just need a read lock. Higher-level considerations prevent ++ * conflicting operations on a single page. The lock really protects ++ * the underlying size and block map memory, so pager_extend needs a ++ * write lock. ++ * ++ * An object can now span multiple paging partitions. The allocation ++ * info we keep is a pair (offset,p_index) where the index is in the ++ * array of all partition ptrs, and the offset is partition-relative. ++ * Size wise we are doing ok fitting the pair into a single integer: ++ * the offset really is in pages so we have vm_page_size bits available ++ * for the partition index. ++ */ ++#define DEBUG_READER_CONFLICTS 0 ++ ++#if DEBUG_READER_CONFLICTS ++int default_pager_read_conflicts = 0; ++#endif ++ ++union dp_map { ++ ++ struct { ++ unsigned int p_offset : 24, ++ p_index : 8; ++ } block; ++ ++ union dp_map *indirect; ++}; ++typedef union dp_map *dp_map_t; ++ ++/* quick check for part==block==invalid */ ++#define no_block(e) ((e).indirect == (dp_map_t)NO_BLOCK) ++#define invalidate_block(e) ((e).indirect = (dp_map_t)NO_BLOCK) ++ ++struct dpager { ++ pthread_mutex_t lock; /* lock for extending block map */ ++ /* XXX should be read-write lock */ ++#if DEBUG_READER_CONFLICTS ++ int readers; ++ boolean_t writer; ++#endif ++ dp_map_t map; /* block map */ ++ vm_size_t size; /* size of paging object, in pages */ ++ vm_size_t limit; /* limit (bytes) allowed to grow to */ ++ vm_size_t byte_limit; /* limit, which wasn't ++ rounded to page boundary */ ++ p_index_t cur_partition; ++#ifdef CHECKSUM ++ vm_offset_t *checksum; /* checksum - parallel to block map */ ++#define NO_CHECKSUM ((vm_offset_t)-1) ++#endif /* CHECKSUM */ ++}; ++typedef struct dpager *dpager_t; ++ ++/* ++ * A paging object uses either a one- or a two-level map of offsets ++ * into a paging partition. ++ */ ++#define PAGEMAP_ENTRIES 64 ++ /* number of pages in a second-level map */ ++#define PAGEMAP_SIZE(npgs) ((npgs)*sizeof(vm_offset_t)) ++ ++#define INDIRECT_PAGEMAP_ENTRIES(npgs) \ ++ ((((npgs)-1)/PAGEMAP_ENTRIES) + 1) ++#define INDIRECT_PAGEMAP_SIZE(npgs) \ ++ (INDIRECT_PAGEMAP_ENTRIES(npgs) * sizeof(vm_offset_t *)) ++#define INDIRECT_PAGEMAP(size) \ ++ (size > PAGEMAP_ENTRIES) ++ ++#define ROUNDUP_TO_PAGEMAP(npgs) \ ++ (((npgs) + PAGEMAP_ENTRIES - 1) & ~(PAGEMAP_ENTRIES - 1)) ++ ++/* ++ * Mapping between pager port and paging object. ++ */ ++struct dstruct { ++ hurd_ihash_locp_t htable_locp; /* for the ihash table */ ++ queue_chain_t links; /* Link in pager-port list */ ++ ++ pthread_mutex_t lock; /* Lock for the structure */ ++ pthread_cond_t ++ waiting_seqno, /* someone waiting on seqno */ ++ waiting_read, /* someone waiting on readers */ ++ waiting_write, /* someone waiting on writers */ ++ waiting_refs; /* someone waiting on refs */ ++ ++ memory_object_t pager; /* Pager port */ ++ mach_port_seqno_t seqno; /* Pager port sequence number */ ++ mach_port_t pager_request; /* Request port */ ++ mach_port_urefs_t request_refs; /* Request port user-refs */ ++ mach_port_t pager_name; /* Name port */ ++ mach_port_urefs_t name_refs; /* Name port user-refs */ ++ boolean_t external; /* Is an external object? */ ++ ++ unsigned int readers; /* Reads in progress */ ++ unsigned int writers; /* Writes in progress */ ++ ++ /* This is the reply port of an outstanding ++ default_pager_object_set_size call. */ ++ mach_port_t lock_request; ++ ++ unsigned int errors; /* Pageout error count */ ++ struct dpager dpager; /* Actual pager */ ++}; ++typedef struct dstruct * default_pager_t; ++#define DEFAULT_PAGER_NULL ((default_pager_t)0) ++ ++/* ++ * List of all pagers. A specific pager is ++ * found directly via its port, this list is ++ * only used for monitoring purposes by the ++ * default_pager_object* calls ++ */ ++struct pager_port { ++ struct hurd_ihash htable; ++ pthread_mutex_t lock; ++ queue_head_t leak_queue; ++}; ++ ++/* The list of pagers. */ ++extern struct pager_port all_pagers; ++ ++#endif /* __MACH_DEFPAGER_PRIV_H__ */ +diff --git a/mach-defpager/setup.c b/mach-defpager/setup.c +index 7c1afbc..e4ec8d9 100644 +--- a/mach-defpager/setup.c ++++ b/mach-defpager/setup.c +@@ -25,8 +25,8 @@ + #include <string.h> + #include <strings.h> + +-#include <default_pager.h> +-#include <kalloc.h> ++#include "default_pager.h" ++#include "kalloc.h" + + #include "file_io.h" + #include "default_pager_S.h" |