Here is a patch that does it all. Any comments ?
2006-12-30 Richard Braun <[EMAIL PROTECTED]>
Added alignment support in the zone allocator.
* kern/zalloc.c (ALIGN_SIZE_UP): New macro.
(zinit): New `align' parameter.
(zget_space): Likewise.
(zone_bootstrap): Updated call to zinit() with alignment of 0.
(zalloc): Updated call to zget_space() with the zone alignment.
* kern/zalloc.h (zone): New member `align'.
(zinit): Declaration updated as required.
* device/dev_lookup.c (dev_lookup_init): Updated call to zinit() with
alignment of 0.
* device/dev_pager.c (dev_pager_hash_init): Likewise.
(device_pager_init): Likewise.
* device/ds_routines.c (ds_init): Likewise.
(ds_trap_init): Likewise.
* device/net_io.c (net_io_init): Likewise.
* i386/i386/fpu.c (fpu_module_init): Likewise.
* i386/i386/pcb.c (pcb_module_init): Likewise.
* i386/intel/pmap.c (pmap_init): Likewise.
* ipc/ipc_init.c (ipc_bootstrap): Likewise.
* ipc/ipc_marequest.c (ipc_marequest_init): Likewise.
* kern/act.c (global_act_init): Likewise.
* kern/kalloc.c (kalloc_init): Likewise.
* kern/processor.c (pset_sys_init): Likewise.
* kern/task.c (task_init): Likewise.
* kern/thread.c (thread_init): Likewise.
* vm/vm_external.c (vm_external_module_initialize): Likewise.
* vm/vm_fault.c (vm_fault_init): Likewise.
* vm/vm_map.c (vm_map_init): Likewise.
* vm/vm_object.c (vm_object_bootstrap): Likewise.
* vm/vm_resident.c (vm_page_module_init): Likewise.
Index: device/dev_lookup.c
===================================================================
RCS file: /sources/hurd/gnumach/device/Attic/dev_lookup.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 dev_lookup.c
--- device/dev_lookup.c 25 Feb 1997 21:28:14 -0000 1.1.1.1
+++ device/dev_lookup.c 30 Dec 2006 10:42:23 -0000
@@ -401,7 +401,7 @@ dev_lookup_init()
simple_lock_init(&dev_port_lock);
- dev_hdr_zone = zinit(sizeof(struct mach_device),
+ dev_hdr_zone = zinit(sizeof(struct mach_device), 0,
sizeof(struct mach_device) * NDEVICES,
PAGE_SIZE,
FALSE,
Index: device/dev_pager.c
===================================================================
RCS file: /sources/hurd/gnumach/device/dev_pager.c,v
retrieving revision 1.3.2.5
diff -u -p -r1.3.2.5 dev_pager.c
--- device/dev_pager.c 10 Nov 2006 01:22:57 -0000 1.3.2.5
+++ device/dev_pager.c 30 Dec 2006 10:42:24 -0000
@@ -174,6 +174,7 @@ void dev_pager_hash_init(void)
size = sizeof(struct dev_pager_entry);
dev_pager_hash_zone = zinit(
size,
+ 0,
size * 1000,
PAGE_SIZE,
FALSE,
@@ -727,6 +728,7 @@ void device_pager_init(void)
*/
size = sizeof(struct dev_pager);
dev_pager_zone = zinit(size,
+ 0,
(vm_size_t) size * 1000,
PAGE_SIZE,
FALSE,
Index: device/ds_routines.c
===================================================================
RCS file: /sources/hurd/gnumach/device/Attic/ds_routines.c,v
retrieving revision 1.6.2.7
diff -u -p -r1.6.2.7 ds_routines.c
--- device/ds_routines.c 11 Nov 2006 00:54:05 -0000 1.6.2.7
+++ device/ds_routines.c 30 Dec 2006 10:42:24 -0000
@@ -1471,7 +1471,7 @@ void ds_init()
*/
device_io_map->wait_for_space = TRUE;
- io_inband_zone = zinit(sizeof(io_buf_ptr_inband_t),
+ io_inband_zone = zinit(sizeof(io_buf_ptr_inband_t), 0,
1000 * sizeof(io_buf_ptr_inband_t),
10 * sizeof(io_buf_ptr_inband_t),
FALSE,
@@ -1519,7 +1519,7 @@ zone_t io_trap_zone;
void
ds_trap_init(void)
{
- io_trap_zone = zinit(IOTRAP_REQSIZE,
+ io_trap_zone = zinit(IOTRAP_REQSIZE, 0,
256 * IOTRAP_REQSIZE,
16 * IOTRAP_REQSIZE,
FALSE,
Index: device/net_io.c
===================================================================
RCS file: /sources/hurd/gnumach/device/net_io.c,v
retrieving revision 1.2.2.11
diff -u -p -r1.2.2.11 net_io.c
--- device/net_io.c 13 Nov 2006 21:30:36 -0000 1.2.2.11
+++ device/net_io.c 30 Dec 2006 10:42:25 -0000
@@ -1494,6 +1494,7 @@ net_io_init()
size = sizeof(struct net_rcv_port);
net_rcv_zone = zinit(size,
+ 0,
size * 1000,
PAGE_SIZE,
FALSE,
@@ -1501,6 +1502,7 @@ net_io_init()
size = sizeof(struct net_hash_entry);
net_hash_entry_zone = zinit(size,
+ 0,
size * 100,
PAGE_SIZE,
FALSE,
Index: i386/i386/fpu.c
===================================================================
RCS file: /sources/hurd/gnumach/i386/i386/fpu.c,v
retrieving revision 1.2.4.9
diff -u -p -r1.2.4.9 fpu.c
--- i386/i386/fpu.c 12 Dec 2006 23:30:49 -0000 1.2.4.9
+++ i386/i386/fpu.c 30 Dec 2006 10:42:25 -0000
@@ -152,7 +152,7 @@ init_fpu()
void
fpu_module_init()
{
- ifps_zone = zinit(sizeof(struct i386_fpsave_state),
+ ifps_zone = zinit(sizeof(struct i386_fpsave_state), 0,
THREAD_MAX * sizeof(struct i386_fpsave_state),
THREAD_CHUNK * sizeof(struct i386_fpsave_state),
0, "i386 fpsave state");
Index: i386/i386/pcb.c
===================================================================
RCS file: /sources/hurd/gnumach/i386/i386/pcb.c,v
retrieving revision 1.2.4.8
diff -u -p -r1.2.4.8 pcb.c
--- i386/i386/pcb.c 12 Nov 2006 23:45:06 -0000 1.2.4.8
+++ i386/i386/pcb.c 30 Dec 2006 10:42:25 -0000
@@ -311,7 +311,7 @@ thread_t switch_context(old, continuatio
void pcb_module_init()
{
- pcb_zone = zinit(sizeof(struct pcb),
+ pcb_zone = zinit(sizeof(struct pcb), 0,
THREAD_MAX * sizeof(struct pcb),
THREAD_CHUNK * sizeof(struct pcb),
0, "i386 pcb state");
Index: i386/intel/pmap.c
===================================================================
RCS file: /sources/hurd/gnumach/i386/intel/pmap.c,v
retrieving revision 1.4.2.13
diff -u -p -r1.4.2.13 pmap.c
--- i386/intel/pmap.c 21 Dec 2006 00:12:01 -0000 1.4.2.13
+++ i386/intel/pmap.c 30 Dec 2006 10:42:26 -0000
@@ -741,9 +741,9 @@ void pmap_init()
* and of the physical-to-virtual entries.
*/
s = (vm_size_t) sizeof(struct pmap);
- pmap_zone = zinit(s, 400*s, 4096, 0, "pmap"); /* XXX */
+ pmap_zone = zinit(s, 0, 400*s, 4096, 0, "pmap"); /* XXX */
s = (vm_size_t) sizeof(struct pv_entry);
- pv_list_zone = zinit(s, 10000*s, 4096, 0, "pv_list"); /* XXX */
+ pv_list_zone = zinit(s, 0, 10000*s, 4096, 0, "pv_list"); /* XXX */
#if NCPUS > 1
/*
Index: ipc/ipc_init.c
===================================================================
RCS file: /sources/hurd/gnumach/ipc/ipc_init.c,v
retrieving revision 1.3.2.1
diff -u -p -r1.3.2.1 ipc_init.c
--- ipc/ipc_init.c 20 Mar 2006 11:31:36 -0000 1.3.2.1
+++ ipc/ipc_init.c 30 Dec 2006 10:42:26 -0000
@@ -77,25 +77,25 @@ ipc_bootstrap(void)
ipc_port_timestamp_lock_init();
ipc_port_timestamp_data = 0;
- ipc_space_zone = zinit(sizeof(struct ipc_space),
+ ipc_space_zone = zinit(sizeof(struct ipc_space), 0,
ipc_space_max * sizeof(struct ipc_space),
sizeof(struct ipc_space),
IPC_ZONE_TYPE, "ipc spaces");
ipc_tree_entry_zone =
- zinit(sizeof(struct ipc_tree_entry),
+ zinit(sizeof(struct ipc_tree_entry), 0,
ipc_tree_entry_max * sizeof(struct ipc_tree_entry),
sizeof(struct ipc_tree_entry),
IPC_ZONE_TYPE, "ipc tree entries");
ipc_object_zones[IOT_PORT] =
- zinit(sizeof(struct ipc_port),
+ zinit(sizeof(struct ipc_port), 0,
ipc_port_max * sizeof(struct ipc_port),
sizeof(struct ipc_port),
0, "ipc ports");
ipc_object_zones[IOT_PORT_SET] =
- zinit(sizeof(struct ipc_pset),
+ zinit(sizeof(struct ipc_pset), 0,
ipc_pset_max * sizeof(struct ipc_pset),
sizeof(struct ipc_pset),
IPC_ZONE_TYPE, "ipc port sets");
Index: ipc/ipc_marequest.c
===================================================================
RCS file: /sources/hurd/gnumach/ipc/ipc_marequest.c,v
retrieving revision 1.2.2.2
diff -u -p -r1.2.2.2 ipc_marequest.c
--- ipc/ipc_marequest.c 3 Dec 2006 20:16:16 -0000 1.2.2.2
+++ ipc/ipc_marequest.c 30 Dec 2006 10:42:26 -0000
@@ -143,7 +143,7 @@ ipc_marequest_init()
}
ipc_marequest_zone =
- zinit(sizeof(struct ipc_marequest),
+ zinit(sizeof(struct ipc_marequest), 0,
ipc_marequest_max * sizeof(struct ipc_marequest),
sizeof(struct ipc_marequest),
IPC_ZONE_TYPE, "ipc msg-accepted requests");
Index: kern/act.c
===================================================================
RCS file: /sources/hurd/gnumach/kern/act.c,v
retrieving revision 1.2.2.4
diff -u -p -r1.2.2.4 act.c
--- kern/act.c 3 Dec 2006 20:16:16 -0000 1.2.2.4
+++ kern/act.c 30 Dec 2006 10:42:27 -0000
@@ -69,7 +69,7 @@ global_act_init()
{
#ifndef ACT_STATIC_KLUDGE
act_zone = zinit(
- sizeof(struct Act),
+ sizeof(struct Act), 0,
ACT_MAX * sizeof(struct Act), /* XXX */
ACT_CHUNK * sizeof(struct Act),
0, "activations");
Index: kern/kalloc.c
===================================================================
RCS file: /sources/hurd/gnumach/kern/kalloc.c,v
retrieving revision 1.1.1.1.4.3
diff -u -p -r1.1.1.1.4.3 kalloc.c
--- kern/kalloc.c 10 Nov 2006 01:22:58 -0000 1.1.1.1.4.3
+++ kern/kalloc.c 30 Dec 2006 10:42:27 -0000
@@ -145,7 +145,7 @@ void kalloc_init()
if (size == MINSIZE) {
first_k_zone = i;
}
- k_zone[i] = zinit(size, k_zone_max[i] * size, size,
+ k_zone[i] = zinit(size, 0, k_zone_max[i] * size, size,
size >= PAGE_SIZE ? ZONE_COLLECTABLE : 0,
k_zone_name[i]);
}
Index: kern/processor.c
===================================================================
RCS file: /sources/hurd/gnumach/kern/processor.c,v
retrieving revision 1.2.2.4
diff -u -p -r1.2.2.4 processor.c
--- kern/processor.c 10 Nov 2006 01:22:58 -0000 1.2.2.4
+++ kern/processor.c 30 Dec 2006 10:42:27 -0000
@@ -113,7 +113,7 @@ void pset_sys_init(void)
/*
* Allocate the zone for processor sets.
*/
- pset_zone = zinit(sizeof(struct processor_set), 128*PAGE_SIZE,
+ pset_zone = zinit(sizeof(struct processor_set), 0, 128*PAGE_SIZE,
PAGE_SIZE, 0, "processor sets");
/*
Index: kern/task.c
===================================================================
RCS file: /sources/hurd/gnumach/kern/task.c,v
retrieving revision 1.3.4.6
diff -u -p -r1.3.4.6 task.c
--- kern/task.c 10 Nov 2006 01:22:59 -0000 1.3.4.6
+++ kern/task.c 30 Dec 2006 10:42:27 -0000
@@ -61,7 +61,7 @@ extern void eml_task_deallocate(task_t);
void task_init(void)
{
task_zone = zinit(
- sizeof(struct task),
+ sizeof(struct task), 0,
TASK_MAX * sizeof(struct task),
TASK_CHUNK * sizeof(struct task),
0, "tasks");
Index: kern/thread.c
===================================================================
RCS file: /sources/hurd/gnumach/kern/thread.c,v
retrieving revision 1.3.4.7
diff -u -p -r1.3.4.7 thread.c
--- kern/thread.c 12 Nov 2006 23:45:07 -0000 1.3.4.7
+++ kern/thread.c 30 Dec 2006 10:42:28 -0000
@@ -299,7 +299,7 @@ void stack_privilege(
void thread_init(void)
{
thread_zone = zinit(
- sizeof(struct thread),
+ sizeof(struct thread), 0,
THREAD_MAX * sizeof(struct thread),
THREAD_CHUNK * sizeof(struct thread),
0, "threads");
Index: kern/zalloc.c
===================================================================
RCS file: /sources/hurd/gnumach/kern/zalloc.c,v
retrieving revision 1.3.2.5
diff -u -p -r1.3.2.5 zalloc.c
--- kern/zalloc.c 10 Nov 2006 01:22:59 -0000 1.3.2.5
+++ kern/zalloc.c 30 Dec 2006 10:42:28 -0000
@@ -72,6 +72,9 @@ MACRO_BEGIN
\
} \
MACRO_END
+#define ALIGN_SIZE_UP(size, align) \
+((size) = (((size) + ((align) - 1)) & ~((align) - 1)))
+
/*
* Support for garbage collection of unused zone pages:
*/
@@ -146,7 +149,7 @@ MACRO_BEGIN \
} \
MACRO_END
-static vm_offset_t zget_space();
+static vm_offset_t zget_space(vm_offset_t size, vm_size_t align);
decl_simple_lock_data(,zget_space_lock)
vm_offset_t zalloc_next_space;
@@ -182,8 +185,9 @@ int num_zones;
* are stored in a zone, which is initially a static structure that
* is initialized by zone_init.
*/
-zone_t zinit(size, max, alloc, memtype, name)
+zone_t zinit(size, align, max, alloc, memtype, name)
vm_size_t size; /* the size of an element */
+ vm_size_t align; /* alignment of elements */
vm_size_t max; /* maximum memory to use */
vm_size_t alloc; /* allocation size */
unsigned int memtype; /* flags specifying type of memory */
@@ -192,12 +196,11 @@ zone_t zinit(size, max, alloc, memtype,
register zone_t z;
if (zone_zone == ZONE_NULL)
- z = (zone_t) zget_space(sizeof(struct zone));
+ z = (zone_t) zget_space(sizeof(struct zone), 0);
else
z = (zone_t) zalloc(zone_zone);
if (z == ZONE_NULL)
panic("zinit");
-
if (alloc == 0)
alloc = PAGE_SIZE;
@@ -210,11 +213,18 @@ zone_t zinit(size, max, alloc, memtype,
if ((max = round_page(max)) < (alloc = round_page(alloc)))
max = alloc;
+ if (align > 0) {
+ if (align >= PAGE_SIZE)
+ panic("zinit");
+ ALIGN_SIZE_UP(size, align);
+ }
+
z->free_elements = 0;
z->cur_size = 0;
z->max_size = max;
z->elem_size = ((size-1) + sizeof(z->free_elements)) -
((size-1) % sizeof(z->free_elements));
+ z->align = align;
z->alloc_size = alloc;
z->type = memtype;
@@ -268,13 +278,18 @@ void zcram(zone_t zone, vm_offset_t newm
* of memory from zone_map.
*/
-static vm_offset_t zget_space(vm_offset_t size)
+static vm_offset_t zget_space(vm_offset_t size, vm_size_t align)
{
vm_offset_t new_space = 0;
vm_offset_t result;
vm_size_t space_to_add = 0; /*'=0' to quiet gcc warnings */
simple_lock(&zget_space_lock);
+ if (align > 0) {
+ assert(align < PAGE_SIZE);
+ ALIGN_SIZE_UP(zalloc_next_space, align);
+ }
+
while ((zalloc_next_space + size) > zalloc_end_of_space) {
/*
* Add at least one page to allocation area.
@@ -359,7 +374,7 @@ void zone_bootstrap()
zalloc_wasted_space = 0;
zone_zone = ZONE_NULL;
- zone_zone = zinit(sizeof(struct zone), 128 * sizeof(struct zone),
+ zone_zone = zinit(sizeof(struct zone), 0, 128 * sizeof(struct zone),
sizeof(struct zone), 0, "zones");
}
@@ -487,7 +502,7 @@ vm_offset_t zalloc(zone_t zone)
zone_lock(zone);
REMOVE_FROM_ZONE(zone, addr, vm_offset_t);
} else {
- addr = zget_space(zone->elem_size);
+ addr = zget_space(zone->elem_size, zone->align);
if (addr == 0)
panic("zalloc: zone %s exhausted",
zone->zone_name);
Index: kern/zalloc.h
===================================================================
RCS file: /sources/hurd/gnumach/kern/zalloc.h,v
retrieving revision 1.2
diff -u -p -r1.2 zalloc.h
--- kern/zalloc.h 5 Apr 2001 06:39:20 -0000 1.2
+++ kern/zalloc.h 30 Dec 2006 10:42:28 -0000
@@ -59,6 +59,7 @@ struct zone {
vm_size_t cur_size; /* current memory utilization */
vm_size_t max_size; /* how large can this zone grow */
vm_size_t elem_size; /* size of an element */
+ vm_size_t align; /* alignment of elements */
vm_size_t alloc_size; /* size used for more memory */
boolean_t doing_alloc; /* is zone expanding now? */
char *zone_name; /* a name for the zone */
@@ -71,8 +72,8 @@ typedef struct zone *zone_t;
#define ZONE_NULL ((zone_t) 0)
/* Exported to everyone */
-zone_t zinit(vm_size_t size, vm_size_t max, vm_size_t alloc,
- unsigned int memtype, char *name);
+zone_t zinit(vm_size_t size, vm_size_t align, vm_size_t max,
+ vm_size_t alloc, unsigned int memtype, char *name);
vm_offset_t zalloc(zone_t zone);
vm_offset_t zget(zone_t zone);
void zfree(zone_t zone, vm_offset_t elem);
Index: vm/vm_external.c
===================================================================
RCS file: /sources/hurd/gnumach/vm/vm_external.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 vm_external.c
--- vm/vm_external.c 25 Feb 1997 21:28:36 -0000 1.1.1.1
+++ vm/vm_external.c 30 Dec 2006 10:42:30 -0000
@@ -142,16 +142,16 @@ void vm_external_module_initialize()
{
vm_size_t size = (vm_size_t) sizeof(struct vm_external);
- vm_external_zone = zinit(size, 16*1024*size, size,
+ vm_external_zone = zinit(size, 0, 16*1024*size, size,
0, "external page bitmaps");
- vm_object_small_existence_map_zone = zinit(SMALL_SIZE,
+ vm_object_small_existence_map_zone = zinit(SMALL_SIZE, 0,
round_page(LARGE_SIZE * SMALL_SIZE),
round_page(SMALL_SIZE),
ZONE_EXHAUSTIBLE,
"object small existence maps");
- vm_object_large_existence_map_zone = zinit(LARGE_SIZE,
+ vm_object_large_existence_map_zone = zinit(LARGE_SIZE, 0,
round_page(8 * LARGE_SIZE),
round_page(LARGE_SIZE),
ZONE_EXHAUSTIBLE,
Index: vm/vm_fault.c
===================================================================
RCS file: /sources/hurd/gnumach/vm/vm_fault.c,v
retrieving revision 1.3.2.5
diff -u -p -r1.3.2.5 vm_fault.c
--- vm/vm_fault.c 3 Dec 2006 21:50:21 -0000 1.3.2.5
+++ vm/vm_fault.c 30 Dec 2006 10:42:31 -0000
@@ -107,7 +107,7 @@ extern struct db_watchpoint *db_watchpoi
*/
void vm_fault_init()
{
- vm_fault_state_zone = zinit(sizeof(vm_fault_state_t),
+ vm_fault_state_zone = zinit(sizeof(vm_fault_state_t), 0,
THREAD_MAX * sizeof(vm_fault_state_t),
sizeof(vm_fault_state_t),
0, "vm fault state");
Index: vm/vm_map.c
===================================================================
RCS file: /sources/hurd/gnumach/vm/vm_map.c,v
retrieving revision 1.3.2.6
diff -u -p -r1.3.2.6 vm_map.c
--- vm/vm_map.c 11 Nov 2006 01:12:24 -0000 1.3.2.6
+++ vm/vm_map.c 30 Dec 2006 10:42:32 -0000
@@ -158,17 +158,17 @@ int kentry_count = 256; /* to
init ken
void vm_map_init()
{
- vm_map_zone = zinit((vm_size_t) sizeof(struct vm_map), 40*1024,
+ vm_map_zone = zinit((vm_size_t) sizeof(struct vm_map), 0, 40*1024,
PAGE_SIZE, 0, "maps");
vm_map_entry_zone = zinit((vm_size_t) sizeof(struct vm_map_entry),
- 1024*1024, PAGE_SIZE*5,
+ 0, 1024*1024, PAGE_SIZE*5,
0, "non-kernel map entries");
- vm_map_kentry_zone = zinit((vm_size_t) sizeof(struct vm_map_entry),
+ vm_map_kentry_zone = zinit((vm_size_t) sizeof(struct vm_map_entry), 0,
kentry_data_size, kentry_data_size,
ZONE_FIXED /* XXX */, "kernel map
entries");
vm_map_copy_zone = zinit((vm_size_t) sizeof(struct vm_map_copy),
- 16*1024, PAGE_SIZE, 0,
+ 0, 16*1024, PAGE_SIZE, 0,
"map copies");
/*
Index: vm/vm_object.c
===================================================================
RCS file: /sources/hurd/gnumach/vm/vm_object.c,v
retrieving revision 1.2.4.7
diff -u -p -r1.2.4.7 vm_object.c
--- vm/vm_object.c 10 Nov 2006 01:22:59 -0000 1.2.4.7
+++ vm/vm_object.c 30 Dec 2006 10:42:33 -0000
@@ -244,7 +244,7 @@ vm_object_t vm_object_allocate(
*/
void vm_object_bootstrap(void)
{
- vm_object_zone = zinit((vm_size_t) sizeof(struct vm_object),
+ vm_object_zone = zinit((vm_size_t) sizeof(struct vm_object), 0,
round_page(512*1024),
round_page(12*1024),
0, "objects");
Index: vm/vm_resident.c
===================================================================
RCS file: /sources/hurd/gnumach/vm/vm_resident.c,v
retrieving revision 1.7.4.7
diff -u -p -r1.7.4.7 vm_resident.c
--- vm/vm_resident.c 3 Dec 2006 21:50:21 -0000 1.7.4.7
+++ vm/vm_resident.c 30 Dec 2006 10:42:33 -0000
@@ -425,7 +425,7 @@ void pmap_startup(
*/
void vm_page_module_init(void)
{
- vm_page_zone = zinit((vm_size_t) sizeof(struct vm_page),
+ vm_page_zone = zinit((vm_size_t) sizeof(struct vm_page), 0,
VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS,
PAGE_SIZE,
0, "vm pages");