From c466abda737927b219568a7ea61742e44070da65 Mon Sep 17 00:00:00 2001 From: Stephan de Wit <33954429+swhite2@users.noreply.github.com> Date: Mon, 11 Jan 2021 17:14:56 +0100 Subject: [PATCH] Add documentation for using dtrace on opnsense (#299) --- source/development/how-tos/dtrace.rst | 219 ++ source/development/how-tos/files/example.d | 252 +++ .../how-tos/images/dtrace_output_docs.png | Bin 0 -> 42181 bytes .../how-tos/images/example-dtrace.svg | 1842 +++++++++++++++++ .../how-tos/images/queue_behaviour.png | Bin 0 -> 6027 bytes 5 files changed, 2313 insertions(+) create mode 100755 source/development/how-tos/dtrace.rst create mode 100644 source/development/how-tos/files/example.d create mode 100755 source/development/how-tos/images/dtrace_output_docs.png create mode 100755 source/development/how-tos/images/example-dtrace.svg create mode 100755 source/development/how-tos/images/queue_behaviour.png diff --git a/source/development/how-tos/dtrace.rst b/source/development/how-tos/dtrace.rst new file mode 100755 index 00000000..a7af424e --- /dev/null +++ b/source/development/how-tos/dtrace.rst @@ -0,0 +1,219 @@ +============================== +Profiling/Debugging the kernel +============================== + +-------- +Overview +-------- + +Kernel development often involves writing code without an IDE. Even if an IDE is used, +proper profiling support is often lacking. Luckily, FreeBSD includes DTrace. + +Since OPNsense runs on a fork of FreeBSD, DTrace is natively available on the +system for developers to use in debugging and profiling. To quote the FreeBSD handbook on DTrace: + +:: + + “DTrace, also known as Dynamic Tracing, was developed by Sun™ as a tool + for locating performance bottlenecks in production and pre-production + systems. In addition to diagnosing performance problems, DTrace can be used + to help investigate and debug unexpected behavior in both the FreeBSD kernel + and in userland programs. + + DTrace is a remarkable profiling tool, with an impressive array of features + for diagnosing system issues. It may also be used to run pre-written scripts + to take advantage of its capabilities. Users can author their own utilities + using the DTrace D Language, allowing them to customize their profiling based + on specific needs.” + + +We will be looking at setting up DTrace on OPNsense, and running a sample script +to perform some useful analysis on kernel space. An example for generating a FlameGraph +will also be presented. Keep in mind that user space can also be analyzed using DTrace, +but this is beyond the scope of this document. + +Although detailed steps for enabling DTrace in a custom kernel are widely available, +this document provides an explanation in combination with the use of OPNsense-specific tools. +Further resources will be provided at the end of this document. + +.. note:: + + All generic DTrace concepts, as well as default probe providers are + documented `here `__. + If you are interested in using DTrace to profile performance issues, we suggest reading + the documentation before proceeding. We will not go into too much detail here to prevent + cluttering the document and keep it simple and to-the-point. + +--------------- +Enabling DTrace +--------------- + +Make sure the OPNsense/src repository is present on the system and navigate to +:code:`/usr/src/sys/[ARCHITECTURE, e.g. amd64]/conf` and open up :code:`GENERIC`. +Add the following options: + +.. code-block:: sh + + makeoptions DEBUG=-g # Will build a debug kernel (using gdb debug symbols) + makeoptions WITH_CTF=1 # Adds CTF type data to built executables + options KDTRACE_FRAME # Ensure frames are compiled in + +.. note:: + + CTF type data is described + `here `__. + The idea is to represent the types used in a C program within the executable, + allowing users of DTrace to access symbols and function parameters during runtime. + +As a best practice, under stock FreeBSD you would save the file under a different name +(e.g. DTRACE) and build the kernel by specifying :code:`KERNCONF=DTRACE`. +The opnsense-tools require the name to be :code:`GENERIC`, so we will leave it as is. +It is advisable to create a backup of the original :code:`GENERIC` file though. +Make sure the OPNsense-tools repository is installed and navigate to :code:`/usr/tools/config/[VERSION]`. +Open up :code:`SMP` and make sure the following line is either removed or commented out: + +.. code-block:: sh + + nomakeoptions DEBUG + +Furthermore, should you wish to enable DTrace in Userspace, it is imperative that you also +add the following line to :code:`/usr/tools/conf/[VERSION]/make.conf` + +.. code-block:: sh + + STRIP= + CFLAGS+=-fno-omit-frame-pointer + +Now clean and build the new kernel + +.. code-block:: sh + + # make clean-obj,kernel kernel + +A kernel package will be available at the following location: + + :code:`/usr/local/opnsense/build/[Version]/[Architecture]/sets/kernel*.txz` + +Install the package using our :code:`opnsense-update` command: + +.. code-block:: sh + + # opnsense-update -ikfr [version] -l /location/from/ + +Where [version] is the version part of the kernel package, such as :code:`21.1.a_83` + +--------------------- +Test the installation +--------------------- + +Follow the steps described in the section 'Getting Started' `here `__ + +-------------- +DTrace program +-------------- + +Although it is possible to instruct DTrace to execute a certain function on the +command line (and there are a lot of one-liners for this `here `__), instead we present a D script that measures some statistics on the ixgbe 10GbE driver and +shows some interesting capabilities of DTrace in one go. Specifically, it measures the amount +of interrupts fired on the packet receive side, as well as the time spent in the relevant functions +in nanoseconds. It also measures how many threads on average are waiting to be serviced because +another thread is busy. + +.. literalinclude:: ./files/example.d + :language: D + +The one-line command to pre-process, compile and run the script is: + +.. code-block:: sh + + # dtrace -C -s example.d + +The :code:`-C` option specifies that the standard C preprocessor should evaluate the file, ensuring +that the C-specific code like macro definitions are defined. + +The output (when pinging the device): + +.. image:: ./images/dtrace_output_docs.png + :alt: Dtrace Output + +Notice how the queue behaviour section shows no output, this is because there is no actual +queue behaviour going on. There is simply too little traffic for the kernel to be queueing threads. +When stressing the driver, it might look something like this: + +.. image:: ./images/queue_behaviour.png + :alt: Queue behaviour + +------------ +Flame Graphs +------------ + +If you run the following command: + +.. code-block:: sh + + # dtrace -n uiomove:entry'{ @[stack] = count(); }' + +Let it run for a while, and exit using :code:`CTRL-C` + +You will see all `stack frames `__ associated with +:code:`uiomove()` that have taken place, aggregated to only unique frames. The number below the individual +frame represents the amount of times that particular frame was executed. Although this is nice, +it isn't particulary visually pleasing or helpful in spotting potential bottlenecks. + +A senior performance analyst at Netflix, named Brendan Gregg, developed the +`FlameGraph `__ for use with DTrace (and other profiling tools). +The program consists of a set of Perl files that take in the data produced by a command +similar to the one we executed, and generate a graph that helps spot 'hot code paths'. +This time however, we will look at the kernel as a whole and sample it in a set interval. + +1. Clone the `repository `__ and instruct dtrace to +sample kernel stacks at a rate of 997 Hertz for 60 seconds: + +.. code-block:: sh + + # dtrace -x stackframes=100 -n 'profile-997 /arg0/ { @[stack()] = count(); } tick-60s { exit(0); }' -o out.kern_stacks + +2. Collapse the individual lines in the output file by folding it into single lines: + +.. code-block:: sh + + # ./stackcollapse.pl out.kern_stacks > out.kern_folded + +Having a separate folded input file allows for grepping functions of interest: + +.. code-block:: sh + + # grep cpuid out.kern_folded | ./flamegraph.pl > cpuid.svg + +.. note:: + + If you get the message "Command not found", use the command + :code:`perl stackcollapse.pl out.kern_stacks > out.kern_folded` + +3. Generate a flame graph: + +.. code-block:: sh + + # ./flamegraph.pl out.kern_folded > kernel.svg + +.. image:: ./images/example-dtrace.svg + :alt: FlameGraph + +The output image is an SVG file, enabling interaction within a browser. + +--------------- +Other Resources +--------------- +Brendan Gregg's collection of DTrace programs: +http://www.brendangregg.com/dtrace.html + +Using the right datatypes in DTrace to increase profiling performance: +http://dtrace.org/blogs/brendan/2011/11/25/dtrace-variable-types/ + +FreeBSD DTrace manual page: +https://www.freebsd.org/cgi/man.cgi?query=dtrace + +FreeBSD DTrace one-liners: +https://wiki.freebsd.org/DTrace/One-Liners + + diff --git a/source/development/how-tos/files/example.d b/source/development/how-tos/files/example.d new file mode 100644 index 00000000..f5b4b871 --- /dev/null +++ b/source/development/how-tos/files/example.d @@ -0,0 +1,252 @@ + +/* RX threads, retrieved from procstat -a -t, listing thread information for all (kernel) processes */ +inline int qg0 = 100018; +inline int qg1 = 100019; +inline int qg2 = 100020; +inline int qg3 = 100021; +inline int qg4 = 100022; +inline int qg5 = 100023; +inline int qg6 = 100024; +inline int qg7 = 100025; + +/* Because of this preprocessor statement, this script should be compiled with -C option */ +#define PROBE_PREDICATE \ + pid == 0 && \ + (tid == qg0 || \ + tid == qg1 || \ + tid == qg2 || \ + tid == qg3 || \ + tid == qg4 || \ + tid == qg5 || \ + tid == qg6 || \ + tid == qg7) \ + \ + + +#define DRIVER_CHECK self->driver_prefix == "ix" + +/********************************************/ +/* Iflib rx info & interrupt info */ +/********************************************/ + +struct iflib_intr_info { + uint64_t fast_intr_ts; + uint64_t fast_intr_elapsed; + uint64_t filter_routine_ts; + uint64_t task_tx_ts; +}; + +struct iflib_intr_info ii[int]; + +struct iflib_task_info { + uint64_t task_rx_ts; + uint64_t rxeof_ts; +}; + +struct iflib_task_info iti[int]; + +/* RX (and TX) interrupt entry point, will call driver supplied filter */ +fbt::iflib_fast_intr:entry +{ + ii[tid].fast_intr_ts = timestamp; + this->info = ((kernel`iflib_filter_info_t)arg0); + self->rxq_id = (uint16_t)((kernel`iflib_rxq_t)this->info->ifi_ctx)->ifr_id; + @intcounts[tid, self->rxq_id, probefunc] = count(); + +} + +fbt::iflib_fast_intr:return +/ii[tid].fast_intr_ts/ +{ + @time[tid, self->rxq_id, probefunc] = avg(timestamp - ii[tid].fast_intr_ts); + @fi_time_min[tid, self->rxq_id, probefunc] = min(timestamp - ii[tid].fast_intr_ts); + @fi_time_max[tid, self->rxq_id, probefunc] = max(timestamp - ii[tid].fast_intr_ts); +} + +/* axgbe driver filter routine */ +fbt::axgbe_msix_que:entry, fbt::ixgbe_msix_que:entry +{ + ii[tid].filter_routine_ts = timestamp; + @intcounts[tid, self->rxq_id, probefunc] = count(); +} + +fbt::axgbe_msix_que:return, fbt::ixgbe_msix_que:return +/ii[tid].filter_routine_ts/ +{ + @fr_time_avg[tid, self->rxq_id, probefunc] = avg(timestamp - ii[tid].filter_routine_ts); + @fr_time_min[tid, self->rxq_id, probefunc] = min(timestamp - ii[tid].filter_routine_ts); + @fr_time_max[tid, self->rxq_id, probefunc] = max(timestamp - ii[tid].filter_routine_ts); +} + + +/* + * at this point, iflib has enqueued the _task_fn_rx / _task_fn_tx function, + * we could measure some relevant things here. + * The threads that run the queued functions are all in the range of the threads + * defined at the top of this file + * We could also inspect the queue structure to determine the average amount of functions + * waiting to be serviced, this information could be pulled out of the iflib interrupt handler + * Also, the thread that runs the queued function is different from the thread that runs the interrupt handler, + * so query again for the relevant drivers and include it in the probe predicates + */ + +char *driver_name[2]; + + +fbt::_task_fn_rx:entry +/PROBE_PREDICATE && (!self->prefix_set)/ +{ + + + /* get taskqueue structure information to determine amount of functions waiting to be serviced */ + this->rxq = ((kernel`iflib_rxq_t)arg0); + this->grouptask = (struct grouptask)(this->rxq->ifr_task); + self->gt_name = stringof(this->grouptask.gt_name); + this->if_ctx = (if_ctx_t)(this->rxq)->ifr_ctx; + this->dev = (device_t)(this->if_ctx)->ifc_dev; + this->driver = (driver_t *)(this->dev)->driver; + driver_name[0] = (const char *)(this->driver)->name; + driver_name[1] = (const char *)(this->driver)->name + 1; + self->driver_prefix = stringof(*(driver_name)); + self->prefix_set = 1; + +} + +fbt::_task_fn_rx:entry +/PROBE_PREDICATE && DRIVER_CHECK/ +{ + iti[tid].task_rx_ts = timestamp; + @_task_fn_rx_count[tid, self->gt_name, probefunc] = count(); +} + +fbt::_task_fn_rx:return +/PROBE_PREDICATE && iti[tid].task_rx_ts && DRIVER_CHECK/ +{ + @task_rx_avg[tid, self->gt_name, probefunc] = avg(timestamp - iti[tid].task_rx_ts); + @task_rx_min[tid, self->gt_name, probefunc] = min(timestamp - iti[tid].task_rx_ts); + @task_rx_max[tid, self->gt_name, probefunc] = max(timestamp - iti[tid].task_rx_ts); +} + + +fbt::iflib_rxeof:entry +/PROBE_PREDICATE && DRIVER_CHECK/ +{ + iti[tid].rxeof_ts = timestamp; + @rxeof_count[tid, self->gt_name, probefunc] = count(); + +} + +fbt::iflib_rxeof:return +/PROBE_PREDICATE && iti[tid].rxeof_ts && DRIVER_CHECK/ +{ + @rxeof_avg[tid, self->gt_name, probefunc] = avg(timestamp - iti[tid].rxeof_ts); + @rxeof_min[tid, self->gt_name, probefunc] = min(timestamp - iti[tid].rxeof_ts); + @rxeof_max[tid, self->gt_name, probefunc] = max(timestamp - iti[tid].rxeof_ts); + +} + +fbt::ixgbe_isc_rxd_refill:entry +/PROBE_PREDICATE && DRIVER_CHECK/ +{ + this->ts = timestamp; + @rxd_refill_count[tid, self->gt_name, probefunc] = count(); +} + +fbt::ixgbe_isc_rxd_refill:return +/PROBE_PREDICATE && this->ts && DRIVER_CHECK/ +{ + + @rxd_refill_avg[tid, self->gt_name, probefunc] = avg(timestamp - this->ts); + @rxd_refill_min[tid, self->gt_name, probefunc] = min(timestamp - this->ts); + @rxd_refill_max[tid, self->gt_name, probefunc] = max(timestamp - this->ts); +} + + +/* notice how the ixgbe driver is missing, this is because of the dtrace compiler optimization - the return probe is missing */ +fbt::ixgbe_isc_rxd_available:entry +/PROBE_PREDICATE && DRIVER_CHECK/ +{ + this->ts = timestamp; + @rxd_avail_count[tid, self->gt_name, probefunc] = count(); +} + +fbt::ixgbe_isc_rxd_available:return +/PROBE_PREDICATE && (this->ts != 0) && DRIVER_CHECK/ +{ + @rxd_avail_avg[tid, self->gt_name, probefunc] = avg(timestamp - this->ts); + @rxd_avail_min[tid, self->gt_name, probefunc] = min(timestamp - this->ts); + @rxd_avail_max[tid, self->gt_name, probefunc] = max(timestamp - this->ts); +} + +fbt::ixgbe_isc_rxd_pkt_get:entry +/PROBE_PREDICATE && DRIVER_CHECK/ +{ + this->ts = timestamp; + @rxd_pkt_get_count[tid, self->gt_name, probefunc] = count(); +} + +fbt::ixgbe_isc_rxd_pkt_get:return +/PROBE_PREDICATE && (this->ts != 0) && DRIVER_CHECK/ +{ + @rxd_pkt_get_avg[tid, self->gt_name, probefunc] = avg(timestamp - this->ts); + @rxd_pkt_get_min[tid, self->gt_name, probefunc] = min(timestamp - this->ts); + @rxd_pkt_get_max[tid, self->gt_name, probefunc] = max(timestamp - this->ts); +} + + +/********************************************/ +/* Queue behaviour */ +/********************************************/ + +int qlen[int]; + +/* enqueue and deqeueue probes to determine the run length of the queues */ +sched:::enqueue +/PROBE_PREDICATE && DRIVER_CHECK/ +{ + this->q_len = qlen[tid]++; + + @q_len_all_threads_avg[tid] = avg(this->q_len); + @q_len_all_threads_min[tid] = min(this->q_len); + @q_len_all_threads_max[tid] = max(this->q_len); +} + +sched:::dequeue +/PROBE_PREDICATE && qlen[tid] && DRIVER_CHECK/ +{ + qlen[tid]--; + +} + + +END +{ + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("-------INTERRUPTS-------\n"); + printf("\n"); + printf("thread core function count avg time(ns) min time max time avg time(driver) min time(driver) max time(driver)\n"); + printf("------ ---- --------------------- --------------- ------------ -------- -------- ---------------- ---------------- ----------------\n"); + printa("%6d %4d %21s %@15d %@12d %@8d %@8d %@16d %@16d %@16d\n", @intcounts, @time, @fi_time_min, @fi_time_max, @fr_time_avg, @fr_time_min, @fr_time_max); + printf("\n"); + + printf("-------DRIVER/IFLIB FUNCTIONS RX-------\n"); + printf("thread grouptask name function avg time(ns) min time(ns) max time(ns) count\n"); + printf("------ -------------- ------------------------------ ------------ ------------ ------------ -----------\n"); + printa("%6d %14s %30s %@12d %@12d %@12d %@11d\n", @task_rx_avg, @task_rx_min, @task_rx_max, @_task_fn_rx_count); + printa("%6d %14s %30s %@12d %@12d %@12d %@11d\n", @rxeof_avg, @rxeof_min, @rxeof_max, @rxeof_count); + printa("%6d %14s %30s %@12d %@12d %@12d %@11d\n", @rxd_refill_avg, @rxd_refill_min, @rxd_refill_max, @rxd_refill_count); + printa("%6d %14s %30s %@12d %@12d %@12d %@11d\n", @rxd_avail_avg, @rxd_avail_min, @rxd_avail_max, @rxd_avail_count); + printa("%6d %14s %30s %@12d %@12d %@12d %@11d\n", @rxd_pkt_get_avg, @rxd_pkt_get_min, @rxd_pkt_get_max, @rxd_pkt_get_count); + printf("\n"); + + + printf("---------QUEUE BEHAVIOUR---------\n"); + printf("thread avg run length min run length max run length\n"); + printf("------ -------------- -------------- --------------\n"); + printa("%6d %@14d %@14d %@14d\n", @q_len_all_threads_avg, @q_len_all_threads_min, @q_len_all_threads_max); + printf("\n"); +} + diff --git a/source/development/how-tos/images/dtrace_output_docs.png b/source/development/how-tos/images/dtrace_output_docs.png new file mode 100755 index 0000000000000000000000000000000000000000..ab3037f4b887f7f9c34399cda561df307f440fbf GIT binary patch literal 42181 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�s?!e!2Y;A}3vFDS<%Hk0x` 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 + + + + + + + + + + + + +Flame Graph + +Reset Zoom +Search + +unix`mutex_enter (195 samples, 0.34%) + + + +genunix`as_fault (12 samples, 0.02%) + + + +genunix`disp_lock_exit (27 samples, 0.05%) + + + +genunix`vsd_free (17 samples, 0.03%) + + + +genunix`pn_fixslash (44 samples, 0.08%) + + + +unix`mutex_exit (105 samples, 0.18%) + + + +genunix`falloc (1,363 samples, 2.37%) +g.. + + +genunix`traverse (30 samples, 0.05%) + + + +genunix`fop_lookup (55 samples, 0.10%) + + + +genunix`kmem_cache_free (29 samples, 0.05%) + + + +lofs`makelonode (39 samples, 0.07%) + + + +genunix`vsd_free (155 samples, 0.27%) + + + +unix`strlen (2,659 samples, 4.63%) +unix`.. + + +unix`clear_int_flag (180 samples, 0.31%) + + + +unix`mutex_exit (38 samples, 0.07%) + + + +genunix`kmem_cpu_reload (5 samples, 0.01%) + + + +unix`mutex_exit (26 samples, 0.05%) + + + +genunix`vn_vfslocks_getlock (47 samples, 0.08%) + + + +unix`bzero (8 samples, 0.01%) + + + +genunix`vn_exists (50 samples, 0.09%) + + + +unix`mutex_enter (727 samples, 1.27%) + + + +genunix`kmem_cache_alloc (179 samples, 0.31%) + + + +unix`mutex_enter (905 samples, 1.58%) + + + +genunix`ufalloc (10 samples, 0.02%) + + + +genunix`vn_rele (25 samples, 0.04%) + + + +genunix`vn_exists (17 samples, 0.03%) + + + +unix`lock_try (778 samples, 1.35%) + + + +genunix`rwst_enter_common (314 samples, 0.55%) + + + +genunix`fsop_root (62 samples, 0.11%) + + + +lofs`table_lock_enter (44 samples, 0.08%) + + + +unix`mutex_exit (138 samples, 0.24%) + + + +unix`mutex_enter (316 samples, 0.55%) + + + +genunix`kmem_cache_free (5 samples, 0.01%) + + + +unix`preempt (14 samples, 0.02%) + + + +genunix`vn_alloc (1,189 samples, 2.07%) +g.. + + +genunix`kmem_cache_alloc (126 samples, 0.22%) + + + +genunix`vfs_getops (157 samples, 0.27%) + + + +lofs`lsave (27 samples, 0.05%) + + + +unix`tsc_read (160 samples, 0.28%) + + + +lofs`lfind (26 samples, 0.05%) + + + +unix`atomic_add_64 (205 samples, 0.36%) + + + +unix`mutex_enter (320 samples, 0.56%) + + + +genunix`traverse (17 samples, 0.03%) + + + +unix`mutex_enter (197 samples, 0.34%) + + + +genunix`vn_mountedvfs (20 samples, 0.03%) + + + +genunix`audit_unfalloc (340 samples, 0.59%) + + + +genunix`kmem_cache_free (209 samples, 0.36%) + + + +genunix`kmem_zalloc (13 samples, 0.02%) + + + +genunix`thread_lock (33 samples, 0.06%) + + + +unix`tsc_read (186 samples, 0.32%) + + + +genunix`vn_vfsrlock (12 samples, 0.02%) + + + +lofs`lo_inactive (21 samples, 0.04%) + + + +genunix`rwst_destroy (20 samples, 0.03%) + + + +unix`mutex_enter (379 samples, 0.66%) + + + +genunix`vn_setops (41 samples, 0.07%) + + + +genunix`vn_recycle (33 samples, 0.06%) + + + +lofs`lo_inactive (6,307 samples, 10.98%) +lofs`lo_inactive + + +lofs`table_lock_enter (220 samples, 0.38%) + + + +genunix`cv_broadcast (25 samples, 0.04%) + + + +unix`mutex_exit (358 samples, 0.62%) + + + +genunix`kmem_cache_alloc (234 samples, 0.41%) + + + +unix`rw_enter (525 samples, 0.91%) + + + +unix`membar_consumer (237 samples, 0.41%) + + + +unix`swtch (5 samples, 0.01%) + + + +genunix`rwst_enter_common (32 samples, 0.06%) + + + +lofs`freelonode (5,313 samples, 9.25%) +lofs`freelonode + + +genunix`vn_openat (46,342 samples, 80.68%) +genunix`vn_openat + + +genunix`vn_rele (19 samples, 0.03%) + + + +genunix`proc_exit (5 samples, 0.01%) + + + +unix`mutex_exit (512 samples, 0.89%) + + + +genunix`kmem_free (35 samples, 0.06%) + + + +unix`mutex_enter (252 samples, 0.44%) + + + +genunix`rwst_exit (12 samples, 0.02%) + + + +genunix`crgetuid (22 samples, 0.04%) + + + +genunix`kmem_free (17 samples, 0.03%) + + + +unix`mutex_init (53 samples, 0.09%) + + + +ufs`ufs_iaccess (648 samples, 1.13%) + + + +all (57,441 samples, 100%) + + + +genunix`fop_inactive (6,689 samples, 11.64%) +genunix`fop_inact.. + + +genunix`kmem_cache_alloc (9 samples, 0.02%) + + + +genunix`kmem_cache_free (184 samples, 0.32%) + + + +genunix`pn_get_buf (13 samples, 0.02%) + + + +unix`strlen (107 samples, 0.19%) + + + +unix`mutex_exit (46 samples, 0.08%) + + + +genunix`post_syscall (12 samples, 0.02%) + + + +unix`mutex_init (38 samples, 0.07%) + + + +unix`rw_exit (439 samples, 0.76%) + + + +lofs`lo_lookup (65 samples, 0.11%) + + + +genunix`clear_stale_fd (44 samples, 0.08%) + + + +unix`mutex_enter (238 samples, 0.41%) + + + +genunix`pn_get_buf (687 samples, 1.20%) + + + +genunix`vn_free (1,663 samples, 2.90%) +ge.. + + +unix`mutex_enter (980 samples, 1.71%) + + + +genunix`crhold (5 samples, 0.01%) + + + +unix`mutex_exit (59 samples, 0.10%) + + + +genunix`vn_reinit (48 samples, 0.08%) + + + +genunix`vfs_getops (21 samples, 0.04%) + + + +genunix`open (49,669 samples, 86.47%) +genunix`open + + +genunix`kmem_cache_alloc (39 samples, 0.07%) + + + +genunix`vn_vfslocks_getlock (79 samples, 0.14%) + + + +unix`clear_int_flag (39 samples, 0.07%) + + + +genunix`kmem_cache_free (215 samples, 0.37%) + + + +unix`mutex_destroy (53 samples, 0.09%) + + + +genunix`vn_vfsunlock (3,578 samples, 6.23%) +genunix`.. + + +genunix`dnlc_lookup (1,843 samples, 3.21%) +gen.. + + +genunix`lookupnameatcred (45,978 samples, 80.04%) +genunix`lookupnameatcred + + +genunix`crgetmapped (41 samples, 0.07%) + + + +genunix`anon_zero (7 samples, 0.01%) + + + +genunix`rwst_tryenter (628 samples, 1.09%) + + + +unix`mutex_enter (309 samples, 0.54%) + + + +genunix`vn_rele (14 samples, 0.02%) + + + +genunix`vn_setpath (1,969 samples, 3.43%) +gen.. + + +unix`mutex_enter (111 samples, 0.19%) + + + +genunix`cv_broadcast (40 samples, 0.07%) + + + +genunix`kmem_cache_alloc (66 samples, 0.11%) + + + +genunix`audit_getstate (21 samples, 0.04%) + + + +genunix`vn_setpath (58 samples, 0.10%) + + + +genunix`open (17 samples, 0.03%) + + + +unix`bcopy (896 samples, 1.56%) + + + +unix`mutex_enter (99 samples, 0.17%) + + + +genunix`traverse (5,557 samples, 9.67%) +genunix`traverse + + +genunix`pn_getcomponent (41 samples, 0.07%) + + + +unix`mutex_enter (640 samples, 1.11%) + + + +unix`mutex_destroy (176 samples, 0.31%) + + + +unix`lwp_getdatamodel (6 samples, 0.01%) + + + +genunix`unfalloc (39 samples, 0.07%) + + + +genunix`syscall_mstate (355 samples, 0.62%) + + + +genunix`cv_init (65 samples, 0.11%) + + + +unix`mutex_enter (95 samples, 0.17%) + + + +unix`bcmp (42 samples, 0.07%) + + + +unix`mutex_exit (350 samples, 0.61%) + + + +genunix`kmem_free (288 samples, 0.50%) + + + +unix`mutex_exit (58 samples, 0.10%) + + + +genunix`kmem_alloc (32 samples, 0.06%) + + + +unix`mutex_exit (356 samples, 0.62%) + + + +unix`mutex_init (46 samples, 0.08%) + + + +genunix`rwst_init (173 samples, 0.30%) + + + +genunix`rwst_enter_common (28 samples, 0.05%) + + + +genunix`openat (49,647 samples, 86.43%) +genunix`openat + + +unix`mutex_enter (303 samples, 0.53%) + + + +lofs`lfind (278 samples, 0.48%) + + + +unix`mutex_exit (90 samples, 0.16%) + + + +genunix`cv_init (49 samples, 0.09%) + + + +unix`tsc_gethrtimeunscaled (43 samples, 0.07%) + + + +genunix`rwst_tryenter (32 samples, 0.06%) + + + +genunix`pn_fixslash (14 samples, 0.02%) + + + +genunix`gethrtime_unscaled (420 samples, 0.73%) + + + +genunix`post_syscall (4,245 samples, 7.39%) +genunix`po.. + + +genunix`kmem_zalloc (280 samples, 0.49%) + + + +genunix`vn_alloc (20 samples, 0.03%) + + + +genunix`vn_mountedvfs (43 samples, 0.07%) + + + +genunix`audit_getstate (15 samples, 0.03%) + + + +zfs`zfs_lookup (22 samples, 0.04%) + + + +genunix`crgetuid (6 samples, 0.01%) + + + +unix`copystr (598 samples, 1.04%) + + + +unix`i_ddi_splhigh (23 samples, 0.04%) + + + +unix`trap (13 samples, 0.02%) + + + +genunix`audit_getstate (27 samples, 0.05%) + + + +genunix`vn_mountedvfs (56 samples, 0.10%) + + + +unix`mutex_destroy (17 samples, 0.03%) + + + +genunix`cv_broadcast (14 samples, 0.02%) + + + +genunix`segvn_fault (11 samples, 0.02%) + + + +genunix`vn_rele (39 samples, 0.07%) + + + +genunix`kmem_free (457 samples, 0.80%) + + + +genunix`vn_vfsunlock (20 samples, 0.03%) + + + +genunix`vn_vfslocks_rele (34 samples, 0.06%) + + + +unix`atomic_cas_64 (318 samples, 0.55%) + + + +unix`mutex_enter (337 samples, 0.59%) + + + +unix`do_splx (31 samples, 0.05%) + + + +genunix`ufalloc_file (20 samples, 0.03%) + + + +genunix`fd_reserve (35 samples, 0.06%) + + + +genunix`copen (49,444 samples, 86.08%) +genunix`copen + + +unix`mutex_enter (279 samples, 0.49%) + + + +unix`0xfffffffffb800c91 (4,361 samples, 7.59%) +unix`0xfff.. + + +genunix`crgetmapped (55 samples, 0.10%) + + + +genunix`cv_init (56 samples, 0.10%) + + + +genunix`dnlc_lookup (26 samples, 0.05%) + + + +genunix`kmem_alloc (11 samples, 0.02%) + + + +genunix`cv_init (53 samples, 0.09%) + + + +unix`copyinstr (25 samples, 0.04%) + + + +genunix`gethrtime_unscaled (203 samples, 0.35%) + + + +genunix`kmem_cache_alloc (11 samples, 0.02%) + + + +genunix`vn_free (26 samples, 0.05%) + + + +unix`mutex_exit (149 samples, 0.26%) + + + +genunix`vn_recycle (319 samples, 0.56%) + + + +genunix`vn_rele (64 samples, 0.11%) + + + +unix`bcmp (11 samples, 0.02%) + + + +genunix`kmem_cache_free (154 samples, 0.27%) + + + +unix`lock_clear_splx (28 samples, 0.05%) + + + +genunix`unfalloc (729 samples, 1.27%) + + + +genunix`fop_lookup (85 samples, 0.15%) + + + +zfs`specvp_check (10 samples, 0.02%) + + + +genunix`lookupnameatcred (22 samples, 0.04%) + + + +unix`tsc_read (367 samples, 0.64%) + + + +genunix`memcmp (38 samples, 0.07%) + + + +unix`splx (6 samples, 0.01%) + + + +unix`mutex_exit (95 samples, 0.17%) + + + +genunix`gethrtime_unscaled (7 samples, 0.01%) + + + +genunix`rwst_init (13 samples, 0.02%) + + + +genunix`audit_getstate (31 samples, 0.05%) + + + +genunix`kmem_cache_alloc (32 samples, 0.06%) + + + +genunix`disp_lock_exit (2,096 samples, 3.65%) +genu.. + + +unix`mutex_exit (49 samples, 0.09%) + + + +unix`copyinstr (18 samples, 0.03%) + + + +ufs`ufs_lookup (46 samples, 0.08%) + + + +genunix`clear_stale_fd (10 samples, 0.02%) + + + +genunix`rwst_destroy (296 samples, 0.52%) + + + +genunix`syscall_mstate (1,336 samples, 2.33%) +g.. + + +genunix`kmem_alloc (934 samples, 1.63%) + + + +unix`atomic_add_32 (325 samples, 0.57%) + + + +unix`mutex_enter (947 samples, 1.65%) + + + +unix`mutex_exit (56 samples, 0.10%) + + + +unix`mutex_enter (318 samples, 0.55%) + + + +lofs`lo_root (80 samples, 0.14%) + + + +genunix`lookuppnvp (44,242 samples, 77.02%) +genunix`lookuppnvp + + +genunix`lookupnameat (46,075 samples, 80.21%) +genunix`lookupnameat + + +unix`setbackdq (5 samples, 0.01%) + + + +lofs`lo_root (31 samples, 0.05%) + + + +genunix`kmem_cache_alloc (17 samples, 0.03%) + + + +unix`mutex_exit (212 samples, 0.37%) + + + +genunix`vn_vfsrlock (2,414 samples, 4.20%) +genun.. + + +genunix`vfs_matchops (28 samples, 0.05%) + + + +unix`prunstop (36 samples, 0.06%) + + + +unix`mutex_exit (155 samples, 0.27%) + + + +unix`mutex_init (31 samples, 0.05%) + + + +unix`atomic_add_32_nv (100 samples, 0.17%) + + + +genunix`lookupnameat (69 samples, 0.12%) + + + +unix`_sys_rtt (6 samples, 0.01%) + + + +genunix`kmem_cache_alloc (49 samples, 0.09%) + + + +unix`tsc_gethrtimeunscaled (17 samples, 0.03%) + + + +genunix`fop_lookup (29,216 samples, 50.86%) +genunix`fop_lookup + + +unix`mutex_exit (142 samples, 0.25%) + + + +genunix`crgetmapped (31 samples, 0.05%) + + + +unix`do_splx (1,993 samples, 3.47%) +uni.. + + +genunix`kmem_cache_free (22 samples, 0.04%) + + + +unix`mutex_enter (95 samples, 0.17%) + + + +genunix`crhold (11 samples, 0.02%) + + + +unix`mutex_enter (823 samples, 1.43%) + + + +unix`mutex_exit (29 samples, 0.05%) + + + +genunix`vn_vfsrlock (3,342 samples, 5.82%) +genunix.. + + +unix`tsc_gethrtimeunscaled (13 samples, 0.02%) + + + +genunix`vn_rele (73 samples, 0.13%) + + + +unix`mutex_exit (337 samples, 0.59%) + + + +genunix`vn_vfslocks_getlock (973 samples, 1.69%) + + + +zfs`specvp_check (20 samples, 0.03%) + + + +genunix`vsd_free (14 samples, 0.02%) + + + +unix`mutex_enter (314 samples, 0.55%) + + + +genunix`cv_destroy (81 samples, 0.14%) + + + +genunix`cv_broadcast (25 samples, 0.04%) + + + +unix`mutex_enter (122 samples, 0.21%) + + + +unix`mutex_exit (55 samples, 0.10%) + + + +genunix`set_errno (24 samples, 0.04%) + + + +genunix`cv_destroy (42 samples, 0.07%) + + + +genunix`fd_find (13 samples, 0.02%) + + + +genunix`vn_invalid (47 samples, 0.08%) + + + +genunix`vfs_matchops (336 samples, 0.58%) + + + +unix`tsc_gethrtimeunscaled (59 samples, 0.10%) + + + +genunix`fop_inactive (39 samples, 0.07%) + + + +genunix`kmem_free (693 samples, 1.21%) + + + +genunix`syscall_mstate (412 samples, 0.72%) + + + +genunix`thread_lock (670 samples, 1.17%) + + + +lofs`lsave (162 samples, 0.28%) + + + +unix`atomic_add_64 (95 samples, 0.17%) + + + +genunix`audit_getstate (66 samples, 0.11%) + + + +genunix`dnlc_lookup (70 samples, 0.12%) + + + +genunix`vn_mountedvfs (30 samples, 0.05%) + + + +genunix`cv_broadcast (19 samples, 0.03%) + + + +genunix`kmem_alloc (533 samples, 0.93%) + + + +unix`mutex_exit (160 samples, 0.28%) + + + +genunix`memcmp (38 samples, 0.07%) + + + +unix`strlen (1,238 samples, 2.16%) +u.. + + +genunix`lookuppnatcred (12 samples, 0.02%) + + + +genunix`crfree (13 samples, 0.02%) + + + +lofs`table_lock_enter (43 samples, 0.07%) + + + +genunix`rwst_exit (18 samples, 0.03%) + + + +genunix`cv_destroy (31 samples, 0.05%) + + + +genunix`rwst_init (236 samples, 0.41%) + + + +genunix`vn_vfslocks_rele (1,420 samples, 2.47%) +ge.. + + +genunix`falloc (36 samples, 0.06%) + + + +genunix`setf (187 samples, 0.33%) + + + +zfs`zfs_fastaccesschk_execute (50 samples, 0.09%) + + + +genunix`vn_vfslocks_getlock (120 samples, 0.21%) + + + +genunix`fd_reserve (9 samples, 0.02%) + + + +genunix`vn_setops (160 samples, 0.28%) + + + +unix`sys_syscall (51,908 samples, 90.37%) +unix`sys_syscall + + +genunix`kmem_free (115 samples, 0.20%) + + + +genunix`vsd_free (48 samples, 0.08%) + + + +genunix`rexit (5 samples, 0.01%) + + + +genunix`vn_mountedvfs (11 samples, 0.02%) + + + +genunix`lookuppnatcred (44,681 samples, 77.79%) +genunix`lookuppnatcred + + +unix`splr (92 samples, 0.16%) + + + +genunix`vn_vfsrlock (13 samples, 0.02%) + + + +unix`mutex_exit (371 samples, 0.65%) + + + +genunix`kmem_cache_free (5 samples, 0.01%) + + + +genunix`dnlc_lookup (263 samples, 0.46%) + + + +genunix`audit_unfalloc (32 samples, 0.06%) + + + +unix`0xfffffffffb8001d6 (13 samples, 0.02%) + + + +genunix`rwst_destroy (146 samples, 0.25%) + + + +genunix`gethrtime_unscaled (182 samples, 0.32%) + + + +unix`mutex_enter (575 samples, 1.00%) + + + +unix`mutex_exit (148 samples, 0.26%) + + + +genunix`ufalloc_file (294 samples, 0.51%) + + + +unix`mutex_exit (163 samples, 0.28%) + + + +unix`membar_consumer (106 samples, 0.18%) + + + +genunix`crgetmapped (36 samples, 0.06%) + + + +genunix`memcmp (277 samples, 0.48%) + + + +genunix`cv_destroy (77 samples, 0.13%) + + + +genunix`kmem_cache_free (116 samples, 0.20%) + + + +genunix`kmem_cache_alloc (29 samples, 0.05%) + + + +genunix`fd_reserve (8 samples, 0.01%) + + + +zfs`zfs_lookup (946 samples, 1.65%) + + + +genunix`kmem_alloc (795 samples, 1.38%) + + + +unix`tsc_gethrtimeunscaled (11 samples, 0.02%) + + + +genunix`segvn_faultpage (7 samples, 0.01%) + + + +genunix`set_errno (9 samples, 0.02%) + + + +unix`splr (400 samples, 0.70%) + + + +genunix`rwst_destroy (32 samples, 0.06%) + + + +genunix`rwst_init (28 samples, 0.05%) + + + +unix`atomic_add_32 (292 samples, 0.51%) + + + +unix`0xfffffffffb800ca0 (517 samples, 0.90%) + + + +genunix`syscall_mstate (89 samples, 0.15%) + + + +genunix`kmem_alloc (73 samples, 0.13%) + + + +genunix`vn_vfsunlock (40 samples, 0.07%) + + + +unix`mutex_enter (1,202 samples, 2.09%) +u.. + + +lofs`makelfsnode (28 samples, 0.05%) + + + +unix`0xfffffffffb800c86 (472 samples, 0.82%) + + + +genunix`vn_rele (6,943 samples, 12.09%) +genunix`vn_rele + + +unix`mutex_exit (56 samples, 0.10%) + + + +genunix`kmem_cache_free (51 samples, 0.09%) + + + +genunix`gethrtime_unscaled (11 samples, 0.02%) + + + +unix`pagefault (13 samples, 0.02%) + + + +genunix`secpolicy_vnode_access2 (217 samples, 0.38%) + + + +genunix`vn_vfslocks_getlock (1,357 samples, 2.36%) +g.. + + +unix`bcmp (295 samples, 0.51%) + + + +unix`mutex_enter (97 samples, 0.17%) + + + +unix`membar_consumer (123 samples, 0.21%) + + + +genunix`audit_getstate (16 samples, 0.03%) + + + +unix`mutex_enter (455 samples, 0.79%) + + + +lofs`makelonode (4,212 samples, 7.33%) +lofs`makel.. + + +genunix`kmem_cache_alloc (168 samples, 0.29%) + + + +genunix`vn_vfslocks_getlock (62 samples, 0.11%) + + + +genunix`secpolicy_vnode_access2 (72 samples, 0.13%) + + + +genunix`kmem_cache_free (73 samples, 0.13%) + + + +genunix`vn_reinit (424 samples, 0.74%) + + + +genunix`pn_getcomponent (454 samples, 0.79%) + + + +genunix`fsop_root (297 samples, 0.52%) + + + +genunix`crgetuid (30 samples, 0.05%) + + + +genunix`kmem_free (785 samples, 1.37%) + + + +unix`mutex_exit (171 samples, 0.30%) + + + +genunix`crgetmapped (58 samples, 0.10%) + + + +unix`mutex_enter (299 samples, 0.52%) + + + +genunix`rwst_exit (167 samples, 0.29%) + + + +genunix`audit_falloc (8 samples, 0.01%) + + + +genunix`rwst_exit (110 samples, 0.19%) + + + +genunix`exit (5 samples, 0.01%) + + + +unix`mutex_exit (250 samples, 0.44%) + + + +lofs`freelonode (35 samples, 0.06%) + + + +genunix`rwst_tryenter (37 samples, 0.06%) + + + +ufs`ufs_iaccess (91 samples, 0.16%) + + + +unix`tsc_gethrtimeunscaled (12 samples, 0.02%) + + + +genunix`kmem_cache_alloc (241 samples, 0.42%) + + + +FSS`fss_preempt (8 samples, 0.01%) + + + +genunix`fd_reserve (15 samples, 0.03%) + + + +genunix`cv_broadcast (16 samples, 0.03%) + + + +genunix`crgetmapped (57 samples, 0.10%) + + + +unix`mutex_exit (379 samples, 0.66%) + + + +unix`mutex_destroy (31 samples, 0.05%) + + + +lofs`table_lock_enter (189 samples, 0.33%) + + + +genunix`rwst_enter_common (264 samples, 0.46%) + + + +genunix`kmem_free (11 samples, 0.02%) + + + +unix`atomic_add_32 (134 samples, 0.23%) + + + +genunix`ufalloc (551 samples, 0.96%) + + + +genunix`audit_falloc (313 samples, 0.54%) + + + +lofs`lo_lookup (19,887 samples, 34.62%) +lofs`lo_lookup + + +unix`atomic_add_64 (110 samples, 0.19%) + + + +genunix`vn_vfsunlock (2,372 samples, 4.13%) +genu.. + + +genunix`openat (17 samples, 0.03%) + + + +unix`bcmp (45 samples, 0.08%) + + + +genunix`audit_getstate (62 samples, 0.11%) + + + +genunix`crfree (9 samples, 0.02%) + + + +genunix`kmem_cache_free (18 samples, 0.03%) + + + +genunix`vn_vfslocks_rele (903 samples, 1.57%) + + + +genunix`vn_invalid (20 samples, 0.03%) + + + +genunix`vn_vfslocks_rele (50 samples, 0.09%) + + + +genunix`lookuppnvp (10 samples, 0.02%) + + + +genunix`fd_find (161 samples, 0.28%) + + + +ufs`ufs_lookup (5,399 samples, 9.40%) +ufs`ufs_lookup + + +unix`0xfffffffffb800c7c (42 samples, 0.07%) + + + +genunix`vn_openat (14 samples, 0.02%) + + + +genunix`setf (16 samples, 0.03%) + + + +genunix`traverse (7,243 samples, 12.61%) +genunix`traverse + + +genunix`rwst_tryenter (734 samples, 1.28%) + + + +unix`mutex_enter (366 samples, 0.64%) + + + +genunix`fop_lookup (6,470 samples, 11.26%) +genunix`fop_lookup + + +unix`mutex_exit (135 samples, 0.24%) + + + +lofs`makelfsnode (82 samples, 0.14%) + + + +genunix`copen (7 samples, 0.01%) + + + diff --git a/source/development/how-tos/images/queue_behaviour.png b/source/development/how-tos/images/queue_behaviour.png new file mode 100755 index 0000000000000000000000000000000000000000..19ef46697b98ecb872048b2085e761d83583452d GIT binary patch literal 6027 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 WZgW^nk>~;)bji%pwD|m=k^cesduE{k literal 0 HcmV?d00001