Changes in kernel/generic/src/mm/as.c [83b6ba9f:59fb782] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/as.c
r83b6ba9f r59fb782 488 488 489 489 /* 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); 491 493 492 494 for (btree_key_t i = 0; i < node->keys; i++) { … … 519 521 return (uintptr_t) -1; 520 522 } 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/remove541 * 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 523 565 524 /** Create address space area of common attributes. … … 609 568 } 610 569 611 if (overflows_into_positive(*base, size)) { 612 mutex_unlock(&as->lock); 570 if (overflows_into_positive(*base, size)) 613 571 return NULL; 614 }615 572 616 573 if (!check_area_conflicts(as, *base, pages, guarded, NULL)) { … … 629 586 area->resident = 0; 630 587 area->base = *base; 588 area->sh_info = NULL; 631 589 area->backend = backend; 632 area->sh_info = NULL;633 590 634 591 if (backend_data) … … 636 593 else 637 594 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 667 596 if (area->backend && area->backend->create) { 668 597 if (!area->backend->create(area)) { 669 598 free(area); 670 599 mutex_unlock(&as->lock); 671 if (!(attrs & AS_AREA_ATTR_PARTIAL))672 sh_info_remove_reference(si);673 600 return NULL; 674 601 } 675 602 } 676 603 677 604 btree_create(&area->used_space); 678 605 btree_insert(&as->as_area_btree, *base, (void *) area, … … 784 711 } 785 712 786 mutex_lock(&area->sh_info->lock); 787 if (area->sh_info->shared) { 713 if (area->sh_info) { 788 714 /* 789 715 * Remapping of shared address space areas 790 716 * is not supported. 791 717 */ 792 mutex_unlock(&area->sh_info->lock);793 718 mutex_unlock(&area->lock); 794 719 mutex_unlock(&as->lock); 795 720 return ENOTSUP; 796 721 } 797 mutex_unlock(&area->sh_info->lock);798 722 799 723 size_t pages = SIZE2FRAMES((address - area->base) + size); … … 959 883 } 960 884 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 */ 892 NO_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 961 924 /** Destroy address space area. 962 925 * … … 993 956 * Visit only the pages mapped by used_space B+tree. 994 957 */ 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; 997 960 btree_key_t i; 998 961 962 node = list_get_instance(cur, btree_node_t, leaf_link); 999 963 for (i = 0; i < node->keys; i++) { 1000 964 uintptr_t ptr = node->key[i]; … … 1040 1004 area->attributes |= AS_AREA_ATTR_PARTIAL; 1041 1005 1042 sh_info_remove_reference(area->sh_info); 1006 if (area->sh_info) 1007 sh_info_remove_reference(area->sh_info); 1043 1008 1044 1009 mutex_unlock(&area->lock); … … 1127 1092 */ 1128 1093 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 1137 1101 /* 1138 1102 * Call the backend to setup sharing. 1139 * This only happens once for each sh_info.1140 1103 */ 1141 1104 src_area->backend->share(src_area); 1105 } else { 1106 mutex_lock(&sh_info->lock); 1107 sh_info->refcount++; 1108 mutex_unlock(&sh_info->lock); 1142 1109 } 1143 1110 … … 1258 1225 } 1259 1226 1260 if (area->backend != &anon_backend) { 1227 if ((area->sh_info) || (area->backend != &anon_backend)) { 1228 /* Copying shared areas not supported yet */ 1261 1229 /* Copying non-anonymous memory not supported yet */ 1262 1230 mutex_unlock(&area->lock); … … 1264 1232 return ENOTSUP; 1265 1233 } 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);1276 1234 1277 1235 /* … … 1280 1238 size_t used_pages = 0; 1281 1239 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); 1284 1243 btree_key_t i; 1285 1244 … … 1305 1264 size_t frame_idx = 0; 1306 1265 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); 1309 1269 btree_key_t i; 1310 1270 … … 1356 1316 frame_idx = 0; 1357 1317 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); 1360 1321 btree_key_t i; 1361 1322 … … 2221 2182 size_t area_cnt = 0; 2222 2183 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); 2225 2187 area_cnt += node->keys; 2226 2188 } … … 2233 2195 size_t area_idx = 0; 2234 2196 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); 2237 2200 btree_key_t i; 2238 2201 … … 2268 2231 2269 2232 /* 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); 2272 2236 btree_key_t i; 2273 2237
Note:
See TracChangeset
for help on using the changeset viewer.