From: Pierre Habouzit Date: Sun, 15 Jan 2012 20:59:27 +0000 (+0100) Subject: Improve documentation, improve has_pollin handling. X-Git-Url: http://git.madism.org/?p=~madcoder%2Fpwqr.git;a=commitdiff_plain;h=0dfcf387adaf2a156322d6e1076dac207e8384b7;ds=sidebyside Improve documentation, improve has_pollin handling. Sometimes writing documentation helps finding design issues :P Signed-off-by: Pierre Habouzit --- diff --git a/Documentation/pwqr.adoc b/Documentation/pwqr.adoc index 240c20a..7c40b1e 100644 --- a/Documentation/pwqr.adoc +++ b/Documentation/pwqr.adoc @@ -8,7 +8,7 @@ the machines, the amount of blocked threads ... kernel-land design ------------------ -In the kernel, threads registered in the pwq regulator can be in 4 states: +In the kernel, threads registered in the pwq regulator can be in 5 states: blocked:: This is the state of threads that are curently blocked in a syscall. @@ -55,8 +55,14 @@ When `running + waiting` overcommits:: require anything from userland. It's something userland discovers only when it needs a waiting thread, which may never happen. + -If there are no waiting threads, then well, the workqueue overcommits, and -that's one of the TODO items at the moment (see Notes) +If there are no waiting threads, then well, the workqueue overcommits, and the +pwqr file descriptor is made available for reading. When userlands reads, it +will get the amount of overcommit at the time of the `read(3)` call. ++ +NOTE: the availability for reading is only done after a delay (0.05s roughly +in the current implementation). And once you've read, this enables a new +notification in another 0.05s and so on, to allow a slow decrease of the +number of threads. When `running + waiting` undercommits:: If waiting is non-zero then well, we don't care, it's that userland @@ -92,7 +98,7 @@ state, the overcommit is huge. There are several ways to "fix" this: -in kernel (poll solution):: +in kernel (poll solution, actually implemented right now):: Let the file descriptor be pollable, and let it be readable (returning something like the amount of overcommit at read() time for example) so that userland is notified that it should try to reduce the amount of @@ -166,16 +172,17 @@ the call, as would be returned by `sysconf(_SC_NPROCESSORS_ONLN)`. Available operations on the pwqr file descriptor are: `poll`, `epoll` and friends:: - the PWQR file descriptor can be watched for POLLIN events (not POLLOUT - ones as it can not be written to). + the PWQR file descriptor can be watched for `POLLIN` events (not + `POLLOUT` ones as it can not be written to). `read`:: The file returned can be read upon. The read blocks (or fails setting `EAGAIN` if in non blocking mode) until the regulator believes the pool is overcommitting. The buffer passed to read should be able to - hold an integer. When `read(3)` is successful, it writes the amount of - overcommiting threads (understand: the number of threads to park so - that the pool isn't overcommiting anymore). + hold an integer. When `read(3)` is successful, it returns in the + buffer passed to `read(3)` the amount of overcommiting threads + (understand: the number of threads to park so that the pool isn't + overcommiting anymore). RETURN VALUE ~~~~~~~~~~~~ diff --git a/kernel/pwqr.c b/kernel/pwqr.c index 233bd7a..6d822ea 100644 --- a/kernel/pwqr.c +++ b/kernel/pwqr.c @@ -172,10 +172,13 @@ static inline void __pwqr_sb_update_state(struct pwqr_sb *sb, int running_delta) sb->running += running_delta; if (sb->running < sb->concurrency && sb->waiting == 0 && sb->parked) { + sb->has_pollin = 0; pwqr_arm_timer(sb, PWQR_STATE_UC, PWQR_UC_DELAY); } else if (sb->running > sb->concurrency) { - pwqr_arm_timer(sb, PWQR_STATE_OC, PWQR_OC_DELAY); + if (!sb->has_pollin) + pwqr_arm_timer(sb, PWQR_STATE_OC, PWQR_OC_DELAY); } else { + sb->has_pollin = 0; sb->state = PWQR_STATE_NONE; if (!timer_pending(&sb->timer)) del_timer(&sb->timer);