From: Gerrit Huizenga Fix a NULL dereference bug by checking before locking. Parent shares recalculation fix. Signed-Off-By: Matt Helsley Signed-Off-By: Gerrit Huizenga Signed-off-by: Andrew Morton --- kernel/ckrm/ckrm_numtasks.c | 24 +++++++++++++++++++----- 1 files changed, 19 insertions(+), 5 deletions(-) diff -puN kernel/ckrm/ckrm_numtasks.c~ckrm-fix-a-null-dereference-bug kernel/ckrm/ckrm_numtasks.c --- 25/kernel/ckrm/ckrm_numtasks.c~ckrm-fix-a-null-dereference-bug Wed Jul 13 14:44:53 2005 +++ 25-akpm/kernel/ckrm/ckrm_numtasks.c Wed Jul 13 14:44:53 2005 @@ -303,6 +303,7 @@ static void numtasks_res_free(void *my_r return; } + /* * Recalculate the guarantee and limit in real units... and propagate the * same to children. @@ -357,9 +358,13 @@ recalc_and_propagate(struct ckrm_numtask while ((child = ckrm_get_next_child(res->core, child)) != NULL) { childres = ckrm_get_res_class(child, resid, struct ckrm_numtasks); - spin_lock(&childres->cnt_lock); - recalc_and_propagate(childres, res); - spin_unlock(&childres->cnt_lock); + if (childres) { + spin_lock(&childres->cnt_lock); + recalc_and_propagate(childres, res); + spin_unlock(&childres->cnt_lock); + } else { + printk(KERN_ERR "%s: numtasks resclass missing\n",__FUNCTION__); + } } ckrm_unlock_hier(res->core); return; @@ -376,7 +381,7 @@ static int numtasks_set_share_values(voi if (res->parent) { parres = - ckrm_get_res_class(res->parent, resid, struct ckrm_numtasks); + ckrm_get_res_class(res->parent, resid, struct ckrm_numtasks); spin_lock(&parres->cnt_lock); spin_lock(&res->cnt_lock); par = &parres->shares; @@ -390,7 +395,16 @@ static int numtasks_set_share_values(voi if ((rc == 0) && parres) { /* Calculate parent's unused units */ - recalc_and_propagate(parres, NULL); + if (parres->cnt_guarantee == CKRM_SHARE_DONTCARE) { + parres->cnt_unused = CKRM_SHARE_DONTCARE; + } else if (par->total_guarantee) { + u64 temp = (u64) par->unused_guarantee * parres->cnt_guarantee; + do_div(temp, par->total_guarantee); + parres->cnt_unused = (int) temp; + } else { + parres->cnt_unused = 0; + } + recalc_and_propagate(res, parres); } spin_unlock(&res->cnt_lock); if (res->parent) _