Ignore:
File:
1 edited

Legend:

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

    r7e752b2 r8d308b9  
    4545#include <typedefs.h>
    4646#include <mm/frame.h>
     47#include <mm/reserve.h>
    4748#include <mm/as.h>
    4849#include <panic.h>
     
    5960#include <macros.h>
    6061#include <config.h>
     62#include <str.h>
    6163
    6264zones_t zones;
     
    180182 *
    181183 */
    182 #ifdef CONFIG_DEBUG
    183 NO_TRACE static size_t total_frames_free(void)
     184NO_TRACE static size_t frame_total_free_get_internal(void)
    184185{
    185186        size_t total = 0;
    186187        size_t i;
     188
    187189        for (i = 0; i < zones.count; i++)
    188190                total += zones.info[i].free_count;
     
    190192        return total;
    191193}
    192 #endif /* CONFIG_DEBUG */
     194
     195NO_TRACE size_t frame_total_free_get(void)
     196{
     197        size_t total;
     198
     199        irq_spinlock_lock(&zones.lock, true);
     200        total = frame_total_free_get_internal();
     201        irq_spinlock_unlock(&zones.lock, true);
     202
     203        return total;
     204}
     205
    193206
    194207/** Find a zone with a given frames.
     
    472485 * @param frame_idx Frame index relative to zone.
    473486 *
    474  */
    475 NO_TRACE static void zone_frame_free(zone_t *zone, size_t frame_idx)
     487 * @return          Number of freed frames.
     488 *
     489 */
     490NO_TRACE static size_t zone_frame_free(zone_t *zone, size_t frame_idx)
    476491{
    477492        ASSERT(zone_flags_available(zone->flags));
    478493       
    479494        frame_t *frame = &zone->frames[frame_idx];
    480        
    481         /* Remember frame order */
    482         uint8_t order = frame->buddy_order;
     495        size_t size = 0;
    483496       
    484497        ASSERT(frame->refcount);
    485498       
    486499        if (!--frame->refcount) {
    487                 buddy_system_free(zone->buddy_system, &frame->buddy_link);
    488                
     500                size = 1 << frame->buddy_order;
     501                buddy_system_free(zone->buddy_system, &frame->buddy_link);             
    489502                /* Update zone information. */
    490                 zone->free_count += (1 << order);
    491                 zone->busy_count -= (1 << order);
    492         }
     503                zone->free_count += size;
     504                zone->busy_count -= size;
     505        }
     506       
     507        return size;
    493508}
    494509
     
    516531        ASSERT(link);
    517532        zone->free_count--;
     533        reserve_force_alloc(1);
    518534}
    519535
     
    645661        for (i = 0; i < cframes; i++) {
    646662                zones.info[znum].busy_count++;
    647                 zone_frame_free(&zones.info[znum],
     663                (void) zone_frame_free(&zones.info[znum],
    648664                    pfn - zones.info[znum].base + i);
    649665        }
     
    683699        /* Free unneeded frames */
    684700        for (i = count; i < (size_t) (1 << order); i++)
    685                 zone_frame_free(&zones.info[znum], i + frame_idx);
     701                (void) zone_frame_free(&zones.info[znum], i + frame_idx);
    686702}
    687703
     
    695711 * not to be 2^order size. Once the allocator is running it is no longer
    696712 * possible, merged configuration data occupies more space :-/
    697  *
    698  * The function uses
    699713 *
    700714 */
     
    9991013        size_t hint = pzone ? (*pzone) : 0;
    10001014       
     1015        /*
     1016         * If not told otherwise, we must first reserve the memory.
     1017         */
     1018        if (!(flags & FRAME_NO_RESERVE))
     1019                reserve_force_alloc(size);
     1020
    10011021loop:
    10021022        irq_spinlock_lock(&zones.lock, true);
     
    10331053                if (flags & FRAME_ATOMIC) {
    10341054                        irq_spinlock_unlock(&zones.lock, true);
     1055                        if (!(flags & FRAME_NO_RESERVE))
     1056                                reserve_free(size);
    10351057                        return NULL;
    10361058                }
    10371059               
    10381060#ifdef CONFIG_DEBUG
    1039                 size_t avail = total_frames_free();
     1061                size_t avail = frame_total_free_get_internal();
    10401062#endif
    10411063               
     
    10881110}
    10891111
     1112void *frame_alloc(uint8_t order, frame_flags_t flags)
     1113{
     1114        return frame_alloc_generic(order, flags, NULL);
     1115}
     1116
     1117void *frame_alloc_noreserve(uint8_t order, frame_flags_t flags)
     1118{
     1119        return frame_alloc_generic(order, flags | FRAME_NO_RESERVE, NULL);
     1120}
     1121
    10901122/** Free a frame.
    10911123 *
     
    10951127 *
    10961128 * @param frame Physical Address of of the frame to be freed.
    1097  *
    1098  */
    1099 void frame_free(uintptr_t frame)
    1100 {
     1129 * @param flags Flags to control memory reservation.
     1130 *
     1131 */
     1132void frame_free_generic(uintptr_t frame, frame_flags_t flags)
     1133{
     1134        size_t size;
     1135       
    11011136        irq_spinlock_lock(&zones.lock, true);
    11021137       
     
    11061141        pfn_t pfn = ADDR2PFN(frame);
    11071142        size_t znum = find_zone(pfn, 1, 0);
     1143
    11081144       
    11091145        ASSERT(znum != (size_t) -1);
    11101146       
    1111         zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
     1147        size = zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
    11121148       
    11131149        irq_spinlock_unlock(&zones.lock, true);
     
    11181154        mutex_lock(&mem_avail_mtx);
    11191155        if (mem_avail_req > 0)
    1120                 mem_avail_req--;
     1156                mem_avail_req -= min(mem_avail_req, size);
    11211157       
    11221158        if (mem_avail_req == 0) {
     
    11251161        }
    11261162        mutex_unlock(&mem_avail_mtx);
     1163       
     1164        if (!(flags & FRAME_NO_RESERVE))
     1165                reserve_free(size);
     1166}
     1167
     1168void frame_free(uintptr_t frame)
     1169{
     1170        frame_free_generic(frame, 0);
     1171}
     1172
     1173void frame_free_noreserve(uintptr_t frame)
     1174{
     1175        frame_free_generic(frame, FRAME_NO_RESERVE);
    11271176}
    11281177
     
    13551404        bool available = zone_flags_available(flags);
    13561405       
     1406        uint64_t size;
     1407        const char *size_suffix;
     1408        bin_order_suffix(FRAMES2SIZE(count), &size, &size_suffix, false);
     1409       
    13571410        printf("Zone number:       %zu\n", znum);
    13581411        printf("Zone base address: %p\n", (void *) base);
    1359         printf("Zone size:         %zu frames (%zu KiB)\n", count,
    1360             SIZE2KB(FRAMES2SIZE(count)));
     1412        printf("Zone size:         %zu frames (%" PRIu64 " %s)\n", count,
     1413            size, size_suffix);
    13611414        printf("Zone flags:        %c%c%c\n",
    13621415            available ? 'A' : ' ',
     
    13651418       
    13661419        if (available) {
    1367                 printf("Allocated space:   %zu frames (%zu KiB)\n",
    1368                     busy_count, SIZE2KB(FRAMES2SIZE(busy_count)));
    1369                 printf("Available space:   %zu frames (%zu KiB)\n",
    1370                     free_count, SIZE2KB(FRAMES2SIZE(free_count)));
     1420                bin_order_suffix(FRAMES2SIZE(busy_count), &size, &size_suffix,
     1421                    false);
     1422                printf("Allocated space:   %zu frames (%" PRIu64 " %s)\n",
     1423                    busy_count, size, size_suffix);
     1424                bin_order_suffix(FRAMES2SIZE(free_count), &size, &size_suffix,
     1425                    false);
     1426                printf("Available space:   %zu frames (%" PRIu64 " %s)\n",
     1427                    free_count, size, size_suffix);
    13711428        }
    13721429}
Note: See TracChangeset for help on using the changeset viewer.