Changeset 82cbf8c6 in mainline for kernel/genarch/src/mm/page_ht.c
- Timestamp:
- 2017-10-08T19:37:24Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2fd26bb
- Parents:
- 81b9d3e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/mm/page_ht.c
r81b9d3e r82cbf8c6 49 49 #include <arch.h> 50 50 #include <assert.h> 51 #include <adt/hash.h> 51 52 #include <adt/hash_table.h> 52 53 #include <align.h> 53 54 54 static size_t hash(sysarg_t[]); 55 static bool compare(sysarg_t[], size_t, link_t *); 56 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 *); 57 59 58 60 static void ht_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int); … … 80 82 81 83 /** Hash table operations for page hash table. */ 82 hash_table_operations_t ht_operations = { 83 .hash = hash, 84 .compare = compare, 85 .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 86 89 }; 87 90 … … 95 98 }; 96 99 97 /** Compute page hash table index. 98 * 99 * @param key Array of two keys (i.e. page and address space). 100 * 101 * @return Index into page hash table. 102 * 103 */ 104 size_t hash(sysarg_t key[]) 105 { 106 as_t *as = (as_t *) key[KEY_AS]; 107 uintptr_t page = (uintptr_t) key[KEY_PAGE]; 108 109 /* 110 * Virtual page addresses have roughly the same probability 111 * of occurring. Least significant bits of VPN compose the 112 * hash index. 113 * 114 */ 115 size_t index = ((page >> PAGE_WIDTH) & (PAGE_HT_ENTRIES - 1)); 116 117 /* 118 * Address space structures are likely to be allocated from 119 * similar addresses. Least significant bits compose the 120 * hash index. 121 * 122 */ 123 index |= ((sysarg_t) as) & (PAGE_HT_ENTRIES - 1); 124 125 return index; 126 } 127 128 /** Compare page hash table item with page and/or address space. 129 * 130 * @param key Array of one or two keys (i.e. page and/or address space). 131 * @param keys Number of keys passed. 132 * @param item Item to compare the keys with. 133 * 134 * @return true on match, false otherwise. 135 * 136 */ 137 bool compare(sysarg_t key[], size_t keys, link_t *item) 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); 127 } 128 129 /** Callback on page hash table item removal. 130 * 131 * @param item Page hash table item being removed. 132 * 133 */ 134 void ht_remove_callback(ht_link_t *item) 138 135 { 139 136 assert(item); 140 assert(keys > 0); 141 assert(keys <= PAGE_HT_KEYS); 142 143 /* 144 * Convert item to PTE. 145 * 146 */ 147 pte_t *pte = hash_table_get_instance(item, pte_t, link); 148 149 if (keys == PAGE_HT_KEYS) 150 return (key[KEY_AS] == (uintptr_t) pte->as) && 151 (key[KEY_PAGE] == pte->page); 152 153 return (key[KEY_AS] == (uintptr_t) pte->as); 154 } 155 156 /** Callback on page hash table item removal. 157 * 158 * @param item Page hash table item being removed. 159 * 160 */ 161 void remove_callback(link_t *item) 162 { 163 assert(item); 164 165 /* 166 * Convert item to PTE. 167 * 168 */ 169 pte_t *pte = hash_table_get_instance(item, pte_t, link); 170 137 138 pte_t *pte = hash_table_get_inst(item, pte_t, link); 171 139 slab_free(pte_cache, pte); 172 140 } … … 186 154 unsigned int flags) 187 155 { 188 sysarg_t key[2] = {189 (uintptr_t) as,190 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) 191 159 }; 192 160 … … 218 186 write_barrier(); 219 187 220 hash_table_insert(&page_ht, key,&pte->link);188 hash_table_insert(&page_ht, &pte->link); 221 189 } 222 190 … … 236 204 void ht_mapping_remove(as_t *as, uintptr_t page) 237 205 { 238 sysarg_t key[2] = {239 (uintptr_t) as,240 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) 241 209 }; 242 210 … … 249 217 * by remove_callback(). 250 218 */ 251 hash_table_remove(&page_ht, key , 2);219 hash_table_remove(&page_ht, key); 252 220 253 221 irq_spinlock_unlock(&page_ht_lock, true); 254 222 } 255 223 256 static pte_t *ht_mapping_find_internal(as_t *as, uintptr_t page, bool nolock) 257 { 258 sysarg_t key[2] = { 259 (uintptr_t) as, 260 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) 261 230 }; 262 231 263 232 assert(nolock || page_table_locked(as)); 264 233 265 link_t *cur = hash_table_find(&page_ht, key);234 ht_link_t *cur = hash_table_find(&page_ht, key); 266 235 if (cur) 267 return hash_table_get_inst ance(cur, pte_t, link);236 return hash_table_get_inst(cur, pte_t, link); 268 237 269 238 return NULL;
Note:
See TracChangeset
for help on using the changeset viewer.