Subversion Repositories HelenOS-historic

Rev

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

Rev 822 Rev 824
Line 573... Line 573...
573
 
573
 
574
/** Return old configuration frames into the zone
574
/** Return old configuration frames into the zone
575
 *
575
 *
576
 * We have several cases
576
 * We have several cases
577
 * - the conf. data is outside of zone -> exit, shall we call frame_free??
577
 * - the conf. data is outside of zone -> exit, shall we call frame_free??
578
 * - the conf. data was created by zone_create -> free every frame
578
 * - the conf. data was created by zone_create or
579
 * - the conf. data was created by merge in frame_alloc -> free first frame
579
 *   updated with reduce_region -> free every frame
-
 
580
 *
-
 
581
 * @param newzone The actual zone where freeing should occur
-
 
582
 * @param oldzone Pointer to old zone configuration data that should
580
 *   (the difference is in order)
583
 *                be freed from new zone
581
 */
584
 */
582
static void return_config_frames(zone_t *newzone, zone_t *oldzone)
585
static void return_config_frames(zone_t *newzone, zone_t *oldzone)
583
{
586
{
584
    pfn_t pfn;
587
    pfn_t pfn;
585
    frame_t *frame;
588
    frame_t *frame;
Line 591... Line 594...
591
   
594
   
592
    if (pfn < newzone->base || pfn >= newzone->base + newzone->count)
595
    if (pfn < newzone->base || pfn >= newzone->base + newzone->count)
593
        return;
596
        return;
594
 
597
 
595
    frame = &newzone->frames[pfn - newzone->base];
598
    frame = &newzone->frames[pfn - newzone->base];
596
    if (frame->buddy_order) {
599
    ASSERT(!frame->buddy_order);
597
        /* Normally zone config data is hidden, show it again */
-
 
598
        newzone->busy_count += (1 << frame->buddy_order);
-
 
599
        zone_frame_free(newzone, pfn - newzone->base);
-
 
600
        return;
-
 
601
    }
-
 
602
 
600
 
603
    for (i=0; i < cframes; i++) {
601
    for (i=0; i < cframes; i++) {
604
        newzone->busy_count++;
602
        newzone->busy_count++;
605
        zone_frame_free(newzone, pfn+i-newzone->base);
603
        zone_frame_free(newzone, pfn+i-newzone->base);
606
    }
604
    }
607
}
605
}
608
 
606
 
-
 
607
 
-
 
608
/** Reduce allocated block to count of order 0 frames
-
 
609
 *
-
 
610
 * The allocated block need 2^order frames of space. Reduce all frames
-
 
611
 * in block to order 0 and free the unneded frames. This means, that
-
 
612
 * when freeing the block, you have to free every frame from block.
-
 
613
 *
-
 
614
 * @param zone
-
 
615
 * @param frame_idx Index to block
-
 
616
 * @param count Allocated space in block
-
 
617
 */
-
 
618
static void zone_reduce_region(zone_t *zone, pfn_t frame_idx, count_t count)
-
 
619
{
-
 
620
    count_t i;
-
 
621
    __u8 order;
-
 
622
    frame_t *frame;
-
 
623
   
-
 
624
    ASSERT(frame_idx+count < zone->count);
-
 
625
 
-
 
626
    order = zone->frames[frame_idx].buddy_order;
-
 
627
    ASSERT((1 << order) >= count);
-
 
628
 
-
 
629
    /* Reduce all blocks to order 0 */
-
 
630
    for (i=0; i < (1 << order); i++) {
-
 
631
        frame = &zone->frames[i + frame_idx];
-
 
632
        frame->buddy_order = 0;
-
 
633
        if (! frame->refcount)
-
 
634
            frame->refcount = 1;
-
 
635
        ASSERT(frame->refcount == 1);
-
 
636
    }
-
 
637
    /* Free unneeded frames */
-
 
638
    for (i=count; i < (1 << order); i++) {
-
 
639
        zone_frame_free(zone, i + frame_idx);
-
 
640
    }
-
 
641
}
-
 
642
 
609
/** Merge zones z1 and z2
643
/** Merge zones z1 and z2
610
 *
644
 *
611
 * - the zones must be 2 zones with no zone existing in between,
645
 * - the zones must be 2 zones with no zone existing in between,
612
 *   which means that z2 = z1+1
646
 *   which means that z2 = z1+1
613
 *
647
 *
Line 651... Line 685...
651
 
685
 
652
    newzone = (zone_t *)PA2KA(PFN2ADDR(pfn));
686
    newzone = (zone_t *)PA2KA(PFN2ADDR(pfn));
653
 
687
 
654
    _zone_merge(newzone, zone1, zone2);
688
    _zone_merge(newzone, zone1, zone2);
655
 
689
 
-
 
690
    /* Free unneeded config frames */
-
 
691
    zone_reduce_region(newzone, pfn - newzone->base,  cframes);
656
    /* Subtract zone information from busy frames */
692
    /* Subtract zone information from busy frames */
657
    newzone->busy_count -= (1 << order);
693
    newzone->busy_count -= cframes;
658
 
694
 
-
 
695
    /* Replace existing zones in zoneinfo list */
659
    zones.info[z1] = newzone;
696
    zones.info[z1] = newzone;
660
    for (i=z2+1;i < zones.count;i++)
697
    for (i=z2+1;i < zones.count;i++)
661
        zones.info[i-1] = zones.info[i];
698
        zones.info[i-1] = zones.info[i];
662
    zones.count--;
699
    zones.count--;
663
 
700
 
Line 981... Line 1018...
981
    printf("#  Base address\tFree Frames\tBusy Frames\n");
1018
    printf("#  Base address\tFree Frames\tBusy Frames\n");
982
    printf("   ------------\t-----------\t-----------\n");
1019
    printf("   ------------\t-----------\t-----------\n");
983
    for (i=0;i<zones.count;i++) {
1020
    for (i=0;i<zones.count;i++) {
984
        zone = zones.info[i];
1021
        zone = zones.info[i];
985
        spinlock_lock(&zone->lock);
1022
        spinlock_lock(&zone->lock);
986
        printf("%d  %L\t%d\t\t%d\n",i,PFN2ADDR(zone->base),
1023
        printf("%d: %L\t%d\t\t%d\n",i,PFN2ADDR(zone->base),
987
               zone->free_count, zone->busy_count);
1024
               zone->free_count, zone->busy_count);
988
        spinlock_unlock(&zone->lock);
1025
        spinlock_unlock(&zone->lock);
989
    }
1026
    }
990
    spinlock_unlock(&zones.lock);
1027
    spinlock_unlock(&zones.lock);
991
    interrupts_restore(ipl);
1028
    interrupts_restore(ipl);
Line 1002... Line 1039...
1002
 
1039
 
1003
    ipl = interrupts_disable();
1040
    ipl = interrupts_disable();
1004
    spinlock_lock(&zones.lock);
1041
    spinlock_lock(&zones.lock);
1005
 
1042
 
1006
    for (i=0;i < zones.count; i++) {
1043
    for (i=0;i < zones.count; i++) {
1007
        if (i == num || zones.info[i]->base == ADDR2PFN(num)) {
1044
        if (i == num || PFN2ADDR(zones.info[i]->base) == num) {
1008
            zone = zones.info[i];
1045
            zone = zones.info[i];
1009
            break;
1046
            break;
1010
        }
1047
        }
1011
    }
1048
    }
1012
    if (!zone) {
1049
    if (!zone) {