Changeset ecbdc724 in mainline for genarch/src/mm/page_pt.c


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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.