diff options
author | Neal H. Walfield <neal@gnu.org> | 2008-12-18 22:54:15 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@gnu.org> | 2008-12-18 22:54:15 +0100 |
commit | 207770cea7fece43bf5517fec7abd88a3a7d6146 (patch) | |
tree | 6f41abd1dc4782f34b339b00da956d0c778ef1b7 | |
parent | f5cfa7cbb8a2fff68cf87a3a685428507ce977b4 (diff) |
Support batching requests for object_discarded_clear.
libviengoos/
2008-12-18 Neal H. Walfield <neal@gnu.org>
* viengoos/cap.h (object_discarded_clear): Take additional
parameter count. Take multiple object addresses.
viengoos/
2008-12-18 Neal H. Walfield <neal@gnu.org>
* server.c (server_loop): Handle multiple objects in
object_discarded_clear.
libhurd-mm/
2008-12-18 Neal H. Walfield <neal@gnu.org>
* anonymous.c (fault): Batch object discard requests.
-rw-r--r-- | libhurd-mm/ChangeLog | 4 | ||||
-rw-r--r-- | libhurd-mm/anonymous.c | 66 | ||||
-rw-r--r-- | libviengoos/ChangeLog | 5 | ||||
-rw-r--r-- | libviengoos/viengoos/cap.h | 17 | ||||
-rw-r--r-- | viengoos/ChangeLog | 5 | ||||
-rw-r--r-- | viengoos/server.c | 114 |
6 files changed, 148 insertions, 63 deletions
diff --git a/libhurd-mm/ChangeLog b/libhurd-mm/ChangeLog index a74f7d7..3a9a35b 100644 --- a/libhurd-mm/ChangeLog +++ b/libhurd-mm/ChangeLog @@ -1,5 +1,9 @@ 2008-12-18 Neal H. Walfield <neal@gnu.org> + * anonymous.c (fault): Batch object discard requests. + +2008-12-18 Neal H. Walfield <neal@gnu.org> + * exceptions.c (hurd_activation_state_alloc): Cast UTCB to a void *. 2008-12-18 Neal H. Walfield <neal@gnu.org> diff --git a/libhurd-mm/anonymous.c b/libhurd-mm/anonymous.c index dac8309..a653ae2 100644 --- a/libhurd-mm/anonymous.c +++ b/libhurd-mm/anonymous.c @@ -229,6 +229,59 @@ fault (struct pager *pager, uintptr_t offset, int count, bool read_only, hurd_btree_storage_desc_t *storage_descs; storage_descs = (hurd_btree_storage_desc_t *) &anon->storage; + struct hurd_message_buffer *mb = NULL; + int discards = 0; + void queue_clear (vg_addr_t addr) + { + if (mb + && (VG_ADDR_IS_VOID (addr) + || vg_message_space (mb->request) < sizeof (vg_addr_t))) + { + hurd_activation_message_register (mb); + error_t err = vg_ipc (VG_IPC_RECEIVE | VG_IPC_SEND + | VG_IPC_RECEIVE_ACTIVATE + | VG_IPC_SEND_SET_THREAD_TO_CALLER + | VG_IPC_SEND_SET_ASROOT_TO_CALLERS + | VG_IPC_RECEIVE_SET_THREAD_TO_CALLER + | VG_IPC_RECEIVE_SET_ASROOT_TO_CALLERS, + VG_ADDR_VOID, + mb->receiver_strong, VG_ADDR_VOID, + VG_ADDR_VOID, VG_ADDR_VOID, + mb->sender, VG_ADDR_VOID); + if (err) + hurd_activation_message_unregister (mb); + else + { + int i; + err = vg_object_discarded_clear_reply_unmarshal (mb->reply, &i); + assert (! err); + assert (i == discards); + } + + hurd_message_buffer_free (mb); + mb = NULL; + discards = 0; + } + + if (VG_ADDR_IS_VOID (addr)) + return; + + if (! mb) + { + mb = hurd_message_buffer_alloc (); + + vg_object_discarded_clear_receive_marshal (mb->reply); + vg_object_discarded_clear_send_marshal (mb->request, addr, + mb->receiver); + discards = 1; + } + else + { + vg_message_append_data (mb->request, sizeof (addr), (void *) &addr); + discards ++; + } + } + int i; for (i = 0; i < count; i ++) { @@ -248,14 +301,11 @@ fault (struct pager *pager, uintptr_t offset, int count, bool read_only, assert (storage_desc); assert (anon->policy.discardable); - error_t err; /* We pass the fault address and not the underlying storage address as object_discarded_clear also returns a mapping and we are likely to access the data at the fault address. */ - err = vg_object_discarded_clear (VG_ADDR_VOID, VG_ADDR_VOID, - storage_desc->storage); - assertx (err == 0, "%d", err); + queue_clear (storage_desc->storage); debug (5, "Clearing discarded bit for %p / " VG_ADDR_FMT, (void *) fault_addr + i * PAGESIZE, @@ -300,8 +350,9 @@ fault (struct pager *pager, uintptr_t offset, int count, bool read_only, page.type = vg_cap_page; VG_CAP_POLICY_SET (&page, anon->policy); - vg_addr_t addr = vg_addr_chop (VG_PTR_TO_ADDR (fault_addr + i * PAGESIZE), - PAGESIZE_LOG2); + vg_addr_t addr + = vg_addr_chop (VG_PTR_TO_ADDR (fault_addr + i * PAGESIZE), + PAGESIZE_LOG2); as_ensure_use (addr, @@ -323,6 +374,9 @@ fault (struct pager *pager, uintptr_t offset, int count, bool read_only, 0, PAGESIZE_LOG2)); } + /* Flush any pending discards. */ + queue_clear (VG_ADDR_VOID); + #if 0 int faulted; for (i = 0; i < count; i += faulted) diff --git a/libviengoos/ChangeLog b/libviengoos/ChangeLog index 3006d73..180a7a4 100644 --- a/libviengoos/ChangeLog +++ b/libviengoos/ChangeLog @@ -1,5 +1,10 @@ 2008-12-18 Neal H. Walfield <neal@gnu.org> + * viengoos/cap.h (object_discarded_clear): Take additional + parameter count. Take multiple object addresses. + +2008-12-18 Neal H. Walfield <neal@gnu.org> + * viengoos/misc.h (vg_method_id_string): Handle VG_messenger_id. 2008-12-18 Neal H. Walfield <neal@gnu.org> diff --git a/libviengoos/viengoos/cap.h b/libviengoos/viengoos/cap.h index b456d34..50562d9 100644 --- a/libviengoos/viengoos/cap.h +++ b/libviengoos/viengoos/cap.h @@ -417,7 +417,7 @@ enum VG_CAP_COPY_PRIORITY_SET = 1 << 5, }; -/* Copy the capability in capability slot SOURCE to the slot at VG_ADDR +/* Copy the capability in capability slot SOURCE to the slot at ADDR in the object OBJECT. If OBJECT is VG_ADDR_VOID, then the calling thread's address space root is used. @@ -445,21 +445,26 @@ RPC(cap_copy, 5, 0, 0, cap_t, source_object, vg_addr_t, source_addr, uintptr_t, flags, struct vg_cap_properties, properties) -/* Overwrite the capability slot at VG_ADDR in the object OBJECT with a +/* Overwrite the capability slot at ADDR in the object OBJECT with a void capability. */ RPC(cap_rubout, 1, 0, 0, /* cap_t activity, cap_t object, */ vg_addr_t, addr) -/* Returns the public bits of the capability at address VG_ADDR in OBJECT +/* Returns the public bits of the capability at address ADDR in OBJECT in TYPE and VG_CAP_PROPERTIES. */ RPC(cap_read, 1, 2, 0, /* cap_t activity, cap_t object, */ vg_addr_t, addr, /* Out: */ uintptr_t, type, struct vg_cap_properties, properties) -/* Clear the discarded bit of the object at VG_ADDR in object OBJECT. */ -RPC(object_discarded_clear, 1, 0, 0, - /* cap_t activity, cap_t object, */ vg_addr_t, addr) +/* Clear the discarded bit of the objects at ADDR in object OBJECT. + Note: this function takes multiple addresses. Add further + addresses manually using vg_message_add. COUNT indicates the + number of objects successfully discarded. Stops after the first + error. */ +RPC(object_discarded_clear, 1, 1, 0, + /* cap_t activity, cap_t object, */ vg_addr_t, addr, + int, count) /* If the object designated by OBJECT is in memory, discard it. OBJECT must have write authority. This does not set the object's diff --git a/viengoos/ChangeLog b/viengoos/ChangeLog index d30da99..bc19cff 100644 --- a/viengoos/ChangeLog +++ b/viengoos/ChangeLog @@ -1,5 +1,10 @@ 2008-12-18 Neal H. Walfield <neal@gnu.org> + * server.c (server_loop): Handle multiple objects in + object_discarded_clear. + +2008-12-18 Neal H. Walfield <neal@gnu.org> + * server.c (server_loop): Set SLOT to 0, not TARGET. 2008-12-18 Neal H. Walfield <neal@gnu.org> diff --git a/viengoos/server.c b/viengoos/server.c index c1cdb90..e423c14 100644 --- a/viengoos/server.c +++ b/viengoos/server.c @@ -1449,71 +1449,83 @@ server_loop (void) DEBUG (4, VG_ADDR_FMT, VG_ADDR_PRINTF (object_addr)); - /* We can't look up the object use OBJECT as object_lookup - returns NULL if the object's discardable bit is set! - Instead, we lookup the capability, find the object's - folio and then clear its discarded bit. */ - struct vg_cap cap = CAP (&thread->aspace, object_addr, -1, true); - if (cap.type == vg_cap_void) - REPLY (ENOENT); - if (vg_cap_type_weak_p (cap.type)) - REPLY (EPERM); - - int idx = (cap.oid % (1 + VG_FOLIO_OBJECTS)) - 1; - vg_oid_t foid = cap.oid - idx - 1; + vg_addr_t *addr = (void *) vg_message_data (message) + + sizeof (uintptr_t); + int count = ((vg_message_data_count (message) - sizeof (uintptr_t)) + / sizeof (vg_addr_t)); + int i; + for (i = 0; i < count; i ++) + { + /* We can't look up the object use OBJECT as object_lookup + returns NULL if the object's discardable bit is set! + Instead, we lookup the capability, find the object's + folio and then clear its discarded bit. */ + struct vg_cap cap = CAP (target_root, addr[i], -1, true); + if (cap.type == vg_cap_void) + REPLY (ENOENT); + if (vg_cap_type_weak_p (cap.type)) + REPLY (EPERM); - struct vg_folio *folio = (struct vg_folio *) - object_find (activity, foid, VG_OBJECT_POLICY_VOID); + int idx = (cap.oid % (1 + VG_FOLIO_OBJECTS)) - 1; + vg_oid_t foid = cap.oid - idx - 1; - if (folio_object_version (folio, idx) != cap.version) - REPLY (ENOENT); + struct vg_folio *folio = (struct vg_folio *) + object_find (activity, foid, VG_OBJECT_POLICY_VOID); - bool was_discarded = folio_object_discarded (folio, idx); - folio_object_discarded_set (folio, idx, false); + if (folio_object_version (folio, idx) != cap.version) + REPLY (ENOENT); - vg_object_discarded_clear_reply (activity, reply); + bool was_discarded = folio_object_discarded (folio, idx); + folio_object_discarded_set (folio, idx, false); #if 0 - /* XXX: Surprisingly, it appears that this may be more - expensive than just faulting the pages normally. This - needs more investivation. */ - if (was_discarded - && cap.type == vg_cap_page - && VG_CAP_GUARD_BITS (&cap) == 0 - && (vg_addr_depth (object_addr) == VG_ADDR_BITS - PAGESIZE_LOG2)) - /* The target object was discarded, appears to be a page - and seems to be installed at a point where it would - appear in the hardware address space. If this is - really the case, then we can map it now and save a - fault later. */ - { - profile_region ("object_discard-prefault"); - - struct vg_object *page = vg_cap_to_object (principal, &cap); - if (page) + /* XXX: Surprisingly, it appears that this may be more + expensive than just faulting the pages normally. This + needs more investigation. */ + if (target == thread + && was_discarded + && cap.type == vg_cap_page + && VG_CAP_GUARD_BITS (&cap) == 0 + && (vg_addr_depth (object_addr) + == VG_ADDR_BITS - PAGESIZE_LOG2)) + /* The target object was discarded, appears to be a page + and seems to be installed at a point where it would + appear in the hardware address space. If this is + really the case, then we can map it now and save a + fault later. */ { - object_to_object_desc (page)->mapped = true; + profile_region ("object_discard-prefault"); - l4_fpage_t fpage = l4_fpage ((uintptr_t) page, PAGESIZE); - fpage = l4_fpage_add_rights (fpage, - L4_FPAGE_READABLE - | L4_FPAGE_WRITABLE); + struct vg_object *page = vg_cap_to_object (principal, &cap); + if (page) + { + object_to_object_desc (page)->mapped = true; - uintptr_t page_addr = vg_addr_prefix (object_addr); + l4_fpage_t fpage = l4_fpage ((uintptr_t) page, + PAGESIZE); + fpage = l4_fpage_add_rights (fpage, + L4_FPAGE_READABLE + | L4_FPAGE_WRITABLE); - l4_map_item_t map_item = l4_map_item (fpage, page_addr); + uintptr_t page_addr = vg_addr_prefix (object_addr); - l4_msg_append_map_item (msg, map_item); + l4_map_item_t map_item = l4_map_item (fpage, page_addr); - DEBUG (4, "Prefaulting "VG_ADDR_FMT"(%x) <- %p (%x/%x/%x)", - VG_ADDR_PRINTF (object_addr), page_addr, - page, l4_address (fpage), l4_size (fpage), - l4_rights (fpage)); - } + l4_msg_append_map_item (msg, map_item); - profile_region_end (); - } + DEBUG (4, "Prefaulting "VG_ADDR_FMT + "(%x) <- %p (%x/%x/%x)", + VG_ADDR_PRINTF (object_addr), page_addr, + page, l4_address (fpage), l4_size (fpage), + l4_rights (fpage)); + } + + profile_region_end (); + } #endif + } + + vg_object_discarded_clear_reply (activity, reply, i); break; } |