~jakub/helenos/ia64-revival

« back to all changes in this revision

Viewing changes to kernel/generic/src/mm/frame.c

  • Committer: Jakub Jermar
  • Date: 2011-04-13 14:45:41 UTC
  • mfrom: (527.1.397 main-clone)
  • Revision ID: jakub@jermar.eu-20110413144541-x0j3r1zxqhsljx1o
MergeĀ mainlineĀ changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
74
74
/* Helper functions */
75
75
/********************/
76
76
 
77
 
static inline size_t frame_index(zone_t *zone, frame_t *frame)
 
77
NO_TRACE static inline size_t frame_index(zone_t *zone, frame_t *frame)
78
78
{
79
79
        return (size_t) (frame - zone->frames);
80
80
}
81
81
 
82
 
static inline size_t frame_index_abs(zone_t *zone, frame_t *frame)
 
82
NO_TRACE static inline size_t frame_index_abs(zone_t *zone, frame_t *frame)
83
83
{
84
84
        return (size_t) (frame - zone->frames) + zone->base;
85
85
}
86
86
 
87
 
static inline bool frame_index_valid(zone_t *zone, size_t index)
 
87
NO_TRACE static inline bool frame_index_valid(zone_t *zone, size_t index)
88
88
{
89
89
        return (index < zone->count);
90
90
}
91
91
 
92
 
static inline size_t make_frame_index(zone_t *zone, frame_t *frame)
 
92
NO_TRACE static inline size_t make_frame_index(zone_t *zone, frame_t *frame)
93
93
{
94
94
        return (frame - zone->frames);
95
95
}
99
99
 * @param frame Frame structure to be initialized.
100
100
 *
101
101
 */
102
 
static void frame_initialize(frame_t *frame)
 
