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 /viengoos | |
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.
Diffstat (limited to 'viengoos')
-rw-r--r-- | viengoos/ChangeLog | 5 | ||||
-rw-r--r-- | viengoos/server.c | 114 |
2 files changed, 68 insertions, 51 deletions
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; } |