diff options
author | phk <phk@FreeBSD.org> | 2003-02-07 23:08:24 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2003-02-07 23:08:24 +0000 |
commit | e8f2dea5ddc06968c8deacd684154cd56b9664ff (patch) | |
tree | 926f1fc791d8d4e6893f5573cb0b3fed3a603f7c /sys/geom/notes | |
parent | 3c791c8729585027435477ccde6a53be4ba01225 (diff) | |
download | FreeBSD-src-e8f2dea5ddc06968c8deacd684154cd56b9664ff.zip FreeBSD-src-e8f2dea5ddc06968c8deacd684154cd56b9664ff.tar.gz |
Commit the correct copy of the g_stat structure.
Add debug.sizeof.g_stat sysctl.
Set the id field of the g_stat when we create consumers and providers.
Remove biocount from consumer, we will use the counters in the g_stat
structure instead. Replace one field which will need to be atomically
manipulated with two fields which will not (stat.nop and stat.nend).
Change add companion field to bio_children: bio_inbed for the exact
same reason.
Don't output the biocount in the confdot output.
Fix KASSERT in g_io_request().
Add sysctl kern.geom.collectstats defaulting to off.
Collect the following raw statistics conditioned on this sysctl:
for each consumer and provider {
total number of operations started.
total number of operations completed.
time last operation completed.
sum of idle-time.
for each of BIO_READ, BIO_WRITE and BIO_DELETE {
number of operations completed.
number of bytes completed.
number of ENOMEM errors.
number of other errors.
sum of transaction time.
}
}
API for getting hold of these statistics data not included yet.
Diffstat (limited to 'sys/geom/notes')
-rw-r--r-- | sys/geom/notes | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/sys/geom/notes b/sys/geom/notes new file mode 100644 index 0000000..88e0f52 --- /dev/null +++ b/sys/geom/notes @@ -0,0 +1,40 @@ +$FreeBSD$ + +For the lack of a better place to put them, this file will contain +notes on some of the more intricate details of geom. + +----------------------------------------------------------------------- +Locking of bio_children and bio_inbed + +bio_children is used by g_std_done() and g_clone_bio() to keep track +of children cloned off a request. g_clone_bio will increment the +bio_children counter for each time it is called and g_std_done will +increment bio_inbed for every call, and if the two counters are +equal, call g_io_deliver() on the parent bio. + +The general assumption is that g_clone_bio() is called only in +the g_down thread, and g_std_done() only in the g_up thread and +therefore the two fields do not generally need locking. These +restrictions are not enforced by the code, but only with great +care should they be violated. + +It is the responsibility of the class implementation to avoid the +following race condition: A class intend to split a bio in two +children. It clones the bio, and requests I/O on the child. +This I/O operation completes before the second child is cloned +and g_std_done() sees the counters both equal 1 and finishes off +the bio. + +There is no race present in the common case where the bio is split +in multiple parts in the class start method and the I/O is requested +on another GEOM class below: There is only one g_down thread and +the class below will not get its start method run until we return +from our start method, and consequently the I/O cannot complete +prematurely. + +In all other cases, this race needs to be mitigated, for instance +by cloning all children before I/O is request on any of them. + +Notice that cloning an "extra" child and calling g_std_done() on +it directly opens another race since the assumption is that +g_std_done() only is called in the g_up thread. |