diff options
author | Sergio Lopez <sergio.lopez@sinrega.org> | 2010-08-27 00:24:01 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2010-08-27 00:24:01 +0200 |
commit | a6eab640cacccec9b6ca18915c2bc6e4746df1e6 (patch) | |
tree | 80d0e9721fc31caefaa405d981ec96c2caee35cc | |
parent | 2a16fe6746b96aff3b54c36e02ad1628ecf0dd8e (diff) |
make unblocked reads from external objects return a zeroed page.
* serverboot/default_pager.c (struct dstruct): Add boolean_t external field.
(default_pager_add): Set ds->external to TRUE or FALSE depending whether the
object is external.
(default_read): Add external parameter. If no_block(block) returns 1, if
external is TRUE, zero fill the page and return PAGER_SUCCESS instead of
PAGER_ABSENT.
(seqnos_memory_object_data_request): Pass ds->external as additional
parameter to default_read.
-rw-r--r-- | serverboot/default_pager.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/serverboot/default_pager.c b/serverboot/default_pager.c index aa7b0885..3a3f0e4f 100644 --- a/serverboot/default_pager.c +++ b/serverboot/default_pager.c @@ -1668,7 +1668,7 @@ ok: * if it is different from <addr>, it must be deallocated after use. */ int -default_read(ds, addr, size, offset, out_addr, deallocate) +default_read(ds, addr, size, offset, out_addr, deallocate, external) register dpager_t ds; vm_offset_t addr; /* pointer to block to fill */ register vm_size_t size; @@ -1676,6 +1676,7 @@ default_read(ds, addr, size, offset, out_addr, deallocate) vm_offset_t *out_addr; /* returns pointer to data */ boolean_t deallocate; + boolean_t external; { register union dp_map block; vm_offset_t raddr; @@ -1692,8 +1693,18 @@ default_read(ds, addr, size, offset, out_addr, deallocate) * Find the block in the paging partition */ block = pager_read_offset(ds, offset); - if ( no_block(block) ) + if ( no_block(block) ) { + if (external) { + /* + * An external object is requesting unswapped data, + * zero fill the page and return. + */ + bzero((char *) addr, vm_page_size); + *out_addr = addr; + return (PAGER_SUCCESS); + } return (PAGER_ABSENT); + } /* * Read it, trying for the entire page. @@ -1844,6 +1855,7 @@ struct dstruct { 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 */ @@ -2301,10 +2313,12 @@ void default_pager_add(ds, internal) /* possibly generate an immediate no-senders notification */ sync = 0; pset = default_pager_internal_set; + ds->external = FALSE; } else { /* delay notification till send right is created */ sync = 1; pset = default_pager_external_set; + ds->external = TRUE; } kr = mach_port_request_notification(default_pager_self, pager, @@ -2655,7 +2669,8 @@ ddprintf ("seqnos_memory_object_data_request <%p>: pager_port_unlock: <%p>[s:%d, else rc = default_read(&ds->dpager, dpt->dpt_buffer, vm_page_size, offset, - &addr, protection_required & VM_PROT_WRITE); + &addr, protection_required & VM_PROT_WRITE, + ds->external); switch (rc) { case PAGER_SUCCESS: |