Changeset 2a003d5b in mainline for genarch/src/mm/page_ht.c


Ignore:
Timestamp:
2006-01-26T14:13:50Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c2b95d3
Parents:
4a2f4bb
Message:

Page hash table modifications.

File:
1 edited

Legend:

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

    r4a2f4bb r2a003d5b  
    3535#include <typedefs.h>
    3636#include <arch/asm.h>
     37#include <synch/spinlock.h>
     38#include <arch.h>
    3739#include <debug.h>
     40
     41/**
     42 * This lock protects the page hash table. Note that software must
     43 * be still careful about ordering of writes to ensure consistent
     44 * view of the page hash table for hardware helpers such as VHPT
     45 * walker on ia64.
     46 */
     47SPINLOCK_INITIALIZE(page_ht_lock);
     48
     49/**
     50 * Page hash table pointer.
     51 * The page hash table may be accessed only when page_ht_lock is held.
     52 */
     53pte_t *page_ht = NULL;
    3854
    3955static void ht_mapping_insert(__address page, asid_t asid, __address frame, int flags, __address root);
     
    4864 *
    4965 * Map virtual address 'page' to physical address 'frame'
    50  * using 'flags'.
     66 * using 'flags'. In order not to disturb hardware searching,
     67 * new mappings are appended to the end of the collision
     68 * chain.
    5169 *
    5270 * @param page Virtual address of the page to be mapped.
     
    5876void ht_mapping_insert(__address page, asid_t asid, __address frame, int flags, __address root)
    5977{
    60         pte_t *t, *u = NULL;
     78        pte_t *t, *u;
     79        ipl_t ipl;
     80       
     81        ipl = interrupts_disable();
     82        spinlock_lock(&page_ht_lock);
    6183       
    6284        t = HT_HASH(page, asid);
    6385        if (!HT_SLOT_EMPTY(t)) {
    64                 u = (pte_t *) malloc(sizeof(pte_t));    /* FIXME: use slab allocator for this */
    65                 if (!u)
    66                         panic("could not allocate memory for hash table\n");
    67                 *u = *t;
     86       
     87                /*
     88                 * The slot is occupied.
     89                 * Walk through the collision chain and append the mapping to its end.
     90                 */
     91                 
     92                do {
     93                        u = t;
     94                        if (HT_COMPARE(page, asid, t)) {
     95                                /*
     96                                 * Nothing to do,
     97                                 * the record is already there.
     98                                 */
     99                                spinlock_unlock(&page_ht_lock);
     100                                interrupts_restore(ipl);
     101                                return;
     102                        }
     103                } while ((t = HT_GET_NEXT(t)));
     104       
     105                t = (pte_t *) malloc(sizeof(pte_t));    /* FIXME: use slab allocator for this */
     106                if (!t)
     107                        panic("could not allocate memory\n");
     108
     109                HT_SET_NEXT(u, t);
    68110        }
    69         HT_SET_NEXT(t, u);
     111       
    70112        HT_SET_RECORD(t, page, asid, frame, flags);
     113        HT_SET_NEXT(t, NULL);
     114       
     115        spinlock_unlock(&page_ht_lock);
     116        interrupts_restore(ipl);
    71117}
    72118
     
    74120 *
    75121 * Find mapping for virtual page.
     122 *
     123 * Interrupts must be disabled.
    76124 *
    77125 * @param page Virtual page.
     
    85133        pte_t *t;
    86134       
     135        spinlock_lock(&page_ht_lock);
    87136        t = HT_HASH(page, asid);
    88         while (!HT_COMPARE(page, asid, t) && HT_GET_NEXT(t))
    89                 t = HT_GET_NEXT(t);
     137        if (!HT_SLOT_EMPTY(t)) {
     138                while (!HT_COMPARE(page, asid, t) && HT_GET_NEXT(t))
     139                        t = HT_GET_NEXT(t);
     140                t = HT_COMPARE(page, asid, t) ? t : NULL;
     141        } else {
     142                t = NULL;
     143        }
     144        spinlock_unlock(&page_ht_lock);
     145        return t;
     146}
     147
     148/** Invalidate page hash table.
     149 *
     150 * Interrupts must be disabled.
     151 */
     152void ht_invalidate_all(void)
     153{
     154        pte_t *t, *u;
     155        int i;
    90156       
    91         return HT_COMPARE(page, asid, t) ? t : NULL;
     157        spinlock_lock(&page_ht_lock);
     158        for (i = 0; i < HT_ENTRIES; i++) {
     159                if (!HT_SLOT_EMPTY(&page_ht[i])) {
     160                        t = HT_GET_NEXT(&page_ht[i]);
     161                        while (t) {
     162                                u = t;
     163                                t = HT_GET_NEXT(t);
     164                                free(u);                /* FIXME: use slab allocator for this */
     165                        }
     166                        HT_INVALIDATE_SLOT(&page_ht[i]);
     167                }
     168        }
     169        spinlock_unlock(&page_ht_lock);
    92170}
Note: See TracChangeset for help on using the changeset viewer.