Changeset 2299914 in mainline


Ignore:
Timestamp:
2006-03-16T12:57:31Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e898a8d7
Parents:
b7dcabb
Message:

Page table locking.

Files:
10 edited

Legend:

Unmodified
Added
Removed
  • arch/ia64/src/mm/tlb.c

    rb7dcabb r2299914  
    424424       
    425425        va = istate->cr_ifa;    /* faulting address */
     426        page_table_lock(AS, true);
    426427        t = page_mapping_find(AS, va);
    427428        if (t) {
     
    431432                 */
    432433                itc_pte_copy(t);
     434                page_table_unlock(AS, true);
    433435        } else {
    434436                /*
    435437                 * Forward the page fault to address space page fault handler.
    436438                 */
     439                page_table_unlock(AS, true);
    437440                if (!as_page_fault(va)) {
     441                        page_table_unlock(AS, true);
    438442                        panic("%s: va=%P, rid=%d\n", __FUNCTION__, istate->cr_ifa, rr.map.rid);
    439443                }
     
    467471        }
    468472
     473        page_table_lock(AS, true);
    469474        t = page_mapping_find(AS, va);
    470475        if (t) {
     
    474479                 */
    475480                dtc_pte_copy(t);
     481                page_table_unlock(AS, true);
    476482        } else {
    477483                /*
    478484                 * Forward the page fault to address space page fault handler.
    479485                 */
     486                page_table_unlock(AS, true);
    480487                if (!as_page_fault(va)) {
    481488                        panic("%s: va=%P, rid=%d, iip=%P\n", __FUNCTION__, va, rid, istate->cr_iip);
     
    505512        pte_t *t;
    506513
     514        page_table_lock(AS, true);
    507515        t = page_mapping_find(AS, istate->cr_ifa);
    508516        ASSERT(t && t->p);
     
    515523                dtc_pte_copy(t);
    516524        }
     525        page_table_unlock(AS, true);
    517526}
    518527
     
    526535        pte_t *t;
    527536
     537        page_table_lock(AS, true);
    528538        t = page_mapping_find(AS, istate->cr_ifa);
    529539        ASSERT(t && t->p);
     
    536546                itc_pte_copy(t);
    537547        }
     548        page_table_unlock(AS, true);
    538549}
    539550
     
    547558        pte_t *t;
    548559
     560        page_table_lock(AS, true);
    549561        t = page_mapping_find(AS, istate->cr_ifa);
    550562        ASSERT(t && t->p);
     
    557569                dtc_pte_copy(t);
    558570        }
     571        page_table_unlock(AS, true);
    559572}
    560573
     
    571584       
    572585        va = istate->cr_ifa;    /* faulting address */
     586        page_table_lock(AS, true);
    573587        t = page_mapping_find(AS, va);
    574588        ASSERT(t);
     
    583597                else
    584598                        dtc_pte_copy(t);
     599                page_table_unlock(AS, true);
    585600        } else {
     601                page_table_unlock(AS, true);
    586602                if (!as_page_fault(va)) {
    587603                        panic("%s: va=%P, rid=%d\n", __FUNCTION__, va, rr.map.rid);
  • arch/mips32/src/mm/tlb.c

    rb7dcabb r2299914  
    8888{
    8989        entry_lo_t lo;
    90         entry_hi_t hi; 
     90        entry_hi_t hi;
     91        asid_t asid;
    9192        __address badvaddr;
    9293        pte_t *pte;
     
    9495        badvaddr = cp0_badvaddr_read();
    9596
    96         spinlock_lock(&AS->lock);               
     97        spinlock_lock(&AS->lock);
     98        asid = AS->asid;
     99        spinlock_unlock(&AS->lock);
     100
     101        page_table_lock(AS, true);
    97102
    98103        pte = find_mapping_and_check(badvaddr);
     
    105110        pte->a = 1;
    106111
    107         prepare_entry_hi(&hi, AS->asid, badvaddr);
     112        prepare_entry_hi(&hi, asid, badvaddr);
    108113        prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn);
    109114
     
    123128        tlbwr();
    124129
    125         spinlock_unlock(&AS->lock);
     130        page_table_unlock(AS, true);
    126131        return;
    127132       
    128133fail:
    129         spinlock_unlock(&AS->lock);
     134        page_table_unlock(AS, true);
    130135        tlb_refill_fail(istate);
    131136}
     
    155160        tlbp();
    156161        index.value = cp0_index_read();
    157        
    158         spinlock_lock(&AS->lock);       
     162
     163        page_table_lock(AS, true);     
    159164       
    160165        /*
     
    192197        tlbwi();
    193198
    194         spinlock_unlock(&AS->lock);     
     199        page_table_unlock(AS, true);
    195200        return;
    196201       
    197202fail:
    198         spinlock_unlock(&AS->lock);
     203        page_table_unlock(AS, true);
    199204        tlb_invalid_fail(istate);
    200205}
     
    224229        tlbp();
    225230        index.value = cp0_index_read();
    226        
    227         spinlock_lock(&AS->lock);       
     231
     232        page_table_lock(AS, true);     
    228233       
    229234        /*
     
    268273        tlbwi();
    269274
    270         spinlock_unlock(&AS->lock);     
     275        page_table_unlock(AS, true);
    271276        return;
    272277       
    273278fail:
    274         spinlock_unlock(&AS->lock);
     279        page_table_unlock(AS, true);
    275280        tlb_modified_fail(istate);
    276281}
     
    350355                 * Resort to higher-level page fault handler.
    351356                 */
     357                page_table_unlock(AS, true);
    352358                if (as_page_fault(badvaddr)) {
    353359                        /*
     
    355361                         * The mapping ought to be in place.
    356362                         */
     363                        page_table_lock(AS, true);
    357364                        pte = page_mapping_find(AS, badvaddr);
    358365                        ASSERT(pte && pte->p);
    359366                        return pte;
     367                } else {
     368                        page_table_lock(AS, true);
     369                        printf("Page fault.\n");
     370                        return NULL;
    360371                }
    361         }
    362 
    363         /*
    364          * Handler cannot succeed if badvaddr has no mapping.
    365          */
    366         if (!pte) {
    367                 printf("No such mapping.\n");
    368                 return NULL;
    369         }
    370 
    371         /*
    372          * Handler cannot succeed if the mapping is marked as invalid.
    373          */
    374         if (!pte->p) {
    375                 printf("Invalid mapping.\n");
    376                 return NULL;
    377         }
    378 
    379         return pte;
     372               
     373        }
    380374}
    381375
  • genarch/src/mm/as_ht.c

    rb7dcabb r2299914  
    3535#include <memstr.h>
    3636#include <adt/hash_table.h>
     37#include <synch/spinlock.h>
    3738
    3839static pte_t *ht_create(int flags);
    3940
     41static void ht_lock(as_t *as, bool lock);
     42static void ht_unlock(as_t *as, bool unlock);
     43
    4044as_operations_t as_ht_operations = {
    41         .page_table_create = ht_create
     45        .page_table_create = ht_create,
     46        .page_table_lock = ht_lock,
     47        .page_table_unlock = ht_unlock,
    4248};
    4349
     
    5965        return NULL;
    6066}
     67
     68/** Lock page table.
     69 *
     70 * Lock address space and page hash table.
     71 * Interrupts must be disabled.
     72 *
     73 * @param as Address space.
     74 * @param lock If false, do not attempt to lock the address space.
     75 */
     76void ht_lock(as_t *as, bool lock)
     77{
     78        if (lock)
     79                spinlock_lock(&as->lock);
     80        spinlock_lock(&page_ht_lock);
     81}
     82
     83/** Unlock page table.
     84 *
     85 * Unlock address space and page hash table.
     86 * Interrupts must be disabled.
     87 *
     88 * @param as Address space.
     89 * @param unlock If false, do not attempt to lock the address space.
     90 */
     91void ht_unlock(as_t *as, bool unlock)
     92{
     93        spinlock_unlock(&page_ht_lock);
     94        if (unlock)
     95                spinlock_unlock(&as->lock);
     96}
  • genarch/src/mm/as_pt.c

    rb7dcabb r2299914  
    4040static pte_t *ptl0_create(int flags);
    4141
     42static void pt_lock(as_t *as, bool lock);
     43static void pt_unlock(as_t *as, bool unlock);
     44
    4245as_operations_t as_pt_operations = {
    43         .page_table_create = ptl0_create
     46        .page_table_create = ptl0_create,
     47        .page_table_lock = pt_lock,
     48        .page_table_unlock = pt_unlock
    4449};
    4550
     
    7782        return (pte_t *) KA2PA((__address) dst_ptl0);
    7883}
     84
     85/** Lock page tables.
     86 *
     87 * Lock only the address space.
     88 * Interrupts must be disabled.
     89 *
     90 * @param as Address space.
     91 * @param lock If false, do not attempt to lock the address space.
     92 */
     93void pt_lock(as_t *as, bool lock)
     94{
     95        if (lock)
     96                spinlock_lock(&as->lock);
     97}
     98
     99/** Unlock page tables.
     100 *
     101 * Unlock the address space.
     102 * Interrupts must be disabled.
     103 *
     104 * @param as Address space.
     105 * @param unlock If false, do not attempt to unlock the address space.
     106 */
     107void pt_unlock(as_t *as, bool unlock)
     108{
     109        if (unlock)
     110                spinlock_unlock(&as->lock);
     111}
  • genarch/src/mm/page_ht.c

    rb7dcabb r2299914  
    5353
    5454/**
    55  * This lock protects the page hash table.
     55 * This lock protects the page hash table. It must be acquired
     56 * after address space lock and after any address space area
     57 * locks.
    5658 */
    5759SPINLOCK_INITIALIZE(page_ht_lock);
     
    156158 * using 'flags'.
    157159 *
    158  * The address space must be locked and interruptsmust be disabled.
     160 * The page table must be locked and interrupts must be disabled.
    159161 *
    160162 * @param as Address space to which page belongs.
     
    168170        __native key[2] = { (__address) as, page = ALIGN_DOWN(page, PAGE_SIZE) };
    169171       
    170         spinlock_lock(&page_ht_lock);
    171 
    172172        if (!hash_table_find(&page_ht, key)) {
    173173                t = (pte_t *) malloc(sizeof(pte_t), FRAME_ATOMIC);
     
    187187                hash_table_insert(&page_ht, key, &t->link);
    188188        }
    189        
    190         spinlock_unlock(&page_ht_lock);
    191189}
    192190
     
    197195 * this call visible.
    198196 *
    199  * The address space must be locked and interrupts must be disabled.
     197 * The page table must be locked and interrupts must be disabled.
    200198 *
    201199 * @param as Address space to wich page belongs.
     
    206204        __native key[2] = { (__address) as, page = ALIGN_DOWN(page, PAGE_SIZE) };
    207205       
    208         spinlock_lock(&page_ht_lock);
    209 
    210206        /*
    211207         * Note that removed PTE's will be freed
     
    213209         */
    214210        hash_table_remove(&page_ht, key, 2);
    215 
    216         spinlock_unlock(&page_ht_lock);
    217211}
    218212
     
    222216 * Find mapping for virtual page.
    223217 *
    224  * The address space must be locked and interrupts must be disabled.
     218 * The page table must be locked and interrupts must be disabled.
    225219 *
    226220 * @param as Address space to wich page belongs.
     
    235229        __native key[2] = { (__address) as, page = ALIGN_DOWN(page, PAGE_SIZE) };
    236230       
    237         spinlock_lock(&page_ht_lock);
    238 
    239231        hlp = hash_table_find(&page_ht, key);
    240232        if (hlp)
    241233                t = hash_table_get_instance(hlp, pte_t, link);
    242234
    243         spinlock_unlock(&page_ht_lock);
    244235        return t;
    245236}
  • genarch/src/mm/page_pt.c

    rb7dcabb r2299914  
    5353 * using 'flags'.
    5454 *
    55  * The address space must be locked and interrupts must be disabled.
     55 * The page table must be locked and interrupts must be disabled.
    5656 *
    5757 * @param as Address space to wich page belongs.
     
    106106 * Empty page tables except PTL0 are freed.
    107107 *
    108  * The address space must be locked and interrupts must be disabled.
     108 * The page table must be locked and interrupts must be disabled.
    109109 *
    110110 * @param as Address space to wich page belongs.
     
    226226 * Find mapping for virtual page.
    227227 *
    228  * The address space must be locked and interrupts must be disabled.
     228 * The page table must be locked and interrupts must be disabled.
    229229 *
    230230 * @param as Address space to which page belongs.
  • generic/include/mm/as.h

    rb7dcabb r2299914  
    9494struct as_operations {
    9595        pte_t *(* page_table_create)(int flags);
     96        void (* page_table_lock)(as_t *as, bool lock);
     97        void (* page_table_unlock)(as_t *as, bool unlock);
    9698};
    9799typedef struct as_operations as_operations_t;
  • generic/include/mm/page.h

    rb7dcabb r2299914  
    8383
    8484extern void page_init(void);
     85extern void page_table_lock(as_t *as, bool lock);
     86extern void page_table_unlock(as_t *as, bool unlock);
    8587extern void page_mapping_insert(as_t *as, __address page, __address frame, int flags);
    8688extern void page_mapping_remove(as_t *as, __address page);
  • generic/src/mm/as.c

    rb7dcabb r2299914  
    174174       
    175175        ipl = interrupts_disable();
    176         spinlock_lock(&as->lock);
     176        page_table_lock(as, true);
    177177       
    178178        area = find_area_and_lock(as, page);
     
    184184       
    185185        spinlock_unlock(&area->lock);
    186         spinlock_unlock(&as->lock);
     186        page_table_unlock(as, true);
    187187        interrupts_restore(ipl);
    188188}
     
    199199int as_page_fault(__address page)
    200200{
     201        pte_t *pte;
    201202        as_area_t *area;
    202203        __address frame;
    203204       
    204205        ASSERT(AS);
     206
    205207        spinlock_lock(&AS->lock);
    206        
    207208        area = find_area_and_lock(AS, page);   
    208209        if (!area) {
     
    213214                spinlock_unlock(&AS->lock);
    214215                return 0;
     216        }
     217
     218        page_table_lock(AS, false);
     219       
     220        /*
     221         * To avoid race condition between two page faults
     222         * on the same address, we need to make sure
     223         * the mapping has not been already inserted.
     224         */
     225        if ((pte = page_mapping_find(AS, page))) {
     226                if (PTE_PRESENT(pte)) {
     227                        page_table_unlock(AS, false);
     228                        spinlock_unlock(&area->lock);
     229                        spinlock_unlock(&AS->lock);
     230                        return 1;
     231                }
    215232        }
    216233
     
    238255         */
    239256        page_mapping_insert(AS, page, frame, get_area_flags(area));
     257        page_table_unlock(AS, false);
    240258       
    241259        spinlock_unlock(&area->lock);
    242260        spinlock_unlock(&AS->lock);
    243 
    244261        return 1;
    245262}
     
    358375}
    359376
     377/** Lock page table.
     378 *
     379 * This function should be called before any page_mapping_insert(),
     380 * page_mapping_remove() and page_mapping_find().
     381 *
     382 * Locking order is such that address space areas must be locked
     383 * prior to this call. Address space can be locked prior to this
     384 * call in which case the lock argument is false.
     385 *
     386 * @param as Address space.
     387 * @param as_locked If false, do not attempt to lock as->lock.
     388 */
     389void page_table_lock(as_t *as, bool lock)
     390{
     391        ASSERT(as_operations);
     392        ASSERT(as_operations->page_table_lock);
     393
     394        as_operations->page_table_lock(as, lock);
     395}
     396
     397/** Unlock page table.
     398 *
     399 * @param as Address space.
     400 * @param as_locked If false, do not attempt to unlock as->lock.
     401 */
     402void page_table_unlock(as_t *as, bool unlock)
     403{
     404        ASSERT(as_operations);
     405        ASSERT(as_operations->page_table_unlock);
     406
     407        as_operations->page_table_unlock(as, unlock);
     408}
     409
    360410/** Find address space area and change it.
    361411 *
     
    398448                         * Releasing physical memory.
    399449                         * This depends on the fact that the memory was allocated using frame_alloc().
    400                          */
     450                         */
     451                        page_table_lock(as, false);
    401452                        pte = page_mapping_find(as, area->base + i*PAGE_SIZE);
    402453                        if (pte && PTE_VALID(pte)) {
     454                                __address frame;
     455
    403456                                ASSERT(PTE_PRESENT(pte));
    404                                 frame_free(ADDR2PFN(PTE_GET_FRAME(pte)));
     457                                frame = PTE_GET_FRAME(pte);
    405458                                page_mapping_remove(as, area->base + i*PAGE_SIZE);
     459                                page_table_unlock(as, false);
     460
     461                                frame_free(ADDR2PFN(frame));
     462                        } else {
     463                                page_table_unlock(as, false);
    406464                        }
    407465                }
  • generic/src/mm/page.c

    rb7dcabb r2299914  
    7777 * using 'flags'. Allocate and setup any missing page tables.
    7878 *
    79  * The address space must be locked and interrupts must be disabled.
     79 * The page table must be locked and interrupts must be disabled.
    8080 *
    8181 * @param as Address space to wich page belongs.
     
    9898 * this call visible.
    9999 *
    100  * The address space must be locked and interrupts must be disabled.
     100 * The page table must be locked and interrupts must be disabled.
    101101 *
    102102 * @param as Address space to wich page belongs.
     
    115115 * Find mapping for virtual page.
    116116 *
    117  * The address space must be locked and interrupts must be disabled.
     117 * The page table must be locked and interrupts must be disabled.
    118118 *
    119119 * @param as Address space to wich page belongs.
Note: See TracChangeset for help on using the changeset viewer.