Ignore:
File:
1 edited

Legend:

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

    r83b6ba9f r59fb782  
    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++) {
     
    519521        return (uintptr_t) -1;
    520522}
    521 
    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 
    564523
    565524/** Create address space area of common attributes.
     
    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,
     
    784711        }
    785712       
    786         mutex_lock(&area->sh_info->lock);
    787         if (area->sh_info->shared) {
     713        if (area->sh_info) {
    788714                /*
    789715                 * Remapping of shared address space areas
    790716                 * is not supported.
    791717                 */
    792                 mutex_unlock(&area->sh_info->lock);
    793718                mutex_unlock(&area->lock);
    794719                mutex_unlock(&as->lock);
    795720                return ENOTSUP;
    796721        }
    797         mutex_unlock(&area->sh_info->lock);
    798722       
    799723        size_t pages = SIZE2FRAMES((address - area->base) + size);
     
    959883}
    960884
     885/** Remove reference to address space area share info.
     886 *
     887 * If the reference count drops to 0, the sh_info is deallocated.
     888 *
     889 * @param sh_info Pointer to address space area share info.
     890 *
     891 */
     892NO_TRACE static void sh_info_remove_reference(share_info_t *sh_info)
     893{
     894        bool dealloc = false;
     895       
     896        mutex_lock(&sh_info->lock);
     897        ASSERT(sh_info->refcount);
     898       
     899        if (--sh_info->refcount == 0) {
     900                dealloc = true;
     901               
     902                /*
     903                 * Now walk carefully the pagemap B+tree and free/remove
     904                 * reference from all frames found there.
     905                 */
     906                list_foreach(sh_info->pagemap.leaf_list, cur) {
     907                        btree_node_t *node
     908                            = list_get_instance(cur, btree_node_t, leaf_link);
     909                        btree_key_t i;
     910                       
     911                        for (i = 0; i < node->keys; i++)
     912                                frame_free((uintptr_t) node->value[i]);
     913                }
     914               
     915        }
     916        mutex_unlock(&sh_info->lock);
     917       
     918        if (dealloc) {
     919                btree_destroy(&sh_info->pagemap);
     920                free(sh_info);
     921        }
     922}
     923
    961924/** Destroy address space area.
    962925 *
     
    993956         * Visit only the pages mapped by used_space B+tree.
    994957         */
    995         list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
    996             node) {
     958        list_foreach(area->used_space.leaf_list, cur) {
     959                btree_node_t *node;
    997960                btree_key_t i;
    998961               
     962                node = list_get_instance(cur, btree_node_t, leaf_link);
    999963                for (i = 0; i < node->keys; i++) {
    1000964                        uintptr_t ptr = node->key[i];
     
    10401004        area->attributes |= AS_AREA_ATTR_PARTIAL;
    10411005       
    1042         sh_info_remove_reference(area->sh_info);
     1006        if (area->sh_info)
     1007                sh_info_remove_reference(area->sh_info);
    10431008       
    10441009        mutex_unlock(&area->lock);
     
    11271092         */
    11281093        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) {
     1094        if (!sh_info) {
     1095                sh_info = (share_info_t *) malloc(sizeof(share_info_t), 0);
     1096                mutex_initialize(&sh_info->lock, MUTEX_PASSIVE);
     1097                sh_info->refcount = 2;
     1098                btree_create(&sh_info->pagemap);
     1099                src_area->sh_info = sh_info;
     1100               
    11371101                /*
    11381102                 * Call the backend to setup sharing.
    1139                  * This only happens once for each sh_info.
    11401103                 */
    11411104                src_area->backend->share(src_area);
     1105        } else {
     1106                mutex_lock(&sh_info->lock);
     1107                sh_info->refcount++;
     1108                mutex_unlock(&sh_info->lock);
    11421109        }
    11431110       
     
    12581225        }
    12591226       
    1260         if (area->backend != &anon_backend) {
     1227        if ((area->sh_info) || (area->backend != &anon_backend)) {
     1228                /* Copying shared areas not supported yet */
    12611229                /* Copying non-anonymous memory not supported yet */
    12621230                mutex_unlock(&area->lock);
     
    12641232                return ENOTSUP;
    12651233        }
    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);
    12761234       
    12771235        /*
     
    12801238        size_t used_pages = 0;
    12811239       
    1282         list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
    1283             node) {
     1240        list_foreach(area->used_space.leaf_list, cur) {
     1241                btree_node_t *node
     1242                    = list_get_instance(cur, btree_node_t, leaf_link);
    12841243                btree_key_t i;
    12851244               
     
    13051264        size_t frame_idx = 0;
    13061265       
    1307         list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
    1308             node) {
     1266        list_foreach(area->used_space.leaf_list, cur) {
     1267                btree_node_t *node = list_get_instance(cur, btree_node_t,
     1268                    leaf_link);
    13091269                btree_key_t i;
    13101270               
     
    13561316        frame_idx = 0;
    13571317       
    1358         list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
    1359             node) {
     1318        list_foreach(area->used_space.leaf_list, cur) {
     1319                btree_node_t *node
     1320                    = list_get_instance(cur, btree_node_t, leaf_link);
    13601321                btree_key_t i;
    13611322               
     
    22212182        size_t area_cnt = 0;
    22222183       
    2223         list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
    2224             node) {
     2184        list_foreach(as->as_area_btree.leaf_list, cur) {
     2185                btree_node_t *node =
     2186                    list_get_instance(cur, btree_node_t, leaf_link);
    22252187                area_cnt += node->keys;
    22262188        }
     
    22332195        size_t area_idx = 0;
    22342196       
    2235         list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
    2236             node) {
     2197        list_foreach(as->as_area_btree.leaf_list, cur) {
     2198                btree_node_t *node =
     2199                    list_get_instance(cur, btree_node_t, leaf_link);
    22372200                btree_key_t i;
    22382201               
     
    22682231       
    22692232        /* Print out info about address space areas */
    2270         list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
    2271             node) {
     2233        list_foreach(as->as_area_btree.leaf_list, cur) {
     2234                btree_node_t *node
     2235                    = list_get_instance(cur, btree_node_t, leaf_link);
    22722236                btree_key_t i;
    22732237               
Note: See TracChangeset for help on using the changeset viewer.