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