From 1903a00a5848d94681b0746e3d68331d44ccce42 Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Tue, 17 Mar 2009 20:33:32 +0100 Subject: Tweak availability computation. Treat priority correctly. --- viengoos/ager.c | 91 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/viengoos/ager.c b/viengoos/ager.c index 3000c0f..98c67a1 100644 --- a/viengoos/ager.c +++ b/viengoos/ager.c @@ -62,8 +62,9 @@ to frames. Instead, we should unmap based on a random distribution. */ -/* The frequency with which we assemble statistics. */ -#define FREQ (sizeof (((struct object_desc *)0)->age) * 8) +/* The frequency with which we assemble statistics (in terms of number + of scans). */ +#define FREQ 4 static int period; @@ -117,9 +118,9 @@ update_stats (void) bool have_self = false; - /* The list is sort lowest priority towards the head. */ + /* The list is sorted lowest priority towards the tail. */ struct activity *child - = activity_children_list_tail (&activity->children); + = activity_children_list_head (&activity->children); if (! child) /* No children. There is no need to execute the below loop. */ @@ -173,7 +174,7 @@ update_stats (void) for (p = child; p && p->policy.sibling_rel.priority == priority; - p = activity_children_list_prev (p)) + p = activity_children_list_next (p)) { claimed += ACTIVITY_STATS (p)->claimed; disowned += ACTIVITY_STATS (p)->disowned; @@ -208,7 +209,7 @@ update_stats (void) for (p = child; p && p->policy.sibling_rel.priority == priority; - p = activity_children_list_prev (p)) + p = activity_children_list_next (p)) params (p->policy.sibling_rel.weight, p->frames_total); @@ -227,54 +228,50 @@ update_stats (void) uintptr_t avail = share; +#if 0 /* The max of our share and our current allocation. */ if (my_alloced > avail) avail = my_alloced; +#endif /* The number of frames this activity can steal from other activities in this priority group (i.e., the frames other activities have allocated in excess of their share). */ - uintptr_t could_steal = excess; - if (weight == 0) - could_steal = 0; - else + intptr_t could_steal = excess; + if (weight > 0) { - /* We can't steal from ourselves. */ if (my_alloced > share) + /* We can't steal from ourselves. */ could_steal -= my_alloced - share; + else + /* If we steal, we steal relative to our current + allocation. Not relative to our current share. + Intuition: if we are not using anything, other + tasks are using our share. What we then steal is + our share. If we added the amount to steal to our + share, we'd come up with twice our share. */ + could_steal -= share - my_alloced; + + /* We steal proportional to our weight. */ + if (could_steal > 0) + { + could_steal *= could_steal * (weight - my_weight) / weight; + avail += could_steal; + } } - /* If we steal, we steal relative to our current allocation. - Not relative to our current share. Intuition: we are not - using anything, other takes are using our share. What we - steal is our share. If we added the amount to steal to - our share, we'd come up with twice our share. */ - if (my_alloced + could_steal > share) - avail = my_alloced + could_steal; - - /* The number of frames that this activity can use, which other activities in its priority group have (so far) shown no interest in. */ - uintptr_t could_use = unused; + intptr_t could_use = unused; if (share >= my_alloced) /* What everone else does not want minus what this activity does not want, i.e., don't count its contribution to unused twice. */ could_use -= share - my_alloced; - else - { - /* The activity contributes nothing to the unused pool. - In fact, it is already using some of it. Subtract - that. */ - if (unused > my_alloced - share) - could_use -= my_alloced - share; - else - could_use = 0; - } - - avail += could_use; + if (could_use > 0) + avail += could_use; /* Adjust for allocation trends. */ @@ -286,7 +283,7 @@ update_stats (void) period and pay for it, proportionally. */ { if (weight > 0) - avail -= ((uint64_t) delta * my_weight) / weight; + avail -= ((uint64_t) delta * (weight - my_weight)) / weight; else if (avail > delta) avail -= delta; else @@ -300,22 +297,24 @@ update_stats (void) else free = 0; - debug (5, "Period %"PRIdPTR": " OBJECT_NAME_FMT ": " - "alloced: "PAGES_FMT" of "PAGES_FMT"\n" + debug (5, "Period %d: " OBJECT_NAME_FMT ": " + "alloced: "PAGES_FMT" (group: "PAGES_FMT")\n" " priority: %d, weight: %d/%"PRIdPTR", " - "prio group frames: "PAGES_FMT"\n" - " claimed: "PAGES_FMT", disowned: "PAGES_FMT"\n" + "prio group's avail frames: "PAGES_FMT"\n" " share: "PAGES_FMT", excess: "PAGES_FMT", unused: "PAGES_FMT"\n" - " could steal: "PAGES_FMT", could use: "PAGES_FMT"\n" - " free: "PAGES_FMT", avail: "PAGES_FMT, + " claimed: "PAGES_FMT", disowned: "PAGES_FMT"\n" + " could steal: "PAGES_FMT", could use: "PAGES_FMT", " + "delta: "PAGES_FMT"\n" + " free: "PAGES_FMT" => avail: "PAGES_FMT, period / FREQ, OBJECT_NAME_PRINTF ((struct vg_object *) activity), PAGES_PRINTF (my_alloced), PAGES_PRINTF (alloced), priority, my_weight, weight, PAGES_PRINTF (frames), - PAGES_PRINTF (my_claimed), PAGES_PRINTF (my_disowned), PAGES_PRINTF (share), PAGES_PRINTF (excess), PAGES_PRINTF (unused), + PAGES_PRINTF (my_claimed), PAGES_PRINTF (my_disowned), PAGES_PRINTF (could_steal), PAGES_PRINTF (could_use), + PAGES_PRINTF (delta), PAGES_PRINTF (free), PAGES_PRINTF (avail)); return avail; } @@ -367,7 +366,7 @@ update_stats (void) for (p = child; p && p->policy.sibling_rel.priority == priority; - p = activity_children_list_prev (p)) + p = activity_children_list_next (p)) { stats (p, comp_avail (p, p->policy.sibling_rel.weight, p->frames_total, @@ -392,7 +391,7 @@ update_stats (void) frames = 0; } - debug (5, OBJECT_NAME_FMT " (s: %d/%d; c: %d/%d): " + debug (5, OBJECT_NAME_FMT " (sib: %d/%d; child: %d/%d): " "%d/%d frames, %d/%d avail, %d free goal, %d bad_karma " "(" OBJECT_NAME_FMT ")", OBJECT_NAME_PRINTF ((struct vg_object *) activity), @@ -603,7 +602,7 @@ ager (void) /* Make the print atomic. */ ss_mutex_lock (&kernel_lock); uint64_t a = zalloc_memory + available_list_count (&available); - debug (0, "%"PRIdPTR": "PAGES_FMT" of "PAGES_FMT" (%d%%) free\n" + debug (0, "%d: "PAGES_FMT" of "PAGES_FMT" (%d%%) free\n" " laundry: "PAGES_FMT"; "PAGES_FMT" active ("PAGES_FMT" new); " PAGES_FMT" inactive ("PAGES_FMT" new), "PAGES_FMT" shared unmapped", period / FREQ, @@ -625,7 +624,7 @@ ager_run (struct timer *timer) { ager (); - timer->expire = time_data.ns_since_boot + 250 * 1000 * 1000; + timer->expire = time_data.ns_since_boot + 500 * 1000 * 1000; timer_register (timer); } @@ -634,7 +633,7 @@ static struct timer ager_timer; void ager_bootstrap (void) { - ager_timer.expire = time_data.ns_since_boot + 250 * 1000 * 1000; + ager_timer.expire = time_data.ns_since_boot + 500 * 1000 * 1000; ager_timer.callback = ager_run; timer_register (&ager_timer); -- cgit v1.2.3