* Replace an existing page in the trie with another one. * Panics if there is not an old page in the trie at the new page's index. */
| 839 | * Panics if there is not an old page in the trie at the new page's index. |
| 840 | */ |
| 841 | vm_page_t |
| 842 | vm_radix_replace(struct vm_radix *rtree, vm_page_t newpage) |
| 843 | { |
| 844 | struct vm_radix_node *rnode, *tmp; |
| 845 | vm_page_t m; |
| 846 | vm_pindex_t index; |
| 847 | int slot; |
| 848 | |
| 849 | index = newpage->pindex; |
| 850 | rnode = vm_radix_root_load(rtree, LOCKED); |
| 851 | if (rnode == NULL) |
| 852 | panic("%s: replacing page on an empty trie", __func__); |
| 853 | if (vm_radix_isleaf(rnode)) { |
| 854 | m = vm_radix_topage(rnode); |
| 855 | if (m->pindex != index) |
| 856 | panic("%s: original replacing root key not found", |
| 857 | __func__); |
| 858 | rtree->rt_root = (uintptr_t)newpage | VM_RADIX_ISLEAF; |
| 859 | return (m); |
| 860 | } |
| 861 | for (;;) { |
| 862 | slot = vm_radix_slot(index, rnode->rn_clev); |
| 863 | tmp = vm_radix_node_load(&rnode->rn_child[slot], LOCKED); |
| 864 | if (vm_radix_isleaf(tmp)) { |
| 865 | m = vm_radix_topage(tmp); |
| 866 | if (m->pindex == index) { |
| 867 | vm_radix_node_store(&rnode->rn_child[slot], |
| 868 | (struct vm_radix_node *)((uintptr_t)newpage | |
| 869 | VM_RADIX_ISLEAF), LOCKED); |
| 870 | return (m); |
| 871 | } else |
| 872 | break; |
| 873 | } else if (tmp == NULL || vm_radix_keybarr(tmp, index)) |
| 874 | break; |
| 875 | rnode = tmp; |
| 876 | } |
| 877 | panic("%s: original replacing page not found", __func__); |
| 878 | } |
| 879 | |
| 880 | void |
| 881 | vm_radix_wait(void) |
no test coverage detected