Messages in this thread Patch in this message | | | From | MAEDA Naoaki <> | Date | Fri, 28 Apr 2006 10:38:06 +0900 | Subject | [PATCH 7/9] CPU controller - Add routines to change share values and show stat |
| |
7/9: cpu_shares_n_stats
Adds routine to change share values and show statistics.
Signed-off-by: MAEDA Naoaki <maeda.naoaki@jp.fujitsu.com> Signed-off-by: Kurosawa Takahiro <kurosawa@valinux.co.jp>
kernel/res_group/cpu.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 120 insertions(+)
Index: linux-2.6.17-rc3/kernel/res_group/cpu.c =================================================================== --- linux-2.6.17-rc3.orig/kernel/res_group/cpu.c +++ linux-2.6.17-rc3/kernel/res_group/cpu.c @@ -113,12 +113,132 @@ static void cpu_free_shares_struct(struc kfree(res); } +static int recalc_shares(int self_shares, int parent_shares, int parent_divisor) +{ + u64 numerator; + + if (parent_divisor == 0) + return 0; + numerator = (u64) self_shares * parent_shares; + do_div(numerator, parent_divisor); + return numerator; +} + +static int recalc_unused_shares(int self_cnt_min_shares, + int self_unused_min_shares, int self_divisor) +{ + u64 numerator; + + if (self_divisor == 0) + return 0; + numerator = (u64) self_unused_min_shares * self_cnt_min_shares; + do_div(numerator, self_divisor); + return numerator; +} + +static void recalc_self(struct cpu_res *res, struct cpu_res *parres) +{ + struct res_shares *par = &parres->shares; + struct res_shares *self = &res->shares; + u64 cnt_total, cnt_min_shares; + + /* calculate total and current min_shares */ + cnt_total = recalc_shares(self->min_shares, + parres->cnt_total_min_shares, + par->child_shares_divisor); + cnt_min_shares = recalc_unused_shares(self->unused_min_shares, + cnt_total, + par->child_shares_divisor); + cpu_rc_set_share(&res->cpu_rc, (int) cnt_min_shares); + res->cnt_total_min_shares = (int) cnt_total; +} + +static void +recalc_and_propagate(struct cpu_res *res) +{ + struct resource_group *child = NULL; + struct cpu_res *parres, *childres; + + parres = get_res_group_cpu(res->rgroup->parent); + + if (parres) + recalc_self(res, parres); + + /* propagate to children */ + spin_lock(&res->rgroup->group_lock); + for_each_child(child, res->rgroup) { + childres = get_res_group_cpu(child); + if (childres) + recalc_and_propagate(childres); + } + spin_unlock(&res->rgroup->group_lock); + return; +} + +static void cpu_shares_changed(struct res_shares *my_res) +{ + struct cpu_res *parres, *res; + struct res_shares *cur, *par; + u64 temp = 0; + + res = get_shares_cpu(my_res); + if (!res) + return; + cur = &res->shares; + + if (!is_res_group_root(res->rgroup)) { + spin_lock(&res->rgroup->parent->group_lock); + parres = get_res_group_cpu(res->rgroup->parent); + par = &parres->shares; + } else { + par = NULL; + parres = NULL; + } + + if (parres) { + /* adjust parent's unused min_shares */ + temp = recalc_unused_shares(parres->cnt_total_min_shares, + par->unused_min_shares, + par->child_shares_divisor); + cpu_rc_set_share(&parres->cpu_rc, temp); + } else { + /* adjust root resouce group's unused min_shares */ + temp = recalc_unused_shares(SHARE_DEFAULT_DIVISOR, + cur->unused_min_shares, + cur->child_shares_divisor); + cpu_rc_set_share(&res->cpu_rc, temp); + } + recalc_and_propagate(res); + + if (!is_res_group_root(res->rgroup)) + spin_unlock(&res->rgroup->parent->group_lock); +} + +static ssize_t cpu_show_stats(struct res_shares *my_res, char *buf, + size_t buf_size) +{ + struct cpu_res *res; + unsigned int load = 0; + ssize_t i; + + res = get_shares_cpu(my_res); + if (!res) + return -EINVAL; + + load = cpu_rc_load(&res->cpu_rc); + i = snprintf(buf, buf_size, "%s:effective_min_shares=%d, load=%d\n", + res_ctlr_name, res->cpu_rc.share, load); + return i; +} + struct res_controller cpu_ctlr = { .name = res_ctlr_name, .depth_supported = 3, .ctlr_id = NO_RES_ID, .alloc_shares_struct = cpu_alloc_shares_struct, .free_shares_struct = cpu_free_shares_struct, + .shares_changed = cpu_shares_changed, + .show_stats = cpu_show_stats, }; int __init init_cpu_res(void) - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |