Changeset ecbdc724 in mainline


Ignore:
Timestamp:
2006-02-10T22:37:27Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d7d6385
Parents:
0882a9a
Message:

Change pt_mapping_remove() to deallocate frames for empty PTL1, PTL2 and PTL3.

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • arch/amd64/include/mm/page.h

    r0882a9a recbdc724  
    4848#endif
    4949
     50#define PTL0_ENTRIES_ARCH       512
     51#define PTL1_ENTRIES_ARCH       512
     52#define PTL2_ENTRIES_ARCH       512
     53#define PTL3_ENTRIES_ARCH       512
     54
    5055#define PTL0_INDEX_ARCH(vaddr)  (((vaddr)>>39)&0x1ff)
    5156#define PTL1_INDEX_ARCH(vaddr)  (((vaddr)>>30)&0x1ff)
     
    7378#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)         set_pt_flags((pte_t *)(ptl2), (index_t)(i), (x))
    7479#define SET_FRAME_FLAGS_ARCH(ptl3, i, x)        set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x))
     80
     81#define PTE_VALID_ARCH(p)                       (*((__u64 *) (p)) != 0)
    7582
    7683#ifndef __ASM__
  • arch/ia32/include/mm/page.h

    r0882a9a recbdc724  
    4545 * IA-32 has 2-level page tables, so PTL1 and PTL2 are left out.
    4646 */
     47#define PTL0_ENTRIES_ARCH       1024
     48#define PTL1_ENTRIES_ARCH       0
     49#define PTL2_ENTRIES_ARCH       0
     50#define PTL3_ENTRIES_ARCH       1024
     51
    4752#define PTL0_INDEX_ARCH(vaddr)  (((vaddr)>>22)&0x3ff)
    4853#define PTL1_INDEX_ARCH(vaddr)  0
     
    7075#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
    7176#define SET_FRAME_FLAGS_ARCH(ptl3, i, x)        set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x))
     77
     78#define PTE_VALID_ARCH(p)                       (*((__u32 *) (p)) != 0)
    7279
    7380#ifndef __ASM__
  • arch/mips32/include/mm/page.h

    r0882a9a recbdc724  
    5959 */
    6060 
     61#define PTL0_ENTRIES_ARCH       64
     62#define PTL1_ENTRIES_ARCH       0
     63#define PTL2_ENTRIES_ARCH       0
     64#define PTL3_ENTRIES_ARCH       4096
     65
    6166#define PTL0_INDEX_ARCH(vaddr)  ((vaddr)>>26)
    6267#define PTL1_INDEX_ARCH(vaddr)  0
     
    8590#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
    8691#define SET_FRAME_FLAGS_ARCH(ptl3, i, x)        set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x))
     92
     93#define PTE_VALID_ARCH(p)                       (*((__u32 *) (p)) != 0)
    8794
    8895#ifndef __ASM__
  • doc/TODO

    r0882a9a recbdc724  
    55  + [mips] use some heuristics to get memory map and memory size
    66  + reimplement heap so that it can allocate/deallocate
    7     itself frames as necessary
     7    itself frames as necessary                                          [DONE]
    88  + provide native four-level portable page table interface             [DONE]
    99    + every architecture uses its native page table format
    1010    + kernel provides unified four-level page table interface
    11       for all architectures
    12   + track usage of frames containing middle-level page tables
    13     (frame leak)
     11      or page hash table interface to architectures
     12  + deallocation of memory of empty page tables                         [DONE]
    1413
    1514+ get user mode support for all architectures
  • genarch/include/mm/page_pt.h

    r0882a9a recbdc724  
    3939#include <typedefs.h>
    4040#include <mm/page.h>
     41
     42/*
     43 * Number of entries in each level.
     44 */
     45#define PTL0_ENTRIES                    PTL0_ENTRIES_ARCH
     46#define PTL1_ENTRIES                    PTL1_ENTRIES_ARCH
     47#define PTL2_ENTRIES                    PTL2_ENTRIES_ARCH
     48#define PTL3_ENTRIES                    PTL3_ENTRIES_ARCH
    4149
    4250/*
     
    8593#define SET_FRAME_FLAGS(ptl3, i, x)     SET_FRAME_FLAGS_ARCH(ptl3, i, x)
    8694
     95/*
     96 * Determine whether the mapping is valid.
     97 */
     98#define PTE_VALID(p)                    PTE_VALID_ARCH((p))
     99
    87100extern page_mapping_operations_t pt_mapping_operations;
    88101
  • genarch/src/mm/page_pt.c

    r0882a9a recbdc724  
    104104 * this call visible.
    105105 *
     106 * Empty page tables except PTL0 are freed.
     107 *
    106108 * The address space must be locked and interrupts must be disabled.
    107109 *
     
    112114{
    113115        pte_t *ptl0, *ptl1, *ptl2, *ptl3;
     116        bool empty = true;
     117        int i;
     118
     119        /*
     120         * First, remove the mapping, if it exists.
     121         */
    114122
    115123        ptl0 = (pte_t *) PA2KA((__address) as->page_table);
     
    132140        /* Destroy the mapping. Setting to PAGE_NOT_PRESENT is not sufficient. */
    133141        memsetb((__address) &ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0);
     142
     143        /*
     144         * Second, free all empty tables along the way from PTL3 down to PTL0.
     145         */
     146       
     147        /* check PTL3 */
     148        for (i = 0; i < PTL3_ENTRIES; i++) {
     149                if (PTE_VALID(&ptl3[i])) {
     150                        empty = false;
     151                        break;
     152                }
     153        }
     154        if (empty) {
     155                /*
     156                 * PTL3 is empty.
     157                 * Release the frame and remove PTL3 pointer from preceding table.
     158                 */
     159                frame_free(ADDR2PFN(KA2PA((__address) ptl3)));
     160                if (PTL2_ENTRIES)
     161                        memsetb((__address) &ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0);
     162                else if (PTL1_ENTRIES)
     163                        memsetb((__address) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
     164                else
     165                        memsetb((__address) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
     166        } else {
     167                /*
     168                 * PTL3 is not empty.
     169                 * Therefore, there must be a path from PTL0 to PTL3 and
     170                 * thus nothing to free in higher levels.
     171                 */
     172                return;
     173        }
     174       
     175        /* check PTL2, empty is still true */
     176        if (PTL2_ENTRIES) {
     177                for (i = 0; i < PTL2_ENTRIES; i++) {
     178                        if (PTE_VALID(&ptl2[i])) {
     179                                empty = false;
     180                                break;
     181                        }
     182                }
     183                if (empty) {
     184                        /*
     185                         * PTL2 is empty.
     186                         * Release the frame and remove PTL2 pointer from preceding table.
     187                         */
     188                        frame_free(ADDR2PFN(KA2PA((__address) ptl2)));
     189                        if (PTL1_ENTRIES)
     190                                memsetb((__address) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
     191                        else
     192                                memsetb((__address) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
     193                }
     194                else {
     195                        /*
     196                         * PTL2 is not empty.
     197                         * Therefore, there must be a path from PTL0 to PTL2 and
     198                         * thus nothing to free in higher levels.
     199                         */
     200                        return;
     201                }
     202        }
     203
     204        /* check PTL1, empty is still true */
     205        if (PTL1_ENTRIES) {
     206                for (i = 0; i < PTL1_ENTRIES; i++) {
     207                        if (PTE_VALID(&ptl1[i])) {
     208                                empty = false;
     209                                break;
     210                        }
     211                }
     212                if (empty) {
     213                        /*
     214                         * PTL1 is empty.
     215                         * Release the frame and remove PTL1 pointer from preceding table.
     216                         */
     217                        frame_free(ADDR2PFN(KA2PA((__address) ptl1)));
     218                        memsetb((__address) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
     219                }
     220        }
     221
    134222}
    135223
Note: See TracChangeset for help on using the changeset viewer.