102
NO_TRACE static void frame_initialize(frame_t *frame)
103
103
{
104
104
        frame->refcount = 1;
105
105
        frame->buddy_order = 0;
120
120
 * @return Zone number on success, -1 on error.
121
121
 *
122
122
 */
123
 
static size_t zones_insert_zone(pfn_t base, size_t count)
 
123
NO_TRACE static size_t zones_insert_zone(pfn_t base, size_t count,
 
124
    zone_flags_t flags)
124
125
{
125
126
        if (zones.count + 1 == ZONES_MAX) {
126
127
                printf("Maximum zone count %u exceeded!\n", ZONES_MAX);
130
131
        size_t i;
131
132
        for (i = 0; i < zones.count; i++) {
132
133
                /* 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 "
 
148
                                    "with previous zone (%p %p)!\n",
 
149
                                    (void *) PFN2ADDR(base), (void *) PFN2ADDR(count),
 
150
                                    (void *) PFN2ADDR(zones.info[i].base),
 
151
                                    (void *) PFN2ADDR(zones.info[i].count));
 
152
                        }
 
153
                        
136
154
                        return (size_t) -1;
137
155
                }
138
156
                if (base < zones.info[i].base)
143
161
        size_t j;
144
162
        for (j = zones.count; j > i; j--) {
145
163
                zones.info[j] = zones.info[j - 1];
146
 
                zones.info[j].buddy_system->data =
147
 
                    (void *) &zones.info[j - 1];
 
164
                if (zones.info[j].buddy_system != NULL)
 
165
                        zones.info[j].buddy_system->data =
 
166
                            (void *) &zones.info[j];
148
167
        }
149
168
        
150
169
        zones.count++;
161
180
 *
162
181
 */
163
182
#ifdef CONFIG_DEBUG
164
 
static size_t total_frames_free(void)
 
183
NO_TRACE static size_t total_frames_free(void)
165
184
{
166
185
        size_t total = 0;
167
186
        size_t i;
184
203
 * @return Zone index or -1 if not found.
185
204
 *
186
205
 */
187
 
size_t find_zone(pfn_t frame, size_t count, size_t hint)
 
206
NO_TRACE size_t find_zone(pfn_t frame, size_t count, size_t hint)
188
207
{
189
208
        if (hint >= zones.count)
190
209
                hint = 0;
205
224
}
206
225
 
207
226
/** @return True if zone can allocate specified order */
208
 
static bool zone_can_alloc(zone_t *zone, uint8_t order)
 
227
NO_TRACE static bool zone_can_alloc(zone_t *zone, uint8_t order)
209
228
{
210
229
        return (zone_flags_available(zone->flags)
211
230
            && buddy_system_can_alloc(zone->buddy_system, order));
221
240
 * @param hind  Preferred zone.
222
241
 *
223
242
 */
224
 
static size_t find_free_zone(uint8_t order, zone_flags_t flags, size_t hint)
 
243
NO_TRACE static size_t find_free_zone(uint8_t order, zone_flags_t flags,
 
244
    size_t hint)
225
245
{
226
246
        if (hint >= zones.count)
227
247
                hint = 0;
261
281
 *              parameter!!
262
282
 *
263
283
 */
264
 
static link_t *zone_buddy_find_block(buddy_system_t *buddy, link_t *child,
265
 
    uint8_t order)
 
284
NO_TRACE static link_t *zone_buddy_find_block(buddy_system_t *buddy,
 
285
    link_t *child, uint8_t order)
266
286
{
267
287
        frame_t *frame = list_get_instance(child, frame_t, buddy_link);
268
288
        zone_t *zone = (zone_t *) buddy->data;
284
304
 * @return Buddy for given block if found.
285
305
 *
286
306
 */
287
 
static link_t *zone_buddy_find_buddy(buddy_system_t *buddy, link_t *block) 
 
307
NO_TRACE static link_t *zone_buddy_find_buddy(buddy_system_t *buddy,
 
308
    link_t *block)
288
309
{
289
310
        frame_t *frame = list_get_instance(block, frame_t, buddy_link);
290
311
        zone_t *zone = (zone_t *) buddy->data;
320
341
 * @return Right block.
321
342
 *
322
343
 */
323
 
static link_t *zone_buddy_bisect(buddy_system_t *buddy, link_t *block)
 
344
NO_TRACE static link_t *zone_buddy_bisect(buddy_system_t *buddy, link_t *block)
324
345
{
325
346
        frame_t *frame_l = list_get_instance(block, frame_t, buddy_link);
326
347
        frame_t *frame_r = (frame_l + (1 << (frame_l->buddy_order - 1)));
338
359
 *         address).
339
360
 *
340
361
 */
341
 
static link_t *zone_buddy_coalesce(buddy_system_t *buddy, link_t *block_1,
342
 
    link_t *block_2)
 
362
NO_TRACE static link_t *zone_buddy_coalesce(buddy_system_t *buddy,
 
363
    link_t *block_1, link_t *block_2)
343
364
{
344
365
        frame_t *frame1 = list_get_instance(block_1, frame_t, buddy_link);
345
366
        frame_t *frame2 = list_get_instance(block_2, frame_t, buddy_link);
354
375
 * @param order Order to set.
355
376
 *
356
377
 */
357
 
static void zone_buddy_set_order(buddy_system_t *buddy, link_t *block,
 
378
NO_TRACE static void zone_buddy_set_order(buddy_system_t *buddy, link_t *block,
358
379
    uint8_t order)
359
380
{
360
381
        list_get_instance(block, frame_t, buddy_link)->buddy_order = order;
368
389
 * @return Order of block.
369
390
 *
370
391
 */
371
 
static uint8_t zone_buddy_get_order(buddy_system_t *buddy, link_t *block)
 
392
NO_TRACE static uint8_t zone_buddy_get_order(buddy_system_t *buddy,
 
393
    link_t *block)
372
394
{
373
395
        return list_get_instance(block, frame_t, buddy_link)->buddy_order;
374
396
}
379
401
 * @param block Buddy system block.
380
402
 *
381
403
 */
382
 
static void zone_buddy_mark_busy(buddy_system_t *buddy, link_t * block)
 
404
NO_TRACE static void zone_buddy_mark_busy(buddy_system_t *buddy, link_t *block)
383
405
{
384
406
        list_get_instance(block, frame_t, buddy_link)->refcount = 1;
385
407
}
388
410
 *
389
411
 * @param buddy Buddy system.
390
412
 * @param block Buddy system block.
 
413
 *
391
414
 */
392
 
static void zone_buddy_mark_available(buddy_system_t *buddy, link_t *block)
 
415
NO_TRACE static void zone_buddy_mark_available(buddy_system_t *buddy,
 
416
    link_t *block)
393
417
{
394
418
        list_get_instance(block, frame_t, buddy_link)->refcount = 0;
395
419
}
420
444
 * @return Frame index in zone.
421
445
 *
422
446
 */
423
 
static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order)
 
447
NO_TRACE static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order)
424
448
{
425
449
        ASSERT(zone_flags_available(zone->flags));
426
450
        
448
472
 * @param frame_idx Frame index relative to zone.
449
473
 *
450
474
 */
451
 
static void zone_frame_free(zone_t *zone, size_t frame_idx)
 
475
NO_TRACE static void zone_frame_free(zone_t *zone, size_t frame_idx)
452
476
{
453
477
        ASSERT(zone_flags_available(zone->flags));
454
478
        
469
493
}
470
494
 
471
495
/** Return frame from zone. */
472
 
static frame_t *zone_get_frame(zone_t *zone, size_t frame_idx)
 
496
NO_TRACE static frame_t *zone_get_frame(zone_t *zone, size_t frame_idx)
473
497
{
474
498
        ASSERT(frame_idx < zone->count);
475
499
        return &zone->frames[frame_idx];
476
500
}
477
501
 
478
502
/** Mark frame in zone unavailable to allocation. */
479
 
static void zone_mark_unavailable(zone_t *zone, size_t frame_idx)
 
503
NO_TRACE static void zone_mark_unavailable(zone_t *zone, size_t frame_idx)
480
504
{
481
505
        ASSERT(zone_flags_available(zone->flags));
482
506
        
505
529
 * @param buddy  Merged zone buddy.
506
530
 *
507
531
 */
508
 
static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1, buddy_system_t *buddy)
 
532
NO_TRACE static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1,
 
533
    buddy_system_t *buddy)
509
534
{
510
535
        ASSERT(zone_flags_available(zones.info[z1].flags));
511
536
        ASSERT(zone_flags_available(zones.info[z2].flags));
601
626
 * @param count Old zone frame count.
602
627
 *
603
628
 */
604
 
static void return_config_frames(size_t znum, pfn_t pfn, size_t count)
 
629
NO_TRACE static void return_config_frames(size_t znum, pfn_t pfn, size_t count)
605
630
{
606
631
        ASSERT(zone_flags_available(zones.info[znum].flags));
607
632
        
636
661
 * @param count     Allocated frames in block.
637
662
 *
638
663
 */
639
 
static void zone_reduce_region(size_t znum, pfn_t frame_idx, size_t count)
 
664
NO_TRACE static void zone_reduce_region(size_t znum, pfn_t frame_idx,
 
665
    size_t count)
640
666
{
641
667
        ASSERT(zone_flags_available(zones.info[znum].flags));
642
668
        ASSERT(frame_idx + count < zones.info[znum].count);
737
763
        size_t i;
738
764
        for (i = z2 + 1; i < zones.count; i++) {
739
765
                zones.info[i - 1] = zones.info[i];
740
 
                zones.info[i - 1].buddy_system->data =
741
 
                    (void *) &zones.info[i - 1];
 
766
                if (zones.info[i - 1].buddy_system != NULL)
 
767
                        zones.info[i - 1].buddy_system->data =
 
768
                            (void *) &zones.info[i - 1];
742
769
        }
743
770
        
744
771
        zones.count--;
776
803
 * @return Initialized zone.
777
804
 *
778
805
 */
779
 
static void zone_construct(zone_t *zone, buddy_system_t *buddy, pfn_t start,
780
 
    size_t count, zone_flags_t flags)
 
806
NO_TRACE static void zone_construct(zone_t *zone, buddy_system_t *buddy,
 
807
    pfn_t start, size_t count, zone_flags_t flags)
781
808
{
782
809
        zone->base = start;
783
810
        zone->count = count;
820
847
 * @return Size of zone configuration info (in bytes).
821
848
 *
822
849
 */
823
 
uintptr_t zone_conf_size(size_t count)
 
850
size_t zone_conf_size(size_t count)
824
851
{
825
852
        return (count * sizeof(frame_t) + buddy_conf_size(fnzb(count)));
826
853
}
851
878
                 * nobody tries to do that. If some platform requires, remove
852
879
                 * the assert
853
880
                 */
854
 
                ASSERT(confframe != NULL);
 
881
                ASSERT(confframe != ADDR2PFN((uintptr_t ) NULL));
855
882
                
856
883
                /* If confframe is supposed to be inside our zone, then make sure
857
884
                 * it does not span kernel & init
887
914
                                panic("Cannot find configuration data for zone.");
888
915
                }
889
916
                
890
 
                size_t znum = zones_insert_zone(start, count);
 
917
                size_t znum = zones_insert_zone(start, count, flags);
891
918
                if (znum == (size_t) -1) {
892
919
                        irq_spinlock_unlock(&zones.lock, true);
893
920
                        return (size_t) -1;
910
937
        }
911
938
        
912
939
        /* Non-available zone */
913
 
        size_t znum = zones_insert_zone(start, count);
 
940
        size_t znum = zones_insert_zone(start, count, flags);
914
941
        if (znum == (size_t) -1) {
915
942
                irq_spinlock_unlock(&zones.lock, true);
916
943
                return (size_t) -1;
1022
1049
                 */
1023
1050
                
1024
1051
#ifdef CONFIG_DEBUG
1025
 
                printf("Thread %" PRIu64 " waiting for %" PRIs " frames, "
1026
 
                    "%" PRIs " available.\n", THREAD->tid, size, avail);
 
1052
                printf("Thread %" PRIu64 " waiting for %zu frames, "
 
1053
                    "%zu available.\n", THREAD->tid, size, avail);
1027
1054
#endif
1028
1055
                
1029
1056
                mutex_lock(&mem_avail_mtx);
1077
1104
         * First, find host frame zone for addr.
1078
1105
         */
1079
1106
        pfn_t pfn = ADDR2PFN(frame);
1080
 
        size_t znum = find_zone(pfn, 1, NULL);
 
1107
        size_t znum = find_zone(pfn, 1, 0);
1081
1108
        
1082
1109
        ASSERT(znum != (size_t) -1);
1083
1110
        
1107
1134
 * @param pfn Frame number of the frame to be freed.
1108
1135
 *
1109
1136
 */
1110
 
void frame_reference_add(pfn_t pfn)
 
1137
NO_TRACE void frame_reference_add(pfn_t pfn)
1111
1138
{
1112
1139
        irq_spinlock_lock(&zones.lock, true);
1113
1140
        
1114
1141
        /*
1115
1142
         * First, find host frame zone for addr.
1116
1143
         */
1117
 
        size_t znum = find_zone(pfn, 1, NULL);
 
1144
        size_t znum = find_zone(pfn, 1, 0);
1118
1145
        
1119
1146
        ASSERT(znum != (size_t) -1);
1120
1147
        
1126
1153
/** Mark given range unavailable in frame zones.
1127
1154
 *
1128
1155
 */
1129
 
void frame_mark_unavailable(pfn_t start, size_t count)
 
1156
NO_TRACE void frame_mark_unavailable(pfn_t start, size_t count)
1130
1157
{
1131
1158
        irq_spinlock_lock(&zones.lock, true);
1132
1159
        
1270
1297
                
1271
1298
                bool available = zone_flags_available(flags);
1272
1299
                
1273
 
                printf("%-4" PRIs, i);
 
1300
                printf("%-4zu", i);
1274
1301
                
1275
1302
#ifdef __32_BITS__
1276
 
                printf("  %10p", base);
 
1303
                printf("  %p", (void *) base);
1277
1304
#endif
1278
1305
                
1279
1306
#ifdef __64_BITS__
1280
 
                printf(" %18p", base);
 
1307
                printf(" %p", (void *) base);
1281
1308
#endif
1282
1309
                
1283
 
                printf(" %12" PRIs " %c%c%c      ", count,
 
1310
                printf(" %12zu %c%c%c      ", count,
1284
1311
                    available ? 'A' : ' ',
1285
1312
                    (flags & ZONE_RESERVED) ? 'R' : ' ',
1286
1313
                    (flags & ZONE_FIRMWARE) ? 'F' : ' ');
1287
1314
                
1288
1315
                if (available)
1289
 
                        printf("%14" PRIs " %14" PRIs,
 
1316
                        printf("%14zu %14zu",
1290
1317
                            free_count, busy_count);
1291
1318
                
1292
1319
                printf("\n");
1327
1354
        
1328
1355
        bool available = zone_flags_available(flags);
1329
1356
        
1330
 
        printf("Zone number:       %" PRIs "\n", znum);
1331
 
        printf("Zone base address: %p\n", base);
1332
 
        printf("Zone size:         %" PRIs " frames (%" PRIs " KiB)\n", count,
 
1357
        printf("Zone number:       %zu\n", znum);
 
1358
        printf("Zone base address: %p\n", (void *) base);
 
1359
        printf("Zone size:         %zu frames (%zu KiB)\n", count,
1333
1360
            SIZE2KB(FRAMES2SIZE(count)));
1334
1361
        printf("Zone flags:        %c%c%c\n",
1335
1362
            available ? 'A' : ' ',
1337
1364
            (flags & ZONE_FIRMWARE) ? 'F' : ' ');
1338
1365
        
1339
1366
        if (available) {
1340
 
                printf("Allocated space:   %" PRIs " frames (%" PRIs " KiB)\n",
 
1367
                printf("Allocated space:   %zu frames (%zu KiB)\n",
1341
1368
                    busy_count, SIZE2KB(FRAMES2SIZE(busy_count)));
1342
 
                printf("Available space:   %" PRIs " frames (%" PRIs " KiB)\n",
 
1369
                printf("Available space:   %zu frames (%zu KiB)\n",
1343
1370
                    free_count, SIZE2KB(FRAMES2SIZE(free_count)));
1344
1371
        }
1345
1372
}