Ignore:
File:
1 edited

Legend:

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

    r7e752b2 rd060900  
    4545#include <typedefs.h>
    4646#include <mm/frame.h>
     47#include <mm/reserve.h>
    4748#include <mm/as.h>
    4849#include <panic.h>
     
    472473 * @param frame_idx Frame index relative to zone.
    473474 *
    474  */
    475 NO_TRACE static void zone_frame_free(zone_t *zone, size_t frame_idx)
     475 * @return          Number of freed frames.
     476 *
     477 */
     478NO_TRACE static size_t zone_frame_free(zone_t *zone, size_t frame_idx)
    476479{
    477480        ASSERT(zone_flags_available(zone->flags));
    478481       
    479482        frame_t *frame = &zone->frames[frame_idx];
    480        
    481         /* Remember frame order */
    482         uint8_t order = frame->buddy_order;
     483        size_t size = 1 << frame->buddy_order;
    483484       
    484485        ASSERT(frame->refcount);
     
    488489               
    489490                /* Update zone information. */
    490                 zone->free_count += (1 << order);
    491                 zone->busy_count -= (1 << order);
    492         }
     491                zone->free_count += size;
     492                zone->busy_count -= size;
     493        }
     494       
     495        return size;
    493496}
    494497
     
    516519        ASSERT(link);
    517520        zone->free_count--;
     521        reserve_force_alloc(1);
    518522}
    519523
     
    645649        for (i = 0; i < cframes; i++) {
    646650                zones.info[znum].busy_count++;
    647                 zone_frame_free(&zones.info[znum],
     651                (void) zone_frame_free(&zones.info[znum],
    648652                    pfn - zones.info[znum].base + i);
    649653        }
     
    683687        /* Free unneeded frames */
    684688        for (i = count; i < (size_t) (1 << order); i++)
    685                 zone_frame_free(&zones.info[znum], i + frame_idx);
     689                (void) zone_frame_free(&zones.info[znum], i + frame_idx);
    686690}
    687691
     
    695699 * not to be 2^order size. Once the allocator is running it is no longer
    696700 * possible, merged configuration data occupies more space :-/
    697  *
    698  * The function uses
    699701 *
    700702 */
     
    837839                        buddy_system_free(zone->buddy_system, &zone->frames[i].buddy_link);
    838840                }
     841
     842                /* "Unreserve" new frames. */
     843                reserve_free(count);
    839844        } else
    840845                zone->frames = NULL;
     
    9991004        size_t hint = pzone ? (*pzone) : 0;
    10001005       
     1006        /*
     1007         * If not told otherwise, we must first reserve the memory.
     1008         */
     1009        if (!(flags & FRAME_NO_RESERVE)) {
     1010                if (flags & FRAME_ATOMIC) {
     1011                        if (!reserve_try_alloc(size))
     1012                                return NULL;
     1013                } else {
     1014                        reserve_force_alloc(size);
     1015                }
     1016        }
     1017       
    10011018loop:
    10021019        irq_spinlock_lock(&zones.lock, true);
     
    10331050                if (flags & FRAME_ATOMIC) {
    10341051                        irq_spinlock_unlock(&zones.lock, true);
     1052                        if (!(flags & FRAME_NO_RESERVE))
     1053                                reserve_free(size);
    10351054                        return NULL;
    10361055                }
     
    10881107}
    10891108
     1109void *frame_alloc(uint8_t order, frame_flags_t flags)
     1110{
     1111        return frame_alloc_generic(order, flags, NULL);
     1112}
     1113
     1114void *frame_alloc_noreserve(uint8_t order, frame_flags_t flags)
     1115{
     1116        return frame_alloc_generic(order, flags | FRAME_NO_RESERVE, NULL);
     1117}
     1118
    10901119/** Free a frame.
    10911120 *
     
    10951124 *
    10961125 * @param frame Physical Address of of the frame to be freed.
    1097  *
    1098  */
    1099 void frame_free(uintptr_t frame)
    1100 {
     1126 * @param flags Flags to control memory reservation.
     1127 *
     1128 */
     1129void frame_free_generic(uintptr_t frame, frame_flags_t flags)
     1130{
     1131        size_t size;
     1132       
    11011133        irq_spinlock_lock(&zones.lock, true);
    11021134       
     
    11061138        pfn_t pfn = ADDR2PFN(frame);
    11071139        size_t znum = find_zone(pfn, 1, 0);
     1140
    11081141       
    11091142        ASSERT(znum != (size_t) -1);
    11101143       
    1111         zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
     1144        size = zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
    11121145       
    11131146        irq_spinlock_unlock(&zones.lock, true);
     
    11181151        mutex_lock(&mem_avail_mtx);
    11191152        if (mem_avail_req > 0)
    1120                 mem_avail_req--;
     1153                mem_avail_req -= min(mem_avail_req, size);
    11211154       
    11221155        if (mem_avail_req == 0) {
     
    11251158        }
    11261159        mutex_unlock(&mem_avail_mtx);
     1160       
     1161        if (!(flags & FRAME_NO_RESERVE))
     1162                reserve_free(size);
     1163}
     1164
     1165void frame_free(uintptr_t frame)
     1166{
     1167        frame_free_generic(frame, 0);
     1168}
     1169
     1170void frame_free_noreserve(uintptr_t frame)
     1171{
     1172        frame_free_generic(frame, FRAME_NO_RESERVE);
    11271173}
    11281174
Note: See TracChangeset for help on using the changeset viewer.