summaryrefslogtreecommitdiffstats
path: root/sys/geom/notes
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2003-02-07 23:08:24 +0000
committerphk <phk@FreeBSD.org>2003-02-07 23:08:24 +0000
commite8f2dea5ddc06968c8deacd684154cd56b9664ff (patch)
tree926f1fc791d8d4e6893f5573cb0b3fed3a603f7c /sys/geom/notes
parent3c791c8729585027435477ccde6a53be4ba01225 (diff)
downloadFreeBSD-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/notes40
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.
OpenPOWER on IntegriCloud