Ignore:
File:
1 edited

Legend:

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

    raf96dd57 r05411e8  
    6666 * available.
    6767 */
    68 static mutex_t mem_avail_mtx;
    69 static condvar_t mem_avail_cv;
    70 static size_t mem_avail_req = 0;  /**< Number of frames requested. */
    71 static size_t mem_avail_gen = 0;  /**< Generation counter. */
     68mutex_t mem_avail_mtx;
     69condvar_t mem_avail_cv;
     70size_t mem_avail_req = 0;  /**< Number of frames requested. */
     71size_t mem_avail_gen = 0;  /**< Generation counter. */
    7272
    7373/********************/
     
    7575/********************/
    7676
    77 NO_TRACE static inline size_t frame_index(zone_t *zone, frame_t *frame)
     77static inline size_t frame_index(zone_t *zone, frame_t *frame)
    7878{
    7979        return (size_t) (frame - zone->frames);
    8080}
    8181
    82 NO_TRACE static inline size_t frame_index_abs(zone_t *zone, frame_t *frame)
     82static inline size_t frame_index_abs(zone_t *zone, frame_t *frame)
    8383{
    8484        return (size_t) (frame - zone->frames) + zone->base;
    8585}
    8686
    87 NO_TRACE static inline bool frame_index_valid(zone_t *zone, size_t index)
     87static inline bool frame_index_valid(zone_t *zone, size_t index)
    8888{
    8989        return (index < zone->count);
    9090}
    9191
    92 NO_TRACE static inline size_t make_frame_index(zone_t *zone, frame_t *frame)
     92static inline size_t make_frame_index(zone_t *zone, frame_t *frame)
    9393{
    9494        return (frame - zone->frames);
     
    100100 *
    101101 */
    102 NO_TRACE static void frame_initialize(frame_t *frame)
     102static void frame_initialize(frame_t *frame)
    103103{
    104104        frame->refcount = 1;
     
    121121 *
    122122 */
    123 NO_TRACE static size_t zones_insert_zone(pfn_t base, size_t count,
    124     zone_flags_t flags)
     123static size_t zones_insert_zone(pfn_t base, size_t count)
    125124{
    126125        if (zones.count + 1 == ZONES_MAX) {
     
    132131        for (i = 0; i < zones.count; i++) {
    133132                /* Check for overlap */
    134                 if (overlaps(zones.info[i].base, zones.info[i].count,
    135                     base, count)) {
    136                        
    137                         /*
    138                          * If the overlaping zones are of the same type
    139                          * and the new zone is completely within the previous
    140                          * one, then quietly ignore the new zone.
    141                          *
    142                          */
    143                        
    144                         if ((zones.info[i].flags != flags) ||
    145                             (!iswithin(zones.info[i].base, zones.info[i].count,
    146                             base, count))) {
    147                                 printf("Zone (%p, %p) overlaps with previous zone (%p, %p)!\n",
    148                                     PFN2ADDR(base), PFN2ADDR(count),
    149                                     PFN2ADDR(zones.info[i].base),
    150                                     PFN2ADDR(zones.info[i].count));
    151                         }
    152                        
     133                if (overlaps(base, count,
     134                    zones.info[i].base, zones.info[i].count)) {
     135                        printf("Zones overlap!\n");
    153136                        return (size_t) -1;
    154137                }
     
    161144        for (j = zones.count; j > i; j--) {
    162145                zones.info[j] = zones.info[j - 1];
    163                 if (zones.info[j].buddy_system != NULL)
    164                         zones.info[j].buddy_system->data =
    165                             (void *) &zones.info[j];
     146                zones.info[j].buddy_system->data =
     147                    (void *) &zones.info[j - 1];
    166148        }
    167149       
     
    180162 */
    181163#ifdef CONFIG_DEBUG
    182 NO_TRACE static size_t total_frames_free(void)
     164static size_t total_frames_free(void)
    183165{
    184166        size_t total = 0;
     
    189171        return total;
    190172}
    191 #endif /* CONFIG_DEBUG */
     173#endif
    192174
    193175/** Find a zone with a given frames.
     
    203185 *
    204186 */
    205 NO_TRACE size_t find_zone(pfn_t frame, size_t count, size_t hint)
     187size_t find_zone(pfn_t frame, size_t count, size_t hint)
    206188{
    207189        if (hint >= zones.count)
     
    217199                if (i >= zones.count)
    218200                        i = 0;
    219                
    220201        } while (i != hint);
    221202       
     
    224205
    225206/** @return True if zone can allocate specified order */
    226 NO_TRACE static bool zone_can_alloc(zone_t *zone, uint8_t order)
     207static bool zone_can_alloc(zone_t *zone, uint8_t order)
    227208{
    228209        return (zone_flags_available(zone->flags)
     
    240221 *
    241222 */
    242 NO_TRACE static size_t find_free_zone(uint8_t order, zone_flags_t flags,
    243     size_t hint)
     223static size_t find_free_zone(uint8_t order, zone_flags_t flags, size_t hint)
    244224{
    245225        if (hint >= zones.count)
     
    262242                if (i >= zones.count)
    263243                        i = 0;
    264                
    265244        } while (i != hint);
    266245       
     
    281260 *
    282261 */
    283 NO_TRACE static link_t *zone_buddy_find_block(buddy_system_t *buddy,
    284     link_t *child, uint8_t order)
     262static link_t *zone_buddy_find_block(buddy_system_t *buddy, link_t *child,
     263    uint8_t order)
    285264{
    286265        frame_t *frame = list_get_instance(child, frame_t, buddy_link);
     
    304283 *
    305284 */
    306 NO_TRACE static link_t *zone_buddy_find_buddy(buddy_system_t *buddy,
    307     link_t *block)
     285static link_t *zone_buddy_find_buddy(buddy_system_t *buddy, link_t *block)
    308286{
    309287        frame_t *frame = list_get_instance(block, frame_t, buddy_link);
     
    318296                index = (frame_index(zone, frame)) +
    319297                    (1 << frame->buddy_order);
    320         } else {  /* is_right */
     298        } else {        /* is_right */
    321299                index = (frame_index(zone, frame)) -
    322300                    (1 << frame->buddy_order);
     
    341319 *
    342320 */
    343 NO_TRACE static link_t *zone_buddy_bisect(buddy_system_t *buddy, link_t *block)
     321static link_t *zone_buddy_bisect(buddy_system_t *buddy, link_t *block)
    344322{
    345323        frame_t *frame_l = list_get_instance(block, frame_t, buddy_link);
     
    359337 *
    360338 */
    361 NO_TRACE static link_t *zone_buddy_coalesce(buddy_system_t *buddy,
    362     link_t *block_1, link_t *block_2)
     339static link_t *zone_buddy_coalesce(buddy_system_t *buddy, link_t *block_1,
     340    link_t *block_2)
    363341{
    364342        frame_t *frame1 = list_get_instance(block_1, frame_t, buddy_link);
     
    375353 *
    376354 */
    377 NO_TRACE static void zone_buddy_set_order(buddy_system_t *buddy, link_t *block,
     355static void zone_buddy_set_order(buddy_system_t *buddy, link_t *block,
    378356    uint8_t order)
    379357{
     
    389367 *
    390368 */
    391 NO_TRACE static uint8_t zone_buddy_get_order(buddy_system_t *buddy,
    392     link_t *block)
     369static uint8_t zone_buddy_get_order(buddy_system_t *buddy, link_t *block)
    393370{
    394371        return list_get_instance(block, frame_t, buddy_link)->buddy_order;
     
    401378 *
    402379 */
    403 NO_TRACE static void zone_buddy_mark_busy(buddy_system_t *buddy, link_t *block)
     380static void zone_buddy_mark_busy(buddy_system_t *buddy, link_t * block)
    404381{
    405382        list_get_instance(block, frame_t, buddy_link)->refcount = 1;
     
    410387 * @param buddy Buddy system.
    411388 * @param block Buddy system block.
    412  *
    413  */
    414 NO_TRACE static void zone_buddy_mark_available(buddy_system_t *buddy,
    415     link_t *block)
     389 */
     390static void zone_buddy_mark_available(buddy_system_t *buddy, link_t *block)
    416391{
    417392        list_get_instance(block, frame_t, buddy_link)->refcount = 0;
     
    444419 *
    445420 */
    446 NO_TRACE static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order)
     421static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order)
    447422{
    448423        ASSERT(zone_flags_available(zone->flags));
     
    472447 *
    473448 */
    474 NO_TRACE static void zone_frame_free(zone_t *zone, size_t frame_idx)
     449static void zone_frame_free(zone_t *zone, size_t frame_idx)
    475450{
    476451        ASSERT(zone_flags_available(zone->flags));
     
    493468
    494469/** Return frame from zone. */
    495 NO_TRACE static frame_t *zone_get_frame(zone_t *zone, size_t frame_idx)
     470static frame_t *zone_get_frame(zone_t *zone, size_t frame_idx)
    496471{
    497472        ASSERT(frame_idx < zone->count);
     
    500475
    501476/** Mark frame in zone unavailable to allocation. */
    502 NO_TRACE static void zone_mark_unavailable(zone_t *zone, size_t frame_idx)
     477static void zone_mark_unavailable(zone_t *zone, size_t frame_idx)
    503478{
    504479        ASSERT(zone_flags_available(zone->flags));
     
    529504 *
    530505 */
    531 NO_TRACE static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1,
    532     buddy_system_t *buddy)
     506static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1, buddy_system_t *buddy)
    533507{
    534508        ASSERT(zone_flags_available(zones.info[z1].flags));
     
    626600 *
    627601 */
    628 NO_TRACE static void return_config_frames(size_t znum, pfn_t pfn, size_t count)
     602static void return_config_frames(size_t znum, pfn_t pfn, size_t count)
    629603{
    630604        ASSERT(zone_flags_available(zones.info[znum].flags));
     
    661635 *
    662636 */
    663 NO_TRACE static void zone_reduce_region(size_t znum, pfn_t frame_idx,
    664     size_t count)
     637static void zone_reduce_region(size_t znum, pfn_t frame_idx, size_t count)
    665638{
    666639        ASSERT(zone_flags_available(zones.info[znum].flags));
     
    700673bool zone_merge(size_t z1, size_t z2)
    701674{
    702         irq_spinlock_lock(&zones.lock, true);
     675        ipl_t ipl = interrupts_disable();
     676        spinlock_lock(&zones.lock);
    703677       
    704678        bool ret = true;
     
    763737        for (i = z2 + 1; i < zones.count; i++) {
    764738                zones.info[i - 1] = zones.info[i];
    765                 if (zones.info[i - 1].buddy_system != NULL)
    766                         zones.info[i - 1].buddy_system->data =
    767                             (void *) &zones.info[i - 1];
     739                zones.info[i - 1].buddy_system->data =
     740                    (void *) &zones.info[i - 1];
    768741        }
    769742       
     
    771744       
    772745errout:
    773         irq_spinlock_unlock(&zones.lock, true);
     746        spinlock_unlock(&zones.lock);
     747        interrupts_restore(ipl);
    774748       
    775749        return ret;
     
    803777 *
    804778 */
    805 NO_TRACE static void zone_construct(zone_t *zone, buddy_system_t *buddy,
    806     pfn_t start, size_t count, zone_flags_t flags)
     779static void zone_construct(zone_t *zone, buddy_system_t *buddy, pfn_t start, size_t count, zone_flags_t flags)
    807780{
    808781        zone->base = start;
     
    847820 *
    848821 */
    849 size_t zone_conf_size(size_t count)
     822uintptr_t zone_conf_size(size_t count)
    850823{
    851824        return (count * sizeof(frame_t) + buddy_conf_size(fnzb(count)));
     
    868841 *
    869842 */
    870 size_t zone_create(pfn_t start, size_t count, pfn_t confframe,
    871     zone_flags_t flags)
    872 {
    873         irq_spinlock_lock(&zones.lock, true);
     843size_t zone_create(pfn_t start, size_t count, pfn_t confframe, zone_flags_t flags)
     844{
     845        ipl_t ipl = interrupts_disable();
     846        spinlock_lock(&zones.lock);
    874847       
    875848        if (zone_flags_available(flags)) {  /* Create available zone */
     
    914887                }
    915888               
    916                 size_t znum = zones_insert_zone(start, count, flags);
     889                size_t znum = zones_insert_zone(start, count);
    917890                if (znum == (size_t) -1) {
    918                         irq_spinlock_unlock(&zones.lock, true);
     891                        spinlock_unlock(&zones.lock);
     892                        interrupts_restore(ipl);
    919893                        return (size_t) -1;
    920894                }
     
    931905                }
    932906               
    933                 irq_spinlock_unlock(&zones.lock, true);
     907                spinlock_unlock(&zones.lock);
     908                interrupts_restore(ipl);
    934909               
    935910                return znum;
     
    937912       
    938913        /* Non-available zone */
    939         size_t znum = zones_insert_zone(start, count, flags);
     914        size_t znum = zones_insert_zone(start, count);
    940915        if (znum == (size_t) -1) {
    941                 irq_spinlock_unlock(&zones.lock, true);
     916                spinlock_unlock(&zones.lock);
     917                interrupts_restore(ipl);
    942918                return (size_t) -1;
    943919        }
    944920        zone_construct(&zones.info[znum], NULL, start, count, flags);
    945921       
    946         irq_spinlock_unlock(&zones.lock, true);
     922        spinlock_unlock(&zones.lock);
     923        interrupts_restore(ipl);
    947924       
    948925        return znum;
     
    956933void frame_set_parent(pfn_t pfn, void *data, size_t hint)
    957934{
    958         irq_spinlock_lock(&zones.lock, true);
     935        ipl_t ipl = interrupts_disable();
     936        spinlock_lock(&zones.lock);
    959937       
    960938        size_t znum = find_zone(pfn, 1, hint);
     
    965943            pfn - zones.info[znum].base)->parent = data;
    966944       
    967         irq_spinlock_unlock(&zones.lock, true);
     945        spinlock_unlock(&zones.lock);
     946        interrupts_restore(ipl);
    968947}
    969948
    970949void *frame_get_parent(pfn_t pfn, size_t hint)
    971950{
    972         irq_spinlock_lock(&zones.lock, true);
     951        ipl_t ipl = interrupts_disable();
     952        spinlock_lock(&zones.lock);
    973953       
    974954        size_t znum = find_zone(pfn, 1, hint);
     
    979959            pfn - zones.info[znum].base)->parent;
    980960       
    981         irq_spinlock_unlock(&zones.lock, true);
     961        spinlock_unlock(&zones.lock);
     962        interrupts_restore(ipl);
    982963       
    983964        return res;
     
    996977{
    997978        size_t size = ((size_t) 1) << order;
     979        ipl_t ipl;
    998980        size_t hint = pzone ? (*pzone) : 0;
    999981       
    1000982loop:
    1001         irq_spinlock_lock(&zones.lock, true);
     983        ipl = interrupts_disable();
     984        spinlock_lock(&zones.lock);
    1002985       
    1003986        /*
     
    1010993           if it does not help, reclaim all */
    1011994        if ((znum == (size_t) -1) && (!(flags & FRAME_NO_RECLAIM))) {
    1012                 irq_spinlock_unlock(&zones.lock, true);
     995                spinlock_unlock(&zones.lock);
     996                interrupts_restore(ipl);
     997               
    1013998                size_t freed = slab_reclaim(0);
    1014                 irq_spinlock_lock(&zones.lock, true);
     999               
     1000                ipl = interrupts_disable();
     1001                spinlock_lock(&zones.lock);
    10151002               
    10161003                if (freed > 0)
     
    10191006               
    10201007                if (znum == (size_t) -1) {
    1021                         irq_spinlock_unlock(&zones.lock, true);
     1008                        spinlock_unlock(&zones.lock);
     1009                        interrupts_restore(ipl);
     1010                       
    10221011                        freed = slab_reclaim(SLAB_RECLAIM_ALL);
    1023                         irq_spinlock_lock(&zones.lock, true);
     1012                       
     1013                        ipl = interrupts_disable();
     1014                        spinlock_lock(&zones.lock);
    10241015                       
    10251016                        if (freed > 0)
     
    10311022        if (znum == (size_t) -1) {
    10321023                if (flags & FRAME_ATOMIC) {
    1033                         irq_spinlock_unlock(&zones.lock, true);
     1024                        spinlock_unlock(&zones.lock);
     1025                        interrupts_restore(ipl);
    10341026                        return NULL;
    10351027                }
     
    10391031#endif
    10401032               
    1041                 irq_spinlock_unlock(&zones.lock, true);
    1042                
     1033                spinlock_unlock(&zones.lock);
     1034                interrupts_restore(ipl);
     1035
    10431036                if (!THREAD)
    10441037                        panic("Cannot wait for memory to become available.");
     
    10761069            + zones.info[znum].base;
    10771070       
    1078         irq_spinlock_unlock(&zones.lock, true);
     1071        spinlock_unlock(&zones.lock);
     1072        interrupts_restore(ipl);
    10791073       
    10801074        if (pzone)
     
    10981092void frame_free(uintptr_t frame)
    10991093{
    1100         irq_spinlock_lock(&zones.lock, true);
     1094        ipl_t ipl = interrupts_disable();
     1095        spinlock_lock(&zones.lock);
    11011096       
    11021097        /*
     
    11101105        zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
    11111106       
    1112         irq_spinlock_unlock(&zones.lock, true);
     1107        spinlock_unlock(&zones.lock);
     1108        interrupts_restore(ipl);
    11131109       
    11141110        /*
     
    11341130 *
    11351131 */
    1136 NO_TRACE void frame_reference_add(pfn_t pfn)
    1137 {
    1138         irq_spinlock_lock(&zones.lock, true);
     1132void frame_reference_add(pfn_t pfn)
     1133{
     1134        ipl_t ipl = interrupts_disable();
     1135        spinlock_lock(&zones.lock);
    11391136       
    11401137        /*
     
    11471144        zones.info[znum].frames[pfn - zones.info[znum].base].refcount++;
    11481145       
    1149         irq_spinlock_unlock(&zones.lock, true);
    1150 }
    1151 
    1152 /** Mark given range unavailable in frame zones.
    1153  *
    1154  */
    1155 NO_TRACE void frame_mark_unavailable(pfn_t start, size_t count)
    1156 {
    1157         irq_spinlock_lock(&zones.lock, true);
     1146        spinlock_unlock(&zones.lock);
     1147        interrupts_restore(ipl);
     1148}
     1149
     1150/** Mark given range unavailable in frame zones. */
     1151void frame_mark_unavailable(pfn_t start, size_t count)
     1152{
     1153        ipl_t ipl = interrupts_disable();
     1154        spinlock_lock(&zones.lock);
    11581155       
    11591156        size_t i;
     
    11671164        }
    11681165       
    1169         irq_spinlock_unlock(&zones.lock, true);
    1170 }
    1171 
    1172 /** Initialize physical memory management.
    1173  *
    1174  */
     1166        spinlock_unlock(&zones.lock);
     1167        interrupts_restore(ipl);
     1168}
     1169
     1170/** Initialize physical memory management. */
    11751171void frame_init(void)
    11761172{
    11771173        if (config.cpu_active == 1) {
    11781174                zones.count = 0;
    1179                 irq_spinlock_initialize(&zones.lock, "frame.zones.lock");
     1175                spinlock_initialize(&zones.lock, "zones.lock");
    11801176                mutex_initialize(&mem_avail_mtx, MUTEX_ACTIVE);
    11811177                condvar_initialize(&mem_avail_cv);
     
    12081204}
    12091205
    1210 /** Return total size of all zones.
    1211  *
    1212  */
     1206/** Return total size of all zones. */
    12131207uint64_t zones_total_size(void)
    12141208{
    1215         irq_spinlock_lock(&zones.lock, true);
     1209        ipl_t ipl = interrupts_disable();
     1210        spinlock_lock(&zones.lock);
    12161211       
    12171212        uint64_t total = 0;
     
    12201215                total += (uint64_t) FRAMES2SIZE(zones.info[i].count);
    12211216       
    1222         irq_spinlock_unlock(&zones.lock, true);
     1217        spinlock_unlock(&zones.lock);
     1218        interrupts_restore(ipl);
    12231219       
    12241220        return total;
     
    12331229        ASSERT(free != NULL);
    12341230       
    1235         irq_spinlock_lock(&zones.lock, true);
     1231        ipl_t ipl = interrupts_disable();
     1232        spinlock_lock(&zones.lock);
    12361233       
    12371234        *total = 0;
     
    12511248        }
    12521249       
    1253         irq_spinlock_unlock(&zones.lock, true);
    1254 }
    1255 
    1256 /** Prints list of zones.
    1257  *
    1258  */
     1250        spinlock_unlock(&zones.lock);
     1251        interrupts_restore(ipl);
     1252}
     1253
     1254/** Prints list of zones. */
    12591255void zones_print_list(void)
    12601256{
    12611257#ifdef __32_BITS__
    1262         printf("[nr] [base addr] [frames    ] [flags ] [free frames ] [busy frames ]\n");
     1258        printf("#  base address frames       flags    free frames  busy frames\n");
     1259        printf("-- ------------ ------------ -------- ------------ ------------\n");
    12631260#endif
    12641261
    12651262#ifdef __64_BITS__
    1266         printf("[nr] [base address    ] [frames    ] [flags ] [free frames ] [busy frames ]\n");
     1263        printf("#  base address          frames      flags    free frames  busy frames\n");
     1264        printf("-- -------------------- ------------ -------- ------------ ------------\n");
    12671265#endif
    12681266       
     
    12801278        size_t i;
    12811279        for (i = 0;; i++) {
    1282                 irq_spinlock_lock(&zones.lock, true);
     1280                ipl_t ipl = interrupts_disable();
     1281                spinlock_lock(&zones.lock);
    12831282               
    12841283                if (i >= zones.count) {
    1285                         irq_spinlock_unlock(&zones.lock, true);
     1284                        spinlock_unlock(&zones.lock);
     1285                        interrupts_restore(ipl);
    12861286                        break;
    12871287                }
     
    12931293                size_t busy_count = zones.info[i].busy_count;
    12941294               
    1295                 irq_spinlock_unlock(&zones.lock, true);
     1295                spinlock_unlock(&zones.lock);
     1296                interrupts_restore(ipl);
    12961297               
    12971298                bool available = zone_flags_available(flags);
    12981299               
    1299                 printf("%-4" PRIs, i);
     1300                printf("%-2" PRIs, i);
    13001301               
    13011302#ifdef __32_BITS__
    1302                 printf("  %10p", base);
     1303                printf("   %10p", base);
    13031304#endif
    13041305               
    13051306#ifdef __64_BITS__
    1306                 printf(" %18p", base);
     1307                printf("   %18p", base);
    13071308#endif
    13081309               
     
    13131314               
    13141315                if (available)
    1315                         printf("%14" PRIs " %14" PRIs,
     1316                        printf("%12" PRIs " %12" PRIs,
    13161317                            free_count, busy_count);
    13171318               
     
    13271328void zone_print_one(size_t num)
    13281329{
    1329         irq_spinlock_lock(&zones.lock, true);
     1330        ipl_t ipl = interrupts_disable();
     1331        spinlock_lock(&zones.lock);
    13301332        size_t znum = (size_t) -1;
    13311333       
     
    13391341       
    13401342        if (znum == (size_t) -1) {
    1341                 irq_spinlock_unlock(&zones.lock, true);
     1343                spinlock_unlock(&zones.lock);
     1344                interrupts_restore(ipl);
    13421345                printf("Zone not found.\n");
    13431346                return;
     
    13501353        size_t busy_count = zones.info[i].busy_count;
    13511354       
    1352         irq_spinlock_unlock(&zones.lock, true);
     1355        spinlock_unlock(&zones.lock);
     1356        interrupts_restore(ipl);
    13531357       
    13541358        bool available = zone_flags_available(flags);
Note: See TracChangeset for help on using the changeset viewer.