Changes in kernel/generic/src/mm/as.c [826599a2:908bb96] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/as.c
r826599a2 r908bb96 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++) { … … 520 522 } 521 523 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 524 /** Create address space area of common attributes. 566 525 * … … 572 531 * @param attrs Attributes of the area. 573 532 * @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 *. 575 534 * @param base Starting virtual address of the area. 576 535 * If set to -1, a suitable mappable area is found. … … 585 544 mem_backend_data_t *backend_data, uintptr_t *base, uintptr_t bound) 586 545 { 587 if ((*base != (uintptr_t) -1) && !IS_ALIGNED(*base, PAGE_SIZE))546 if ((*base != (uintptr_t) -1) && ((*base % PAGE_SIZE) != 0)) 588 547 return NULL; 589 548 … … 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, … … 761 688 int as_area_resize(as_t *as, uintptr_t address, size_t size, unsigned int flags) 762 689 { 763 if (!IS_ALIGNED(address, PAGE_SIZE))764 return EINVAL;765 766 690 mutex_lock(&as->lock); 767 691 … … 784 708 } 785 709 786 mutex_lock(&area->sh_info->lock); 787 if (area->sh_info->shared) { 710 if (area->sh_info) { 788 711 /* 789 712 * Remapping of shared address space areas 790 713 * is not supported. 791 714 */ 792 mutex_unlock(&area->sh_info->lock);793 715 mutex_unlock(&area->lock); 794 716 mutex_unlock(&as->lock); 795 717 return ENOTSUP; 796 718 } 797 mutex_unlock(&area->sh_info->lock);798 719 799 720 size_t pages = SIZE2FRAMES((address - area->base) + size); … … 959 880 } 960 881 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 */ 889 NO_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 961 921 /** Destroy address space area. 962 922 * … … 993 953 * Visit only the pages mapped by used_space B+tree. 994 954 */ 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; 997 957 btree_key_t i; 998 958 959 node = list_get_instance(cur, btree_node_t, leaf_link); 999 960 for (i = 0; i < node->keys; i++) { 1000 961 uintptr_t ptr = node->key[i]; … … 1040 1001 area->attributes |= AS_AREA_ATTR_PARTIAL; 1041 1002 1042 sh_info_remove_reference(area->sh_info); 1003 if (area->sh_info) 1004 sh_info_remove_reference(area->sh_info); 1043 1005 1044 1006 mutex_unlock(&area->lock); … … 1127 1089 */ 1128 1090 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 1137 1098 /* 1138 1099 * Call the backend to setup sharing. 1139 * This only happens once for each sh_info.1140 1100 */ 1141 1101 src_area->backend->share(src_area); 1102 } else { 1103 mutex_lock(&sh_info->lock); 1104 sh_info->refcount++; 1105 mutex_unlock(&sh_info->lock); 1142 1106 } 1143 1107 … … 1258 1222 } 1259 1223 1260 if (area->backend != &anon_backend) { 1224 if ((area->sh_info) || (area->backend != &anon_backend)) { 1225 /* Copying shared areas not supported yet */ 1261 1226 /* Copying non-anonymous memory not supported yet */ 1262 1227 mutex_unlock(&area->lock); … … 1264 1229 return ENOTSUP; 1265 1230 } 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 1231 1277 1232 /* … … 1280 1235 size_t used_pages = 0; 1281 1236 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); 1284 1240 btree_key_t i; 1285 1241 … … 1305 1261 size_t frame_idx = 0; 1306 1262 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); 1309 1266 btree_key_t i; 1310 1267 … … 1356 1313 frame_idx = 0; 1357 1314 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); 1360 1318 btree_key_t i; 1361 1319 … … 1392 1350 * Interrupts are assumed disabled. 1393 1351 * 1394 * @param address Faulting address.1395 * @param access 1396 * 1397 * @param istate 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. 1398 1356 * 1399 1357 * @return AS_PF_FAULT on page fault. … … 1403 1361 * 1404 1362 */ 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); 1363 int as_page_fault(uintptr_t page, pf_access_t access, istate_t *istate) 1364 { 1408 1365 int rc = AS_PF_FAULT; 1409 1366 … … 1495 1452 task_kill_self(true); 1496 1453 } 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); 1499 1456 } 1500 1457 … … 1722 1679 { 1723 1680 ASSERT(mutex_locked(&area->lock)); 1724 ASSERT( IS_ALIGNED(page, PAGE_SIZE));1681 ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE)); 1725 1682 ASSERT(count); 1726 1683 1727 btree_node_t *leaf = NULL;1684 btree_node_t *leaf; 1728 1685 size_t pages = (size_t) btree_search(&area->used_space, page, &leaf); 1729 1686 if (pages) { … … 1733 1690 return false; 1734 1691 } 1735 1736 ASSERT(leaf != NULL);1737 1692 1738 1693 if (!leaf->keys) { … … 2008 1963 { 2009 1964 ASSERT(mutex_locked(&area->lock)); 2010 ASSERT( IS_ALIGNED(page, PAGE_SIZE));1965 ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE)); 2011 1966 ASSERT(count); 2012 1967 … … 2185 2140 { 2186 2141 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, 2188 2143 AS_AREA_ATTR_NONE, &anon_backend, NULL, &virt, bound); 2189 2144 if (area == NULL) … … 2223 2178 size_t area_cnt = 0; 2224 2179 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); 2227 2183 area_cnt += node->keys; 2228 2184 } … … 2235 2191 size_t area_idx = 0; 2236 2192 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); 2239 2196 btree_key_t i; 2240 2197 … … 2270 2227 2271 2228 /* 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); 2274 2232 btree_key_t i; 2275 2233
Note:
See TracChangeset
for help on using the changeset viewer.