diff options
| author | jjc <none@none> | 2006-10-26 15:49:27 -0700 |
|---|---|---|
| committer | jjc <none@none> | 2006-10-26 15:49:27 -0700 |
| commit | 03400a7143a154fcab314dfc95202e420d051575 (patch) | |
| tree | 5a86937804c18e64ae063302be7fd2c421acdb69 /usr/src/uts/common/syscall/lgrpsys.c | |
| parent | 04cbdd1e8c01bfd0d7d46781de12990200cd77db (diff) | |
| download | illumos-joyent-03400a7143a154fcab314dfc95202e420d051575.tar.gz | |
6469235 s10u3_06;Panic lgrp->lgrp_parent->lgrp_id == lpl->lpl_parent->lpl_lgrpid, file: ../../common/os/lgrp
6482597 lgrp_affinity_set22 test fails intermittently
6483137 lgrp_affinity_best() should walk lgroup hierarchy to find best lgroup when bound to CPU
Diffstat (limited to 'usr/src/uts/common/syscall/lgrpsys.c')
| -rw-r--r-- | usr/src/uts/common/syscall/lgrpsys.c | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/usr/src/uts/common/syscall/lgrpsys.c b/usr/src/uts/common/syscall/lgrpsys.c index 17fa2e1ff9..44d616fa34 100644 --- a/usr/src/uts/common/syscall/lgrpsys.c +++ b/usr/src/uts/common/syscall/lgrpsys.c @@ -456,13 +456,16 @@ lgrp_affinity_get(lgrp_affinity_args_t *ap) /* * Find lgroup for which this thread has most affinity in specified partition + * starting from home lgroup unless specified starting lgroup is preferred */ lpl_t * -lgrp_affinity_best(kthread_t *t, struct cpupart *cpupart, lgrp_id_t start) +lgrp_affinity_best(kthread_t *t, struct cpupart *cpupart, lgrp_id_t start, + boolean_t prefer_start) { lgrp_affinity_t *affs; lgrp_affinity_t best_aff; lpl_t *best_lpl; + lgrp_id_t finish; lgrp_id_t home; lgrp_id_t lgrpid; lpl_t *lpl; @@ -484,34 +487,42 @@ lgrp_affinity_best(kthread_t *t, struct cpupart *cpupart, lgrp_id_t start) cpu_t *cp; /* - * See whether thread has more affinity for root lgroup - * than lgroup containing CPU + * Find which lpl has most affinity among leaf lpl directly + * containing CPU and its ancestor lpls */ cp = cpu[t->t_bind_cpu]; - lpl = cp->cpu_lpl; - lgrpid = LGRP_ROOTID; - if (affs[lgrpid] > affs[lpl->lpl_lgrpid]) - return (&cpupart->cp_lgrploads[lgrpid]); - return (lpl); + + best_lpl = lpl = cp->cpu_lpl; + best_aff = affs[best_lpl->lpl_lgrpid]; + while (lpl->lpl_parent != NULL) { + lpl = lpl->lpl_parent; + lgrpid = lpl->lpl_lgrpid; + if (affs[lgrpid] > best_aff) { + best_lpl = lpl; + best_aff = affs[lgrpid]; + } + } + return (best_lpl); } /* - * Start searching at given lgroup + * Start searching from home lgroup unless given starting lgroup is + * preferred or home lgroup isn't in given pset. Use root lgroup as + * starting point if both home and starting lgroups aren't in given + * pset. */ ASSERT(start >= 0 && start <= lgrp_alloc_max); - lgrpid = start; - - /* - * Use starting lgroup given above as best first - */ home = t->t_lpl->lpl_lgrpid; - if (LGRP_CPUS_IN_PART(lgrpid, cpupart)) - best_lpl = &cpupart->cp_lgrploads[lgrpid]; + if (!prefer_start && LGRP_CPUS_IN_PART(home, cpupart)) + lgrpid = home; + else if (start != LGRP_NONE && LGRP_CPUS_IN_PART(start, cpupart)) + lgrpid = start; else - best_lpl = &cpupart->cp_lgrploads[home]; - - best_aff = affs[best_lpl->lpl_lgrpid]; + lgrpid = LGRP_ROOTID; + best_lpl = &cpupart->cp_lgrploads[lgrpid]; + best_aff = affs[lgrpid]; + finish = lgrpid; do { /* * Skip any lgroups that don't have CPU resources @@ -535,7 +546,7 @@ lgrp_affinity_best(kthread_t *t, struct cpupart *cpupart, lgrp_id_t start) if (++lgrpid > lgrp_alloc_max) lgrpid = 0; /* wrap the search */ - } while (lgrpid != start); + } while (lgrpid != finish); /* * No lgroup (in this pset) with any affinity @@ -596,7 +607,7 @@ lgrp_affinity_set_thread(kthread_t *t, lgrp_id_t lgrp, lgrp_affinity_t aff, * Find lgroup for which thread has most affinity, * starting with lgroup for which affinity being set */ - best_lpl = lgrp_affinity_best(t, t->t_cpupart, lgrp); + best_lpl = lgrp_affinity_best(t, t->t_cpupart, lgrp, B_TRUE); /* * Rehome if found lgroup with more affinity than home or lgroup for |
