Userland should busy-wait briefly before using usleep() #4424
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The userland code uses the
do {usleep()} while (unavaliable)
patternfor closing races in asynchronous device initialization. However, the
normal case is that calling
usleep()
introduces an unnecessarily longdelay because the other side typically finishes what it was doing much
faster than the period in which we sleep. The periods in which we
usleep()
are short, but they can add to a significant period of timewhen scripts trigger the codepaths using
usleep()
in a loop.libzfs_load_module
uses the alternative pattern ofdo {sched_yield()} while (unavaliable)
for 10ms before falling back to thedo {usleep()} while (unavaliable)
pattern, which is much better for latencies. As ageneral principle, I would like to encourage contributors to avoid the
do {usleep()} while (unavaliable)
pattern for closing asynchronousraces. Modifying the places that use it to do what
libzfs_load_module
does should achieve that.
There are some minor behavior changes worth noting.
One is that reusing the exact code structure from
libzfs_load_module
meant that
zpool_label_disk_wait()
will return the error code passedby
stat64()
. I had considered altering it to maintaining the currenterror behavior, but after looking at its consumers, I felt that they
would benefit from a more accurate error code.
Another is that while I used the same timeouts, time spent in the
kernel no longer can extend the timeouts, so the maximum timeouts should
be somewhat shorter. That should be more noticeable on a heavily loaded
system. One might consider the busy-wait to be a cause for concern
there, but the use of
sched_yield()
should lower the number ofiterations in which we busy-wait before falling back to
usleep()
.The last is that I made a slight improvement to the original algorithm
where if we would timeout after returning from
usleep()
, we will nowskip the call and timeout early.
Signed-off-by: Richard Yao [email protected]