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