Ignore:
File:
1 edited

Legend:

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

    rf72906c rc5396c1  
    234234         * the bitmap if the last argument is NULL.
    235235         */
    236        
    237236        return ((zone->flags & ZONE_AVAILABLE) &&
    238237            bitmap_allocate_range(&zone->bitmap, count, zone->base,
    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  */
    257 NO_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  */
    283 NO_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  */
    303 NO_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;
     238            constraint, NULL));
    323239}
    324240
     
    332248 * @param constraint Indication of bits that cannot be set in the
    333249 *                   physical frame number of the first allocated frame.
    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.
     250 * @param hind       Preferred zone.
    338251 *
    339252 */
     
    344257                hint = 0;
    345258       
    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);
     259        size_t i = hint;
     260        do {
     261                /*
     262                 * Check whether the zone meets the search criteria.
     263                 */
     264                if (ZONE_FLAGS_MATCH(zones.info[i].flags, flags)) {
     265                        /*
     266                         * Check if the zone can satisfy the allocation request.
     267                         */
     268                        if (zone_can_alloc(&zones.info[i], count, constraint))
     269                                return i;
     270                }
     271               
     272                i++;
     273                if (i >= zones.count)
     274                        i = 0;
     275               
     276        } while (i != hint);
     277       
     278        return (size_t) -1;
    357279}
    358280
     
    390312        size_t index;
    391313        int avail = bitmap_allocate_range(&zone->bitmap, count, zone->base,
    392             FRAME_LOWPRIO, constraint, &index);
     314            constraint, &index);
    393315       
    394316        ASSERT(avail);
     
    961883}
    962884
     885uintptr_t frame_alloc_noreserve(size_t count, frame_flags_t flags,
     886    uintptr_t constraint)
     887{
     888        return frame_alloc_generic(count, flags | FRAME_NO_RESERVE, constraint,
     889            NULL);
     890}
     891
    963892/** Free frames of physical memory.
    964893 *
     
    12081137        /*
    12091138         * Because printing may require allocation of memory, we may not hold
    1210          * the frame allocator locks when printing zone statistics. Therefore,
     1139         * the frame allocator locks when printing zone statistics.  Therefore,
    12111140         * we simply gather the statistics under the protection of the locks and
    12121141         * print the statistics when the locks have been released.
     
    12171146         */
    12181147       
    1219         size_t free_lowmem = 0;
    1220         size_t free_highmem = 0;
    1221         size_t free_highprio = 0;
    1222        
    12231148        for (size_t i = 0;; i++) {
    12241149                irq_spinlock_lock(&zones.lock, true);
     
    12291154                }
    12301155               
    1231                 pfn_t fbase = zones.info[i].base;
    1232                 uintptr_t base = PFN2ADDR(fbase);
     1156                uintptr_t base = PFN2ADDR(zones.info[i].base);
    12331157                size_t count = zones.info[i].count;
    12341158                zone_flags_t flags = zones.info[i].flags;
     
    12361160                size_t busy_count = zones.info[i].busy_count;
    12371161               
     1162                irq_spinlock_unlock(&zones.lock, true);
     1163               
    12381164                bool available = ((flags & ZONE_AVAILABLE) != 0);
    1239                 bool lowmem = ((flags & ZONE_LOWMEM) != 0);
    1240                 bool highmem = ((flags & ZONE_HIGHMEM) != 0);
    1241                 bool highprio = is_high_priority(fbase, count);
    1242                
    1243                 if (available) {
    1244                         if (lowmem)
    1245                                 free_lowmem += free_count;
    1246                        
    1247                         if (highmem)
    1248                                 free_highmem += free_count;
    1249                        
    1250                         if (highprio) {
    1251                                 free_highprio += free_count;
    1252                         } else {
    1253                                 /*
    1254                                  * Walk all frames of the zone and examine
    1255                                  * all high priority memory to get accurate
    1256                                  * statistics.
    1257                                  */
    1258                                
    1259                                 for (size_t index = 0; index < count; index++) {
    1260                                         if (is_high_priority(fbase + index, 0)) {
    1261                                                 if (!bitmap_get(&zones.info[i].bitmap, index))
    1262                                                         free_highprio++;
    1263                                         } else
    1264                                                 break;
    1265                                 }
    1266                         }
    1267                 }
    1268                
    1269                 irq_spinlock_unlock(&zones.lock, true);
    12701165               
    12711166                printf("%-4zu", i);
     
    12921187                printf("\n");
    12931188        }
    1294        
    1295         printf("\n");
    1296        
    1297         uint64_t size;
    1298         const char *size_suffix;
    1299        
    1300         bin_order_suffix(FRAMES2SIZE(free_lowmem), &size, &size_suffix,
    1301             false);
    1302         printf("Available low memory:    %zu frames (%" PRIu64 " %s)\n",
    1303             free_lowmem, size, size_suffix);
    1304        
    1305         bin_order_suffix(FRAMES2SIZE(free_highmem), &size, &size_suffix,
    1306             false);
    1307         printf("Available high memory:   %zu frames (%" PRIu64 " %s)\n",
    1308             free_highmem, size, size_suffix);
    1309        
    1310         bin_order_suffix(FRAMES2SIZE(free_highprio), &size, &size_suffix,
    1311             false);
    1312         printf("Available high priority: %zu frames (%" PRIu64 " %s)\n",
    1313             free_highprio, size, size_suffix);
    13141189}
    13151190
     
    13371212        }
    13381213       
    1339         size_t free_lowmem = 0;
    1340         size_t free_highmem = 0;
    1341         size_t free_highprio = 0;
    1342        
    1343         pfn_t fbase = zones.info[znum].base;
    1344         uintptr_t base = PFN2ADDR(fbase);
     1214        uintptr_t base = PFN2ADDR(zones.info[znum].base);
    13451215        zone_flags_t flags = zones.info[znum].flags;
    13461216        size_t count = zones.info[znum].count;
     
    13481218        size_t busy_count = zones.info[znum].busy_count;
    13491219       
     1220        irq_spinlock_unlock(&zones.lock, true);
     1221       
    13501222        bool available = ((flags & ZONE_AVAILABLE) != 0);
    1351         bool lowmem = ((flags & ZONE_LOWMEM) != 0);
    1352         bool highmem = ((flags & ZONE_HIGHMEM) != 0);
    1353         bool highprio = is_high_priority(fbase, count);
    1354        
    1355         if (available) {
    1356                 if (lowmem)
    1357                         free_lowmem = free_count;
    1358                
    1359                 if (highmem)
    1360                         free_highmem = free_count;
    1361                
    1362                 if (highprio) {
    1363                         free_highprio = free_count;
    1364                 } else {
    1365                         /*
    1366                          * Walk all frames of the zone and examine
    1367                          * all high priority memory to get accurate
    1368                          * statistics.
    1369                          */
    1370                        
    1371                         for (size_t index = 0; index < count; index++) {
    1372                                 if (is_high_priority(fbase + index, 0)) {
    1373                                         if (!bitmap_get(&zones.info[znum].bitmap, index))
    1374                                                 free_highprio++;
    1375                                 } else
    1376                                         break;
    1377                         }
    1378                 }
    1379         }
    1380        
    1381         irq_spinlock_unlock(&zones.lock, true);
    13821223       
    13831224        uint64_t size;
    13841225        const char *size_suffix;
    1385        
    13861226        bin_order_suffix(FRAMES2SIZE(count), &size, &size_suffix, false);
    13871227       
    1388         printf("Zone number:             %zu\n", znum);
    1389         printf("Zone base address:       %p\n", (void *) base);
    1390         printf("Zone size:               %zu frames (%" PRIu64 " %s)\n", count,
     1228        printf("Zone number:       %zu\n", znum);
     1229        printf("Zone base address: %p\n", (void *) base);
     1230        printf("Zone size:         %zu frames (%" PRIu64 " %s)\n", count,
    13911231            size, size_suffix);
    1392         printf("Zone flags:              %c%c%c%c%c\n",
     1232        printf("Zone flags:        %c%c%c%c%c\n",
    13931233            available ? 'A' : '-',
    13941234            (flags & ZONE_RESERVED) ? 'R' : '-',
     
    14001240                bin_order_suffix(FRAMES2SIZE(busy_count), &size, &size_suffix,
    14011241                    false);
    1402                 printf("Allocated space:         %zu frames (%" PRIu64 " %s)\n",
     1242                printf("Allocated space:   %zu frames (%" PRIu64 " %s)\n",
    14031243                    busy_count, size, size_suffix);
    1404                
    14051244                bin_order_suffix(FRAMES2SIZE(free_count), &size, &size_suffix,
    14061245                    false);
    1407                 printf("Available space:         %zu frames (%" PRIu64 " %s)\n",
     1246                printf("Available space:   %zu frames (%" PRIu64 " %s)\n",
    14081247                    free_count, size, size_suffix);
    1409                
    1410                 bin_order_suffix(FRAMES2SIZE(free_lowmem), &size, &size_suffix,
    1411                     false);
    1412                 printf("Available low memory:    %zu frames (%" PRIu64 " %s)\n",
    1413                     free_lowmem, size, size_suffix);
    1414                
    1415                 bin_order_suffix(FRAMES2SIZE(free_highmem), &size, &size_suffix,
    1416                     false);
    1417                 printf("Available high memory:   %zu frames (%" PRIu64 " %s)\n",
    1418                     free_highmem, size, size_suffix);
    1419                
    1420                 bin_order_suffix(FRAMES2SIZE(free_highprio), &size, &size_suffix,
    1421                     false);
    1422                 printf("Available high priority: %zu frames (%" PRIu64 " %s)\n",
    1423                     free_highprio, size, size_suffix);
    14241248        }
    14251249}
Note: See TracChangeset for help on using the changeset viewer.