Changeset 2299914 in mainline for generic/src/mm/as.c


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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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                }
Note: See TracChangeset for help on using the changeset viewer.