int aspace_map_region_anywhere( id_t id, vaddr_t * start, size_t extent, vmflags_t flags, vmpagesize_t pagesz, const char * name, paddr_t pmem ) { int status; retry: if ((status = aspace_find_hole(id, 0, extent, pagesz, start))) return status; if ((status = aspace_add_region(id, *start, extent, flags, pagesz, name))) { if (status == -ENOTUNIQ) goto retry; /* we lost a race with someone */ return status; } if ((status = aspace_map_pmem(id, pmem, *start, extent))) { aspace_del_region(id, *start, extent); return status; } return 0; }
static void __xpmem_detach_att(struct xpmem_access_permit * ap, struct xpmem_attachment * att) { aspace_mapping_t mapping; int status, index; /* No address space to update on remote attachments - they are purely for bookkeeping */ if (!(att->flags & XPMEM_FLAG_REMOTE)) { /* Lookup aspace mapping */ status = aspace_lookup_mapping(ap->tg->aspace->id, att->at_vaddr, &mapping); if (status != 0) { XPMEM_ERR("aspace_lookup_mapping() failed (%d)", status); return; } /* On shadow attachments, we added a new aspace region. Remove it now */ if (ap->seg->flags & XPMEM_FLAG_SHADOW) { BUG_ON(mapping.flags & VM_SMARTMAP); /* Remove aspace mapping */ status = aspace_del_region(ap->tg->aspace->id, mapping.start, mapping.end - mapping.start); if (status != 0) { XPMEM_ERR("aspace_del_region() failed (%d)", status); return; } /* Perform remote detachment */ xpmem_detach_remote(xpmem_my_part->domain_link, ap->seg->segid, ap->seg->remote_apid, att->at_vaddr); } else { /* If this was a real attachment, it should be using SMARTMAP */ BUG_ON(!(mapping.flags & VM_SMARTMAP)); } /* Remove from att hash list - only done on local memory */ index = xpmem_att_hashtable_index(att->at_vaddr); write_lock(&ap->tg->att_hashtable[index].lock); list_del(&att->att_hashnode); write_unlock(&ap->tg->att_hashtable[index].lock); } /* Remove from ap list */ spin_lock(&ap->lock); list_del_init(&att->att_node); spin_unlock(&ap->lock); }
static void unmap( void* ptr, size_t extent ) { id_t my_id; int status; // Debug1( "ptr=%p extent=%#lx\n", ptr, extent ); if ( ( status = aspace_get_myid( &my_id ) ) ) { printf("ERROR: aspace_get_myid() status=%d\n", status); return; } if ( ( status = aspace_unmap_pmem( my_id, (vaddr_t) ptr, extent ) ) ) { printf("ERROR: aspace_unmap_pmem() status=%d\n", status); } if ( ( status = aspace_del_region( my_id, (vaddr_t) ptr, extent) ) ) { printf("ERROR: aspace_del_region() status=%d\n", status); } }
int aspace_map_region( id_t id, vaddr_t start, size_t extent, vmflags_t flags, vmpagesize_t pagesz, const char * name, paddr_t pmem ) { int status; if ((status = aspace_add_region(id, start, extent, flags, pagesz, name))) return status; if ((status = aspace_map_pmem(id, pmem, start, extent))) { aspace_del_region(id, start, extent); return status; } return 0; }
/* * Attach a remote XPMEM address segment */ static int xpmem_try_attach_remote(xpmem_segid_t segid, xpmem_apid_t apid, off_t offset, size_t size, vaddr_t * vaddr) { int status = 0; vaddr_t at_vaddr = 0; /* Find free address space */ status = aspace_find_hole(current->aspace->id, 0, size, PAGE_SIZE, &at_vaddr); if (status != 0) { XPMEM_ERR("aspace_find_hole() failed (%d)", status); return status; } /* Add region to aspace */ status = aspace_add_region(current->aspace->id, at_vaddr, size, VM_READ | VM_WRITE | VM_USER, PAGE_SIZE, "xpmem"); if (status != 0) { XPMEM_ERR("aspace_add_region() failed (%d)", status); return status; } /* Attach to remote memory */ status = xpmem_attach_remote(xpmem_my_part->domain_link, segid, apid, offset, size, (u64)at_vaddr); if (status != 0) { XPMEM_ERR("xpmem_attach_remote() failed (%d)", status); aspace_del_region(current->aspace->id, at_vaddr, size); return status; } *vaddr = at_vaddr; return 0; }
static void* map( paddr_t paddr, size_t extent ) { id_t my_id; int status; vaddr_t vstart; // Debug1( "paddr=%#lx extent=%#lx\n", paddr, extent ); if ( ( status = aspace_get_myid( &my_id ) ) ) { printf("ERROR: aspace_get_myid() status=%d\n", status); return (void*) -1; } if ( ( status = aspace_find_hole( my_id, 0, extent, PAGE_SIZE, &vstart ) ) ) { printf("ERROR: aspace_find_hole() status=%d\n", status); return (void*) -1; } // Debug1("vstart=%#lx\n",vstart); if ( ( status = aspace_add_region( my_id, vstart, extent, VM_READ | VM_WRITE | VM_USER, PAGE_SIZE, "application") ) ) { printf("ERROR: aspace_add_region() status=%d\n", status); return (void*) -1; } if ( ( status = aspace_map_pmem( my_id, paddr, vstart, extent ) ) ) { printf("ERROR: aspace_map_pmem() status=%d\n", status); aspace_del_region( my_id, vstart, extent ); return (void*) -1; } // Debug1( "paddr=%#lx vstart=%#lx len=%#lx\n", paddr, vstart, extent ); return (void*) vstart; }