aboutsummaryrefslogtreecommitdiffstats
path: root/src/vpp
diff options
context:
space:
mode:
authorNathan Skrzypczak <nathan.skrzypczak@gmail.com>2021-10-08 14:01:27 +0200
committerDave Wallace <dwallacelf@gmail.com>2021-10-13 15:32:33 +0000
commitd4a70647e6b8de2cb81cbea3c53d08c299b65cc5 (patch)
tree4c9e695232b110ea95326ecb86f706d34c065289 /src/vpp
parenta2c9509a4ab22380937a2b613fcc518da22f5166 (diff)
docs: convert vpp doc md->rst
Type: improvement Change-Id: If453321785b04f9c16e8cea36fb1910efaeb2c59 Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
Diffstat (limited to 'src/vpp')
-rw-r--r--src/vpp/mem/mem.md21
-rw-r--r--src/vpp/mem/mem.rst25
-rw-r--r--src/vpp/stats/stats.md130
-rw-r--r--src/vpp/stats/stats.rst178
4 files changed, 203 insertions, 151 deletions
diff --git a/src/vpp/mem/mem.md b/src/vpp/mem/mem.md
deleted file mode 100644
index 84ab820e5e5..00000000000
--- a/src/vpp/mem/mem.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# VPP mem preload {#mempreload_doc}
-
-Internal VPP memory allocations rely on VPP main-heap, however when using
-external libraries, esp. in plugins (eg. OpenSSL library used by the IKEv2
-plugin), those external libraries usually manages memory using the standard
-libc `malloc()`/`free()`/... calls. This, in turn, makes use of the default
-libc heap.
-
-VPP has no knowledge of this heap and tools such as memory traces cannot be
-used.
-
-In order to enable the use of standard VPP debugging tools, this library
-replaces standard libc memory management calls with version using VPP
-main-heap.
-
-To use it, you need to use the `LD_PRELOAD` mechanism, eg.
-```
-~# LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libvppmem_preload.so /usr/bin/vpp -c /etc/vpp/startup.conf
-```
-
-You can then use tools such as memory traces as usual.
diff --git a/src/vpp/mem/mem.rst b/src/vpp/mem/mem.rst
new file mode 100644
index 00000000000..82ae2ff35df
--- /dev/null
+++ b/src/vpp/mem/mem.rst
@@ -0,0 +1,25 @@
+.. _mempreload_doc:
+
+VPP mem preload
+===============
+
+Internal VPP memory allocations rely on VPP main-heap, however when
+using external libraries, esp. in plugins (e.g. OpenSSL library used by
+the IKEv2 plugin), those external libraries usually manages memory using
+the standard libc ``malloc()``/``free()``/… calls. This, in turn, makes
+use of the default libc heap.
+
+VPP has no knowledge of this heap and tools such as memory traces cannot
+be used.
+
+In order to enable the use of standard VPP debugging tools, this library
+replaces standard libc memory management calls with version using VPP
+main-heap.
+
+To use it, you need to use the ``LD_PRELOAD`` mechanism, e.g.
+
+::
+
+ ~# LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libvppmem_preload.so /usr/bin/vpp -c /etc/vpp/startup.conf
+
+You can then use tools such as memory traces as usual.
diff --git a/src/vpp/stats/stats.md b/src/vpp/stats/stats.md
deleted file mode 100644
index 8671f56e4a5..00000000000
--- a/src/vpp/stats/stats.md
+++ /dev/null
@@ -1,130 +0,0 @@
-# Statistics {#stats_doc}
-
-In VPP most things are measured and counted. There are counters for interface statistics, like RX, TX counters, packet drops, and so on. Every node has a set of per-node counters, one set of error counters, like TTL exceeded, or packet to big or out-of-buffers. And a set of performance counters, like number of clocks, vectors, calls and suspends.
-
-There is also a set of system counters and performance counters, e.g. memory utilization per heap, buffer utilisation and so on.
-
-## VPP Counter Architecture
-
-Counters are exposed directly via shared memory. These are the actual counters in VPP, no sampling or aggregation is done by the statistics infrastructure. With the exception of per node performance data under /sys/node and a few system counters.
-
-
-Clients mount the shared memory segment read-only, using a optimistic concurrency algorithm.
-
-Directory structure as an index.
-
-### Memory layout
-
-The memory segment consists of a shared header, containing atomics for the optimistic concurrency mechanism, and offsets into memory for the directory vectors. The only data structure used is the VPP vectors. All pointers are converted to offsets so that client applications can map the shared memory wherever it pleases.
-
-### Directory layout
-
-### Optimistic concurrency
-
-```
-/*
- * Shared header first in the shared memory segment.
- */
-typedef struct {
- atomic_int_fast64_t epoch;
- atomic_int_fast64_t in_progress;
- atomic_int_fast64_t directory_offset;
- atomic_int_fast64_t error_offset;
- atomic_int_fast64_t stats_offset;
-} stat_segment_shared_header_t;
-
-```
-
-#### Writer
-On the VPP side there is a single writer (controlled by a spinlock). When the writer starts it sets in_progress=1, continues with the update of the data-structures, and when done, bumps epoch++ and sets in_progress=0.
-
-#### Readers
-If in_progress=1, there is no point continuing, so reader sits spinning on the in_progress flag until it is 0. Then it sets start_epoch = epoch and continues copying out the counter data it is interested in, while doing strict boundary checks on all offsets / pointers. When the reader is done, it checks if in_progress=1 or if epoch != start_epoch. If either of those are true is discards the data read.
-
-## How are counters exposed out of VPP?
-
-## Types of Counters
-
-All counters under /err and /if are the directly exposed VPP counters.
-
-* Gauges
-* u64 / float
-* Interface Counters
- * Simple counters, counter_t array of threads of an array of interfaces
- * Combined counters, vlib_counter_t array of threads of an array of interfaces.
-
-
-## Client libraries
-### Writing a new client library
-A new client library can either wrap the C library (libvppapiclient.so) or it can integrate directly with the shared memory. That involves exchanging a file descriptor over the VPP stats Unix domain socket, and opening the memory mapped segment.
-
-### Python
-
-```
-#!/usr/bin/env python3
-from vpp_papi.vpp_stats import VPPStats
-stats = VPPStats('/run/vpp/stats.sock')
-dir = stats.ls(['^/if', '/err/ip4-input', '/sys/node/ip4-input'])
-counters = stats.dump(dir)
-
-# Print the RX counters for the first interface on the first worker core
-print ('RX interface core 0, sw_if_index 0', counters['/if/rx'][0][0])
-
-```
-### C
-```
-#include <vpp-api/client/stat_client.h>
-#include <vppinfra/vec.h>
-
-int main (int argc, char **argv) {
- uint8_t *patterns = 0;
-
- vec_add1(patterns, "^/if");
- vec_add1(patterns, "ip4-input");
-
- int rv = stat_segment_connect(STAT_SEGMENT_SOCKET_FILE);
- uint32_t *dir = stat_segment_ls(patterns);
- stat_segment_data_t *res = stat_segment_dump(dir);
-
- for (int i = 0; i < vec_len(res); i++) {
- switch (res[i].type) {
- case STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE:
- for (k = 0; k < vec_len (res[i].simple_counter_vec) - 1; k++)
- for (j = 0; j < vec_len (res[i].simple_counter_vec[k]); j++)
- fformat (stdout, "[%d @ %d]: %llu packets %s\n",
- j, k, res[i].simple_counter_vec[k][j],
- res[i].name);
- break;
-
- case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED:
- for (k = 0; k < vec_len (res[i].combined_counter_vec); k++)
- for (j = 0; j < vec_len (res[i].combined_counter_vec[k]); j++)
- fformat (stdout, "[%d @ %d]: %llu packets, %llu bytes %s\n",
- j, k, res[i].combined_counter_vec[k][j].packets,
- res[i].combined_counter_vec[k][j].bytes,
- res[i].name);
- break;
-
- case STAT_DIR_TYPE_ERROR_INDEX:
- for (j = 0; j < vec_len (res[i].error_vector); j++)
- fformat (stdout, "[@%d] %llu %s\n", j, res[i].error_vector[j], res[i].name);
- break;
-
- case STAT_DIR_TYPE_SCALAR_INDEX:
- fformat (stdout, "%.2f %s\n", res[i].scalar_value, res[i].name);
- break;
-
- default:
- ;
- }
- }
- stat_segment_data_free (res);
-}
-```
-
-## Integrations
-* CLI command. vpp_get_stats [ls | dump | poll]
-* Prometheus
-
-## Future evolution
-* Deprecate the stats over binary API calls that are based on want_stats
diff --git a/src/vpp/stats/stats.rst b/src/vpp/stats/stats.rst
new file mode 100644
index 00000000000..26e4db8c0db
--- /dev/null
+++ b/src/vpp/stats/stats.rst
@@ -0,0 +1,178 @@
+.. _stats_doc:
+
+Statistics
+==========
+
+In VPP most things are measured and counted. There are counters for
+interface statistics, like RX, TX counters, packet drops, and so on.
+Every node has a set of per-node counters, one set of error counters,
+like TTL exceeded, or packet to big or out-of-buffers. And a set of
+performance counters, like number of clocks, vectors, calls and
+suspends.
+
+There is also a set of system counters and performance counters,
+e.g. memory utilization per heap, buffer utilisation and so on.
+
+VPP Counter Architecture
+------------------------
+
+Counters are exposed directly via shared memory. These are the actual
+counters in VPP, no sampling or aggregation is done by the statistics
+infrastructure. With the exception of per node performance data under
+/sys/node and a few system counters.
+
+Clients mount the shared memory segment read-only, using a optimistic
+concurrency algorithm.
+
+Directory structure as an index.
+
+Memory layout
+~~~~~~~~~~~~~
+
+The memory segment consists of a shared header, containing atomics for
+the optimistic concurrency mechanism, and offsets into memory for the
+directory vectors. The only data structure used is the VPP vectors. All
+pointers are converted to offsets so that client applications can map
+the shared memory wherever it pleases.
+
+Directory layout
+~~~~~~~~~~~~~~~~
+
+Optimistic concurrency
+~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ /*
+ * Shared header first in the shared memory segment.
+ */
+ typedef struct {
+ atomic_int_fast64_t epoch;
+ atomic_int_fast64_t in_progress;
+ atomic_int_fast64_t directory_offset;
+ atomic_int_fast64_t error_offset;
+ atomic_int_fast64_t stats_offset;
+ } stat_segment_shared_header_t;
+
+Writer
+^^^^^^
+
+On the VPP side there is a single writer (controlled by a spinlock).
+When the writer starts it sets in_progress=1, continues with the update
+of the data-structures, and when done, bumps epoch++ and sets
+in_progress=0.
+
+Readers
+^^^^^^^
+
+If in_progress=1, there is no point continuing, so reader sits spinning
+on the in_progress flag until it is 0. Then it sets start_epoch = epoch
+and continues copying out the counter data it is interested in, while
+doing strict boundary checks on all offsets / pointers. When the reader
+is done, it checks if in_progress=1 or if epoch != start_epoch. If
+either of those are true is discards the data read.
+
+How are counters exposed out of VPP?
+------------------------------------
+
+Types of Counters
+-----------------
+
+All counters under /err and /if are the directly exposed VPP counters.
+
+- Gauges
+- u64 / float
+- Interface Counters
+- Simple counters, counter_t array of threads of an array of interfaces
+- Combined counters, vlib_counter_t array of threads of an array of
+ interfaces.
+
+Client libraries
+----------------
+
+Writing a new client library
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A new client library can either wrap the C library (libvppapiclient.so)
+or it can integrate directly with the shared memory. That involves
+exchanging a file descriptor over the VPP stats Unix domain socket, and
+opening the memory mapped segment.
+
+Python
+~~~~~~
+
+::
+
+ #!/usr/bin/env python3
+ from vpp_papi.vpp_stats import VPPStats
+ stats = VPPStats('/run/vpp/stats.sock')
+ dir = stats.ls(['^/if', '/err/ip4-input', '/sys/node/ip4-input'])
+ counters = stats.dump(dir)
+
+ # Print the RX counters for the first interface on the first worker core
+ print ('RX interface core 0, sw_if_index 0', counters['/if/rx'][0][0])
+
+C
+~
+
+::
+
+ #include <vpp-api/client/stat_client.h>
+ #include <vppinfra/vec.h>
+
+ int main (int argc, char **argv) {
+ uint8_t *patterns = 0;
+
+ vec_add1(patterns, "^/if");
+ vec_add1(patterns, "ip4-input");
+
+ int rv = stat_segment_connect(STAT_SEGMENT_SOCKET_FILE);
+ uint32_t *dir = stat_segment_ls(patterns);
+ stat_segment_data_t *res = stat_segment_dump(dir);
+
+ for (int i = 0; i < vec_len(res); i++) {
+ switch (res[i].type) {
+ case STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE:
+ for (k = 0; k < vec_len (res[i].simple_counter_vec) - 1; k++)
+ for (j = 0; j < vec_len (res[i].simple_counter_vec[k]); j++)
+ fformat (stdout, "[%d @ %d]: %llu packets %s\n",
+ j, k, res[i].simple_counter_vec[k][j],
+ res[i].name);
+ break;
+
+ case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED:
+ for (k = 0; k < vec_len (res[i].combined_counter_vec); k++)
+ for (j = 0; j < vec_len (res[i].combined_counter_vec[k]); j++)
+ fformat (stdout, "[%d @ %d]: %llu packets, %llu bytes %s\n",
+ j, k, res[i].combined_counter_vec[k][j].packets,
+ res[i].combined_counter_vec[k][j].bytes,
+ res[i].name);
+ break;
+
+ case STAT_DIR_TYPE_ERROR_INDEX:
+ for (j = 0; j < vec_len (res[i].error_vector); j++)
+ fformat (stdout, "[@%d] %llu %s\n", j, res[i].error_vector[j], res[i].name);
+ break;
+
+ case STAT_DIR_TYPE_SCALAR_INDEX:
+ fformat (stdout, "%.2f %s\n", res[i].scalar_value, res[i].name);
+ break;
+
+ default:
+ ;
+ }
+ }
+ stat_segment_data_free (res);
+ }
+
+Integrations
+------------
+
+- CLI command. vpp_get_stats [ls \| dump \| poll]
+- Prometheus
+
+Future evolution
+----------------
+
+- Deprecate the stats over binary API calls that are based on
+ want_stats