Commit 9b038086 authored by Jakub Kicinski's avatar Jakub Kicinski

docs: networking: convert DIM to RST

Convert the Dynamic Interrupt Moderation doc to RST and
use the RST features like syntax highlight, function and
structure documentation, enumerations, table of contents.
Reviewed-by: default avatarRandy Dunlap <rdunlap@infradead.org>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 40fc7ad2
...@@ -22,6 +22,7 @@ Contents: ...@@ -22,6 +22,7 @@ Contents:
z8530book z8530book
msg_zerocopy msg_zerocopy
failover failover
net_dim
net_failover net_failover
phy phy
sfp-phylink sfp-phylink
......
======================================================
Net DIM - Generic Network Dynamic Interrupt Moderation Net DIM - Generic Network Dynamic Interrupt Moderation
====================================================== ======================================================
Author: :Author: Tal Gilboa <talgi@mellanox.com>
Tal Gilboa <talgi@mellanox.com>
Contents
=========
- Assumptions .. contents:: :depth: 2
- Introduction
- The Net DIM Algorithm
- Registering a Network Device to DIM
- Example
Part 0: Assumptions Assumptions
====================== ===========
This document assumes the reader has basic knowledge in network drivers This document assumes the reader has basic knowledge in network drivers
and in general interrupt moderation. and in general interrupt moderation.
Part I: Introduction Introduction
====================== ============
Dynamic Interrupt Moderation (DIM) (in networking) refers to changing the Dynamic Interrupt Moderation (DIM) (in networking) refers to changing the
interrupt moderation configuration of a channel in order to optimize packet interrupt moderation configuration of a channel in order to optimize packet
...@@ -41,14 +33,15 @@ number of wanted packets per event. The Net DIM algorithm ascribes importance to ...@@ -41,14 +33,15 @@ number of wanted packets per event. The Net DIM algorithm ascribes importance to
increase bandwidth over reducing interrupt rate. increase bandwidth over reducing interrupt rate.
Part II: The Net DIM Algorithm Net DIM Algorithm
=============================== =================
Each iteration of the Net DIM algorithm follows these steps: Each iteration of the Net DIM algorithm follows these steps:
1. Calculates new data sample.
2. Compares it to previous sample. #. Calculates new data sample.
3. Makes a decision - suggests interrupt moderation configuration fields. #. Compares it to previous sample.
4. Applies a schedule work function, which applies suggested configuration. #. Makes a decision - suggests interrupt moderation configuration fields.
#. Applies a schedule work function, which applies suggested configuration.
The first two steps are straightforward, both the new and the previous data are The first two steps are straightforward, both the new and the previous data are
supplied by the driver registered to Net DIM. The previous data is the new data supplied by the driver registered to Net DIM. The previous data is the new data
...@@ -89,19 +82,21 @@ manoeuvre as it may provide partial data or ignore the algorithm suggestion ...@@ -89,19 +82,21 @@ manoeuvre as it may provide partial data or ignore the algorithm suggestion
under some conditions. under some conditions.
Part III: Registering a Network Device to DIM Registering a Network Device to DIM
============================================== ===================================
Net DIM API exposes the main function net_dim(struct dim *dim, Net DIM API exposes the main function net_dim().
struct dim_sample end_sample). This function is the entry point to the Net This function is the entry point to the Net
DIM algorithm and has to be called every time the driver would like to check if DIM algorithm and has to be called every time the driver would like to check if
it should change interrupt moderation parameters. The driver should provide two it should change interrupt moderation parameters. The driver should provide two
data structures: struct dim and struct dim_sample. Struct dim data structures: :c:type:`struct dim <dim>` and
:c:type:`struct dim_sample <dim_sample>`. :c:type:`struct dim <dim>`
describes the state of DIM for a specific object (RX queue, TX queue, describes the state of DIM for a specific object (RX queue, TX queue,
other queues, etc.). This includes the current selected profile, previous data other queues, etc.). This includes the current selected profile, previous data
samples, the callback function provided by the driver and more. samples, the callback function provided by the driver and more.
Struct dim_sample describes a data sample, which will be compared to the :c:type:`struct dim_sample <dim_sample>` describes a data sample,
data sample stored in struct dim in order to decide on the algorithm's next which will be compared to the data sample stored in :c:type:`struct dim <dim>`
in order to decide on the algorithm's next
step. The sample should include bytes, packets and interrupts, measured by step. The sample should include bytes, packets and interrupts, measured by
the driver. the driver.
...@@ -110,9 +105,10 @@ main net_dim() function. The recommended method is to call net_dim() on each ...@@ -110,9 +105,10 @@ main net_dim() function. The recommended method is to call net_dim() on each
interrupt. Since Net DIM has a built-in moderation and it might decide to skip interrupt. Since Net DIM has a built-in moderation and it might decide to skip
iterations under certain conditions, there is no need to moderate the net_dim() iterations under certain conditions, there is no need to moderate the net_dim()
calls as well. As mentioned above, the driver needs to provide an object of type calls as well. As mentioned above, the driver needs to provide an object of type
struct dim to the net_dim() function call. It is advised for each entity :c:type:`struct dim <dim>` to the net_dim() function call. It is advised for
using Net DIM to hold a struct dim as part of its data structure and use it each entity using Net DIM to hold a :c:type:`struct dim <dim>` as part of its
as the main Net DIM API object. The struct dim_sample should hold the latest data structure and use it as the main Net DIM API object.
The :c:type:`struct dim_sample <dim_sample>` should hold the latest
bytes, packets and interrupts count. No need to perform any calculations, just bytes, packets and interrupts count. No need to perform any calculations, just
include the raw data. include the raw data.
...@@ -124,19 +120,19 @@ the data flow. After the work is done, Net DIM algorithm needs to be set to ...@@ -124,19 +120,19 @@ the data flow. After the work is done, Net DIM algorithm needs to be set to
the proper state in order to move to the next iteration. the proper state in order to move to the next iteration.
Part IV: Example Example
================= =======
The following code demonstrates how to register a driver to Net DIM. The actual The following code demonstrates how to register a driver to Net DIM. The actual
usage is not complete but it should make the outline of the usage clear. usage is not complete but it should make the outline of the usage clear.
my_driver.c: .. code-block:: c
#include <linux/dim.h> #include <linux/dim.h>
/* Callback for net DIM to schedule on a decision to change moderation */ /* Callback for net DIM to schedule on a decision to change moderation */
void my_driver_do_dim_work(struct work_struct *work) void my_driver_do_dim_work(struct work_struct *work)
{ {
/* Get struct dim from struct work_struct */ /* Get struct dim from struct work_struct */
struct dim *dim = container_of(work, struct dim, struct dim *dim = container_of(work, struct dim,
work); work);
...@@ -145,11 +141,11 @@ void my_driver_do_dim_work(struct work_struct *work) ...@@ -145,11 +141,11 @@ void my_driver_do_dim_work(struct work_struct *work)
/* Signal net DIM work is done and it should move to next iteration */ /* Signal net DIM work is done and it should move to next iteration */
dim->state = DIM_START_MEASURE; dim->state = DIM_START_MEASURE;
} }
/* My driver's interrupt handler */ /* My driver's interrupt handler */
int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...) int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...)
{ {
... ...
/* A struct to hold current measured data */ /* A struct to hold current measured data */
struct dim_sample dim_sample; struct dim_sample dim_sample;
...@@ -162,13 +158,13 @@ int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...) ...@@ -162,13 +158,13 @@ int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...)
/* Call net DIM */ /* Call net DIM */
net_dim(&my_entity->dim, dim_sample); net_dim(&my_entity->dim, dim_sample);
... ...
} }
/* My entity's initialization function (my_entity was already allocated) */ /* My entity's initialization function (my_entity was already allocated) */
int my_driver_init_my_entity(struct my_driver_entity *my_entity, ...) int my_driver_init_my_entity(struct my_driver_entity *my_entity, ...)
{ {
... ...
/* Initiate struct work_struct with my driver's callback function */ /* Initiate struct work_struct with my driver's callback function */
INIT_WORK(&my_entity->dim.work, my_driver_do_dim_work); INIT_WORK(&my_entity->dim.work, my_driver_do_dim_work);
... ...
} }
...@@ -5961,6 +5961,7 @@ M: Tal Gilboa <talgi@mellanox.com> ...@@ -5961,6 +5961,7 @@ M: Tal Gilboa <talgi@mellanox.com>
S: Maintained S: Maintained
F: include/linux/dim.h F: include/linux/dim.h
F: lib/dim/ F: lib/dim/
F: Documentation/networking/net_dim.rst
DZ DECSTATION DZ11 SERIAL DRIVER DZ DECSTATION DZ11 SERIAL DRIVER
M: "Maciej W. Rozycki" <macro@linux-mips.org> M: "Maciej W. Rozycki" <macro@linux-mips.org>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment