Changeset b5ba8f6 in mainline for kernel/generic/src


Ignore:
Timestamp:
2013-09-13T13:11:53Z (12 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1eaa3cf
Parents:
95027b5 (diff), 1c5f6f8 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge mainline changes

Location:
kernel/generic/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/adt/bitmap.c

    r95027b5 rb5ba8f6  
    3737 * setting and clearing ranges of bits and for finding ranges
    3838 * of unset bits.
    39  *
    40  * The bitmap ADT can optionally implement a two-level hierarchy
    41  * for faster range searches. The second level bitmap (of blocks)
    42  * is not precise, but conservative. This means that if the block
    43  * bit is set, it guarantees that all bits in the block are set.
    44  * But if the block bit is unset, nothing can be said about the
    45  * bits in the block.
    46  *
    4739 */
    4840
     
    5648#define ALL_ZEROES  0x00
    5749
    58 /** Compute the size of a bitmap
    59  *
    60  * Compute the size of a bitmap that can store given number
    61  * of elements.
    62  *
    63  * @param elements Number of elements to store.
    64  *
    65  * @return Size of the bitmap (in units of BITMAP_ELEMENT bits).
    66  *
    67  */
    68 static size_t bitmap_bytes(size_t elements)
    69 {
    70         size_t bytes = elements / BITMAP_ELEMENT;
    71        
    72         if ((elements % BITMAP_ELEMENT) != 0)
    73                 bytes++;
    74        
    75         return bytes;
    76 }
    77 
    78 /** Compute the number of 2nd level blocks
    79  *
    80  * Compute the number of 2nd level blocks for a given number
    81  * of elements.
    82  *
    83  * @param elements   Number of elements.
    84  * @param block_size Number of elements in one block.
    85  *
    86  * @return Number of 2nd level blocks.
    87  * @return Zero if block_size is zero.
    88  *
    89  */
    90 static size_t bitmap_blocks(size_t elements, size_t block_size)
    91 {
    92         if (block_size == 0)
    93                 return 0;
    94        
    95         size_t blocks = elements / block_size;
    96        
    97         if ((elements % block_size) != 0)
    98                 blocks++;
    99        
    100         return blocks;
    101 }
    102 
    10350/** Unchecked version of bitmap_get()
    10451 *
     
    11360static unsigned int bitmap_get_fast(bitmap_t *bitmap, size_t element)
    11461{
    115         return !!((bitmap->bits)[element / BITMAP_ELEMENT] &
    116             (1 << (element & BITMAP_REMAINER)));
     62        size_t byte = element / BITMAP_ELEMENT;
     63        uint8_t mask = 1 << (element & BITMAP_REMAINER);
     64       
     65        return !!((bitmap->bits)[byte] & mask);
    11766}
    11867
     
    12271 *
    12372 * @param elements   Number bits stored in bitmap.
    124  * @param block_size Block size of the 2nd level bitmap.
    125  *                   If set to zero, no 2nd level is used.
    12673 *
    12774 * @return Size (in bytes) required for the bitmap.
    12875 *
    12976 */
    130 size_t bitmap_size(size_t elements, size_t block_size)
    131 {
    132         size_t blocks = bitmap_blocks(elements, block_size);
    133        
    134         return (bitmap_bytes(elements) + bitmap_bytes(blocks));
     77size_t bitmap_size(size_t elements)
     78{
     79        size_t size = elements / BITMAP_ELEMENT;
     80       
     81        if ((elements % BITMAP_ELEMENT) != 0)
     82                size++;
     83       
     84        return size;
    13585}
    13686
     
    14191 * @param bitmap     Bitmap structure.
    14292 * @param elements   Number of bits stored in bitmap.
    143  * @param block_size Block size of the 2nd level bitmap.
    144  *                   If set to zero, no 2nd level is used.
    14593 * @param data       Address of the memory used to hold the map.
    14694 *                   The optional 2nd level bitmap follows the 1st
     
    14896 *
    14997 */
    150 void bitmap_initialize(bitmap_t *bitmap, size_t elements, size_t block_size,
    151     void *data)
     98void bitmap_initialize(bitmap_t *bitmap, size_t elements, void *data)
    15299{
    153100        bitmap->elements = elements;
    154101        bitmap->bits = (uint8_t *) data;
    155        
    156         if (block_size > 0) {
    157                 bitmap->block_size = block_size;
    158                 bitmap->blocks = bitmap->bits +
    159                     bitmap_size(elements, 0);
    160         } else {
    161                 bitmap->block_size = 0;
    162                 bitmap->blocks = NULL;
    163         }
    164 }
    165 
    166 static void bitmap_set_range_internal(uint8_t *bits, size_t start, size_t count)
    167 {
    168         if (count == 0)
    169                 return;
    170        
    171         size_t aligned_start = ALIGN_UP(start, BITMAP_ELEMENT);
    172        
    173         /* Leading unaligned bits */
    174         size_t lub = min(aligned_start - start, count);
    175        
    176         /* Aligned middle bits */
    177         size_t amb = (count > lub) ? (count - lub) : 0;
    178        
    179         /* Trailing aligned bits */
    180         size_t tab = amb % BITMAP_ELEMENT;
    181        
    182         if (start + count < aligned_start) {
    183                 /* Set bits in the middle of byte. */
    184                 bits[start / BITMAP_ELEMENT] |=
    185                     ((1 << lub) - 1) << (start & BITMAP_REMAINER);
    186                 return;
    187         }
    188        
    189         if (lub) {
    190                 /* Make sure to set any leading unaligned bits. */
    191                 bits[start / BITMAP_ELEMENT] |=
    192                     ~((1 << (BITMAP_ELEMENT - lub)) - 1);
    193         }
    194        
    195         size_t i;
    196        
    197         for (i = 0; i < amb / BITMAP_ELEMENT; i++) {
    198                 /* The middle bits can be set byte by byte. */
    199                 bits[aligned_start / BITMAP_ELEMENT + i] = ALL_ONES;
    200         }
    201        
    202         if (tab) {
    203                 /* Make sure to set any trailing aligned bits. */
    204                 bits[aligned_start / BITMAP_ELEMENT + i] |= (1 << tab) - 1;
    205         }
     102        bitmap->next_fit = 0;
    206103}
    207104
     
    217114        ASSERT(start + count <= bitmap->elements);
    218115       
    219         bitmap_set_range_internal(bitmap->bits, start, count);
    220        
    221         if (bitmap->block_size > 0) {
    222                 size_t aligned_start = ALIGN_UP(start, bitmap->block_size);
    223                
    224                 /* Leading unaligned bits */
    225                 size_t lub = min(aligned_start - start, count);
    226                
    227                 /* Aligned middle bits */
    228                 size_t amb = (count > lub) ? (count - lub) : 0;
    229                
    230                 size_t aligned_size = amb / bitmap->block_size;
    231                
    232                 bitmap_set_range_internal(bitmap->blocks, aligned_start,
    233                     aligned_size);
    234         }
    235 }
    236 
    237 static void bitmap_clear_range_internal(uint8_t *bits, size_t start,
    238     size_t count)
    239 {
    240116        if (count == 0)
    241117                return;
    242118       
     119        size_t start_byte = start / BITMAP_ELEMENT;
    243120        size_t aligned_start = ALIGN_UP(start, BITMAP_ELEMENT);
    244121       
     
    253130       
    254131        if (start + count < aligned_start) {
    255                 /* Set bits in the middle of byte */
    256                 bits[start / BITMAP_ELEMENT] &=
    257                     ~(((1 << lub) - 1) << (start & BITMAP_REMAINER));
     132                /* Set bits in the middle of byte. */
     133                bitmap->bits[start_byte] |=
     134                    ((1 << lub) - 1) << (start & BITMAP_REMAINER);
    258135                return;
    259136        }
    260137       
    261138        if (lub) {
    262                 /* Make sure to clear any leading unaligned bits. */
    263                 bits[start / BITMAP_ELEMENT] &=
    264                     (1 << (BITMAP_ELEMENT - lub)) - 1;
     139                /* Make sure to set any leading unaligned bits. */
     140                bitmap->bits[start_byte] |=
     141                    ~((1 << (BITMAP_ELEMENT - lub)) - 1);
    265142        }
    266143       
     
    268145       
    269146        for (i = 0; i < amb / BITMAP_ELEMENT; i++) {
    270                 /* The middle bits can be cleared byte by byte. */
    271                 bits[aligned_start / BITMAP_ELEMENT + i] = ALL_ZEROES;
     147                /* The middle bits can be set byte by byte. */
     148                bitmap->bits[aligned_start / BITMAP_ELEMENT + i] =
     149                    ALL_ONES;
    272150        }
    273151       
    274152        if (tab) {
    275                 /* Make sure to clear any trailing aligned bits. */
    276                 bits[aligned_start / BITMAP_ELEMENT + i] &= ~((1 << tab) - 1);
     153                /* Make sure to set any trailing aligned bits. */
     154                bitmap->bits[aligned_start / BITMAP_ELEMENT + i] |=
     155                    (1 << tab) - 1;
    277156        }
    278157}
     
    289168        ASSERT(start + count <= bitmap->elements);
    290169       
    291         bitmap_clear_range_internal(bitmap->bits, start, count);
    292        
    293         if (bitmap->block_size > 0) {
    294                 size_t aligned_start = start / bitmap->block_size;
    295                
    296                 size_t aligned_end = (start + count) / bitmap->block_size;
    297                
    298                 if (((start + count) % bitmap->block_size) != 0)
    299                         aligned_end++;
    300                
    301                 size_t aligned_size = aligned_end - aligned_start;
    302                
    303                 bitmap_clear_range_internal(bitmap->blocks, aligned_start,
    304                     aligned_size);
    305         }
     170        if (count == 0)
     171                return;
     172       
     173        size_t start_byte = start / BITMAP_ELEMENT;
     174        size_t aligned_start = ALIGN_UP(start, BITMAP_ELEMENT);
     175       
     176        /* Leading unaligned bits */
     177        size_t lub = min(aligned_start - start, count);
     178       
     179        /* Aligned middle bits */
     180        size_t amb = (count > lub) ? (count - lub) : 0;
     181       
     182        /* Trailing aligned bits */
     183        size_t tab = amb % BITMAP_ELEMENT;
     184       
     185        if (start + count < aligned_start) {
     186                /* Set bits in the middle of byte */
     187                bitmap->bits[start_byte] &=
     188                    ~(((1 << lub) - 1) << (start & BITMAP_REMAINER));
     189                return;
     190        }
     191       
     192        if (lub) {
     193                /* Make sure to clear any leading unaligned bits. */
     194                bitmap->bits[start_byte] &=
     195                    (1 << (BITMAP_ELEMENT - lub)) - 1;
     196        }
     197       
     198        size_t i;
     199       
     200        for (i = 0; i < amb / BITMAP_ELEMENT; i++) {
     201                /* The middle bits can be cleared byte by byte. */
     202                bitmap->bits[aligned_start / BITMAP_ELEMENT + i] =
     203                    ALL_ZEROES;
     204        }
     205       
     206        if (tab) {
     207                /* Make sure to clear any trailing aligned bits. */
     208                bitmap->bits[aligned_start / BITMAP_ELEMENT + i] &=
     209                    ~((1 << tab) - 1);
     210        }
     211       
     212        bitmap->next_fit = start_byte;
    306213}
    307214
     
    351258 * @param count      Number of continuous zero bits to find.
    352259 * @param base       Address of the first bit in the bitmap.
     260 * @param prefered   Prefered address to start searching from.
    353261 * @param constraint Constraint for the address of the first zero bit.
    354262 * @param index      Place to store the index of the first zero
     
    362270 */
    363271int bitmap_allocate_range(bitmap_t *bitmap, size_t count, size_t base,
    364     size_t constraint, size_t *index)
     272    size_t prefered, size_t constraint, size_t *index)
    365273{
    366274        if (count == 0)
    367275                return false;
    368276       
    369         size_t bytes = bitmap_bytes(bitmap->elements);
    370        
    371         for (size_t byte = 0; byte < bytes; byte++) {
     277        size_t size = bitmap_size(bitmap->elements);
     278        size_t next_fit = bitmap->next_fit;
     279       
     280        /*
     281         * Adjust the next-fit value according to the address
     282         * the caller prefers to start the search at.
     283         */
     284        if ((prefered > base) && (prefered < base + bitmap->elements)) {
     285                size_t prefered_fit = (prefered - base) / BITMAP_ELEMENT;
     286               
     287                if (prefered_fit > next_fit)
     288                        next_fit = prefered_fit;
     289        }
     290       
     291        for (size_t pos = 0; pos < size; pos++) {
     292                size_t byte = (next_fit + pos) % size;
     293               
    372294                /* Skip if the current byte has all bits set */
    373295                if (bitmap->bits[byte] == ALL_ONES)
     
    386308                       
    387309                        if (!bitmap_get_fast(bitmap, i)) {
    388                                 bool continuous = true;
     310                                size_t continuous = 1;
    389311                               
    390312                                for (size_t j = 1; j < count; j++) {
    391                                         if ((i + j >= bitmap->elements) ||
    392                                             (bitmap_get_fast(bitmap, i + j))) {
    393                                                 continuous = false;
     313                                        if ((i + j < bitmap->elements) &&
     314                                            (!bitmap_get_fast(bitmap, i + j)))
     315                                                continuous++;
     316                                        else
    394317                                                break;
    395                                         }
    396318                                }
    397319                               
    398                                 if (continuous) {
     320                                if (continuous == count) {
    399321                                        if (index != NULL) {
    400322                                                bitmap_set_range(bitmap, i, count);
     323                                                bitmap->next_fit = i / BITMAP_ELEMENT;
    401324                                                *index = i;
    402325                                        }
    403326                                       
    404327                                        return true;
    405                                 }
     328                                } else
     329                                        i += continuous;
    406330                        }
    407331                }
  • kernel/generic/src/ddi/ddi.c

    r95027b5 rb5ba8f6  
    329329       
    330330        size_t frames = SIZE2FRAMES(size);
    331         *phys = frame_alloc_noreserve(frames, 0, constraint);
     331        *phys = frame_alloc(frames, FRAME_NO_RESERVE, constraint);
    332332        if (*phys == 0)
    333333                return ENOMEM;
  • kernel/generic/src/mm/frame.c

    r95027b5 rb5ba8f6  
    6060#include <config.h>
    6161#include <str.h>
    62 
    63 #define BITMAP_BLOCK_SIZE  128
    6462
    6563zones_t zones;
     
    236234         * the bitmap if the last argument is NULL.
    237235         */
     236       
    238237        return ((zone->flags & ZONE_AVAILABLE) &&
    239238            bitmap_allocate_range(&zone->bitmap, count, zone->base,
    240             constraint, NULL));
     239            FRAME_LOWPRIO, constraint, NULL));
     240}
     241
     242/** Find a zone that can allocate specified number of frames
     243 *
     244 * This function searches among all zones. Assume interrupts are
     245 * disabled and zones lock is locked.
     246 *
     247 * @param count      Number of free frames we are trying to find.
     248 * @param flags      Required flags of the zone.
     249 * @param constraint Indication of bits that cannot be set in the
     250 *                   physical frame number of the first allocated frame.
     251 * @param hint       Preferred zone.
     252 *
     253 * @return Zone that can allocate specified number of frames.
     254 * @return -1 if no zone can satisfy the request.
     255 *
     256 */
     257NO_TRACE static size_t find_free_zone_all(size_t count, zone_flags_t flags,
     258    pfn_t constraint, size_t hint)
     259{
     260        for (size_t pos = 0; pos < zones.count; pos++) {
     261                size_t i = (pos + hint) % zones.count;
     262               
     263                /* Check whether the zone meets the search criteria. */
     264                if (!ZONE_FLAGS_MATCH(zones.info[i].flags, flags))
     265                        continue;
     266               
     267                /* Check if the zone can satisfy the allocation request. */
     268                if (zone_can_alloc(&zones.info[i], count, constraint))
     269                        return i;
     270        }
     271       
     272        return (size_t) -1;
     273}
     274
     275/** Check if frame range  priority memory
     276 *
     277 * @param pfn   Starting frame.
     278 * @param count Number of frames.
     279 *
     280 * @return True if the range contains only priority memory.
     281 *
     282 */
     283NO_TRACE static bool is_high_priority(pfn_t base, size_t count)
     284{
     285        return (base + count <= FRAME_LOWPRIO);
     286}
     287
     288/** Find a zone that can allocate specified number of frames
     289 *
     290 * This function ignores zones that contain only high-priority
     291 * memory. Assume interrupts are disabled and zones lock is locked.
     292 *
     293 * @param count      Number of free frames we are trying to find.
     294 * @param flags      Required flags of the zone.
     295 * @param constraint Indication of bits that cannot be set in the
     296 *                   physical frame number of the first allocated frame.
     297 * @param hint       Preferred zone.
     298 *
     299 * @return Zone that can allocate specified number of frames.
     300 * @return -1 if no low-priority zone can satisfy the request.
     301 *
     302 */
     303NO_TRACE static size_t find_free_zone_lowprio(size_t count, zone_flags_t flags,
     304    pfn_t constraint, size_t hint)
     305{       
     306        for (size_t pos = 0; pos < zones.count; pos++) {
     307                size_t i = (pos + hint) % zones.count;
     308               
     309                /* Skip zones containing only high-priority memory. */
     310                if (is_high_priority(zones.info[i].base, zones.info[i].count))
     311                        continue;
     312               
     313                /* Check whether the zone meets the search criteria. */
     314                if (!ZONE_FLAGS_MATCH(zones.info[i].flags, flags))
     315                        continue;
     316               
     317                /* Check if the zone can satisfy the allocation request. */
     318                if (zone_can_alloc(&zones.info[i], count, constraint))
     319                        return i;
     320        }
     321       
     322        return (size_t) -1;
    241323}
    242324
     
    250332 * @param constraint Indication of bits that cannot be set in the
    251333 *                   physical frame number of the first allocated frame.
    252  * @param hind       Preferred zone.
     334 * @param hint       Preferred zone.
     335 *
     336 * @return Zone that can allocate specified number of frames.
     337 * @return -1 if no zone can satisfy the request.
    253338 *
    254339 */
     
    259344                hint = 0;
    260345       
    261         size_t i = hint;
    262         do {
    263                 /*
    264                  * Check whether the zone meets the search criteria.
    265                  */
    266                 if (ZONE_FLAGS_MATCH(zones.info[i].flags, flags)) {
    267                         /*
    268                          * Check if the zone can satisfy the allocation request.
    269                          */
    270                         if (zone_can_alloc(&zones.info[i], count, constraint))
    271                                 return i;
    272                 }
    273                
    274                 i++;
    275                 if (i >= zones.count)
    276                         i = 0;
    277                
    278         } while (i != hint);
    279        
    280         return (size_t) -1;
     346        /*
     347         * Prefer zones with low-priority memory over
     348         * zones with high-priority memory.
     349         */
     350       
     351        size_t znum = find_free_zone_lowprio(count, flags, constraint, hint);
     352        if (znum != (size_t) -1)
     353                return znum;
     354       
     355        /* Take all zones into account */
     356        return find_free_zone_all(count, flags, constraint, hint);
    281357}
    282358
     
    314390        size_t index;
    315391        int avail = bitmap_allocate_range(&zone->bitmap, count, zone->base,
    316             constraint, &index);
     392            FRAME_LOWPRIO, constraint, &index);
    317393       
    318394        ASSERT(avail);
     
    367443NO_TRACE static void zone_mark_unavailable(zone_t *zone, size_t index)
    368444{
    369         if (!(zone->flags & ZONE_AVAILABLE))
    370                 return;
     445        ASSERT(zone->flags & ZONE_AVAILABLE);
    371446       
    372447        frame_t *frame = zone_get_frame(zone, index);
     
    410485       
    411486        bitmap_initialize(&zones.info[z1].bitmap, zones.info[z1].count,
    412             BITMAP_BLOCK_SIZE, confdata +
    413             (sizeof(frame_t) * zones.info[z1].count));
     487            confdata + (sizeof(frame_t) * zones.info[z1].count));
    414488        bitmap_clear_range(&zones.info[z1].bitmap, 0, zones.info[z1].count);
    415489       
     
    578652                 */
    579653               
    580                 bitmap_initialize(&zone->bitmap, count, BITMAP_BLOCK_SIZE,
    581                     confdata + (sizeof(frame_t) * count));
     654                bitmap_initialize(&zone->bitmap, count, confdata +
     655                    (sizeof(frame_t) * count));
    582656                bitmap_clear_range(&zone->bitmap, 0, count);
    583657               
     
    591665                        frame_initialize(&zone->frames[i]);
    592666        } else {
    593                 bitmap_initialize(&zone->bitmap, 0, 0, NULL);
     667                bitmap_initialize(&zone->bitmap, 0, NULL);
    594668                zone->frames = NULL;
    595669        }
     
    605679size_t zone_conf_size(size_t count)
    606680{
    607         return (count * sizeof(frame_t) +
    608             bitmap_size(count, BITMAP_BLOCK_SIZE));
     681        return (count * sizeof(frame_t) + bitmap_size(count));
    609682}
    610683
     
    887960}
    888961
    889 uintptr_t frame_alloc_noreserve(size_t count, frame_flags_t flags,
    890     uintptr_t constraint)
    891 {
    892         return frame_alloc_generic(count, flags | FRAME_NO_RESERVE, constraint,
    893             NULL);
    894 }
    895 
    896962/** Free frames of physical memory.
    897963 *
     
    11411207        /*
    11421208         * Because printing may require allocation of memory, we may not hold
    1143          * the frame allocator locks when printing zone statistics.  Therefore,
     1209         * the frame allocator locks when printing zone statistics. Therefore,
    11441210         * we simply gather the statistics under the protection of the locks and
    11451211         * print the statistics when the locks have been released.
     
    11501216         */
    11511217       
     1218        size_t free_lowmem = 0;
     1219        size_t free_highmem = 0;
     1220        size_t free_highprio = 0;
     1221       
    11521222        for (size_t i = 0;; i++) {
    11531223                irq_spinlock_lock(&zones.lock, true);
     
    11581228                }
    11591229               
    1160                 uintptr_t base = PFN2ADDR(zones.info[i].base);
     1230                pfn_t fbase = zones.info[i].base;
     1231                uintptr_t base = PFN2ADDR(fbase);
    11611232                size_t count = zones.info[i].count;
    11621233                zone_flags_t flags = zones.info[i].flags;
     
    11641235                size_t busy_count = zones.info[i].busy_count;
    11651236               
     1237                bool available = ((flags & ZONE_AVAILABLE) != 0);
     1238                bool lowmem = ((flags & ZONE_LOWMEM) != 0);
     1239                bool highmem = ((flags & ZONE_HIGHMEM) != 0);
     1240                bool highprio = is_high_priority(fbase, count);
     1241               
     1242                if (available) {
     1243                        if (lowmem)
     1244                                free_lowmem += free_count;
     1245                       
     1246                        if (highmem)
     1247                                free_highmem += free_count;
     1248                       
     1249                        if (highprio) {
     1250                                free_highprio += free_count;
     1251                        } else {
     1252                                /*
     1253                                 * Walk all frames of the zone and examine
     1254                                 * all high priority memory to get accurate
     1255                                 * statistics.
     1256                                 */
     1257                               
     1258                                for (size_t index = 0; index < count; index++) {
     1259                                        if (is_high_priority(fbase + index, 0)) {
     1260                                                if (!bitmap_get(&zones.info[i].bitmap, index))
     1261                                                        free_highprio++;
     1262                                        } else
     1263                                                break;
     1264                                }
     1265                        }
     1266                }
     1267               
    11661268                irq_spinlock_unlock(&zones.lock, true);
    1167                
    1168                 bool available = ((flags & ZONE_AVAILABLE) != 0);
    11691269               
    11701270                printf("%-4zu", i);
     
    11911291                printf("\n");
    11921292        }
     1293       
     1294        printf("\n");
     1295       
     1296        uint64_t size;
     1297        const char *size_suffix;
     1298       
     1299        bin_order_suffix(FRAMES2SIZE(free_lowmem), &size, &size_suffix,
     1300            false);
     1301        printf("Available low memory:    %zu frames (%" PRIu64 " %s)\n",
     1302            free_lowmem, size, size_suffix);
     1303       
     1304        bin_order_suffix(FRAMES2SIZE(free_highmem), &size, &size_suffix,
     1305            false);
     1306        printf("Available high memory:   %zu frames (%" PRIu64 " %s)\n",
     1307            free_highmem, size, size_suffix);
     1308       
     1309        bin_order_suffix(FRAMES2SIZE(free_highprio), &size, &size_suffix,
     1310            false);
     1311        printf("Available high priority: %zu frames (%" PRIu64 " %s)\n",
     1312            free_highprio, size, size_suffix);
    11931313}
    11941314
     
    12161336        }
    12171337       
    1218         uintptr_t base = PFN2ADDR(zones.info[znum].base);
     1338        size_t free_lowmem = 0;
     1339        size_t free_highmem = 0;
     1340        size_t free_highprio = 0;
     1341       
     1342        pfn_t fbase = zones.info[znum].base;
     1343        uintptr_t base = PFN2ADDR(fbase);
    12191344        zone_flags_t flags = zones.info[znum].flags;
    12201345        size_t count = zones.info[znum].count;
     
    12221347        size_t busy_count = zones.info[znum].busy_count;
    12231348       
     1349        bool available = ((flags & ZONE_AVAILABLE) != 0);
     1350        bool lowmem = ((flags & ZONE_LOWMEM) != 0);
     1351        bool highmem = ((flags & ZONE_HIGHMEM) != 0);
     1352        bool highprio = is_high_priority(fbase, count);
     1353       
     1354        if (available) {
     1355                if (lowmem)
     1356                        free_lowmem = free_count;
     1357               
     1358                if (highmem)
     1359                        free_highmem = free_count;
     1360               
     1361                if (highprio) {
     1362                        free_highprio = free_count;
     1363                } else {
     1364                        /*
     1365                         * Walk all frames of the zone and examine
     1366                         * all high priority memory to get accurate
     1367                         * statistics.
     1368                         */
     1369                       
     1370                        for (size_t index = 0; index < count; index++) {
     1371                                if (is_high_priority(fbase + index, 0)) {
     1372                                        if (!bitmap_get(&zones.info[znum].bitmap, index))
     1373                                                free_highprio++;
     1374                                } else
     1375                                        break;
     1376                        }
     1377                }
     1378        }
     1379       
    12241380        irq_spinlock_unlock(&zones.lock, true);
    1225        
    1226         bool available = ((flags & ZONE_AVAILABLE) != 0);
    12271381       
    12281382        uint64_t size;
    12291383        const char *size_suffix;
     1384       
    12301385        bin_order_suffix(FRAMES2SIZE(count), &size, &size_suffix, false);
    12311386       
    1232         printf("Zone number:       %zu\n", znum);
    1233         printf("Zone base address: %p\n", (void *) base);
    1234         printf("Zone size:         %zu frames (%" PRIu64 " %s)\n", count,
     1387        printf("Zone number:             %zu\n", znum);
     1388        printf("Zone base address:       %p\n", (void *) base);
     1389        printf("Zone size:               %zu frames (%" PRIu64 " %s)\n", count,
    12351390            size, size_suffix);
    1236         printf("Zone flags:        %c%c%c%c%c\n",
     1391        printf("Zone flags:              %c%c%c%c%c\n",
    12371392            available ? 'A' : '-',
    12381393            (flags & ZONE_RESERVED) ? 'R' : '-',
     
    12441399                bin_order_suffix(FRAMES2SIZE(busy_count), &size, &size_suffix,
    12451400                    false);
    1246                 printf("Allocated space:   %zu frames (%" PRIu64 " %s)\n",
     1401                printf("Allocated space:         %zu frames (%" PRIu64 " %s)\n",
    12471402                    busy_count, size, size_suffix);
     1403               
    12481404                bin_order_suffix(FRAMES2SIZE(free_count), &size, &size_suffix,
    12491405                    false);
    1250                 printf("Available space:   %zu frames (%" PRIu64 " %s)\n",
     1406                printf("Available space:         %zu frames (%" PRIu64 " %s)\n",
    12511407                    free_count, size, size_suffix);
     1408               
     1409                bin_order_suffix(FRAMES2SIZE(free_lowmem), &size, &size_suffix,
     1410                    false);
     1411                printf("Available low memory:    %zu frames (%" PRIu64 " %s)\n",
     1412                    free_lowmem, size, size_suffix);
     1413               
     1414                bin_order_suffix(FRAMES2SIZE(free_highmem), &size, &size_suffix,
     1415                    false);
     1416                printf("Available high memory:   %zu frames (%" PRIu64 " %s)\n",
     1417                    free_highmem, size, size_suffix);
     1418               
     1419                bin_order_suffix(FRAMES2SIZE(free_highprio), &size, &size_suffix,
     1420                    false);
     1421                printf("Available high priority: %zu frames (%" PRIu64 " %s)\n",
     1422                    free_highprio, size, size_suffix);
    12521423        }
    12531424}
Note: See TracChangeset for help on using the changeset viewer.