Rev 1483 | Rev 1587 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1483 | Rev 1495 | ||
---|---|---|---|
Line 134... | Line 134... | ||
134 | * the address space can be destroyed. |
134 | * the address space can be destroyed. |
135 | */ |
135 | */ |
136 | void as_destroy(as_t *as) |
136 | void as_destroy(as_t *as) |
137 | { |
137 | { |
138 | ipl_t ipl; |
138 | ipl_t ipl; |
139 | bool cond; |
139 | link_t *cur; |
140 | 140 | ||
141 | ASSERT(as->refcount == 0); |
141 | ASSERT(as->refcount == 0); |
142 | 142 | ||
143 | /* |
143 | /* |
144 | * Since there is no reference to this area, |
144 | * Since there is no reference to this area, |
Line 154... | Line 154... | ||
154 | spinlock_unlock(&inactive_as_with_asid_lock); |
154 | spinlock_unlock(&inactive_as_with_asid_lock); |
155 | 155 | ||
156 | /* |
156 | /* |
157 | * Destroy address space areas of the address space. |
157 | * Destroy address space areas of the address space. |
158 | */ |
158 | */ |
159 | for (cond = true; cond; ) { |
159 | for (cur = as->as_area_btree.leaf_head.next; cur != &as->as_area_btree.leaf_head; cur = cur->next) { |
160 | btree_node_t *node; |
160 | btree_node_t *node; |
- | 161 | int i; |
|
161 | 162 | ||
162 | ASSERT(!list_empty(&as->as_area_btree.leaf_head)); |
- | |
163 | node = list_get_instance(&as->as_area_btree.leaf_head.next, btree_node_t, leaf_link); |
163 | node = list_get_instance(cur, btree_node_t, leaf_link); |
164 | if ((cond = node->keys)) |
164 | for (i = 0; i < node->keys; i++) |
165 | as_area_destroy(as, node->key[0]); |
165 | as_area_destroy(as, node->key[i]); |
166 | } |
166 | } |
167 | 167 | ||
168 | btree_destroy(&as->as_area_btree); |
168 | btree_destroy(&as->as_area_btree); |
169 | page_table_destroy(as->page_table); |
169 | page_table_destroy(as->page_table); |
170 | 170 | ||
171 | interrupts_restore(ipl); |
171 | interrupts_restore(ipl); |
172 | 172 | ||
Line 408... | Line 408... | ||
408 | */ |
408 | */ |
409 | int as_area_destroy(as_t *as, __address address) |
409 | int as_area_destroy(as_t *as, __address address) |
410 | { |
410 | { |
411 | as_area_t *area; |
411 | as_area_t *area; |
412 | __address base; |
412 | __address base; |
- | 413 | link_t *cur; |
|
413 | ipl_t ipl; |
414 | ipl_t ipl; |
414 | bool cond; |
- | |
415 | 415 | ||
416 | ipl = interrupts_disable(); |
416 | ipl = interrupts_disable(); |
417 | mutex_lock(&as->lock); |
417 | mutex_lock(&as->lock); |
418 | 418 | ||
419 | area = find_area_and_lock(as, address); |
419 | area = find_area_and_lock(as, address); |
Line 430... | Line 430... | ||
430 | */ |
430 | */ |
431 | tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base, area->pages); |
431 | tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base, area->pages); |
432 | 432 | ||
433 | /* |
433 | /* |
434 | * Visit only the pages mapped by used_space B+tree. |
434 | * Visit only the pages mapped by used_space B+tree. |
435 | * Note that we must be very careful when walking the tree |
- | |
436 | * leaf list and removing used space as the leaf list changes |
- | |
437 | * unpredictibly after each remove. The solution is to actually |
- | |
438 | * not walk the tree at all, but to remove items from the head |
- | |
439 | * of the leaf list until there are some keys left. |
- | |
440 | */ |
435 | */ |
441 | for (cond = true; cond;) { |
436 | for (cur = area->used_space.leaf_head.next; cur != &area->used_space.leaf_head; cur = cur->next) { |
442 | btree_node_t *node; |
437 | btree_node_t *node; |
- | 438 | int i; |
|
443 | 439 | ||
444 | ASSERT(!list_empty(&area->used_space.leaf_head)); |
- | |
445 | node = list_get_instance(area->used_space.leaf_head.next, btree_node_t, leaf_link); |
440 | node = list_get_instance(cur, btree_node_t, leaf_link); |
446 | if ((cond = (bool) node->keys)) { |
441 | for (i = 0; i < node->keys; i++) { |
447 | __address b = node->key[0]; |
442 | __address b = node->key[i]; |
448 | count_t i; |
443 | count_t j; |
449 | pte_t *pte; |
444 | pte_t *pte; |
450 | 445 | ||
451 | for (i = 0; i < (count_t) node->value[0]; i++) { |
446 | for (j = 0; j < (count_t) node->value[i]; j++) { |
452 | page_table_lock(as, false); |
447 | page_table_lock(as, false); |
453 | pte = page_mapping_find(as, b + i*PAGE_SIZE); |
448 | pte = page_mapping_find(as, b + j*PAGE_SIZE); |
454 | ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte)); |
449 | ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte)); |
455 | if (area->backend && area->backend->frame_free) { |
450 | if (area->backend && area->backend->frame_free) { |
456 | area->backend->frame_free(area, |
451 | area->backend->frame_free(area, |
457 | b + i*PAGE_SIZE, PTE_GET_FRAME(pte)); |
452 | b + j*PAGE_SIZE, PTE_GET_FRAME(pte)); |
458 | } |
453 | } |
459 | page_mapping_remove(as, b + i*PAGE_SIZE); |
454 | page_mapping_remove(as, b + j*PAGE_SIZE); |
460 | page_table_unlock(as, false); |
455 | page_table_unlock(as, false); |
461 | } |
456 | } |
462 | } |
457 | } |
463 | } |
458 | } |
464 | 459 | ||
Line 1471... | Line 1466... | ||
1471 | 1466 | ||
1472 | mutex_lock(&sh_info->lock); |
1467 | mutex_lock(&sh_info->lock); |
1473 | ASSERT(sh_info->refcount); |
1468 | ASSERT(sh_info->refcount); |
1474 | if (--sh_info->refcount == 0) { |
1469 | if (--sh_info->refcount == 0) { |
1475 | dealloc = true; |
1470 | dealloc = true; |
1476 | bool cond; |
1471 | link_t *cur; |
1477 | 1472 | ||
1478 | /* |
1473 | /* |
1479 | * Now walk carefully the pagemap B+tree and free/remove |
1474 | * Now walk carefully the pagemap B+tree and free/remove |
1480 | * reference from all frames found there. |
1475 | * reference from all frames found there. |
1481 | */ |
1476 | */ |
1482 | for (cond = true; cond;) { |
1477 | for (cur = sh_info->pagemap.leaf_head.next; cur != &sh_info->pagemap.leaf_head; cur = cur->next) { |
1483 | btree_node_t *node; |
1478 | btree_node_t *node; |
- | 1479 | int i; |
|
1484 | 1480 | ||
1485 | ASSERT(!list_empty(&sh_info->pagemap.leaf_head)); |
- | |
1486 | node = list_get_instance(sh_info->pagemap.leaf_head.next, btree_node_t, leaf_link); |
1481 | node = list_get_instance(cur, btree_node_t, leaf_link); |
1487 | if ((cond = node->keys)) { |
1482 | for (i = 0; i < node->keys; i++) |
1488 | frame_free(ADDR2PFN((__address) node->value[0])); |
1483 | frame_free(ADDR2PFN((__address) node->value[i])); |
1489 | } |
- | |
1490 | } |
1484 | } |
1491 | 1485 | ||
1492 | } |
1486 | } |
1493 | mutex_unlock(&sh_info->lock); |
1487 | mutex_unlock(&sh_info->lock); |
1494 | 1488 |