Ignore:
File:
1 edited

Legend:

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

    re2650d3 r98000fb  
    4343 */
    4444
    45 #include <typedefs.h>
     45#include <arch/types.h>
    4646#include <mm/frame.h>
    4747#include <mm/as.h>
     
    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                }
     
    179162 */
    180163#ifdef CONFIG_DEBUG
    181 NO_TRACE static size_t total_frames_free(void)
     164static size_t total_frames_free(void)
    182165{
    183166        size_t total = 0;
     
    188171        return total;
    189172}
    190 #endif /* CONFIG_DEBUG */
     173#endif
    191174
    192175/** Find a zone with a given frames.
     
    202185 *
    203186 */
    204 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)
    205188{
    206189        if (hint >= zones.count)
     
    216199                if (i >= zones.count)
    217200                        i = 0;
    218                
    219201        } while (i != hint);
    220202       
     
    223205
    224206/** @return True if zone can allocate specified order */
    225 NO_TRACE static bool zone_can_alloc(zone_t *zone, uint8_t order)
     207static bool zone_can_alloc(zone_t *zone, uint8_t order)
    226208{
    227209        return (zone_flags_available(zone->flags)
     
    239221 *
    240222 */
    241 NO_TRACE static size_t find_free_zone(uint8_t order, zone_flags_t flags,
    242     size_t hint)
     223static size_t find_free_zone(uint8_t order, zone_flags_t flags, size_t hint)
    243224{
    244225        if (hint >= zones.count)
     
    261242                if (i >= zones.count)
    262243                        i = 0;
    263                
    264244        } while (i != hint);
    265245       
     
    280260 *
    281261 */
    282 NO_TRACE static link_t *zone_buddy_find_block(buddy_system_t *buddy,
    283     link_t *child, uint8_t order)
     262static link_t *zone_buddy_find_block(buddy_system_t *buddy, link_t *child,
     263    uint8_t order)
    284264{
    285265        frame_t *frame = list_get_instance(child, frame_t, buddy_link);
     
    303283 *
    304284 */
    305 NO_TRACE static link_t *zone_buddy_find_buddy(buddy_system_t *buddy,
    306     link_t *block)
     285static link_t *zone_buddy_find_buddy(buddy_system_t *buddy, link_t *block)
    307286{
    308287        frame_t *frame = list_get_instance(block, frame_t, buddy_link);
     
    317296                index = (frame_index(zone, frame)) +
    318297                    (1 << frame->buddy_order);
    319         } else {  /* is_right */
     298        } else {        /* is_right */
    320299                index = (frame_index(zone, frame)) -
    321300                    (1 << frame->buddy_order);
     
    340319 *
    341320 */
    342 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)
    343322{
    344323        frame_t *frame_l = list_get_instance(block, frame_t, buddy_link);
     
    358337 *
    359338 */
    360 NO_TRACE static link_t *zone_buddy_coalesce(buddy_system_t *buddy,
    361     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)
    362341{
    363342        frame_t *frame1 = list_get_instance(block_1, frame_t, buddy_link);
     
    374353 *
    375354 */
    376 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,
    377356    uint8_t order)
    378357{
     
    388367 *
    389368 */
    390 NO_TRACE static uint8_t zone_buddy_get_order(buddy_system_t *buddy,
    391     link_t *block)
     369static uint8_t zone_buddy_get_order(buddy_system_t *buddy, link_t *block)
    392370{
    393371        return list_get_instance(block, frame_t, buddy_link)->buddy_order;
     
    400378 *
    401379 */
    402 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)
    403381{
    404382        list_get_instance(block, frame_t, buddy_link)->refcount = 1;
     
    409387 * @param buddy Buddy system.
    410388 * @param block Buddy system block.
    411  *
    412  */
    413 NO_TRACE static void zone_buddy_mark_available(buddy_system_t *buddy,
    414     link_t *block)
     389 */
     390static void zone_buddy_mark_available(buddy_system_t *buddy, link_t *block)
    415391{
    416392        list_get_instance(block, frame_t, buddy_link)->refcount = 0;
     
    443419 *
    444420 */
    445 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)
    446422{
    447423        ASSERT(zone_flags_available(zone->flags));
     
    471447 *
    472448 */
    473 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)
    474450{
    475451        ASSERT(zone_flags_available(zone->flags));
     
    492468
    493469/** Return frame from zone. */
    494 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)
    495471{
    496472        ASSERT(frame_idx < zone->count);
     
    499475
    500476/** Mark frame in zone unavailable to allocation. */
    501 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)
    502478{
    503479        ASSERT(zone_flags_available(zone->flags));
     
    528504 *
    529505 */
    530 NO_TRACE static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1,
    531     buddy_system_t *buddy)
     506static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1, buddy_system_t *buddy)
    532507{
    533508        ASSERT(zone_flags_available(zones.info[z1].flags));
     
    625600 *
    626601 */
    627 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)
    628603{
    629604        ASSERT(zone_flags_available(zones.info[znum].flags));
     
    660635 *
    661636 */
    662 NO_TRACE static void zone_reduce_region(size_t znum, pfn_t frame_idx,
    663     size_t count)
     637static void zone_reduce_region(size_t znum, pfn_t frame_idx, size_t count)
    664638{
    665639        ASSERT(zone_flags_available(zones.info[znum].flags));
     
    699673bool zone_merge(size_t z1, size_t z2)
    700674{
    701         irq_spinlock_lock(&zones.lock, true);
     675        ipl_t ipl = interrupts_disable();
     676        spinlock_lock(&zones.lock);
    702677       
    703678        bool ret = true;
     
    769744       
    770745errout:
    771         irq_spinlock_unlock(&zones.lock, true);
     746        spinlock_unlock(&zones.lock);
     747        interrupts_restore(ipl);
    772748       
    773749        return ret;
     
    801777 *
    802778 */
    803 NO_TRACE static void zone_construct(zone_t *zone, buddy_system_t *buddy,
    804     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)
    805780{
    806781        zone->base = start;
     
    845820 *
    846821 */
    847 size_t zone_conf_size(size_t count)
     822uintptr_t zone_conf_size(size_t count)
    848823{
    849824        return (count * sizeof(frame_t) + buddy_conf_size(fnzb(count)));
     
    866841 *
    867842 */
    868 size_t zone_create(pfn_t start, size_t count, pfn_t confframe,
    869     zone_flags_t flags)
    870 {
    871         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);
    872847       
    873848        if (zone_flags_available(flags)) {  /* Create available zone */
     
    912887                }
    913888               
    914                 size_t znum = zones_insert_zone(start, count, flags);
     889                size_t znum = zones_insert_zone(start, count);
    915890                if (znum == (size_t) -1) {
    916                         irq_spinlock_unlock(&zones.lock, true);
     891                        spinlock_unlock(&zones.lock);
     892                        interrupts_restore(ipl);
    917893                        return (size_t) -1;
    918894                }
     
    929905                }
    930906               
    931                 irq_spinlock_unlock(&zones.lock, true);
     907                spinlock_unlock(&zones.lock);
     908                interrupts_restore(ipl);
    932909               
    933910                return znum;
     
    935912       
    936913        /* Non-available zone */
    937         size_t znum = zones_insert_zone(start, count, flags);
     914        size_t znum = zones_insert_zone(start, count);
    938915        if (znum == (size_t) -1) {
    939                 irq_spinlock_unlock(&zones.lock, true);
     916                spinlock_unlock(&zones.lock);
     917                interrupts_restore(ipl);
    940918                return (size_t) -1;
    941919        }
    942920        zone_construct(&zones.info[znum], NULL, start, count, flags);
    943921       
    944         irq_spinlock_unlock(&zones.lock, true);
     922        spinlock_unlock(&zones.lock);
     923        interrupts_restore(ipl);
    945924       
    946925        return znum;
     
    954933void frame_set_parent(pfn_t pfn, void *data, size_t hint)
    955934{
    956         irq_spinlock_lock(&zones.lock, true);
     935        ipl_t ipl = interrupts_disable();
     936        spinlock_lock(&zones.lock);
    957937       
    958938        size_t znum = find_zone(pfn, 1, hint);
     
    963943            pfn - zones.info[znum].base)->parent = data;
    964944       
    965         irq_spinlock_unlock(&zones.lock, true);
     945        spinlock_unlock(&zones.lock);
     946        interrupts_restore(ipl);
    966947}
    967948
    968949void *frame_get_parent(pfn_t pfn, size_t hint)
    969950{
    970         irq_spinlock_lock(&zones.lock, true);
     951        ipl_t ipl = interrupts_disable();
     952        spinlock_lock(&zones.lock);
    971953       
    972954        size_t znum = find_zone(pfn, 1, hint);
     
    977959            pfn - zones.info[znum].base)->parent;
    978960       
    979         irq_spinlock_unlock(&zones.lock, true);
     961        spinlock_unlock(&zones.lock);
     962        interrupts_restore(ipl);
    980963       
    981964        return res;
     
    994977{
    995978        size_t size = ((size_t) 1) << order;
     979        ipl_t ipl;
    996980        size_t hint = pzone ? (*pzone) : 0;
    997981       
    998982loop:
    999         irq_spinlock_lock(&zones.lock, true);
     983        ipl = interrupts_disable();
     984        spinlock_lock(&zones.lock);
    1000985       
    1001986        /*
     
    1008993           if it does not help, reclaim all */
    1009994        if ((znum == (size_t) -1) && (!(flags & FRAME_NO_RECLAIM))) {
    1010                 irq_spinlock_unlock(&zones.lock, true);
     995                spinlock_unlock(&zones.lock);
     996                interrupts_restore(ipl);
     997               
    1011998                size_t freed = slab_reclaim(0);
    1012                 irq_spinlock_lock(&zones.lock, true);
     999               
     1000                ipl = interrupts_disable();
     1001                spinlock_lock(&zones.lock);
    10131002               
    10141003                if (freed > 0)
     
    10171006               
    10181007                if (znum == (size_t) -1) {
    1019                         irq_spinlock_unlock(&zones.lock, true);
     1008                        spinlock_unlock(&zones.lock);
     1009                        interrupts_restore(ipl);
     1010                       
    10201011                        freed = slab_reclaim(SLAB_RECLAIM_ALL);
    1021                         irq_spinlock_lock(&zones.lock, true);
     1012                       
     1013                        ipl = interrupts_disable();
     1014                        spinlock_lock(&zones.lock);
    10221015                       
    10231016                        if (freed > 0)
     
    10291022        if (znum == (size_t) -1) {
    10301023                if (flags & FRAME_ATOMIC) {
    1031                         irq_spinlock_unlock(&zones.lock, true);
     1024                        spinlock_unlock(&zones.lock);
     1025                        interrupts_restore(ipl);
    10321026                        return NULL;
    10331027                }
     
    10371031#endif
    10381032               
    1039                 irq_spinlock_unlock(&zones.lock, true);
    1040                
    1041                 if (!THREAD)
    1042                         panic("Cannot wait for memory to become available.");
     1033                spinlock_unlock(&zones.lock);
     1034                interrupts_restore(ipl);
    10431035               
    10441036                /*
     
    10741066            + zones.info[znum].base;
    10751067       
    1076         irq_spinlock_unlock(&zones.lock, true);
     1068        spinlock_unlock(&zones.lock);
     1069        interrupts_restore(ipl);
    10771070       
    10781071        if (pzone)
     
    10961089void frame_free(uintptr_t frame)
    10971090{
    1098         irq_spinlock_lock(&zones.lock, true);
     1091        ipl_t ipl = interrupts_disable();
     1092        spinlock_lock(&zones.lock);
    10991093       
    11001094        /*
     
    11081102        zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
    11091103       
    1110         irq_spinlock_unlock(&zones.lock, true);
     1104        spinlock_unlock(&zones.lock);
     1105        interrupts_restore(ipl);
    11111106       
    11121107        /*
     
    11321127 *
    11331128 */
    1134 NO_TRACE void frame_reference_add(pfn_t pfn)
    1135 {
    1136         irq_spinlock_lock(&zones.lock, true);
     1129void frame_reference_add(pfn_t pfn)
     1130{
     1131        ipl_t ipl = interrupts_disable();
     1132        spinlock_lock(&zones.lock);
    11371133       
    11381134        /*
     
    11451141        zones.info[znum].frames[pfn - zones.info[znum].base].refcount++;
    11461142       
    1147         irq_spinlock_unlock(&zones.lock, true);
    1148 }
    1149 
    1150 /** Mark given range unavailable in frame zones.
    1151  *
    1152  */
    1153 NO_TRACE void frame_mark_unavailable(pfn_t start, size_t count)
    1154 {
    1155         irq_spinlock_lock(&zones.lock, true);
     1143        spinlock_unlock(&zones.lock);
     1144        interrupts_restore(ipl);
     1145}
     1146
     1147/** Mark given range unavailable in frame zones. */
     1148void frame_mark_unavailable(pfn_t start, size_t count)
     1149{
     1150        ipl_t ipl = interrupts_disable();
     1151        spinlock_lock(&zones.lock);
    11561152       
    11571153        size_t i;
     
    11651161        }
    11661162       
    1167         irq_spinlock_unlock(&zones.lock, true);
    1168 }
    1169 
    1170 /** Initialize physical memory management.
    1171  *
    1172  */
     1163        spinlock_unlock(&zones.lock);
     1164        interrupts_restore(ipl);
     1165}
     1166
     1167/** Initialize physical memory management. */
    11731168void frame_init(void)
    11741169{
    11751170        if (config.cpu_active == 1) {
    11761171                zones.count = 0;
    1177                 irq_spinlock_initialize(&zones.lock, "frame.zones.lock");
     1172                spinlock_initialize(&zones.lock, "zones.lock");
    11781173                mutex_initialize(&mem_avail_mtx, MUTEX_ACTIVE);
    11791174                condvar_initialize(&mem_avail_cv);
     
    12061201}
    12071202
    1208 /** Return total size of all zones.
    1209  *
    1210  */
    1211 uint64_t zones_total_size(void)
    1212 {
    1213         irq_spinlock_lock(&zones.lock, true);
     1203/** Return total size of all zones. */
     1204uint64_t zone_total_size(void)
     1205{
     1206        ipl_t ipl = interrupts_disable();
     1207        spinlock_lock(&zones.lock);
    12141208       
    12151209        uint64_t total = 0;
     
    12181212                total += (uint64_t) FRAMES2SIZE(zones.info[i].count);
    12191213       
    1220         irq_spinlock_unlock(&zones.lock, true);
     1214        spinlock_unlock(&zones.lock);
     1215        interrupts_restore(ipl);
    12211216       
    12221217        return total;
    12231218}
    12241219
    1225 void zones_stats(uint64_t *total, uint64_t *unavail, uint64_t *busy,
    1226     uint64_t *free)
    1227 {
    1228         ASSERT(total != NULL);
    1229         ASSERT(unavail != NULL);
    1230         ASSERT(busy != NULL);
    1231         ASSERT(free != NULL);
    1232        
    1233         irq_spinlock_lock(&zones.lock, true);
    1234        
    1235         *total = 0;
    1236         *unavail = 0;
    1237         *busy = 0;
    1238         *free = 0;
    1239        
    1240         size_t i;
    1241         for (i = 0; i < zones.count; i++) {
    1242                 *total += (uint64_t) FRAMES2SIZE(zones.info[i].count);
    1243                
    1244                 if (zone_flags_available(zones.info[i].flags)) {
    1245                         *busy += (uint64_t) FRAMES2SIZE(zones.info[i].busy_count);
    1246                         *free += (uint64_t) FRAMES2SIZE(zones.info[i].free_count);
    1247                 } else
    1248                         *unavail += (uint64_t) FRAMES2SIZE(zones.info[i].count);
    1249         }
    1250        
    1251         irq_spinlock_unlock(&zones.lock, true);
    1252 }
    1253 
    1254 /** Prints list of zones.
    1255  *
    1256  */
    1257 void zones_print_list(void)
     1220/** Prints list of zones. */
     1221void zone_print_list(void)
    12581222{
    12591223#ifdef __32_BITS__
    1260         printf("[nr] [base addr] [frames    ] [flags ] [free frames ] [busy frames ]\n");
     1224        printf("#  base address frames       flags    free frames  busy frames\n");
     1225        printf("-- ------------ ------------ -------- ------------ ------------\n");
    12611226#endif
    12621227
    12631228#ifdef __64_BITS__
    1264         printf("[nr] [base address    ] [frames    ] [flags ] [free frames ] [busy frames ]\n");
     1229        printf("#  base address          frames      flags    free frames  busy frames\n");
     1230        printf("-- -------------------- ------------ -------- ------------ ------------\n");
    12651231#endif
    12661232       
     
    12781244        size_t i;
    12791245        for (i = 0;; i++) {
    1280                 irq_spinlock_lock(&zones.lock, true);
     1246                ipl_t ipl = interrupts_disable();
     1247                spinlock_lock(&zones.lock);
    12811248               
    12821249                if (i >= zones.count) {
    1283                         irq_spinlock_unlock(&zones.lock, true);
     1250                        spinlock_unlock(&zones.lock);
     1251                        interrupts_restore(ipl);
    12841252                        break;
    12851253                }
     
    12911259                size_t busy_count = zones.info[i].busy_count;
    12921260               
    1293                 irq_spinlock_unlock(&zones.lock, true);
     1261                spinlock_unlock(&zones.lock);
     1262                interrupts_restore(ipl);
    12941263               
    12951264                bool available = zone_flags_available(flags);
    12961265               
    1297                 printf("%-4" PRIs, i);
     1266                printf("%-2" PRIs, i);
    12981267               
    12991268#ifdef __32_BITS__
    1300                 printf("  %10p", base);
     1269                printf("   %10p", base);
    13011270#endif
    13021271               
    13031272#ifdef __64_BITS__
    1304                 printf(" %18p", base);
     1273                printf("   %18p", base);
    13051274#endif
    13061275               
     
    13111280               
    13121281                if (available)
    1313                         printf("%14" PRIs " %14" PRIs,
     1282                        printf("%12" PRIs " %12" PRIs,
    13141283                            free_count, busy_count);
    13151284               
     
    13251294void zone_print_one(size_t num)
    13261295{
    1327         irq_spinlock_lock(&zones.lock, true);
     1296        ipl_t ipl = interrupts_disable();
     1297        spinlock_lock(&zones.lock);
    13281298        size_t znum = (size_t) -1;
    13291299       
     
    13371307       
    13381308        if (znum == (size_t) -1) {
    1339                 irq_spinlock_unlock(&zones.lock, true);
     1309                spinlock_unlock(&zones.lock);
     1310                interrupts_restore(ipl);
    13401311                printf("Zone not found.\n");
    13411312                return;
     
    13481319        size_t busy_count = zones.info[i].busy_count;
    13491320       
    1350         irq_spinlock_unlock(&zones.lock, true);
     1321        spinlock_unlock(&zones.lock);
     1322        interrupts_restore(ipl);
    13511323       
    13521324        bool available = zone_flags_available(flags);
Note: See TracChangeset for help on using the changeset viewer.