summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergio Lopez <sergio.lopez@sinrega.org>2010-08-27 00:24:01 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2010-08-27 00:24:01 +0200
commita6eab640cacccec9b6ca18915c2bc6e4746df1e6 (patch)
tree80d0e9721fc31caefaa405d981ec96c2caee35cc
parent2a16fe6746b96aff3b54c36e02ad1628ecf0dd8e (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.c21
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: