Changeset fb63c06 in mainline


Ignore:
Timestamp:
2016-09-01T16:37:51Z (8 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2a2fbc8
Parents:
346b12a2
Message:

Make page hash table critical sections smaller

After the change of the page mapping interface to work exclusively with
a copy of the actual PTE, the critical section around page hash table
look-ups, insertions and deletions can be much smaller.

This change necessitated the change of the page_ht_lock mutex into a
spinlock, because the page mapping API can be used from within TLB
shootdown sequence, which is basically a spinlock-protected critical
section and we cannot take a mutex while holding a spinlock.

Location:
kernel/genarch
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • kernel/genarch/include/genarch/mm/page_ht.h

    r346b12a2 rfb63c06  
    4444#include <mm/page.h>
    4545#include <mm/slab.h>
    46 #include <synch/mutex.h>
    4746#include <adt/hash_table.h>
    4847
     
    6665
    6766extern slab_cache_t *pte_cache;
    68 extern mutex_t page_ht_lock;
    6967extern hash_table_t page_ht;
    7068extern hash_table_operations_t ht_operations;
  • kernel/genarch/src/mm/as_ht.c

    r346b12a2 rfb63c06  
    7777        if (flags & FLAG_AS_KERNEL) {
    7878                hash_table_create(&page_ht, PAGE_HT_ENTRIES, 2, &ht_operations);
    79                 mutex_initialize(&page_ht_lock, MUTEX_PASSIVE);
    8079                pte_cache = slab_cache_create("pte_t", sizeof(pte_t), 0,
    8180                    NULL, NULL, SLAB_CACHE_MAGDEFERRED);
     
    9998/** Lock page table.
    10099 *
    101  * Lock address space and page hash table.
     100 * Lock address space.
    102101 * Interrupts must be disabled.
    103102 *
     
    110109        if (lock)
    111110                mutex_lock(&as->lock);
    112        
    113         mutex_lock(&page_ht_lock);
    114111}
    115112
    116113/** Unlock page table.
    117114 *
    118  * Unlock address space and page hash table.
     115 * Unlock address space.
    119116 * Interrupts must be disabled.
    120117 *
     
    125122void ht_unlock(as_t *as, bool unlock)
    126123{
    127         mutex_unlock(&page_ht_lock);
    128        
    129124        if (unlock)
    130125                mutex_unlock(&as->lock);
     
    140135bool ht_locked(as_t *as)
    141136{
    142         return (mutex_locked(&page_ht_lock) && mutex_locked(&as->lock));
     137        return mutex_locked(&as->lock);
    143138}
    144139
  • kernel/genarch/src/mm/page_ht.c

    r346b12a2 rfb63c06  
    7171 *
    7272 */
    73 mutex_t page_ht_lock;
     73IRQ_SPINLOCK_STATIC_INITIALIZE(page_ht_lock);
    7474
    7575/** Page hash table.
     
    193193
    194194        ASSERT(page_table_locked(as));
     195
     196        irq_spinlock_lock(&page_ht_lock, true);
    195197       
    196198        if (!hash_table_find(&page_ht, key)) {
     
    219221                hash_table_insert(&page_ht, key, &pte->link);
    220222        }
     223
     224        irq_spinlock_unlock(&page_ht_lock, true);
    221225}
    222226
     
    240244        ASSERT(page_table_locked(as));
    241245       
     246        irq_spinlock_lock(&page_ht_lock, true);
     247
    242248        /*
    243249         * Note that removed PTE's will be freed
     
    245251         */
    246252        hash_table_remove(&page_ht, key, 2);
     253
     254        irq_spinlock_unlock(&page_ht_lock, true);
    247255}
    248256
     
    255263
    256264        ASSERT(nolock || page_table_locked(as));
    257        
     265
    258266        link_t *cur = hash_table_find(&page_ht, key);
    259267        if (cur)
     
    274282bool ht_mapping_find(as_t *as, uintptr_t page, bool nolock, pte_t *pte)
    275283{
     284        irq_spinlock_lock(&page_ht_lock, true);
     285
    276286        pte_t *t = ht_mapping_find_internal(as, page, nolock);
    277287        if (t)
    278288                *pte = *t;
     289
     290        irq_spinlock_unlock(&page_ht_lock, true);
    279291       
    280292        return t != NULL;
     
    290302void ht_mapping_update(as_t *as, uintptr_t page, bool nolock, pte_t *pte)
    291303{
     304        irq_spinlock_lock(&page_ht_lock, true);
     305
    292306        pte_t *t = ht_mapping_find_internal(as, page, nolock);
    293307        if (!t)
     
    306320        t->a = pte->a;
    307321        t->d = pte->d;
     322
     323        irq_spinlock_unlock(&page_ht_lock, true);
    308324}
    309325
Note: See TracChangeset for help on using the changeset viewer.