Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/mm/as.c

    r826599a2 r908bb96  
    488488       
    489489        /* Eventually check the addresses behind each area */
    490         list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t, node) {
     490        list_foreach(as->as_area_btree.leaf_list, cur) {
     491                btree_node_t *node =
     492                    list_get_instance(cur, btree_node_t, leaf_link);
    491493               
    492494                for (btree_key_t i = 0; i < node->keys; i++) {
     
    520522}
    521523
    522 /** Remove reference to address space area share info.
    523  *
    524  * If the reference count drops to 0, the sh_info is deallocated.
    525  *
    526  * @param sh_info Pointer to address space area share info.
    527  *
    528  */
    529 NO_TRACE static void sh_info_remove_reference(share_info_t *sh_info)
    530 {
    531         bool dealloc = false;
    532        
    533         mutex_lock(&sh_info->lock);
    534         ASSERT(sh_info->refcount);
    535        
    536         if (--sh_info->refcount == 0) {
    537                 dealloc = true;
    538                
    539                 /*
    540                  * Now walk carefully the pagemap B+tree and free/remove
    541                  * reference from all frames found there.
    542                  */
    543                 list_foreach(sh_info->pagemap.leaf_list, leaf_link,
    544                     btree_node_t, node) {
    545                         btree_key_t i;
    546                        
    547                         for (i = 0; i < node->keys; i++)
    548                                 frame_free((uintptr_t) node->value[i], 1);
    549                 }
    550                
    551         }
    552         mutex_unlock(&sh_info->lock);
    553        
    554         if (dealloc) {
    555                 if (sh_info->backend && sh_info->backend->destroy_shared_data) {
    556                         sh_info->backend->destroy_shared_data(
    557                             sh_info->backend_shared_data);
    558                 }
    559                 btree_destroy(&sh_info->pagemap);
    560                 free(sh_info);
    561         }
    562 }
    563 
    564 
    565524/** Create address space area of common attributes.
    566525 *
     
    572531 * @param attrs        Attributes of the area.
    573532 * @param backend      Address space area backend. NULL if no backend is used.
    574  * @param backend_data NULL or a pointer to custom backend data.
     533 * @param backend_data NULL or a pointer to an array holding two void *.
    575534 * @param base         Starting virtual address of the area.
    576535 *                     If set to -1, a suitable mappable area is found.
     
    585544    mem_backend_data_t *backend_data, uintptr_t *base, uintptr_t bound)
    586545{
    587         if ((*base != (uintptr_t) -1) && !IS_ALIGNED(*base, PAGE_SIZE))
     546        if ((*base != (uintptr_t) -1) && ((*base % PAGE_SIZE) != 0))
    588547                return NULL;
    589548       
     
    609568        }
    610569
    611         if (overflows_into_positive(*base, size)) {
    612                 mutex_unlock(&as->lock);
     570        if (overflows_into_positive(*base, size))
    613571                return NULL;
    614         }
    615572
    616573        if (!check_area_conflicts(as, *base, pages, guarded, NULL)) {
     
    629586        area->resident = 0;
    630587        area->base = *base;
     588        area->sh_info = NULL;
    631589        area->backend = backend;
    632         area->sh_info = NULL;
    633590       
    634591        if (backend_data)
     
    636593        else
    637594                memsetb(&area->backend_data, sizeof(area->backend_data), 0);
    638 
    639         share_info_t *si = NULL;
    640 
    641         /*
    642          * Create the sharing info structure.
    643          * We do this in advance for every new area, even if it is not going
    644          * to be shared.
    645          */
    646         if (!(attrs & AS_AREA_ATTR_PARTIAL)) {
    647                 si = (share_info_t *) malloc(sizeof(share_info_t), 0);
    648                 mutex_initialize(&si->lock, MUTEX_PASSIVE);
    649                 si->refcount = 1;
    650                 si->shared = false;
    651                 si->backend_shared_data = NULL;
    652                 si->backend = backend;
    653                 btree_create(&si->pagemap);
    654 
    655                 area->sh_info = si;
    656        
    657                 if (area->backend && area->backend->create_shared_data) {
    658                         if (!area->backend->create_shared_data(area)) {
    659                                 free(area);
    660                                 mutex_unlock(&as->lock);
    661                                 sh_info_remove_reference(si);
    662                                 return NULL;
    663                         }
    664                 }
    665         }
    666 
     595       
    667596        if (area->backend && area->backend->create) {
    668597                if (!area->backend->create(area)) {
    669598                        free(area);
    670599                        mutex_unlock(&as->lock);
    671                         if (!(attrs & AS_AREA_ATTR_PARTIAL))
    672                                 sh_info_remove_reference(si);
    673600                        return NULL;
    674601                }
    675602        }
    676 
     603       
    677604        btree_create(&area->used_space);
    678605        btree_insert(&as->as_area_btree, *base, (void *) area,
     
    761688int as_area_resize(as_t *as, uintptr_t address, size_t size, unsigned int flags)
    762689{
    763         if (!IS_ALIGNED(address, PAGE_SIZE))
    764                 return EINVAL;
    765 
    766690        mutex_lock(&as->lock);
    767691       
     
    784708        }
    785709       
    786         mutex_lock(&area->sh_info->lock);
    787         if (area->sh_info->shared) {
     710        if (area->sh_info) {
    788711                /*
    789712                 * Remapping of shared address space areas
    790713                 * is not supported.
    791714                 */
    792                 mutex_unlock(&area->sh_info->lock);
    793715                mutex_unlock(&area->lock);
    794716                mutex_unlock(&as->lock);
    795717                return ENOTSUP;
    796718        }
    797         mutex_unlock(&area->sh_info->lock);
    798719       
    799720        size_t pages = SIZE2FRAMES((address - area->base) + size);
     
    959880}
    960881
     882/** Remove reference to address space area share info.
     883 *
     884 * If the reference count drops to 0, the sh_info is deallocated.
     885 *
     886 * @param sh_info Pointer to address space area share info.
     887 *
     888 */
     889NO_TRACE static void sh_info_remove_reference(share_info_t *sh_info)
     890{
     891        bool dealloc = false;
     892       
     893        mutex_lock(&sh_info->lock);
     894        ASSERT(sh_info->refcount);
     895       
     896        if (--sh_info->refcount == 0) {
     897                dealloc = true;
     898               
     899                /*
     900                 * Now walk carefully the pagemap B+tree and free/remove
     901                 * reference from all frames found there.
     902                 */
     903                list_foreach(sh_info->pagemap.leaf_list, cur) {
     904                        btree_node_t *node
     905                            = list_get_instance(cur, btree_node_t, leaf_link);
     906                        btree_key_t i;
     907                       
     908                        for (i = 0; i < node->keys; i++)
     909                                frame_free((uintptr_t) node->value[i]);
     910                }
     911               
     912        }
     913        mutex_unlock(&sh_info->lock);
     914       
     915        if (dealloc) {
     916                btree_destroy(&sh_info->pagemap);
     917                free(sh_info);
     918        }
     919}
     920
    961921/** Destroy address space area.
    962922 *
     
    993953         * Visit only the pages mapped by used_space B+tree.
    994954         */
    995         list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
    996             node) {
     955        list_foreach(area->used_space.leaf_list, cur) {
     956                btree_node_t *node;
    997957                btree_key_t i;
    998958               
     959                node = list_get_instance(cur, btree_node_t, leaf_link);
    999960                for (i = 0; i < node->keys; i++) {
    1000961                        uintptr_t ptr = node->key[i];
     
    10401001        area->attributes |= AS_AREA_ATTR_PARTIAL;
    10411002       
    1042         sh_info_remove_reference(area->sh_info);
     1003        if (area->sh_info)
     1004                sh_info_remove_reference(area->sh_info);
    10431005       
    10441006        mutex_unlock(&area->lock);
     
    11271089         */
    11281090        share_info_t *sh_info = src_area->sh_info;
    1129        
    1130         mutex_lock(&sh_info->lock);
    1131         sh_info->refcount++;
    1132         bool shared = sh_info->shared;
    1133         sh_info->shared = true;
    1134         mutex_unlock(&sh_info->lock);
    1135 
    1136         if (!shared) {
     1091        if (!sh_info) {
     1092                sh_info = (share_info_t *) malloc(sizeof(share_info_t), 0);
     1093                mutex_initialize(&sh_info->lock, MUTEX_PASSIVE);
     1094                sh_info->refcount = 2;
     1095                btree_create(&sh_info->pagemap);
     1096                src_area->sh_info = sh_info;
     1097               
    11371098                /*
    11381099                 * Call the backend to setup sharing.
    1139                  * This only happens once for each sh_info.
    11401100                 */
    11411101                src_area->backend->share(src_area);
     1102        } else {
     1103                mutex_lock(&sh_info->lock);
     1104                sh_info->refcount++;
     1105                mutex_unlock(&sh_info->lock);
    11421106        }
    11431107       
     
    12581222        }
    12591223       
    1260         if (area->backend != &anon_backend) {
     1224        if ((area->sh_info) || (area->backend != &anon_backend)) {
     1225                /* Copying shared areas not supported yet */
    12611226                /* Copying non-anonymous memory not supported yet */
    12621227                mutex_unlock(&area->lock);
     
    12641229                return ENOTSUP;
    12651230        }
    1266 
    1267         mutex_lock(&area->sh_info->lock);
    1268         if (area->sh_info->shared) {
    1269                 /* Copying shared areas not supported yet */
    1270                 mutex_unlock(&area->sh_info->lock);
    1271                 mutex_unlock(&area->lock);
    1272                 mutex_unlock(&as->lock);
    1273                 return ENOTSUP;
    1274         }
    1275         mutex_unlock(&area->sh_info->lock);
    12761231       
    12771232        /*
     
    12801235        size_t used_pages = 0;
    12811236       
    1282         list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
    1283             node) {
     1237        list_foreach(area->used_space.leaf_list, cur) {
     1238                btree_node_t *node
     1239                    = list_get_instance(cur, btree_node_t, leaf_link);
    12841240                btree_key_t i;
    12851241               
     
    13051261        size_t frame_idx = 0;
    13061262       
    1307         list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
    1308             node) {
     1263        list_foreach(area->used_space.leaf_list, cur) {
     1264                btree_node_t *node = list_get_instance(cur, btree_node_t,
     1265                    leaf_link);
    13091266                btree_key_t i;
    13101267               
     
    13561313        frame_idx = 0;
    13571314       
    1358         list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
    1359             node) {
     1315        list_foreach(area->used_space.leaf_list, cur) {
     1316                btree_node_t *node
     1317                    = list_get_instance(cur, btree_node_t, leaf_link);
    13601318                btree_key_t i;
    13611319               
     
    13921350 * Interrupts are assumed disabled.
    13931351 *
    1394  * @param address Faulting address.
    1395  * @param access  Access mode that caused the page fault (i.e.
    1396  *                read/write/exec).
    1397  * @param istate  Pointer to the interrupted state.
     1352 * @param page   Faulting page.
     1353 * @param access Access mode that caused the page fault (i.e.
     1354 *               read/write/exec).
     1355 * @param istate Pointer to the interrupted state.
    13981356 *
    13991357 * @return AS_PF_FAULT on page fault.
     
    14031361 *
    14041362 */
    1405 int as_page_fault(uintptr_t address, pf_access_t access, istate_t *istate)
    1406 {
    1407         uintptr_t page = ALIGN_DOWN(address, PAGE_SIZE);
     1363int as_page_fault(uintptr_t page, pf_access_t access, istate_t *istate)
     1364{
    14081365        int rc = AS_PF_FAULT;
    14091366
     
    14951452                task_kill_self(true);
    14961453        } else {
    1497                 fault_if_from_uspace(istate, "Page fault: %p.", (void *) address);
    1498                 panic_memtrap(istate, access, address, NULL);
     1454                fault_if_from_uspace(istate, "Page fault: %p.", (void *) page);
     1455                panic_memtrap(istate, access, page, NULL);
    14991456        }
    15001457       
     
    17221679{
    17231680        ASSERT(mutex_locked(&area->lock));
    1724         ASSERT(IS_ALIGNED(page, PAGE_SIZE));
     1681        ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
    17251682        ASSERT(count);
    17261683       
    1727         btree_node_t *leaf = NULL;
     1684        btree_node_t *leaf;
    17281685        size_t pages = (size_t) btree_search(&area->used_space, page, &leaf);
    17291686        if (pages) {
     
    17331690                return false;
    17341691        }
    1735 
    1736         ASSERT(leaf != NULL);
    17371692       
    17381693        if (!leaf->keys) {
     
    20081963{
    20091964        ASSERT(mutex_locked(&area->lock));
    2010         ASSERT(IS_ALIGNED(page, PAGE_SIZE));
     1965        ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
    20111966        ASSERT(count);
    20121967       
     
    21852140{
    21862141        uintptr_t virt = base;
    2187         as_area_t *area = as_area_create(AS, flags, size,
     2142        as_area_t *area = as_area_create(AS, flags | AS_AREA_CACHEABLE, size,
    21882143            AS_AREA_ATTR_NONE, &anon_backend, NULL, &virt, bound);
    21892144        if (area == NULL)
     
    22232178        size_t area_cnt = 0;
    22242179       
    2225         list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
    2226             node) {
     2180        list_foreach(as->as_area_btree.leaf_list, cur) {
     2181                btree_node_t *node =
     2182                    list_get_instance(cur, btree_node_t, leaf_link);
    22272183                area_cnt += node->keys;
    22282184        }
     
    22352191        size_t area_idx = 0;
    22362192       
    2237         list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
    2238             node) {
     2193        list_foreach(as->as_area_btree.leaf_list, cur) {
     2194                btree_node_t *node =
     2195                    list_get_instance(cur, btree_node_t, leaf_link);
    22392196                btree_key_t i;
    22402197               
     
    22702227       
    22712228        /* Print out info about address space areas */
    2272         list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
    2273             node) {
     2229        list_foreach(as->as_area_btree.leaf_list, cur) {
     2230                btree_node_t *node
     2231                    = list_get_instance(cur, btree_node_t, leaf_link);
    22742232                btree_key_t i;
    22752233               
Note: See TracChangeset for help on using the changeset viewer.