Ignore:
File:
1 edited

Legend:

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

    r05411e8 raf96dd57  
    6666 * available.
    6767 */
    68 mutex_t mem_avail_mtx;
    69 condvar_t mem_avail_cv;
    70 size_t mem_avail_req = 0;  /**< Number of frames requested. */
    71 size_t mem_avail_gen = 0;  /**< Generation counter. */
     68static mutex_t mem_avail_mtx;
     69static condvar_t mem_avail_cv;
     70static size_t mem_avail_req = 0;  /**< Number of frames requested. */
     71static size_t mem_avail_gen = 0;  /**< Generation counter. */
    7272
    7373/********************/
     
    7575/********************/
    7676
    77 static inline size_t frame_index(zone_t *zone, frame_t *frame)
     77NO_TRACE static inline size_t frame_index(zone_t *zone, frame_t *frame)
    7878{
    7979        return (size_t) (frame - zone->frames);
    8080}
    8181
    82 static inline size_t frame_index_abs(zone_t *zone, frame_t *frame)
     82NO_TRACE static 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 static inline bool frame_index_valid(zone_t *zone, size_t index)
     87NO_TRACE static inline bool frame_index_valid(zone_t *zone, size_t index)
    8888{
    8989        return (index < zone->count);
    9090}
    9191
    92 static inline size_t make_frame_index(zone_t *zone, frame_t *frame)
     92NO_TRACE static inline size_t make_frame_index(zone_t *zone, frame_t *frame)
    9393{
    9494        return (frame - zone->frames);
     
    100100 *
    101101 */
    102 static void frame_initialize(frame_t *frame)
     102NO_TRACE static void frame_initialize(frame_t *frame)
    103103{
    104104        frame->refcount = 1;
     
    121121 *
    122122 */
    123 static size_t zones_insert_zone(pfn_t base, size_t count)
     123NO_TRACE static size_t zones_insert_zone(pfn_t base, size_t count,
     124    zone_flags_t flags)
    124125{
    125126        if (zones.count + 1 == ZONES_MAX) {
     
    131132        for (i = 0; i < zones.count; i++) {
    132133                /* Check for overlap */
    133                 if (overlaps(base, count,
    134                     zones.info[i].base, zones.info[i].count)) {
    135                         printf("Zones overlap!\n");
     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                       
    136153                        return (size_t) -1;
    137154                }
     
    144161        for (j = zones.count; j > i; j--) {
    145162                zones.info[j] = zones.info[j - 1];
    146                 zones.info[j].buddy_system->data =
    147                     (void *) &zones.info[j - 1];
     163                if (zones.info[j].buddy_system != NULL)
     164                        zones.info[j].buddy_system->data =
     165                            (void *) &zones.info[j];
    148166        }
    149167       
     
    162180 */
    163181#ifdef CONFIG_DEBUG
    164 static size_t total_frames_free(void)
     182NO_TRACE static size_t total_frames_free(void)
    165183{
    166184        size_t total = 0;
     
    171189        return total;
    172190}
    173 #endif
     191#endif /* CONFIG_DEBUG */
    174192
    175193/** Find a zone with a given frames.
     
    185203 *
    186204 */
    187 size_t find_zone(pfn_t frame, size_t count, size_t hint)
     205NO_TRACE size_t find_zone(pfn_t frame, size_t count, size_t hint)
    188206{
    189207        if (hint >= zones.count)
     
    199217                if (i >= zones.count)
    200218                        i = 0;
     219               
    201220        } while (i != hint);
    202221       
     
    205224
    206225/** @return True if zone can allocate specified order */
    207 static bool zone_can_alloc(zone_t *zone, uint8_t order)
     226NO_TRACE static bool zone_can_alloc(zone_t *zone, uint8_t order)
    208227{
    209228        return (zone_flags_available(zone->flags)
     
    221240 *
    222241 */
    223 static size_t find_free_zone(uint8_t order, zone_flags_t flags, size_t hint)
     242NO_TRACE static size_t find_free_zone(uint8_t order, zone_flags_t flags,
     243    size_t hint)
    224244{
    225245        if (hint >= zones.count)
     
    242262                if (i >= zones.count)
    243263                        i = 0;
     264               
    244265        } while (i != hint);
    245266       
     
    260281 *
    261282 */
    262 static link_t *zone_buddy_find_block(buddy_system_t *buddy, link_t *child,
    263     uint8_t order)
     283NO_TRACE static link_t *zone_buddy_find_block(buddy_system_t *buddy,
     284    link_t *child, uint8_t order)
    264285{
    265286        frame_t *frame = list_get_instance(child, frame_t, buddy_link);
     
    283304 *
    284305 */
    285 static link_t *zone_buddy_find_buddy(buddy_system_t *buddy, link_t *block)
     306NO_TRACE static link_t *zone_buddy_find_buddy(buddy_system_t *buddy,
     307    link_t *block)
    286308{
    287309        frame_t *frame = list_get_instance(block, frame_t, buddy_link);
     
    296318                index = (frame_index(zone, frame)) +
    297319                    (1 << frame->buddy_order);
    298         } else {        /* is_right */
     320        } else {  /* is_right */
    299321                index = (frame_index(zone, frame)) -
    300322                    (1 << frame->buddy_order);
     
    319341 *
    320342 */
    321 static link_t *zone_buddy_bisect(buddy_system_t *buddy, link_t *block)
     343NO_TRACE static link_t *zone_buddy_bisect(buddy_system_t *buddy, link_t *block)
    322344{
    323345        frame_t *frame_l = list_get_instance(block, frame_t, buddy_link);
     
    337359 *
    338360 */
    339 static link_t *zone_buddy_coalesce(buddy_system_t *buddy, link_t *block_1,
    340     link_t *block_2)
     361NO_TRACE static link_t *zone_buddy_coalesce(buddy_system_t *buddy,
     362    link_t *block_1, link_t *block_2)
    341363{
    342364        frame_t *frame1 = list_get_instance(block_1, frame_t, buddy_link);
     
    353375 *
    354376 */
    355 static void zone_buddy_set_order(buddy_system_t *buddy, link_t *block,
     377NO_TRACE static void zone_buddy_set_order(buddy_system_t *buddy, link_t *block,
    356378    uint8_t order)
    357379{
     
    367389 *
    368390 */
    369 static uint8_t zone_buddy_get_order(buddy_system_t *buddy, link_t *block)
     391NO_TRACE static uint8_t zone_buddy_get_order(buddy_system_t *buddy,
     392    link_t *block)
    370393{
    371394        return list_get_instance(block, frame_t, buddy_link)->buddy_order;
     
    378401 *
    379402 */
    380 static void zone_buddy_mark_busy(buddy_system_t *buddy, link_t * block)
     403NO_TRACE static void zone_buddy_mark_busy(buddy_system_t *buddy, link_t *block)
    381404{
    382405        list_get_instance(block, frame_t, buddy_link)->refcount = 1;
     
    387410 * @param buddy Buddy system.
    388411 * @param block Buddy system block.
    389  */
    390 static void zone_buddy_mark_available(buddy_system_t *buddy, link_t *block)
     412 *
     413 */
     414NO_TRACE static void zone_buddy_mark_available(buddy_system_t *buddy,
     415    link_t *block)
    391416{
    392417        list_get_instance(block, frame_t, buddy_link)->refcount = 0;
     
    419444 *
    420445 */
    421 static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order)
     446NO_TRACE static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order)
    422447{
    423448        ASSERT(zone_flags_available(zone->flags));
     
    447472 *
    448473 */
    449 static void zone_frame_free(zone_t *zone, size_t frame_idx)
     474NO_TRACE static void zone_frame_free(zone_t *zone, size_t frame_idx)
    450475{
    451476        ASSERT(zone_flags_available(zone->flags));
     
    468493
    469494/** Return frame from zone. */
    470 static frame_t *zone_get_frame(zone_t *zone, size_t frame_idx)
     495NO_TRACE static frame_t *zone_get_frame(zone_t *zone, size_t frame_idx)
    471496{
    472497        ASSERT(frame_idx < zone->count);
     
    475500
    476501/** Mark frame in zone unavailable to allocation. */
    477 static void zone_mark_unavailable(zone_t *zone, size_t frame_idx)
     502NO_TRACE static void zone_mark_unavailable(zone_t *zone, size_t frame_idx)
    478503{
    479504        ASSERT(zone_flags_available(zone->flags));
     
    504529 *
    505530 */
    506 static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1, buddy_system_t *buddy)
     531NO_TRACE static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1,
     532    buddy_system_t *buddy)
    507533{
    508534        ASSERT(zone_flags_available(zones.info[z1].flags));
     
    600626 *
    601627 */
    602 static void return_config_frames(size_t znum, pfn_t pfn, size_t count)
     628NO_TRACE static void return_config_frames(size_t znum, pfn_t pfn, size_t count)
    603629{
    604630        ASSERT(zone_flags_available(zones.info[znum].flags));
     
    635661 *
    636662 */
    637 static void zone_reduce_region(size_t znum, pfn_t frame_idx, size_t count)
     663NO_TRACE static void zone_reduce_region(size_t znum, pfn_t frame_idx,
     664    size_t count)
    638665{
    639666        ASSERT(zone_flags_available(zones.info[znum].flags));
     
    673700bool zone_merge(size_t z1, size_t z2)
    674701{
    675         ipl_t ipl = interrupts_disable();
    676         spinlock_lock(&zones.lock);
     702        irq_spinlock_lock(&zones.lock, true);
    677703       
    678704        bool ret = true;
     
    737763        for (i = z2 + 1; i < zones.count; i++) {
    738764                zones.info[i - 1] = zones.info[i];
    739                 zones.info[i - 1].buddy_system->data =
    740                     (void *) &zones.info[i - 1];
     765                if (zones.info[i - 1].buddy_system != NULL)
     766                        zones.info[i - 1].buddy_system->data =
     767                            (void *) &zones.info[i - 1];
    741768        }
    742769       
     
    744771       
    745772errout:
    746         spinlock_unlock(&zones.lock);
    747         interrupts_restore(ipl);
     773        irq_spinlock_unlock(&zones.lock, true);
    748774       
    749775        return ret;
     
    777803 *
    778804 */
    779 static void zone_construct(zone_t *zone, buddy_system_t *buddy, pfn_t start, size_t count, zone_flags_t flags)
     805NO_TRACE static void zone_construct(zone_t *zone, buddy_system_t *buddy,
     806    pfn_t start, size_t count, zone_flags_t flags)
    780807{
    781808        zone->base = start;
     
    820847 *
    821848 */
    822 uintptr_t zone_conf_size(size_t count)
     849size_t zone_conf_size(size_t count)
    823850{
    824851        return (count * sizeof(frame_t) + buddy_conf_size(fnzb(count)));
     
    841868 *
    842869 */
    843 size_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);
     870size_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);
    847874       
    848875        if (zone_flags_available(flags)) {  /* Create available zone */
     
    887914                }
    888915               
    889                 size_t znum = zones_insert_zone(start, count);
     916                size_t znum = zones_insert_zone(start, count, flags);
    890917                if (znum == (size_t) -1) {
    891                         spinlock_unlock(&zones.lock);
    892                         interrupts_restore(ipl);
     918                        irq_spinlock_unlock(&zones.lock, true);
    893919                        return (size_t) -1;
    894920                }
     
    905931                }
    906932               
    907                 spinlock_unlock(&zones.lock);
    908                 interrupts_restore(ipl);
     933                irq_spinlock_unlock(&zones.lock, true);
    909934               
    910935                return znum;
     
    912937       
    913938        /* Non-available zone */
    914         size_t znum = zones_insert_zone(start, count);
     939        size_t znum = zones_insert_zone(start, count, flags);
    915940        if (znum == (size_t) -1) {
    916                 spinlock_unlock(&zones.lock);
    917                 interrupts_restore(ipl);
     941                irq_spinlock_unlock(&zones.lock, true);
    918942                return (size_t) -1;
    919943        }
    920944        zone_construct(&zones.info[znum], NULL, start, count, flags);
    921945       
    922         spinlock_unlock(&zones.lock);
    923         interrupts_restore(ipl);
     946        irq_spinlock_unlock(&zones.lock, true);
    924947       
    925948        return znum;
     
    933956void frame_set_parent(pfn_t pfn, void *data, size_t hint)
    934957{
    935         ipl_t ipl = interrupts_disable();
    936         spinlock_lock(&zones.lock);
     958        irq_spinlock_lock(&zones.lock, true);
    937959       
    938960        size_t znum = find_zone(pfn, 1, hint);
     
    943965            pfn - zones.info[znum].base)->parent = data;
    944966       
    945         spinlock_unlock(&zones.lock);
    946         interrupts_restore(ipl);
     967        irq_spinlock_unlock(&zones.lock, true);
    947968}
    948969
    949970void *frame_get_parent(pfn_t pfn, size_t hint)
    950971{
    951         ipl_t ipl = interrupts_disable();
    952         spinlock_lock(&zones.lock);
     972        irq_spinlock_lock(&zones.lock, true);
    953973       
    954974        size_t znum = find_zone(pfn, 1, hint);
     
    959979            pfn - zones.info[znum].base)->parent;
    960980       
    961         spinlock_unlock(&zones.lock);
    962         interrupts_restore(ipl);
     981        irq_spinlock_unlock(&zones.lock, true);
    963982       
    964983        return res;
     
    977996{
    978997        size_t size = ((size_t) 1) << order;
    979         ipl_t ipl;
    980998        size_t hint = pzone ? (*pzone) : 0;
    981999       
    9821000loop:
    983         ipl = interrupts_disable();
    984         spinlock_lock(&zones.lock);
     1001        irq_spinlock_lock(&zones.lock, true);
    9851002       
    9861003        /*
     
    9931010           if it does not help, reclaim all */
    9941011        if ((znum == (size_t) -1) && (!(flags & FRAME_NO_RECLAIM))) {
    995                 spinlock_unlock(&zones.lock);
    996                 interrupts_restore(ipl);
    997                
     1012                irq_spinlock_unlock(&zones.lock, true);
    9981013                size_t freed = slab_reclaim(0);
    999                
    1000                 ipl = interrupts_disable();
    1001                 spinlock_lock(&zones.lock);
     1014                irq_spinlock_lock(&zones.lock, true);
    10021015               
    10031016                if (freed > 0)
     
    10061019               
    10071020                if (znum == (size_t) -1) {
    1008                         spinlock_unlock(&zones.lock);
    1009                         interrupts_restore(ipl);
    1010                        
     1021                        irq_spinlock_unlock(&zones.lock, true);
    10111022                        freed = slab_reclaim(SLAB_RECLAIM_ALL);
    1012                        
    1013                         ipl = interrupts_disable();
    1014                         spinlock_lock(&zones.lock);
     1023                        irq_spinlock_lock(&zones.lock, true);
    10151024                       
    10161025                        if (freed > 0)
     
    10221031        if (znum == (size_t) -1) {
    10231032                if (flags & FRAME_ATOMIC) {
    1024                         spinlock_unlock(&zones.lock);
    1025                         interrupts_restore(ipl);
     1033                        irq_spinlock_unlock(&zones.lock, true);
    10261034                        return NULL;
    10271035                }
     
    10311039#endif
    10321040               
    1033                 spinlock_unlock(&zones.lock);
    1034                 interrupts_restore(ipl);
    1035 
     1041                irq_spinlock_unlock(&zones.lock, true);
     1042               
    10361043                if (!THREAD)
    10371044                        panic("Cannot wait for memory to become available.");
     
    10691076            + zones.info[znum].base;
    10701077       
    1071         spinlock_unlock(&zones.lock);
    1072         interrupts_restore(ipl);
     1078        irq_spinlock_unlock(&zones.lock, true);
    10731079       
    10741080        if (pzone)
     
    10921098void frame_free(uintptr_t frame)
    10931099{
    1094         ipl_t ipl = interrupts_disable();
    1095         spinlock_lock(&zones.lock);
     1100        irq_spinlock_lock(&zones.lock, true);
    10961101       
    10971102        /*
     
    11051110        zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
    11061111       
    1107         spinlock_unlock(&zones.lock);
    1108         interrupts_restore(ipl);
     1112        irq_spinlock_unlock(&zones.lock, true);
    11091113       
    11101114        /*
     
    11301134 *
    11311135 */
    1132 void frame_reference_add(pfn_t pfn)
    1133 {
    1134         ipl_t ipl = interrupts_disable();
    1135         spinlock_lock(&zones.lock);
     1136NO_TRACE void frame_reference_add(pfn_t pfn)
     1137{
     1138        irq_spinlock_lock(&zones.lock, true);
    11361139       
    11371140        /*
     
    11441147        zones.info[znum].frames[pfn - zones.info[znum].base].refcount++;
    11451148       
    1146         spinlock_unlock(&zones.lock);
    1147         interrupts_restore(ipl);
    1148 }
    1149 
    1150 /** Mark given range unavailable in frame zones. */
    1151 void frame_mark_unavailable(pfn_t start, size_t count)
    1152 {
    1153         ipl_t ipl = interrupts_disable();
    1154         spinlock_lock(&zones.lock);
     1149        irq_spinlock_unlock(&zones.lock, true);
     1150}
     1151
     1152/** Mark given range unavailable in frame zones.
     1153 *
     1154 */
     1155NO_TRACE void frame_mark_unavailable(pfn_t start, size_t count)
     1156{
     1157        irq_spinlock_lock(&zones.lock, true);
    11551158       
    11561159        size_t i;
     
    11641167        }
    11651168       
    1166         spinlock_unlock(&zones.lock);
    1167         interrupts_restore(ipl);
    1168 }
    1169 
    1170 /** Initialize physical memory management. */
     1169        irq_spinlock_unlock(&zones.lock, true);
     1170}
     1171
     1172/** Initialize physical memory management.
     1173 *
     1174 */
    11711175void frame_init(void)
    11721176{
    11731177        if (config.cpu_active == 1) {
    11741178                zones.count = 0;
    1175                 spinlock_initialize(&zones.lock, "zones.lock");
     1179                irq_spinlock_initialize(&zones.lock, "frame.zones.lock");
    11761180                mutex_initialize(&mem_avail_mtx, MUTEX_ACTIVE);
    11771181                condvar_initialize(&mem_avail_cv);
     
    12041208}
    12051209
    1206 /** Return total size of all zones. */
     1210/** Return total size of all zones.
     1211 *
     1212 */
    12071213uint64_t zones_total_size(void)
    12081214{
    1209         ipl_t ipl = interrupts_disable();
    1210         spinlock_lock(&zones.lock);
     1215        irq_spinlock_lock(&zones.lock, true);
    12111216       
    12121217        uint64_t total = 0;
     
    12151220                total += (uint64_t) FRAMES2SIZE(zones.info[i].count);
    12161221       
    1217         spinlock_unlock(&zones.lock);
    1218         interrupts_restore(ipl);
     1222        irq_spinlock_unlock(&zones.lock, true);
    12191223       
    12201224        return total;
     
    12291233        ASSERT(free != NULL);
    12301234       
    1231         ipl_t ipl = interrupts_disable();
    1232         spinlock_lock(&zones.lock);
     1235        irq_spinlock_lock(&zones.lock, true);
    12331236       
    12341237        *total = 0;
     
    12481251        }
    12491252       
    1250         spinlock_unlock(&zones.lock);
    1251         interrupts_restore(ipl);
    1252 }
    1253 
    1254 /** Prints list of zones. */
     1253        irq_spinlock_unlock(&zones.lock, true);
     1254}
     1255
     1256/** Prints list of zones.
     1257 *
     1258 */
    12551259void zones_print_list(void)
    12561260{
    12571261#ifdef __32_BITS__
    1258         printf("#  base address frames       flags    free frames  busy frames\n");
    1259         printf("-- ------------ ------------ -------- ------------ ------------\n");
     1262        printf("[nr] [base addr] [frames    ] [flags ] [free frames ] [busy frames ]\n");
    12601263#endif
    12611264
    12621265#ifdef __64_BITS__
    1263         printf("#  base address          frames      flags    free frames  busy frames\n");
    1264         printf("-- -------------------- ------------ -------- ------------ ------------\n");
     1266        printf("[nr] [base address    ] [frames    ] [flags ] [free frames ] [busy frames ]\n");
    12651267#endif
    12661268       
     
    12781280        size_t i;
    12791281        for (i = 0;; i++) {
    1280                 ipl_t ipl = interrupts_disable();
    1281                 spinlock_lock(&zones.lock);
     1282                irq_spinlock_lock(&zones.lock, true);
    12821283               
    12831284                if (i >= zones.count) {
    1284                         spinlock_unlock(&zones.lock);
    1285                         interrupts_restore(ipl);
     1285                        irq_spinlock_unlock(&zones.lock, true);
    12861286                        break;
    12871287                }
     
    12931293                size_t busy_count = zones.info[i].busy_count;
    12941294               
    1295                 spinlock_unlock(&zones.lock);
    1296                 interrupts_restore(ipl);
     1295                irq_spinlock_unlock(&zones.lock, true);
    12971296               
    12981297                bool available = zone_flags_available(flags);
    12991298               
    1300                 printf("%-2" PRIs, i);
     1299                printf("%-4" PRIs, i);
    13011300               
    13021301#ifdef __32_BITS__
    1303                 printf("   %10p", base);
     1302                printf("  %10p", base);
    13041303#endif
    13051304               
    13061305#ifdef __64_BITS__
    1307                 printf("   %18p", base);
     1306                printf(" %18p", base);
    13081307#endif
    13091308               
     
    13141313               
    13151314                if (available)
    1316                         printf("%12" PRIs " %12" PRIs,
     1315                        printf("%14" PRIs " %14" PRIs,
    13171316                            free_count, busy_count);
    13181317               
     
    13281327void zone_print_one(size_t num)
    13291328{
    1330         ipl_t ipl = interrupts_disable();
    1331         spinlock_lock(&zones.lock);
     1329        irq_spinlock_lock(&zones.lock, true);
    13321330        size_t znum = (size_t) -1;
    13331331       
     
    13411339       
    13421340        if (znum == (size_t) -1) {
    1343                 spinlock_unlock(&zones.lock);
    1344                 interrupts_restore(ipl);
     1341                irq_spinlock_unlock(&zones.lock, true);
    13451342                printf("Zone not found.\n");
    13461343                return;
     
    13531350        size_t busy_count = zones.info[i].busy_count;
    13541351       
    1355         spinlock_unlock(&zones.lock);
    1356         interrupts_restore(ipl);
     1352        irq_spinlock_unlock(&zones.lock, true);
    13571353       
    13581354        bool available = zone_flags_available(flags);
Note: See TracChangeset for help on using the changeset viewer.