Subversion Repositories HelenOS

Rev

Rev 3191 | Rev 4344 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3191 Rev 3211
Line 198... Line 198...
198
    interrupts_restore(ipl);
198
    interrupts_restore(ipl);
199
 
199
 
200
    return i;
200
    return i;
201
}
201
}
202
 
202
 
203
/**
-
 
204
 * Try to find a zone where can we find the frame.
203
/** Try to find a zone where can we find the frame.
205
 *
204
 *
206
 * Assume interrupts are disabled.
205
 * Assume interrupts are disabled.
207
 *
206
 *
208
 * @param frame     Frame number contained in zone.
207
 * @param frame     Frame number contained in zone.
209
 * @param pzone     If not null, it is used as zone hint. Zone index is
208
 * @param pzone     If not null, it is used as zone hint. Zone index is
Line 235... Line 234...
235
        spinlock_unlock(&z->lock);
234
        spinlock_unlock(&z->lock);
236
 
235
 
237
        i++;
236
        i++;
238
        if (i >= zones.count)
237
        if (i >= zones.count)
239
            i = 0;
238
            i = 0;
240
    } while(i != hint);
239
    } while (i != hint);
241
 
240
 
242
    spinlock_unlock(&zones.lock);
241
    spinlock_unlock(&zones.lock);
243
    return NULL;
242
    return NULL;
244
}
243
}
245
 
244
 
Line 252... Line 251...
252
/** Find and lock zone that can allocate order frames.
251
/** Find and lock zone that can allocate order frames.
253
 *
252
 *
254
 * Assume interrupts are disabled.
253
 * Assume interrupts are disabled.
255
 *
254
 *
256
 * @param order     Size (2^order) of free space we are trying to find.
255
 * @param order     Size (2^order) of free space we are trying to find.
-
 
256
 * @param flags     Required flags of the target zone.
257
 * @param pzone     Pointer to preferred zone or NULL, on return contains
257
 * @param pzone     Pointer to preferred zone or NULL, on return contains
258
 *          zone number.
258
 *          zone number.
259
 */
259
 */
-
 
260
static zone_t *
260
static zone_t *find_free_zone_and_lock(uint8_t order, unsigned int *pzone)
261
find_free_zone_and_lock(uint8_t order, int flags, unsigned int *pzone)
261
{
262
{
262
    unsigned int i;
263
    unsigned int i;
263
    zone_t *z;
264
    zone_t *z;
264
    unsigned int hint = pzone ? *pzone : 0;
265
    unsigned int hint = pzone ? *pzone : 0;
265
   
266
   
-
 
267
    /* Mask off flags that are not applicable. */
-
 
268
    flags &= FRAME_LOW_4_GiB;
-
 
269
 
266
    spinlock_lock(&zones.lock);
270
    spinlock_lock(&zones.lock);
267
    if (hint >= zones.count)
271
    if (hint >= zones.count)
268
        hint = 0;
272
        hint = 0;
269
    i = hint;
273
    i = hint;
270
    do {
274
    do {
271
        z = zones.info[i];
275
        z = zones.info[i];
272
       
276
       
273
        spinlock_lock(&z->lock);
277
        spinlock_lock(&z->lock);
274
 
278
 
-
 
279
        /*
-
 
280
         * Check whether the zone meets the search criteria.
-
 
281
         */
-
 
282
        if ((z->flags & flags) == flags) {
-
 
283
            /*
275
        /* Check if the zone has 2^order frames area available  */
284
             * Check if the zone has 2^order frames area available.
-
 
285
             */
276
        if (zone_can_alloc(z, order)) {
286
            if (zone_can_alloc(z, order)) {
277
            spinlock_unlock(&zones.lock);
287
                spinlock_unlock(&zones.lock);
278
            if (pzone)
288
                if (pzone)
279
                *pzone = i;
289
                    *pzone = i;
280
            return z;
290
                return z;
-
 
291
            }
281
        }
292
        }
282
        spinlock_unlock(&z->lock);
293
        spinlock_unlock(&z->lock);
283
        if (++i >= zones.count)
294
        if (++i >= zones.count)
284
            i = 0;
295
            i = 0;
285
    } while(i != hint);
296
    } while (i != hint);
286
    spinlock_unlock(&zones.lock);
297
    spinlock_unlock(&zones.lock);
287
    return NULL;
298
    return NULL;
288
}
299
}
289
 
