Changeset 1068f6a in mainline for generic/src/mm/as.c
- Timestamp:
- 2006-05-20T19:32:06Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c1982e45
- Parents:
- 9ea6cc5
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/src/mm/as.c
r9ea6cc5 r1068f6a 55 55 #include <arch/mm/asid.h> 56 56 #include <synch/spinlock.h> 57 #include <synch/mutex.h> 57 58 #include <adt/list.h> 58 59 #include <adt/btree.h> … … 75 76 as_operations_t *as_operations = NULL; 76 77 77 /** Address space lock. It protects inactive_as_with_asid_head. */78 /** Address space lock. It protects inactive_as_with_asid_head. Must be acquired before as_t mutex. */ 78 79 SPINLOCK_INITIALIZE(as_lock); 79 80 … … 111 112 as = (as_t *) malloc(sizeof(as_t), 0); 112 113 link_initialize(&as->inactive_as_with_asid_link); 113 spinlock_initialize(&as->lock, "as_lock");114 mutex_initialize(&as->lock); 114 115 btree_create(&as->as_area_btree); 115 116 … … 163 164 164 165 ipl = interrupts_disable(); 165 spinlock_lock(&as->lock);166 mutex_lock(&as->lock); 166 167 167 168 if (!check_area_conflicts(as, base, size, NULL)) { 168 spinlock_unlock(&as->lock);169 mutex_unlock(&as->lock); 169 170 interrupts_restore(ipl); 170 171 return NULL; … … 173 174 a = (as_area_t *) malloc(sizeof(as_area_t), 0); 174 175 175 spinlock_initialize(&a->lock, "as_area_lock");176 mutex_initialize(&a->lock); 176 177 177 178 a->flags = flags; … … 182 183 btree_insert(&as->as_area_btree, base, (void *) a, NULL); 183 184 184 spinlock_unlock(&as->lock);185 mutex_unlock(&as->lock); 185 186 interrupts_restore(ipl); 186 187 … … 204 205 205 206 ipl = interrupts_disable(); 206 spinlock_lock(&as->lock);207 mutex_lock(&as->lock); 207 208 208 209 /* … … 211 212 area = find_area_and_lock(as, address); 212 213 if (!area) { 213 spinlock_unlock(&as->lock);214 mutex_unlock(&as->lock); 214 215 interrupts_restore(ipl); 215 216 return ENOENT; … … 221 222 * with memory mapped devices is not supported. 222 223 */ 223 spinlock_unlock(&area->lock);224 spinlock_unlock(&as->lock);224 mutex_unlock(&area->lock); 225 mutex_unlock(&as->lock); 225 226 interrupts_restore(ipl); 226 227 return ENOTSUP; … … 232 233 * Zero size address space areas are not allowed. 233 234 */ 234 spinlock_unlock(&area->lock);235 spinlock_unlock(&as->lock);235 mutex_unlock(&area->lock); 236 mutex_unlock(&as->lock); 236 237 interrupts_restore(ipl); 237 238 return EPERM; … … 279 280 */ 280 281 if (!check_area_conflicts(as, address, pages * PAGE_SIZE, area)) { 281 spinlock_unlock(&area->lock);282 spinlock_unlock(&as->lock);282 mutex_unlock(&area->lock); 283 mutex_unlock(&as->lock); 283 284 interrupts_restore(ipl); 284 285 return EADDRNOTAVAIL; … … 288 289 area->pages = pages; 289 290 290 spinlock_unlock(&area->lock);291 spinlock_unlock(&as->lock);291 mutex_unlock(&area->lock); 292 mutex_unlock(&as->lock); 292 293 interrupts_restore(ipl); 293 294 … … 310 311 311 312 ipl = interrupts_disable(); 312 spinlock_lock(&as->lock);313 mutex_lock(&as->lock); 313 314 314 315 area = find_area_and_lock(as, address); 315 316 if (!area) { 316 spinlock_unlock(&as->lock);317 mutex_unlock(&as->lock); 317 318 interrupts_restore(ipl); 318 319 return ENOENT; … … 351 352 352 353 area->attributes |= AS_AREA_ATTR_PARTIAL; 353 spinlock_unlock(&area->lock);354 mutex_unlock(&area->lock); 354 355 355 356 /* … … 360 361 free(area); 361 362 362 spinlock_unlock(&AS->lock);363 mutex_unlock(&AS->lock); 363 364 interrupts_restore(ipl); 364 365 return 0; … … 398 399 src_as = src_task->as; 399 400 400 spinlock_lock(&src_as->lock);401 mutex_lock(&src_as->lock); 401 402 src_area = find_area_and_lock(src_as, src_base); 402 403 if (!src_area) { … … 405 406 */ 406 407 spinlock_unlock(&src_task->lock); 407 spinlock_unlock(&src_as->lock);408 mutex_unlock(&src_as->lock); 408 409 interrupts_restore(ipl); 409 410 return ENOENT; … … 411 412 src_size = src_area->pages * PAGE_SIZE; 412 413 src_flags = src_area->flags; 413 spinlock_unlock(&src_area->lock);414 spinlock_unlock(&src_as->lock);414 mutex_unlock(&src_area->lock); 415 mutex_unlock(&src_as->lock); 415 416 416 417 … … 442 443 */ 443 444 if (AS < src_as) { 444 spinlock_lock(&AS->lock);445 spinlock_lock(&src_as->lock);445 mutex_lock(&AS->lock); 446 mutex_lock(&src_as->lock); 446 447 } else { 447 spinlock_lock(&AS->lock);448 spinlock_lock(&src_as->lock);448 mutex_lock(&AS->lock); 449 mutex_lock(&src_as->lock); 449 450 } 450 451 … … 476 477 * attribute. 477 478 */ 478 spinlock_lock(&dst_area->lock);479 mutex_lock(&dst_area->lock); 479 480 dst_area->attributes &= ~AS_AREA_ATTR_PARTIAL; 480 spinlock_unlock(&dst_area->lock);481 482 spinlock_unlock(&AS->lock);483 spinlock_unlock(&src_as->lock);481 mutex_unlock(&dst_area->lock); 482 483 mutex_unlock(&AS->lock); 484 mutex_unlock(&src_as->lock); 484 485 interrupts_restore(ipl); 485 486 … … 512 513 page_mapping_insert(as, page, frame, get_area_flags(area)); 513 514 514 spinlock_unlock(&area->lock);515 mutex_unlock(&area->lock); 515 516 page_table_unlock(as, true); 516 517 interrupts_restore(ipl); … … 533 534 __address frame; 534 535 536 if (!THREAD) 537 return 0; 538 535 539 ASSERT(AS); 536 540 537 spinlock_lock(&AS->lock);541 mutex_lock(&AS->lock); 538 542 area = find_area_and_lock(AS, page); 539 543 if (!area) { … … 542 546 * Signal page fault to low-level handler. 543 547 */ 544 spinlock_unlock(&AS->lock);548 mutex_unlock(&AS->lock); 545 549 goto page_fault; 546 550 } … … 551 555 * Avoid possible race by returning error. 552 556 */ 553 spinlock_unlock(&area->lock);554 spinlock_unlock(&AS->lock);557 mutex_unlock(&area->lock); 558 mutex_unlock(&AS->lock); 555 559 goto page_fault; 556 560 } … … 568 572 if (PTE_PRESENT(pte)) { 569 573 page_table_unlock(AS, false); 570 spinlock_unlock(&area->lock);571 spinlock_unlock(&AS->lock);574 mutex_unlock(&area->lock); 575 mutex_unlock(&AS->lock); 572 576 return 1; 573 577 } … … 599 603 page_table_unlock(AS, false); 600 604 601 spinlock_unlock(&area->lock);602 spinlock_unlock(&AS->lock);605 mutex_unlock(&area->lock); 606 mutex_unlock(&AS->lock); 603 607 return AS_PF_OK; 604 608 … … 622 626 /** Switch address spaces. 623 627 * 628 * Note that this function cannot sleep as it is essentially a part of 629 * the scheduling. Sleeping here would lead to deadlock on wakeup. 630 * 624 631 * @param old Old address space or NULL. 625 632 * @param new New address space. … … 637 644 */ 638 645 if (old) { 639 spinlock_lock(&old->lock);646 mutex_lock_active(&old->lock); 640 647 ASSERT(old->refcount); 641 648 if((--old->refcount == 0) && (old != AS_KERNEL)) { … … 649 656 list_append(&old->inactive_as_with_asid_link, &inactive_as_with_asid_head); 650 657 } 651 spinlock_unlock(&old->lock);658 mutex_unlock(&old->lock); 652 659 } 653 660 … … 655 662 * Second, prepare the new address space. 656 663 */ 657 spinlock_lock(&new->lock);664 mutex_lock_active(&new->lock); 658 665 if ((new->refcount++ == 0) && (new != AS_KERNEL)) { 659 666 if (new->asid != ASID_INVALID) … … 663 670 } 664 671 SET_PTL0_ADDRESS(new->page_table); 665 spinlock_unlock(&new->lock);672 mutex_unlock(&new->lock); 666 673 667 674 if (needs_asid) { … … 673 680 674 681 asid = asid_get(); 675 spinlock_lock(&new->lock);682 mutex_lock_active(&new->lock); 676 683 new->asid = asid; 677 spinlock_unlock(&new->lock);684 mutex_unlock(&new->lock); 678 685 } 679 686 spinlock_unlock(&as_lock); … … 799 806 if (a) { 800 807 /* va is the base address of an address space area */ 801 spinlock_lock(&a->lock);808 mutex_lock(&a->lock); 802 809 return a; 803 810 } … … 812 819 for (i = 0; i < leaf->keys; i++) { 813 820 a = (as_area_t *) leaf->value[i]; 814 spinlock_lock(&a->lock);821 mutex_lock(&a->lock); 815 822 if ((a->base <= va) && (va < a->base + a->pages * PAGE_SIZE)) { 816 823 return a; 817 824 } 818 spinlock_unlock(&a->lock);825 mutex_unlock(&a->lock); 819 826 } 820 827 … … 825 832 if ((lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf))) { 826 833 a = (as_area_t *) lnode->value[lnode->keys - 1]; 827 spinlock_lock(&a->lock);834 mutex_lock(&a->lock); 828 835 if (va < a->base + a->pages * PAGE_SIZE) { 829 836 return a; 830 837 } 831 spinlock_unlock(&a->lock);838 mutex_unlock(&a->lock); 832 839 } 833 840 … … 874 881 if ((node = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf))) { 875 882 a = (as_area_t *) node->value[node->keys - 1]; 876 spinlock_lock(&a->lock);883 mutex_lock(&a->lock); 877 884 if (overlaps(va, size, a->base, a->pages * PAGE_SIZE)) { 878 spinlock_unlock(&a->lock);885 mutex_unlock(&a->lock); 879 886 return false; 880 887 } 881 spinlock_unlock(&a->lock);888 mutex_unlock(&a->lock); 882 889 } 883 890 if ((node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf))) { 884 891 a = (as_area_t *) node->value[0]; 885 spinlock_lock(&a->lock);892 mutex_lock(&a->lock); 886 893 if (overlaps(va, size, a->base, a->pages * PAGE_SIZE)) { 887 spinlock_unlock(&a->lock);894 mutex_unlock(&a->lock); 888 895 return false; 889 896 } 890 spinlock_unlock(&a->lock);897 mutex_unlock(&a->lock); 891 898 } 892 899 … … 898 905 continue; 899 906 900 spinlock_lock(&a->lock);907 mutex_lock(&a->lock); 901 908 if (overlaps(va, size, a->base, a->pages * PAGE_SIZE)) { 902 spinlock_unlock(&a->lock);909 mutex_unlock(&a->lock); 903 910 return false; 904 911 } 905 spinlock_unlock(&a->lock);912 mutex_unlock(&a->lock); 906 913 } 907 914 … … 918 925 } 919 926 920 /** Return size of address space of current task pointed to by base*/927 /** Return size of the address space area with given base. */ 921 928 size_t as_get_size(__address base) 922 929 { … … 929 936 if (src_area){ 930 937 size = src_area->pages * PAGE_SIZE; 931 spinlock_unlock(&src_area->lock);938 mutex_unlock(&src_area->lock); 932 939 } else { 933 940 size = 0;
Note:
See TracChangeset
for help on using the changeset viewer.