Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/genarch/src/mm/page_ht.c

    r82cbf8c6 rfb63c06  
    4848#include <synch/spinlock.h>
    4949#include <arch.h>
    50 #include <assert.h>
    51 #include <adt/hash.h>
     50#include <debug.h>
     51#include <memstr.h>
    5252#include <adt/hash_table.h>
    5353#include <align.h>
    5454
    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 *);
     55static size_t hash(sysarg_t[]);
     56static bool compare(sysarg_t[], size_t, link_t *);
     57static void remove_callback(link_t *);
    5958
    6059static void ht_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int);
     
    8281
    8382/** Hash table operations for page hash table. */
    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
     83hash_table_operations_t ht_operations = {
     84        .hash = hash,
     85        .compare = compare,
     86        .remove_callback = remove_callback
    8987};
    9088
     
    9896};
    9997
    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);
     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 */
     105size_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 */
     138bool 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);
    127155}
    128156
     
    132160 *
    133161 */
    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);
     162void 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       
    139172        slab_free(pte_cache, pte);
    140173}
     
    154187    unsigned int flags)
    155188{
    156         uintptr_t key[2] = {
    157                 [KEY_AS] = (uintptr_t) as,
    158                 [KEY_PAGE] = ALIGN_DOWN(page, PAGE_SIZE)
     189        sysarg_t key[2] = {
     190                (uintptr_t) as,
     191                page = ALIGN_DOWN(page, PAGE_SIZE)
    159192        };
    160193
    161         assert(page_table_locked(as));
     194        ASSERT(page_table_locked(as));
    162195
    163196        irq_spinlock_lock(&page_ht_lock, true);
     
    165198        if (!hash_table_find(&page_ht, key)) {
    166199                pte_t *pte = slab_alloc(pte_cache, FRAME_LOWMEM | FRAME_ATOMIC);
    167                 assert(pte != NULL);
     200                ASSERT(pte != NULL);
    168201               
    169202                pte->g = (flags & PAGE_GLOBAL) != 0;
     
    186219                write_barrier();
    187220               
    188                 hash_table_insert(&page_ht, &pte->link);
     221                hash_table_insert(&page_ht, key, &pte->link);
    189222        }
    190223
     
    204237void ht_mapping_remove(as_t *as, uintptr_t page)
    205238{
    206         uintptr_t key[2] = {
    207                 [KEY_AS] = (uintptr_t) as,
    208                 [KEY_PAGE] = ALIGN_DOWN(page, PAGE_SIZE)
     239        sysarg_t key[2] = {
     240                (uintptr_t) as,
     241                page = ALIGN_DOWN(page, PAGE_SIZE)
    209242        };
    210243
    211         assert(page_table_locked(as));
     244        ASSERT(page_table_locked(as));
    212245       
    213246        irq_spinlock_lock(&page_ht_lock, true);
     
    217250         * by remove_callback().
    218251         */
    219         hash_table_remove(&page_ht, key);
     252        hash_table_remove(&page_ht, key, 2);
    220253
    221254        irq_spinlock_unlock(&page_ht_lock, true);
    222255}
    223256
    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)
     257static 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)
    230262        };
    231263
    232         assert(nolock || page_table_locked(as));
    233 
    234         ht_link_t *cur = hash_table_find(&page_ht, key);
     264        ASSERT(nolock || page_table_locked(as));
     265
     266        link_t *cur = hash_table_find(&page_ht, key);
    235267        if (cur)
    236                 return hash_table_get_inst(cur, pte_t, link);
     268                return hash_table_get_instance(cur, pte_t, link);
    237269       
    238270        return NULL;
     
    276308                panic("Updating non-existent PTE");
    277309       
    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);
     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);
    287319
    288320        t->a = pte->a;
Note: See TracChangeset for help on using the changeset viewer.