diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2012-07-25 15:43:15 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2012-07-25 15:43:15 +0000 |
commit | 2453263d59c2317dbe88d1c9e12893a32abd91b8 (patch) | |
tree | 8e0941ac5a20e5d2f56f011cc452816ddb6f358f /usr/src | |
parent | 87be0498f4e05c54a8c9d1e905a9c55a327a9191 (diff) | |
download | illumos-joyent-2453263d59c2317dbe88d1c9e12893a32abd91b8.tar.gz |
OS-1405 CPU caps can throttle performance more than intended2012072620120626release-20120726release-20120626
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/disp/cpucaps.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/usr/src/uts/common/disp/cpucaps.c b/usr/src/uts/common/disp/cpucaps.c index 26067235a9..68be78a84f 100644 --- a/usr/src/uts/common/disp/cpucaps.c +++ b/usr/src/uts/common/disp/cpucaps.c @@ -578,8 +578,47 @@ cap_poke_waitq(cpucap_t *cap, int64_t gen) cap->cap_below++; - if (!waitq_isempty(wq)) - waitq_runone(wq); + if (!waitq_isempty(wq)) { + int i, ndequeue, p; + + /* + * Since this function is only called once per tick, + * we can hit a situation where we have artificially + * limited the project/zone below its cap. This would + * happen if we have multiple threads queued up but + * only dequeued one thread/tick. To avoid this we + * dequeue multiple threads, calculated based on the + * usage percentage of the cap. It is possible that we + * could dequeue too many threads and some of them + * might be put back on the wait queue quickly, but + * since we know that threads are on the wait queue + * because we're capping, we know that there is unused + * CPU cycles anyway, so this extra work would not + * hurt. Also, the ndequeue number is only an upper + * bound and we might dequeue less, depending on how + * many threads are actually in the wait queue. The + * ndequeue values are empirically derived and could be + * adjusted or calculated in another way if necessary. + */ + p = (int)((100 * cap->cap_usage) / cap->cap_chk_value); + if (p >= 98) + ndequeue = 10; + else if (p >= 95) + ndequeue = 20; + else if (p >= 90) + ndequeue = 40; + else if (p >= 85) + ndequeue = 80; + else + ndequeue = 160; + + for (i = 0; i < ndequeue; i++) { + waitq_runone(wq); + if (waitq_isempty(wq)) + break; + } + DTRACE_PROBE2(cpucaps__pokeq, int, p, int, i); + } } } |