Ignore:
File:
1 edited

Legend:

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

    rc626117 rd1582b50  
    6363#include <proc/thread.h> /* THREAD */
    6464
    65 zones_t zones = {
    66         .count = 0,
    67         .lock = IRQ_SPINLOCK_INITIALIZER("frame.zones.lock"),
    68 };
     65zones_t zones;
    6966
    7067/*
     
    7269 * available.
    7370 */
    74 static IRQ_SPINLOCK_INITIALIZE(mem_avail_lock);
    75 static CONDVAR_INITIALIZE(mem_avail_cv);
     71static mutex_t mem_avail_mtx;
     72static condvar_t mem_avail_cv;
    7673static size_t mem_avail_req = 0;  /**< Number of frames requested. */
    7774static size_t mem_avail_gen = 0;  /**< Generation counter. */
     
    373370{
    374371        assert(zone->flags & ZONE_AVAILABLE);
    375         assert(zone->free_count >= count);
    376372
    377373        /* Allocate frames from zone */
     
    414410
    415411        frame_t *frame = zone_get_frame(zone, index);
     412
    416413        assert(frame->refcount > 0);
    417414
    418415        if (!--frame->refcount) {
    419                 assert(zone->busy_count > 0);
    420 
    421416                bitmap_set(&zone->bitmap, index, 0);
    422417
     
    437432
    438433        frame_t *frame = zone_get_frame(zone, index);
    439         assert(frame->refcount <= 1);
    440 
    441434        if (frame->refcount > 0)
    442435                return;
    443436
    444         assert(zone->free_count > 0);
    445 
    446437        frame->refcount = 1;
    447438        bitmap_set_range(&zone->bitmap, index, 1);
     
    449440        zone->free_count--;
    450441        reserve_force_alloc(1);
    451 }
    452 
    453 /** Mark frame in zone available to allocation. */
    454 _NO_TRACE static void zone_mark_available(zone_t *zone, size_t index)
    455 {
    456         assert(zone->flags & ZONE_AVAILABLE);
    457 
    458         frame_t *frame = zone_get_frame(zone, index);
    459         assert(frame->refcount == 1);
    460 
    461         frame->refcount = 0;
    462         bitmap_set_range(&zone->bitmap, index, 0);
    463 
    464         zone->free_count++;
    465442}
    466443
     
    488465        /* Difference between zone bases */
    489466        pfn_t base_diff = zones.info[z2].base - zones.info[z1].base;
    490         pfn_t gap = base_diff - zones.info[z1].count;
    491467
    492468        zones.info[z1].count = base_diff + zones.info[z2].count;
     
    516492                    zones.info[z2].frames[i];
    517493        }
    518 
    519         /*
    520          * Mark the gap between the original zones as unavailable.
    521          */
    522 
    523         for (size_t i = 0; i < gap; i++) {
    524                 frame_initialize(&zones.info[z1].frames[old_z1->count + i]);
    525                 zone_mark_unavailable(&zones.info[z1], old_z1->count + i);
    526         }
    527494}
    528495
     
    551518
    552519        for (size_t i = 0; i < cframes; i++)
    553                 zone_mark_available(&zones.info[znum],
     520                (void) zone_frame_free(&zones.info[znum],
    554521                    pfn - zones.info[znum].base + i);
    555522}
     
    756723
    757724                                if (overlaps(addr, PFN2ADDR(confcount),
    758                                     KA2PA(ballocs.base), ballocs.size))
     725                                    KA2PA(config.stack_base), config.stack_size))
    759726                                        continue;
    760727
     
    951918#endif
    952919
    953                 /* Disabled interrupts needed to prevent deadlock with TLB shootdown. */
    954                 irq_spinlock_lock(&mem_avail_lock, true);
     920                /*
     921                 * Since the mem_avail_mtx is an active mutex, we need to
     922                 * disable interrupts to prevent deadlock with TLB shootdown.
     923                 */
     924                ipl_t ipl = interrupts_disable();
     925                mutex_lock(&mem_avail_mtx);
    955926
    956927                if (mem_avail_req > 0)
     
    962933
    963934                while (gen == mem_avail_gen)
    964                         condvar_wait(&mem_avail_cv, &mem_avail_lock);
    965 
    966                 irq_spinlock_unlock(&mem_avail_lock, true);
     935                        condvar_wait(&mem_avail_cv, &mem_avail_mtx);
     936
     937                mutex_unlock(&mem_avail_mtx);
     938                interrupts_restore(ipl);
    967939
    968940#ifdef CONFIG_DEBUG
     
    1022994        irq_spinlock_unlock(&zones.lock, true);
    1023995
    1024         /* Signal that some memory has been freed. */
    1025 
    1026         /* Disabled interrupts needed to prevent deadlock with TLB shootdown. */
    1027         irq_spinlock_lock(&mem_avail_lock, true);
     996        /*
     997         * Signal that some memory has been freed.
     998         * Since the mem_avail_mtx is an active mutex,
     999         * we need to disable interruptsto prevent deadlock
     1000         * with TLB shootdown.
     1001         */
     1002
     1003        ipl_t ipl = interrupts_disable();
     1004        mutex_lock(&mem_avail_mtx);
    10281005
    10291006        if (mem_avail_req > 0)
     
    10351012        }
    10361013
    1037         irq_spinlock_unlock(&mem_avail_lock, true);
     1014        mutex_unlock(&mem_avail_mtx);
     1015        interrupts_restore(ipl);
    10381016
    10391017        if (!(flags & FRAME_NO_RESERVE))
     
    11001078void frame_init(void)
    11011079{
     1080        if (config.cpu_active == 1) {
     1081                zones.count = 0;
     1082                irq_spinlock_initialize(&zones.lock, "frame.zones.lock");
     1083                mutex_initialize(&mem_avail_mtx, MUTEX_ACTIVE);
     1084                condvar_initialize(&mem_avail_cv);
     1085        }
     1086
    11021087        /* Tell the architecture to create some memory */
    11031088        frame_low_arch_init();
     
    11061091                frame_mark_unavailable(ADDR2PFN(KA2PA(config.base)),
    11071092                    SIZE2FRAMES(config.kernel_size));
     1093                frame_mark_unavailable(ADDR2PFN(KA2PA(config.stack_base)),
     1094                    SIZE2FRAMES(config.stack_size));
    11081095
    11091096                for (size_t i = 0; i < init.cnt; i++)
Note: See TracChangeset for help on using the changeset viewer.