Changes in kernel/genarch/src/mm/page_ht.c [fb63c06:82cbf8c6] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/mm/page_ht.c
rfb63c06 r82cbf8c6 48 48 #include <synch/spinlock.h> 49 49 #include <arch.h> 50 #include < debug.h>51 #include < memstr.h>50 #include <assert.h> 51 #include <adt/hash.h> 52 52 #include <adt/hash_table.h> 53 53 #include <align.h> 54 54 55 static size_t hash(sysarg_t[]); 56 static bool compare(sysarg_t[], size_t, link_t *); 57 static void remove_callback(link_t *); 55 static size_t ht_hash(const ht_link_t *); 56 static size_t ht_key_hash(void *); 57 static bool ht_key_equal(void *, const ht_link_t *); 58 static void ht_remove_callback(ht_link_t *); 58 59 59 60 static void ht_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int); … … 81 82 82 83 /** Hash table operations for page hash table. */ 83 hash_table_operations_t ht_operations = { 84 .hash = hash, 85 .compare = compare, 86 .remove_callback = remove_callback 84 hash_table_ops_t ht_ops = { 85 .hash = ht_hash, 86 .key_hash = ht_key_hash, 87 .key_equal = ht_key_equal, 88 .remove_callback = ht_remove_callback 87 89 }; 88 90 … … 96 98 }; 97 99 98 /** Compute page hash table index. 99 * 100 * @param key Array of two keys (i.e. page and address space). 101 * 102 * @return Index into page hash table. 103 * 104 */ 105 size_t hash(sysarg_t key[]) 106 { 107 as_t *as = (as_t *) key[KEY_AS]; 108 uintptr_t page = (uintptr_t) key[KEY_PAGE]; 109 110 /* 111 * Virtual page addresses have roughly the same probability 112 * of occurring. Least significant bits of VPN compose the 113 * hash index. 114 * 115 */ 116 size_t index = ((page >> PAGE_WIDTH) & (PAGE_HT_ENTRIES - 1)); 117 118 /* 119 * Address space structures are likely to be allocated from 120 * similar addresses. Least significant bits compose the 121 * hash index. 122 * 123 */ 124 index |= ((sysarg_t) as) & (PAGE_HT_ENTRIES - 1); 125 126 return index; 127 } 128 129 /** Compare page hash table item with page and/or address space. 130 * 131 * @param key Array of one or two keys (i.e. page and/or address space). 132 * @param keys Number of keys passed. 133 * @param item Item to compare the keys with. 134 * 135 * @return true on match, false otherwise. 136 * 137 */ 138 bool compare(sysarg_t key[], size_t keys, link_t *item) 139 { 140 ASSERT(item); 141 ASSERT(keys > 0); 142 ASSERT(keys <= PAGE_HT_KEYS); 143 144 /* 145 * Convert item to PTE. 146 * 147 */ 148 pte_t *pte = hash_table_get_instance(item, pte_t, link); 149 150 if (keys == PAGE_HT_KEYS) 151 return (key[KEY_AS] == (uintptr_t) pte->as) && 152 (key[KEY_PAGE] == pte->page); 153 154 return (key[KEY_AS] == (uintptr_t) pte->as); 100 /** Return the hash of the key stored in the item */ 101 size_t ht_hash(const ht_link_t *item) 102 { 103 pte_t *pte = hash_table_get_inst(item, pte_t, link); 104 size_t hash = 0; 105 hash = hash_combine(hash, (uintptr_t) pte->as); 106 hash = hash_combine(hash, pte->page >> PAGE_WIDTH); 107 return hash; 108 } 109 110 /** Return the hash of the key. */ 111 size_t ht_key_hash(void *arg) 112 { 113 uintptr_t *key = (uintptr_t *) arg; 114 size_t hash = 0; 115 hash = hash_combine(hash, key[KEY_AS]); 116 hash = hash_combine(hash, key[KEY_PAGE] >> PAGE_WIDTH); 117 return hash; 118 } 119 120 /** Return true if the key is equal to the item's lookup key. */ 121 bool ht_key_equal(void *arg, const ht_link_t *item) 122 { 123 uintptr_t *key = (uintptr_t *) arg; 124 pte_t *pte = hash_table_get_inst(item, pte_t, link); 125 return (key[KEY_AS] == (uintptr_t) pte->as) && 126 (key[KEY_PAGE] == pte->page); 155 127 } 156 128 … … 160 132 * 161 133 */ 162 void remove_callback(link_t *item) 163 { 164 ASSERT(item); 165 166 /* 167 * Convert item to PTE. 168 * 169 */ 170 pte_t *pte = hash_table_get_instance(item, pte_t, link); 171 134 void ht_remove_callback(ht_link_t *item) 135 { 136 assert(item); 137 138 pte_t *pte = hash_table_get_inst(item, pte_t, link); 172 139 slab_free(pte_cache, pte); 173 140 } … … 187 154 unsigned int flags) 188 155 { 189 sysarg_t key[2] = {190 (uintptr_t) as,191 page= ALIGN_DOWN(page, PAGE_SIZE)156 uintptr_t key[2] = { 157 [KEY_AS] = (uintptr_t) as, 158 [KEY_PAGE] = ALIGN_DOWN(page, PAGE_SIZE) 192 159 }; 193 160 194 ASSERT(page_table_locked(as));161 assert(page_table_locked(as)); 195 162 196 163 irq_spinlock_lock(&page_ht_lock, true); … … 198 165 if (!hash_table_find(&page_ht, key)) { 199 166 pte_t *pte = slab_alloc(pte_cache, FRAME_LOWMEM | FRAME_ATOMIC); 200 ASSERT(pte != NULL);167 assert(pte != NULL); 201 168 202 169 pte->g = (flags & PAGE_GLOBAL) != 0; … … 219 186 write_barrier(); 220 187 221 hash_table_insert(&page_ht, key,&pte->link);188 hash_table_insert(&page_ht, &pte->link); 222 189 } 223 190 … … 237 204 void ht_mapping_remove(as_t *as, uintptr_t page) 238 205 { 239 sysarg_t key[2] = {240 (uintptr_t) as,241 page= ALIGN_DOWN(page, PAGE_SIZE)206 uintptr_t key[2] = { 207 [KEY_AS] = (uintptr_t) as, 208 [KEY_PAGE] = ALIGN_DOWN(page, PAGE_SIZE) 242 209 }; 243 210 244 ASSERT(page_table_locked(as));211 assert(page_table_locked(as)); 245 212 246 213 irq_spinlock_lock(&page_ht_lock, true); … … 250 217 * by remove_callback(). 251 218 */ 252 hash_table_remove(&page_ht, key , 2);219 hash_table_remove(&page_ht, key); 253 220 254 221 irq_spinlock_unlock(&page_ht_lock, true); 255 222 } 256 223 257 static pte_t *ht_mapping_find_internal(as_t *as, uintptr_t page, bool nolock) 258 { 259 sysarg_t key[2] = { 260 (uintptr_t) as, 261 page = ALIGN_DOWN(page, PAGE_SIZE) 224 static pte_t * 225 ht_mapping_find_internal(as_t *as, uintptr_t page, bool nolock) 226 { 227 uintptr_t key[2] = { 228 [KEY_AS] = (uintptr_t) as, 229 [KEY_PAGE] = ALIGN_DOWN(page, PAGE_SIZE) 262 230 }; 263 231 264 ASSERT(nolock || page_table_locked(as));265 266 link_t *cur = hash_table_find(&page_ht, key);232 assert(nolock || page_table_locked(as)); 233 234 ht_link_t *cur = hash_table_find(&page_ht, key); 267 235 if (cur) 268 return hash_table_get_inst ance(cur, pte_t, link);236 return hash_table_get_inst(cur, pte_t, link); 269 237 270 238 return NULL; … … 308 276 panic("Updating non-existent PTE"); 309 277 310 ASSERT(pte->as == t->as);311 ASSERT(pte->page == t->page);312 ASSERT(pte->frame == t->frame);313 ASSERT(pte->g == t->g);314 ASSERT(pte->x == t->x);315 ASSERT(pte->w == t->w);316 ASSERT(pte->k == t->k);317 ASSERT(pte->c == t->c);318 ASSERT(pte->p == t->p);278 assert(pte->as == t->as); 279 assert(pte->page == t->page); 280 assert(pte->frame == t->frame); 281 assert(pte->g == t->g); 282 assert(pte->x == t->x); 283 assert(pte->w == t->w); 284 assert(pte->k == t->k); 285 assert(pte->c == t->c); 286 assert(pte->p == t->p); 319 287 320 288 t->a = pte->a;
Note:
See TracChangeset
for help on using the changeset viewer.