Changes in kernel/generic/src/mm/as.c [826599a2:5df1963] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/as.c
r826599a2 r5df1963 520 520 } 521 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 565 522 /** Create address space area of common attributes. 566 523 * … … 572 529 * @param attrs Attributes of the area. 573 530 * @param backend Address space area backend. NULL if no backend is used. 574 * @param backend_data NULL or a pointer to custom backend data.531 * @param backend_data NULL or a pointer to an array holding two void *. 575 532 * @param base Starting virtual address of the area. 576 533 * If set to -1, a suitable mappable area is found. … … 609 566 } 610 567 611 if (overflows_into_positive(*base, size)) { 612 mutex_unlock(&as->lock); 568 if (overflows_into_positive(*base, size)) 613 569 return NULL; 614 }615 570 616 571 if (!check_area_conflicts(as, *base, pages, guarded, NULL)) { … … 629 584 area->resident = 0; 630 585 area->base = *base; 586 area->sh_info = NULL; 631 587 area->backend = backend; 632 area->sh_info = NULL;633 588 634 589 if (backend_data) … … 636 591 else 637 592 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 593 667 594 if (area->backend && area->backend->create) { 668 595 if (!area->backend->create(area)) { 669 596 free(area); 670 597 mutex_unlock(&as->lock); 671 if (!(attrs & AS_AREA_ATTR_PARTIAL))672 sh_info_remove_reference(si);673 598 return NULL; 674 599 } 675 600 } 676 601 677 602 btree_create(&area->used_space); 678 603 btree_insert(&as->as_area_btree, *base, (void *) area, … … 784 709 } 785 710 786 mutex_lock(&area->sh_info->lock); 787 if (area->sh_info->shared) { 711 if (area->sh_info) { 788 712 /* 789 713 * Remapping of shared address space areas 790 714 * is not supported. 791 715 */ 792 mutex_unlock(&area->sh_info->lock);793 716 mutex_unlock(&area->lock); 794 717 mutex_unlock(&as->lock); 795 718 return ENOTSUP; 796 719 } 797 mutex_unlock(&area->sh_info->lock);798 720 799 721 size_t pages = SIZE2FRAMES((address - area->base) + size); … … 959 881 } 960 882 883 /** Remove reference to address space area share info. 884 * 885 * If the reference count drops to 0, the sh_info is deallocated. 886 * 887 * @param sh_info Pointer to address space area share info. 888 * 889 */ 890 NO_TRACE static void sh_info_remove_reference(share_info_t *sh_info) 891 { 892 bool dealloc = false; 893 894 mutex_lock(&sh_info->lock); 895 ASSERT(sh_info->refcount); 896 897 if (--sh_info->refcount == 0) { 898 dealloc = true; 899 900 /* 901 * Now walk carefully the pagemap B+tree and free/remove 902 * reference from all frames found there. 903 */ 904 list_foreach(sh_info->pagemap.leaf_list, leaf_link, 905 btree_node_t, node) { 906 btree_key_t i; 907 908 for (i = 0; i < node->keys; i++) 909 frame_free((uintptr_t) node->value[i], 1); 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 961 921 /** Destroy address space area. 962 922 * … … 1040 1000 area->attributes |= AS_AREA_ATTR_PARTIAL; 1041 1001 1042 sh_info_remove_reference(area->sh_info); 1002 if (area->sh_info) 1003 sh_info_remove_reference(area->sh_info); 1043 1004 1044 1005 mutex_unlock(&area->lock); … … 1127 1088 */ 1128 1089 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) { 1090 if (!sh_info) { 1091 sh_info = (share_info_t *) malloc(sizeof(share_info_t), 0); 1092 mutex_initialize(&sh_info->lock, MUTEX_PASSIVE); 1093 sh_info->refcount = 2; 1094 btree_create(&sh_info->pagemap); 1095 src_area->sh_info = sh_info; 1096 1137 1097 /* 1138 1098 * Call the backend to setup sharing. 1139 * This only happens once for each sh_info.1140 1099 */ 1141 1100 src_area->backend->share(src_area); 1101 } else { 1102 mutex_lock(&sh_info->lock); 1103 sh_info->refcount++; 1104 mutex_unlock(&sh_info->lock); 1142 1105 } 1143 1106 … … 1258 1221 } 1259 1222 1260 if (area->backend != &anon_backend) { 1223 if ((area->sh_info) || (area->backend != &anon_backend)) { 1224 /* Copying shared areas not supported yet */ 1261 1225 /* Copying non-anonymous memory not supported yet */ 1262 1226 mutex_unlock(&area->lock); … … 1264 1228 return ENOTSUP; 1265 1229 } 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 1230 1277 1231 /* … … 1725 1679 ASSERT(count); 1726 1680 1727 btree_node_t *leaf = NULL;1681 btree_node_t *leaf; 1728 1682 size_t pages = (size_t) btree_search(&area->used_space, page, &leaf); 1729 1683 if (pages) { … … 1733 1687 return false; 1734 1688 } 1735 1736 ASSERT(leaf != NULL);1737 1689 1738 1690 if (!leaf->keys) {
Note:
See TracChangeset
for help on using the changeset viewer.