Make tgx_sync_thread zio's async
authorBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 25 May 2011 22:22:04 +0000 (15:22 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 31 May 2011 19:17:27 +0000 (12:17 -0700)
commit2fac4c2a74f1abc54d82068e3ae9a62e9a0468b0
treee359584bc6ab9702b17edd37b26ced9ec5da60df
parentf74fae8b305ce3b264489e71adb49c2e4e9e33db
Make tgx_sync_thread zio's async

The majority of the recursive operations performed by the dsl
are done either in the context of the tgx_sync_thread or during
pool import.  It is these recursive operations which contribute
greatly to the stack depth.  When this recursion is coupled with
a synchronous I/O in the same context overflow becomes possible.

Previously to handle this case I have focused on keeping the
individual stack frames as light as possible.  This is a good
idea as long as it can be done in a way which doesn't overly
complicate the code.  However, there is a better solution.

If we treat all zio's issued by the tgx_sync_thread as async then
we can use the tgx_sync_thread stack for the recursive parts, and
the zio_* threads for the I/O parts.  This effectively doubles our
available stack space with the only drawback being a small delay
to schedule the I/O.  However, in practice the scheduling time
is so much smaller than the actual I/O time this isn't an issue.
Another benefit of making the zio async is that the zio pipeline
is now parallel.  That should mean for CPU intensive pipelines
such as compression or dedup performance may be improved.

With this change in place the worst case stack usage observed so
far is 6902 bytes.  This is still higher than I'd like but
significantly improved.  Additional changes to specific functions
should improve this further.  This change allows us to revent
commit 6656bf5 which did some horrible things to the recursive
traverse_visitbp() callpath in the name of saving stack.
module/zfs/zio.c