Ignore:
File:
1 edited

Legend:

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

    r9d58539 r83b6ba9f  
    5959static void anon_destroy(as_area_t *);
    6060
     61static bool anon_is_resizable(as_area_t *);
     62static bool anon_is_shareable(as_area_t *);
     63
    6164static int anon_page_fault(as_area_t *, uintptr_t, pf_access_t);
    6265static void anon_frame_free(as_area_t *, uintptr_t, uintptr_t);
     
    6871        .destroy = anon_destroy,
    6972
     73        .is_resizable = anon_is_resizable,
     74        .is_shareable = anon_is_shareable,
     75
    7076        .page_fault = anon_page_fault,
    7177        .frame_free = anon_frame_free,
     78
     79        .create_shared_data = NULL,
     80        .destroy_shared_data = NULL
    7281};
    7382
    7483bool anon_create(as_area_t *area)
    7584{
     85        if (area->flags & AS_AREA_LATE_RESERVE)
     86                return true;
     87
    7688        return reserve_try_alloc(area->pages);
    7789}
     
    7991bool anon_resize(as_area_t *area, size_t new_pages)
    8092{
     93        if (area->flags & AS_AREA_LATE_RESERVE)
     94                return true;
     95
    8196        if (new_pages > area->pages)
    8297                return reserve_try_alloc(new_pages - area->pages);
     
    100115        ASSERT(mutex_locked(&area->as->lock));
    101116        ASSERT(mutex_locked(&area->lock));
     117        ASSERT(!(area->flags & AS_AREA_LATE_RESERVE));
    102118
    103119        /*
     
    105121         */
    106122        mutex_lock(&area->sh_info->lock);
    107         list_foreach(area->used_space.leaf_list, cur) {
    108                 btree_node_t *node;
     123        list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
     124            node) {
    109125                unsigned int i;
    110126               
    111                 node = list_get_instance(cur, btree_node_t, leaf_link);
    112127                for (i = 0; i < node->keys; i++) {
    113128                        uintptr_t base = node->key[i];
     
    139154void anon_destroy(as_area_t *area)
    140155{
     156        if (area->flags & AS_AREA_LATE_RESERVE)
     157                return;
     158
    141159        reserve_free(area->pages);
    142160}
    143161
     162bool anon_is_resizable(as_area_t *area)
     163{
     164        return true;
     165}
     166
     167bool anon_is_shareable(as_area_t *area)
     168{
     169        return !(area->flags & AS_AREA_LATE_RESERVE);
     170}
    144171
    145172/** Service a page fault in the anonymous memory address space area.
     
    148175 *
    149176 * @param area Pointer to the address space area.
    150  * @param addr Faulting virtual address.
     177 * @param upage Faulting virtual page.
    151178 * @param access Access mode that caused the fault (i.e. read/write/exec).
    152179 *
     
    154181 *     serviced).
    155182 */
    156 int anon_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access)
    157 {
    158         uintptr_t upage = ALIGN_DOWN(addr, PAGE_SIZE);
     183int anon_page_fault(as_area_t *area, uintptr_t upage, pf_access_t access)
     184{
    159185        uintptr_t kpage;
    160186        uintptr_t frame;
     
    162188        ASSERT(page_table_locked(AS));
    163189        ASSERT(mutex_locked(&area->lock));
     190        ASSERT(IS_ALIGNED(upage, PAGE_SIZE));
    164191
    165192        if (!as_area_check_access(area, access))
    166193                return AS_PF_FAULT;
    167194
    168         if (area->sh_info) {
     195        mutex_lock(&area->sh_info->lock);
     196        if (area->sh_info->shared) {
    169197                btree_node_t *leaf;
    170198               
     
    176204                 * mapping, a new frame is allocated and the mapping is created.
    177205                 */
    178                 mutex_lock(&area->sh_info->lock);
    179206                frame = (uintptr_t) btree_search(&area->sh_info->pagemap,
    180207                    upage - area->base, &leaf);
     
    208235                }
    209236                frame_reference_add(ADDR2PFN(frame));
    210                 mutex_unlock(&area->sh_info->lock);
    211237        } else {
    212238
     
    225251                 *   the different causes
    226252                 */
     253
     254                if (area->flags & AS_AREA_LATE_RESERVE) {
     255                        /*
     256                         * Reserve the memory for this page now.
     257                         */
     258                        if (!reserve_try_alloc(1)) {
     259                                mutex_unlock(&area->sh_info->lock);
     260                                return AS_PF_SILENT;
     261                        }
     262                }
     263
    227264                kpage = km_temporary_page_get(&frame, FRAME_NO_RESERVE);
    228265                memsetb((void *) kpage, PAGE_SIZE, 0);
    229266                km_temporary_page_put(kpage);
    230267        }
     268        mutex_unlock(&area->sh_info->lock);
    231269       
    232270        /*
     
    255293        ASSERT(mutex_locked(&area->lock));
    256294
    257         frame_free_noreserve(frame);
     295        if (area->flags & AS_AREA_LATE_RESERVE) {
     296                /*
     297                 * In case of the late reserve areas, physical memory will not
     298                 * be unreserved when the area is destroyed so we need to use
     299                 * the normal unreserving frame_free().
     300                 */
     301                frame_free(frame, 1);
     302        } else {
     303                /*
     304                 * The reserve will be given back when the area is destroyed or
     305                 * resized, so use the frame_free_noreserve() which does not
     306                 * manipulate the reserve or it would be given back twice.
     307                 */
     308                frame_free_noreserve(frame, 1);
     309        }
    258310}
    259311
Note: See TracChangeset for help on using the changeset viewer.