Changeset 03523dc in mainline for kernel/generic/src/mm/backend_anon.c


Ignore:
Timestamp:
2011-01-15T16:12:46Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6b9e85b
Parents:
630a8ef
Message:

Add more hooks to address space area backends so that each backend can
take action also on:

  • as_area_create()
  • as_area_resize()
  • as_area_destroy()

Add basic memory reservation code to anonymous and elf address space
area backends.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/mm/backend_anon.c

    r630a8ef r03523dc  
    3939#include <mm/as.h>
    4040#include <mm/page.h>
     41#include <mm/reserve.h>
    4142#include <genarch/mm/page_pt.h>
    4243#include <genarch/mm/page_ht.h>
     
    5556#endif
    5657
     58static bool anon_create(as_area_t *);
     59static bool anon_resize(as_area_t *, size_t);
     60static void anon_share(as_area_t *area);
     61static void anon_destroy(as_area_t *);
     62
    5763static int anon_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access);
    5864static void anon_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame);
    59 static void anon_share(as_area_t *area);
    6065
    6166mem_backend_t anon_backend = {
     67        .create = anon_create,
     68        .resize = anon_resize,
     69        .share = anon_share,
     70        .destroy = anon_destroy,
     71
    6272        .page_fault = anon_page_fault,
    6373        .frame_free = anon_frame_free,
    64         .share = anon_share
    6574};
     75
     76bool anon_create(as_area_t *area)
     77{
     78        return reserve_try_alloc(area->pages);
     79}
     80
     81bool anon_resize(as_area_t *area, size_t new_pages)
     82{
     83        /**
     84         * @todo
     85         * Reserve also space needed for the supporting strutures allocated
     86         * during page fault.
     87         */
     88
     89        if (new_pages > area->pages)
     90                return reserve_try_alloc(new_pages - area->pages);
     91        else if (new_pages < area->pages)
     92                reserve_free(area->pages - new_pages);
     93
     94        return true;
     95}
     96
     97/** Share the anonymous address space area.
     98 *
     99 * Sharing of anonymous area is done by duplicating its entire mapping
     100 * to the pagemap. Page faults will primarily search for frames there.
     101 *
     102 * The address space and address space area must be already locked.
     103 *
     104 * @param area Address space area to be shared.
     105 */
     106void anon_share(as_area_t *area)
     107{
     108        link_t *cur;
     109
     110        ASSERT(mutex_locked(&area->as->lock));
     111        ASSERT(mutex_locked(&area->lock));
     112
     113        /*
     114         * Copy used portions of the area to sh_info's page map.
     115         */
     116        mutex_lock(&area->sh_info->lock);
     117        for (cur = area->used_space.leaf_head.next;
     118            cur != &area->used_space.leaf_head; cur = cur->next) {
     119                btree_node_t *node;
     120                unsigned int i;
     121               
     122                node = list_get_instance(cur, btree_node_t, leaf_link);
     123                for (i = 0; i < node->keys; i++) {
     124                        uintptr_t base = node->key[i];
     125                        size_t count = (size_t) node->value[i];
     126                        unsigned int j;
     127                       
     128                        for (j = 0; j < count; j++) {
     129                                pte_t *pte;
     130                       
     131                                page_table_lock(area->as, false);
     132                                pte = page_mapping_find(area->as,
     133                                    base + j * PAGE_SIZE);
     134                                ASSERT(pte && PTE_VALID(pte) &&
     135                                    PTE_PRESENT(pte));
     136                                btree_insert(&area->sh_info->pagemap,
     137                                    (base + j * PAGE_SIZE) - area->base,
     138                                    (void *) PTE_GET_FRAME(pte), NULL);
     139                                page_table_unlock(area->as, false);
     140
     141                                pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(pte));
     142                                frame_reference_add(pfn);
     143                        }
     144
     145                }
     146        }
     147        mutex_unlock(&area->sh_info->lock);
     148}
     149
     150void anon_destroy(as_area_t *area)
     151{
     152        reserve_free(area->pages);
     153}
     154
    66155
    67156/** Service a page fault in the anonymous memory address space area.
     
    178267}
    179268
    180 /** Share the anonymous address space area.
    181  *
    182  * Sharing of anonymous area is done by duplicating its entire mapping
    183  * to the pagemap. Page faults will primarily search for frames there.
    184  *
    185  * The address space and address space area must be already locked.
    186  *
    187  * @param area Address space area to be shared.
    188  */
    189 void anon_share(as_area_t *area)
    190 {
    191         link_t *cur;
    192 
    193         ASSERT(mutex_locked(&area->as->lock));
    194         ASSERT(mutex_locked(&area->lock));
    195 
    196         /*
    197          * Copy used portions of the area to sh_info's page map.
    198          */
    199         mutex_lock(&area->sh_info->lock);
    200         for (cur = area->used_space.leaf_head.next;
    201             cur != &area->used_space.leaf_head; cur = cur->next) {
    202                 btree_node_t *node;
    203                 unsigned int i;
    204                
    205                 node = list_get_instance(cur, btree_node_t, leaf_link);
    206                 for (i = 0; i < node->keys; i++) {
    207                         uintptr_t base = node->key[i];
    208                         size_t count = (size_t) node->value[i];
    209                         unsigned int j;
    210                        
    211                         for (j = 0; j < count; j++) {
    212                                 pte_t *pte;
    213                        
    214                                 page_table_lock(area->as, false);
    215                                 pte = page_mapping_find(area->as,
    216                                     base + j * PAGE_SIZE);
    217                                 ASSERT(pte && PTE_VALID(pte) &&
    218                                     PTE_PRESENT(pte));
    219                                 btree_insert(&area->sh_info->pagemap,
    220                                     (base + j * PAGE_SIZE) - area->base,
    221                                     (void *) PTE_GET_FRAME(pte), NULL);
    222                                 page_table_unlock(area->as, false);
    223 
    224                                 pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(pte));
    225                                 frame_reference_add(pfn);
    226                         }
    227 
    228                 }
    229         }
    230         mutex_unlock(&area->sh_info->lock);
    231 }
    232 
    233269/** @}
    234270 */
Note: See TracChangeset for help on using the changeset viewer.