300
 
290
/**************************/
301
/**************************/
Line 316... Line 327...
316
        }
327
        }
317
    } while(index-- > 0);
328
    } while(index-- > 0);
318
    return NULL;
329
    return NULL;
319
}
330
}
320
 
331
 
321
static void zone_buddy_print_id(buddy_system_t *b, link_t *block)
-
 
322
{
-
 
323
    frame_t *frame;
-
 
324
    zone_t *zone;
-
 
325
    index_t index;
-
 
326
 
-
 
327
    frame = list_get_instance(block, frame_t, buddy_link);
-
 
328
    zone = (zone_t *) b->data;
-
 
329
    index = frame_index(zone, frame);
-
 
330
    printf("%" PRIi, index);
-
 
331
}                    
-
 
332
 
-
 
333
/** Buddy system find_buddy implementation.
332
/** Buddy system find_buddy implementation.
334
 *
333
 *
335
 * @param b     Buddy system.
334
 * @param b     Buddy system.
336
 * @param block     Block for which buddy should be found.
335
 * @param block     Block for which buddy should be found.
337
 *
336
 *
Line 467... Line 466...
467
    .coalesce = zone_buddy_coalesce,
466
    .coalesce = zone_buddy_coalesce,
468
    .set_order = zone_buddy_set_order,
467
    .set_order = zone_buddy_set_order,
469
    .get_order = zone_buddy_get_order,
468
    .get_order = zone_buddy_get_order,
470
    .mark_busy = zone_buddy_mark_busy,
469
    .mark_busy = zone_buddy_mark_busy,
471
    .mark_available = zone_buddy_mark_available,
470
    .mark_available = zone_buddy_mark_available,
472
    .find_block = zone_buddy_find_block,
471
    .find_block = zone_buddy_find_block
473
    .print_id = zone_buddy_print_id
-
 
474
};
472
};
475
 
473
 
476
/******************/
474
/******************/
477
/* Zone functions */
475
/* Zone functions */
478
/******************/
476
/******************/
Line 821... Line 819...
821
    uint8_t max_order;
819
    uint8_t max_order;
822
 
820
 
823
    spinlock_initialize(&z->lock, "zone_lock");
821
    spinlock_initialize(&z->lock, "zone_lock");
824
    z->base = start;
822
    z->base = start;
825
    z->count = count;
823
    z->count = count;
-
 
824
 
-
 
825
    /* Mask off flags that are calculated automatically. */
-
 
826
    flags &= ~FRAME_LOW_4_GiB;
-
 
827
    /* Determine calculated flags. */
-
 
828
    if (z->base + count < (1ULL << (32 - FRAME_WIDTH))) /* 4 GiB */
-
 
829
        flags |= FRAME_LOW_4_GiB;
-
 
830
 
826
    z->flags = flags;
831
    z->flags = flags;
-
 
832
 
827
    z->free_count = count;
833
    z->free_count = count;
828
    z->busy_count = 0;
834
    z->busy_count = 0;
829
 
835
 
830
    /*
836
    /*
831
     * Compute order for buddy system, initialize
837
     * Compute order for buddy system, initialize
Line 993... Line 999...
993
    ipl = interrupts_disable();
999
    ipl = interrupts_disable();
994
   
1000
   
995
    /*
1001
    /*
996
     * First, find suitable frame zone.
1002
     * First, find suitable frame zone.
997
     */
1003
     */
998
    zone = find_free_zone_and_lock(order, pzone);
1004
    zone = find_free_zone_and_lock(order, flags, pzone);
999
   
1005
   
1000
    /* If no memory, reclaim some slab memory,
1006
    /* If no memory, reclaim some slab memory,
1001
       if it does not help, reclaim all */
1007
       if it does not help, reclaim all */
1002
    if (!zone && !(flags & FRAME_NO_RECLAIM)) {
1008
    if (!zone && !(flags & FRAME_NO_RECLAIM)) {
1003
        freed = slab_reclaim(0);
1009
        freed = slab_reclaim(0);
1004
        if (freed)
1010
        if (freed)
1005
            zone = find_free_zone_and_lock(order, pzone);
1011
            zone = find_free_zone_and_lock(order, flags, pzone);
1006
        if (!zone) {
1012
        if (!zone) {
1007
            freed = slab_reclaim(SLAB_RECLAIM_ALL);
1013
            freed = slab_reclaim(SLAB_RECLAIM_ALL);
1008
            if (freed)
1014
            if (freed)
1009
                zone = find_free_zone_and_lock(order, pzone);
1015
                zone = find_free_zone_and_lock(order, flags,
-
 
1016
                    pzone);
1010
        }
1017
        }
1011
    }
1018
    }
