Hi folks,

illumos-joyent includes per-zone VFS kstats that emulate a histogram by
aggregating the latency of individual VFS operations into buckets. Here's a
sample of what that looks like:

[root@coke ~]# kstat -m zone_vfs
module: zone_vfs                        instance: 0
name:   global                          class:    zone_vfs
        100ms_ops                       164
        10ms_ops                        1734
        10s_ops                         0
        1s_ops                          23
        ...
        zonename                        global

Using this kstat we can pretty easily see that there were 23 VFS operations
issued by the global zone that took at least one second but not more than
10 seconds, for example. This seems like a useful pattern, and one that
could be used in many places in the kernel. For those curious, this was
implemented as part of OS-338 (https://smartos.org/bugview/OS-338,
illumos-joyent commit 278c9a7a00cbf7a53131a08ae5e86c28de7d2c8e).

If we'd like to use the zone_vfs module's histogram pattern elsewhere in
the kernel we currently have to copy most of the code used by the zone_vfs
kstat module. I'd like to add a minimal histogram abstraction to the kstat
framework so that other kernel systems can easily create and use histograms
to track latency of longer-running operations (in the order of tens to
hundreds of milliseconds).

Specifically, a kernel component would call a function like `(kstat_t *)
kstat_histogram_create(module, instance, name)` which would create a kstat
that has the same latency buckets as zone_vfs. Then the kernel component
would call `(void) kstat_histogram_observe(kstat, hrtime)` to increment the
relevant latency buckets for the given kstat histogram and duration.

Here's a simplified example of what I had in mind:

kstat_t *mystat = kstat_histogram_create("testmodule", 0,
"my_latency_stat");
if (mystat != NULL) {
    kstat_install(mystat);
}

htime_t start = gethrtime();
do_work(); // a longer-running task
hrtime_t duration = gethrtime() - start;
kstat_histogram_observe(mystat, duration);

which could look something like this on the front-end after a few rounds of
calling do_work():

$ kstat -m testmodule
module: testmodule                      instance: 0
name:   my_latency_stat                 class:    hist
bucket_10ms                     3
bucket_100ms                    2
bucket_1s                       1
bucket_10s                      0
total_ms                        1210
count                           3
crtime                          138.923698981
snaptime                        144.456348556

This would be more abstract than what's currently included in the kstat
framework. My intent is that we could make something that's easy to use for
the majority of users in the kernel. The above approach would trade
flexibility for simplicity. Maybe there's a way to retain more flexibility
without adding too much complexity.

The initial use case I'm considering for this would be to add a few
histogram kstats for longer-running ZFS operations, like spa_sync,
dmu_tx_delay, and zil_commit. For this use case I think the above design
works well, but there are definitely drawbacks to such a simple design.

Thoughts on this?

Kody

------------------------------------------
openzfs: openzfs-developer
Permalink: 
https://openzfs.topicbox.com/groups/developer/T0d45cb43ed98ec4c-M9cb612a2e6f1e75e9b0ee3a2
Delivery options: https://openzfs.topicbox.com/groups/developer/subscription

Reply via email to