1012
    if (!zone) {
1019
    if (!zone) {
1013
        /*
1020
        /*
1014
         * Sleep until some frames are available again.
1021
         * Sleep until some frames are available again.
Line 1212... Line 1219...
1212
{
1219
{
1213
    zone_t *zone = NULL;
1220
    zone_t *zone = NULL;
1214
    unsigned int i;
1221
    unsigned int i;
1215
    ipl_t ipl;
1222
    ipl_t ipl;
1216
 
1223
 
1217
    ipl = interrupts_disable();
-
 
1218
    spinlock_lock(&zones.lock);
-
 
1219
 
-
 
1220
#ifdef __32_BITS__  
1224
#ifdef __32_BITS__  
1221
    printf("#  base address free frames  busy frames\n");
1225
    printf("#  base address free frames  busy frames\n");
1222
    printf("-- ------------ ------------ ------------\n");
1226
    printf("-- ------------ ------------ ------------\n");
1223
#endif
1227
#endif
1224
 
1228
 
1225
#ifdef __64_BITS__
1229
#ifdef __64_BITS__
1226
    printf("#  base address         free frames  busy frames\n");
1230
    printf("#  base address         free frames  busy frames\n");
1227
    printf("-- -------------------- ------------ ------------\n");
1231
    printf("-- -------------------- ------------ ------------\n");
1228
#endif
1232
#endif
1229
   
1233
   
-
 
1234
    /*
-
 
1235
     * Because printing may require allocation of memory, we may not hold
-
 
1236
     * the frame allocator locks when printing zone statistics.  Therefore,
-
 
1237
     * we simply gather the statistics under the protection of the locks and
-
 
1238
     * print the statistics when the locks have been released.
-
 
1239
     *
-
 
1240
     * When someone adds/removes zones while we are printing the statistics,
-
 
1241
     * we may end up with inaccurate output (e.g. a zone being skipped from
-
 
1242
     * the listing).
-
 
1243
     */
-
 
1244
 
1230
    for (i = 0; i < zones.count; i++) {
1245
    for (i = 0; ; i++) {
-
 
1246
        uintptr_t base;
-
 
1247
        count_t free_count;
-
 
1248
        count_t busy_count;
-
 
1249
 
-
 
1250
        ipl = interrupts_disable();
-
 
1251
        spinlock_lock(&zones.lock);
-
 
1252
       
-
 
1253
        if (i >= zones.count) {
-
 
1254
            spinlock_unlock(&zones.lock);
-
 
1255
            interrupts_restore(ipl);
-
 
1256
            break;
-
 
1257
        }
-
 
1258
 
1231
        zone = zones.info[i];
1259
        zone = zones.info[i];
1232
        spinlock_lock(&zone->lock);
1260
        spinlock_lock(&zone->lock);
1233
 
1261
 
-
 
1262
        base = PFN2ADDR(zone->base);
-
 
1263
        free_count = zone->free_count;
-
 
1264
        busy_count = zone->busy_count;
-
 
1265
 
-
 
1266
        spinlock_unlock(&zone->lock);
-
 
1267
       
-
 
1268
        spinlock_unlock(&zones.lock);
-
 
1269
        interrupts_restore(ipl);
-
 
1270
 
1234
#ifdef __32_BITS__
1271
#ifdef __32_BITS__
1235
        printf("%-2u   %10p %12" PRIc " %12" PRIc "\n",
1272
        printf("%-2u   %10p %12" PRIc " %12" PRIc "\n", i, base,
1236
            i, PFN2ADDR(zone->base), zone->free_count,
-
 
1237
            zone->busy_count);
1273
            free_count, busy_count);
1238
#endif
1274
#endif
1239
 
1275
 
1240
#ifdef __64_BITS__
1276
#ifdef __64_BITS__
1241
        printf("%-2u   %18p %12" PRIc " %12" PRIc "\n", i,
1277
        printf("%-2u   %18p %12" PRIc " %12" PRIc "\n", i, base,
1242
            PFN2ADDR(zone->base), zone->free_count, zone->busy_count);
1278
            free_count, busy_count);
1243
#endif
1279
#endif
1244
       
1280
       
1245
        spinlock_unlock(&zone->lock);
-
 
1246
    }
1281
    }
1247
   
-
 
1248
    spinlock_unlock(&zones.lock);
-
 
1249
    interrupts_restore(ipl);
-
 
1250
}
1282
}
1251
 
1283
 
1252
/** Prints zone details.
1284
/** Prints zone details.
1253
 *
1285
 *
1254
 * @param num       Zone base address or zone number.
1286
 * @param num       Zone base address or zone number.
Line 1256... Line 1288...
1256
void zone_print_one(unsigned int num)
1288
void zone_print_one(unsigned int num)
1257
{
1289
{
1258
    zone_t *zone = NULL;
1290
    zone_t *zone = NULL;
1259
    ipl_t ipl;
1291
    ipl_t ipl;
1260
    unsigned int i;
1292
    unsigned int i;
-
 
1293
    uintptr_t base;
-
 
1294
    count_t count;
-
 
1295
    count_t busy_count;
-
 
1296
    count_t free_count;
1261
 
1297
 
1262
    ipl = interrupts_disable();
1298
    ipl = interrupts_disable();
1263
    spinlock_lock(&zones.lock);
1299
    spinlock_lock(&zones.lock);
1264
 
1300
 
1265
    for (i = 0; i < zones.count; i++) {
1301
    for (i = 0; i < zones.count; i++) {
Line 1267... Line 1303...
1267
            zone = zones.info[i];
1303
            zone = zones.info[i];
1268
            break;
1304
            break;
1269
        }
1305
        }
1270
    }
1306
    }
1271
    if (!zone) {
1307
    if (!zone) {
-
 
1308
        spinlock_unlock(&zones.lock);
-
 
1309
        interrupts_restore(ipl);
1272
        printf("Zone not found.\n");
1310
        printf("Zone not found.\n");
1273
        goto out;
1311
        return;
1274
    }
1312
    }
1275
   
1313
   
1276
    spinlock_lock(&zone->lock);
1314
    spinlock_lock(&zone->lock);
1277
    printf("Memory zone information\n");
-
 
1278
    printf("Zone base address: %p\n", PFN2ADDR(zone->base));
1315
    base = PFN2ADDR(zone->base);
1279
    printf("Zone size: %" PRIc " frames (%" PRIs " KB)\n", zone->count,
-
 
1280
        SIZE2KB(FRAMES2SIZE(zone->count)));
1316
    count = zone->count;
1281
    printf("Allocated space: %" PRIc " frames (%" PRIs " KB)\n",
-
 
1282
        zone->busy_count, SIZE2KB(FRAMES2SIZE(zone->busy_count)));
1317
    busy_count = zone->busy_count;
1283
    printf("Available space: %" PRIc " frames (%" PRIs " KB)\n",
-
 
1284
        zone->free_count, SIZE2KB(FRAMES2SIZE(zone->free_count)));
1318
    free_count = zone->free_count;
1285
    buddy_system_structure_print(zone->buddy_system, FRAME_SIZE);
-
 
1286
    spinlock_unlock(&zone->lock);
1319
    spinlock_unlock(&zone->lock);
1287
   
-
 
1288
out:
-
 
1289
    spinlock_unlock(&zones.lock);
1320
    spinlock_unlock(&zones.lock);
1290
    interrupts_restore(ipl);
1321
    interrupts_restore(ipl);
-
 
1322
 
-
 
1323
    printf("Zone base address: %p\n", base);
-
 
1324
    printf("Zone size: %" PRIc " frames (%" PRIs " KiB)\n", count,
-
 
1325
        SIZE2KB(FRAMES2SIZE(count)));
-
 
1326
    printf("Allocated space: %" PRIc " frames (%" PRIs " KiB)\n",
-
 
1327
        busy_count, SIZE2KB(FRAMES2SIZE(busy_count)));
-
 
1328
    printf("Available space: %" PRIc " frames (%" PRIs " KiB)\n",
-
 
1329
        free_count, SIZE2KB(FRAMES2SIZE(free_count)));
1291
}
1330
}
1292
 
1331
 
1293
/** @}
1332
/** @}
1294
 */
1333
 */
1295
 
1334