netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next V2] Documentation/networking: Add net DIM documentation
@ 2018-03-21 18:33 Tal Gilboa
  2018-03-21 19:23 ` Marcelo Ricardo Leitner
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Tal Gilboa @ 2018-03-21 18:33 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Tariq Toukan, Tal Gilboa

Net DIM is a generic algorithm, purposed for dynamically
optimizing network devices interrupt moderation. This
document describes how it works and how to use it.

Signed-off-by: Tal Gilboa <talgi@mellanox.com>
---
 Documentation/networking/net_dim.txt | 174 +++++++++++++++++++++++++++++++++++
 1 file changed, 174 insertions(+)
 create mode 100644 Documentation/networking/net_dim.txt

diff --git a/Documentation/networking/net_dim.txt b/Documentation/networking/net_dim.txt
new file mode 100644
index 0000000..9cb31c5
--- /dev/null
+++ b/Documentation/networking/net_dim.txt
@@ -0,0 +1,174 @@
+Net DIM - Generic Network Dynamic Interrupt Moderation
+======================================================
+
+Author:
+	Tal Gilboa <talgi@mellanox.com>
+
+
+Contents
+=========
+
+- Assumptions
+- Introduction
+- The Net DIM Algorithm
+- Registering a Network Device to DIM
+- Example
+
+Part 0: Assumptions
+======================
+
+This document assumes the reader has basic knowledge in network drivers
+and in general interrupt moderation.
+
+
+Part I: Introduction
+======================
+
+Dynamic Interrupt Moderation (DIM) (in networking) refers to changing the
+interrupt moderation configuration of a channel in order to optimize packet
+processing. The mechanism includes an algorithm which decides if and how to
+change moderation parameters for a channel, usually by performing an analysis on
+runtime data sampled from the system. Net DIM is such a mechanism. In each
+iteration of the algorithm, it analyses a given sample of the data, compares it
+to the previous sample and if required, it can decide to change some of the
+interrupt moderation configuration fields. The data sample is composed of data
+bandwidth, the number of packets and the number of events. The time between
+samples is also measured. Net DIM compares the current and the previous data and
+returns an adjusted interrupt moderation configuration object. In some cases,
+the algorithm might decide not to change anything. The configuration fields are
+the minimum duration (microseconds) allowed between events and the maximum
+number of wanted packets per event. The Net DIM algorithm ascribes importance to
+increase bandwidth over reducing interrupt rate.
+
+
+Part II: The Net DIM Algorithm
+===============================
+
+Each iteration of the Net DIM algorithm follows these steps:
+1. Calculates new data sample.
+2. Compares it to previous sample.
+3. Makes a decision - suggests interrupt moderation configuration fields.
+4. Applies a schedule work function, which applies suggested configuration.
+
+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 to the previous iteration. The comparison step checks the difference
+between the new and previous data and decides on the result of the last step.
+A step would result as "better" if bandwidth increases and as "worse" if
+bandwidth reduces. If there is no change in bandwidth, the packet rate is
+compared in a similar fashion - increase == "better" and decrease == "worse".
+In case there is no change in the packet rate as well, the interrupt rate is
+compared. Here the algorithm tries to optimize for lower interrupt rate so an
+increase in the interrupt rate is considered "worse" and a decrease is
+considered "better". Step #2 has an optimization for avoiding false results: it
+only considers a difference between samples as valid if it is greater than a
+certain percentage. Also, since Net DIM does not measure anything by itself, it
+assumes the data provided by the driver is valid.
+
+Step #3 decides on the suggested configuration based on the result from step #2
+and the internal state of the algorithm. The states reflect the "direction" of
+the algorithm: is it going left (reducing moderation), right (increasing
+moderation) or standing still. Another optimization is that if a decision
+to stay still is made multiple times, the interval between iterations of the
+algorithm would increase in order to reduce calculation overhead. Also, after
+"parking" on one of the most left or most right decisions, the algorithm may
+decide to verify this decision by taking a step in the other direction. This is
+done in order to avoid getting stuck in a "deep sleep" scenario. Once a
+decision is made, an interrupt moderation configuration is selected from
+the predefined profiles.
+
+The last step is to notify the registered driver that it should apply the
+suggested configuration. This is done by scheduling a work function, defined by
+the Net DIM API and provided by the registered driver.
+
+As you can see, Net DIM itself does not actively interact with the system. It
+would have trouble making the correct decisions if the wrong data is supplied to
+it and it would be useless if the work function would not apply the suggested
+configuration. This does, however, allow the registered driver some room for
+manoeuvre as it may provide partial data or ignore the algorithm suggestion
+under some conditions.
+
+
+Part III: Registering a Network Device to DIM
+==============================================
+
+Net DIM API exposes the main function net_dim(struct net_dim *dim,
+struct net_dim_sample end_sample). 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
+it should change interrupt moderation parameters. The driver should provide two
+data structures: struct net_dim and struct net_dim_sample. Struct net_dim
+describes the state of DIM for a specific object (RX queue, TX queue,
+other queues, etc.). This includes the current selected profile, previous data
+samples, the callback function provided by the driver and more.
+Struct net_dim_sample describes a data sample, which will be compared to the
+data sample stored in struct net_dim in order to decide on the algorithm's next
+step. The sample should include bytes, packets and interrupts, measured by
+the driver.
+
+In order to use Net DIM from a networking driver, the driver needs to call the
+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
+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
+struct net_dim to the net_dim() function call. It is advised for each entity
+using Net DIM to hold a struct net_dim as part of its data structure and use it
+as the main Net DIM API object. The struct net_dim_sample should hold the latest
+bytes, packets and interrupts count. No need to perform any calculations, just
+include the raw data.
+
+The net_dim() call itself does not return anything. Instead Net DIM relies on
+the driver to provide a callback function, which is called when the algorithm
+decides to make a change in the interrupt moderation parameters. This callback
+will be scheduled and run in a separate thread in order not to add overhead to
+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.
+
+
+Part IV: Example
+=================
+
+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.
+
+my_driver.c:
+
+#include <linux/net_dim.h>
+
+/* Callback for net DIM to schedule on a decision to change moderation */
+void my_driver_do_dim_work(struct work_struct *work)
+{
+	/* Get struct net_dim from struct work_struct */
+	struct net_dim *dim = container_of(work, struct net_dim,
+					   work);
+	/* Do interrupt moderation related stuff */
+	...
+
+	/* Signal net DIM work is done and it should move to next iteration */
+	dim->state = NET_DIM_START_MEASURE;
+}
+
+/* My driver's interrupt handler */
+int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...)
+{
+	...
+	/* A struct to hold current measured data */
+	struct net_dim_sample dim_sample;
+	...
+	/* Initiate data sample struct with current data */
+	net_dim_sample(my_entity->events,
+		       my_entity->packets,
+		       my_entity->bytes,
+		       &dim_sample);
+	/* Call net DIM */
+	net_dim(&my_entity->dim, dim_sample);
+	...
+}
+
+/* My entity's initialization function (my_entity was already allocated) */
+int my_driver_init_my_entity(struct my_driver_entity *my_entity, ...)
+{
+	...
+	/* Initiate struct work_struct with my driver's callback function */
+	INIT_WORK(&my_entity->dim.work, my_driver_do_dim_work);
+	...
+}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next V2] Documentation/networking: Add net DIM documentation
  2018-03-21 18:33 [PATCH net-next V2] Documentation/networking: Add net DIM documentation Tal Gilboa
@ 2018-03-21 19:23 ` Marcelo Ricardo Leitner
  2018-03-21 19:33 ` Florian Fainelli
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Marcelo Ricardo Leitner @ 2018-03-21 19:23 UTC (permalink / raw)
  To: Tal Gilboa; +Cc: David S. Miller, netdev, Tariq Toukan

On Wed, Mar 21, 2018 at 08:33:45PM +0200, Tal Gilboa wrote:
> Net DIM is a generic algorithm, purposed for dynamically
> optimizing network devices interrupt moderation. This
> document describes how it works and how to use it.
> 
> Signed-off-by: Tal Gilboa <talgi@mellanox.com>
> ---
>  Documentation/networking/net_dim.txt | 174 +++++++++++++++++++++++++++++++++++
>  1 file changed, 174 insertions(+)
>  create mode 100644 Documentation/networking/net_dim.txt
> 
> diff --git a/Documentation/networking/net_dim.txt b/Documentation/networking/net_dim.txt
> new file mode 100644
> index 0000000..9cb31c5
> --- /dev/null
> +++ b/Documentation/networking/net_dim.txt
> @@ -0,0 +1,174 @@
> +Net DIM - Generic Network Dynamic Interrupt Moderation
> +======================================================
> +
> +Author:
> +	Tal Gilboa <talgi@mellanox.com>
> +
> +
> +Contents
> +=========
> +
> +- Assumptions
> +- Introduction
> +- The Net DIM Algorithm
> +- Registering a Network Device to DIM
> +- Example
> +
> +Part 0: Assumptions
> +======================
> +
> +This document assumes the reader has basic knowledge in network drivers
> +and in general interrupt moderation.
> +
> +
> +Part I: Introduction
> +======================
> +
> +Dynamic Interrupt Moderation (DIM) (in networking) refers to changing the
> +interrupt moderation configuration of a channel in order to optimize packet
> +processing. The mechanism includes an algorithm which decides if and how to
> +change moderation parameters for a channel, usually by performing an analysis on
> +runtime data sampled from the system. Net DIM is such a mechanism. In each
> +iteration of the algorithm, it analyses a given sample of the data, compares it
> +to the previous sample and if required, it can decide to change some of the
> +interrupt moderation configuration fields. The data sample is composed of data
> +bandwidth, the number of packets and the number of events. The time between
> +samples is also measured. Net DIM compares the current and the previous data and
> +returns an adjusted interrupt moderation configuration object. In some cases,
> +the algorithm might decide not to change anything. The configuration fields are
> +the minimum duration (microseconds) allowed between events and the maximum
> +number of wanted packets per event. The Net DIM algorithm ascribes importance to
> +increase bandwidth over reducing interrupt rate.
> +
> +
> +Part II: The Net DIM Algorithm
> +===============================
> +
> +Each iteration of the Net DIM algorithm follows these steps:
> +1. Calculates new data sample.
> +2. Compares it to previous sample.
> +3. Makes a decision - suggests interrupt moderation configuration fields.
> +4. Applies a schedule work function, which applies suggested configuration.
> +
> +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 to the previous iteration. The comparison step checks the difference
> +between the new and previous data and decides on the result of the last step.
> +A step would result as "better" if bandwidth increases and as "worse" if
> +bandwidth reduces. If there is no change in bandwidth, the packet rate is
> +compared in a similar fashion - increase == "better" and decrease == "worse".
> +In case there is no change in the packet rate as well, the interrupt rate is
> +compared. Here the algorithm tries to optimize for lower interrupt rate so an
> +increase in the interrupt rate is considered "worse" and a decrease is
> +considered "better". Step #2 has an optimization for avoiding false results: it
> +only considers a difference between samples as valid if it is greater than a
> +certain percentage. Also, since Net DIM does not measure anything by itself, it
> +assumes the data provided by the driver is valid.
> +
> +Step #3 decides on the suggested configuration based on the result from step #2
> +and the internal state of the algorithm. The states reflect the "direction" of
> +the algorithm: is it going left (reducing moderation), right (increasing
> +moderation) or standing still. Another optimization is that if a decision
> +to stay still is made multiple times, the interval between iterations of the
> +algorithm would increase in order to reduce calculation overhead. Also, after

I wonder if this increased interval can lead to packet drops due to
some impulse? Like, the card is receiving a low volume of packets and
suddenly a new flow starts at line rate, for example. If the max
interval is not too aggressive, this would't be a problem.

(sorry, I didn't read much of the implementation nor the drivers
already using it)

> +"parking" on one of the most left or most right decisions, the algorithm may
> +decide to verify this decision by taking a step in the other direction. This is
> +done in order to avoid getting stuck in a "deep sleep" scenario. Once a
> +decision is made, an interrupt moderation configuration is selected from
> +the predefined profiles.
> +
> +The last step is to notify the registered driver that it should apply the
> +suggested configuration. This is done by scheduling a work function, defined by
> +the Net DIM API and provided by the registered driver.
> +
> +As you can see, Net DIM itself does not actively interact with the system. It
> +would have trouble making the correct decisions if the wrong data is supplied to
> +it and it would be useless if the work function would not apply the suggested
> +configuration. This does, however, allow the registered driver some room for
> +manoeuvre as it may provide partial data or ignore the algorithm suggestion
> +under some conditions.
> +
> +
> +Part III: Registering a Network Device to DIM
> +==============================================
> +
> +Net DIM API exposes the main function net_dim(struct net_dim *dim,
> +struct net_dim_sample end_sample). 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
> +it should change interrupt moderation parameters. The driver should provide two
> +data structures: struct net_dim and struct net_dim_sample. Struct net_dim
> +describes the state of DIM for a specific object (RX queue, TX queue,
> +other queues, etc.). This includes the current selected profile, previous data
> +samples, the callback function provided by the driver and more.
> +Struct net_dim_sample describes a data sample, which will be compared to the
> +data sample stored in struct net_dim in order to decide on the algorithm's next
> +step. The sample should include bytes, packets and interrupts, measured by
> +the driver.
> +
> +In order to use Net DIM from a networking driver, the driver needs to call the
> +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
> +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
> +struct net_dim to the net_dim() function call. It is advised for each entity
> +using Net DIM to hold a struct net_dim as part of its data structure and use it
> +as the main Net DIM API object. The struct net_dim_sample should hold the latest
> +bytes, packets and interrupts count. No need to perform any calculations, just
> +include the raw data.
> +
> +The net_dim() call itself does not return anything. Instead Net DIM relies on
> +the driver to provide a callback function, which is called when the algorithm
> +decides to make a change in the interrupt moderation parameters. This callback
> +will be scheduled and run in a separate thread in order not to add overhead to
> +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.
> +
> +
> +Part IV: Example
> +=================
> +
> +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.
> +
> +my_driver.c:
> +
> +#include <linux/net_dim.h>
> +
> +/* Callback for net DIM to schedule on a decision to change moderation */
> +void my_driver_do_dim_work(struct work_struct *work)
> +{
> +	/* Get struct net_dim from struct work_struct */
> +	struct net_dim *dim = container_of(work, struct net_dim,
> +					   work);
> +	/* Do interrupt moderation related stuff */
> +	...
> +
> +	/* Signal net DIM work is done and it should move to next iteration */
> +	dim->state = NET_DIM_START_MEASURE;

Doesn't this need some sort of order guarantee? This assignment cannot
happen before the complete usage of 'dim' struct, otherwise the
interrupt handler may overwrite stuff that is still being read.

Or maybe this 2-steps to measure handles it? (START_MEASURE ->
MEASURE_IN_PROGRESS) As it will only overwrite something in the next
irq, it wouldn't be able to race the workqueue. As work-queues can be
preempted, this doesn't seem enough.

> +}
> +
> +/* My driver's interrupt handler */
> +int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...)
> +{
> +	...
> +	/* A struct to hold current measured data */
> +	struct net_dim_sample dim_sample;
> +	...
> +	/* Initiate data sample struct with current data */
> +	net_dim_sample(my_entity->events,
> +		       my_entity->packets,
> +		       my_entity->bytes,
> +		       &dim_sample);
> +	/* Call net DIM */
> +	net_dim(&my_entity->dim, dim_sample);
> +	...
> +}
> +
> +/* My entity's initialization function (my_entity was already allocated) */
> +int my_driver_init_my_entity(struct my_driver_entity *my_entity, ...)
> +{
> +	...
> +	/* Initiate struct work_struct with my driver's callback function */
> +	INIT_WORK(&my_entity->dim.work, my_driver_do_dim_work);
> +	...
> +}
> -- 
> 1.8.3.1
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next V2] Documentation/networking: Add net DIM documentation
  2018-03-21 18:33 [PATCH net-next V2] Documentation/networking: Add net DIM documentation Tal Gilboa
  2018-03-21 19:23 ` Marcelo Ricardo Leitner
@ 2018-03-21 19:33 ` Florian Fainelli
  2018-03-21 19:37 ` Randy Dunlap
  2018-03-22 18:51 ` David Miller
  3 siblings, 0 replies; 8+ messages in thread
From: Florian Fainelli @ 2018-03-21 19:33 UTC (permalink / raw)
  To: Tal Gilboa, David S. Miller; +Cc: netdev, Tariq Toukan

Hi Tal,

On 03/21/2018 11:33 AM, Tal Gilboa wrote:
> Net DIM is a generic algorithm, purposed for dynamically
> optimizing network devices interrupt moderation. This
> document describes how it works and how to use it.

Thanks a lot for providing this documentation, this is very helpful! A
few things that could be good to be expanded upon a little bit:

- HW must support configuring a timeout per channel
- HW must support configuring a number of packets before getting an
interrupt per channel

Does that sound about right?

[snip]

> +In order to use Net DIM from a networking driver, the driver needs to call the
> +main net_dim() function. The recommended method is to call net_dim() on each
> +interrupt.

I would make it a bit clearer that this is on each invocation of the
interrupt service routine function. With NAPI + net DIM working in
concert you would not actually get one packet per interrupt
consistently, it would largely depend on the rate, right?

> 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()
> +calls as well. As mentioned above, the driver needs to provide an object of type
> +struct net_dim to the net_dim() function call. It is advised for each entity
> +using Net DIM to hold a struct net_dim as part of its data structure and use it
> +as the main Net DIM API object. The struct net_dim_sample should hold the latest
> +bytes, packets and interrupts count. No need to perform any calculations, just
> +include the raw data.
> +
> +The net_dim() call itself does not return anything. Instead Net DIM relies on
> +the driver to provide a callback function, which is called when the algorithm
> +decides to make a change in the interrupt moderation parameters. This callback
> +will be scheduled and run in a separate thread in order not to add overhead to
> +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.
> +
> +
> +Part IV: Example
> +=================
> +
> +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.

It could be worth to touch a word or two about reflecting the use of Net
DIM within the driver into ethtool_coalesce::use_adaptive_rx_coalesce
and ethtool_coalesce::use_adaptive_tx_coalesce?

> +
> +my_driver.c:
> +
> +#include <linux/net_dim.h>
> +
> +/* Callback for net DIM to schedule on a decision to change moderation */
> +void my_driver_do_dim_work(struct work_struct *work)
> +{
> +	/* Get struct net_dim from struct work_struct */
> +	struct net_dim *dim = container_of(work, struct net_dim,
> +					   work);
> +	/* Do interrupt moderation related stuff */
> +	...
> +
> +	/* Signal net DIM work is done and it should move to next iteration */
> +	dim->state = NET_DIM_START_MEASURE;
> +}
> +
> +/* My driver's interrupt handler */
> +int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...)
> +{
> +	...
> +	/* A struct to hold current measured data */
> +	struct net_dim_sample dim_sample;
> +	...
> +	/* Initiate data sample struct with current data */
> +	net_dim_sample(my_entity->events,
> +		       my_entity->packets,
> +		       my_entity->bytes,
> +		       &dim_sample);
> +	/* Call net DIM */
> +	net_dim(&my_entity->dim, dim_sample);
> +	...
> +}
> +
> +/* My entity's initialization function (my_entity was already allocated) */
> +int my_driver_init_my_entity(struct my_driver_entity *my_entity, ...)
> +{
> +	...
> +	/* Initiate struct work_struct with my driver's callback function */
> +	INIT_WORK(&my_entity->dim.work, my_driver_do_dim_work);
> +	...
> +}
> 


-- 
Florian

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next V2] Documentation/networking: Add net DIM documentation
  2018-03-21 18:33 [PATCH net-next V2] Documentation/networking: Add net DIM documentation Tal Gilboa
  2018-03-21 19:23 ` Marcelo Ricardo Leitner
  2018-03-21 19:33 ` Florian Fainelli
@ 2018-03-21 19:37 ` Randy Dunlap
  2018-03-21 19:44   ` Florian Fainelli
  2018-03-22 18:51 ` David Miller
  3 siblings, 1 reply; 8+ messages in thread
From: Randy Dunlap @ 2018-03-21 19:37 UTC (permalink / raw)
  To: Tal Gilboa, David S. Miller; +Cc: netdev, Tariq Toukan

On 03/21/2018 11:33 AM, Tal Gilboa wrote:
> Net DIM is a generic algorithm, purposed for dynamically
> optimizing network devices interrupt moderation. This
> document describes how it works and how to use it.
> 
> Signed-off-by: Tal Gilboa <talgi@mellanox.com>
> ---
>  Documentation/networking/net_dim.txt | 174 +++++++++++++++++++++++++++++++++++
>  1 file changed, 174 insertions(+)
>  create mode 100644 Documentation/networking/net_dim.txt
> 
> diff --git a/Documentation/networking/net_dim.txt b/Documentation/networking/net_dim.txt
> new file mode 100644
> index 0000000..9cb31c5
> --- /dev/null
> +++ b/Documentation/networking/net_dim.txt
> @@ -0,0 +1,174 @@
> +Net DIM - Generic Network Dynamic Interrupt Moderation
> +======================================================
> +
> +Author:
> +	Tal Gilboa <talgi@mellanox.com>
> +
> +
> +Contents
> +=========
> +
> +- Assumptions
> +- Introduction
> +- The Net DIM Algorithm
> +- Registering a Network Device to DIM
> +- Example
> +
> +Part 0: Assumptions
> +======================
> +
> +This document assumes the reader has basic knowledge in network drivers
> +and in general interrupt moderation.
> +
> +
> +Part I: Introduction
> +======================
> +
> +Dynamic Interrupt Moderation (DIM) (in networking) refers to changing the
> +interrupt moderation configuration of a channel in order to optimize packet
> +processing. The mechanism includes an algorithm which decides if and how to
> +change moderation parameters for a channel, usually by performing an analysis on
> +runtime data sampled from the system. Net DIM is such a mechanism. In each
> +iteration of the algorithm, it analyses a given sample of the data, compares it
> +to the previous sample and if required, it can decide to change some of the
> +interrupt moderation configuration fields. The data sample is composed of data
> +bandwidth, the number of packets and the number of events. The time between
> +samples is also measured. Net DIM compares the current and the previous data and
> +returns an adjusted interrupt moderation configuration object. In some cases,
> +the algorithm might decide not to change anything. The configuration fields are
> +the minimum duration (microseconds) allowed between events and the maximum
> +number of wanted packets per event. The Net DIM algorithm ascribes importance to
> +increase bandwidth over reducing interrupt rate.
> +
> +
> +Part II: The Net DIM Algorithm
> +===============================
> +
> +Each iteration of the Net DIM algorithm follows these steps:
> +1. Calculates new data sample.
> +2. Compares it to previous sample.
> +3. Makes a decision - suggests interrupt moderation configuration fields.
> +4. Applies a schedule work function, which applies suggested configuration.
> +
> +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 to the previous iteration. The comparison step checks the difference
> +between the new and previous data and decides on the result of the last step.
> +A step would result as "better" if bandwidth increases and as "worse" if
> +bandwidth reduces. If there is no change in bandwidth, the packet rate is
> +compared in a similar fashion - increase == "better" and decrease == "worse".
> +In case there is no change in the packet rate as well, the interrupt rate is
> +compared. Here the algorithm tries to optimize for lower interrupt rate so an
> +increase in the interrupt rate is considered "worse" and a decrease is
> +considered "better". Step #2 has an optimization for avoiding false results: it
> +only considers a difference between samples as valid if it is greater than a
> +certain percentage. Also, since Net DIM does not measure anything by itself, it
> +assumes the data provided by the driver is valid.
> +
> +Step #3 decides on the suggested configuration based on the result from step #2
> +and the internal state of the algorithm. The states reflect the "direction" of
> +the algorithm: is it going left (reducing moderation), right (increasing
> +moderation) or standing still. Another optimization is that if a decision
> +to stay still is made multiple times, the interval between iterations of the
> +algorithm would increase in order to reduce calculation overhead. Also, after
> +"parking" on one of the most left or most right decisions, the algorithm may
> +decide to verify this decision by taking a step in the other direction. This is
> +done in order to avoid getting stuck in a "deep sleep" scenario. Once a
> +decision is made, an interrupt moderation configuration is selected from
> +the predefined profiles.

I think a short description of the predefined profiles could help.

> +
> +The last step is to notify the registered driver that it should apply the
> +suggested configuration. This is done by scheduling a work function, defined by
> +the Net DIM API and provided by the registered driver.
> +
> +As you can see, Net DIM itself does not actively interact with the system. It
> +would have trouble making the correct decisions if the wrong data is supplied to
> +it and it would be useless if the work function would not apply the suggested
> +configuration. This does, however, allow the registered driver some room for
> +manoeuvre as it may provide partial data or ignore the algorithm suggestion
> +under some conditions.
> +
> +
> +Part III: Registering a Network Device to DIM
> +==============================================
> +
> +Net DIM API exposes the main function net_dim(struct net_dim *dim,
> +struct net_dim_sample end_sample). 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
> +it should change interrupt moderation parameters. The driver should provide two

Is it completely up to the driver to decide when to call net_dim()?
So it could be based on TX traffic, RX traffic, time, queue depths, etc.?

> +data structures: struct net_dim and struct net_dim_sample. Struct net_dim
> +describes the state of DIM for a specific object (RX queue, TX queue,
> +other queues, etc.). This includes the current selected profile, previous data
> +samples, the callback function provided by the driver and more.
> +Struct net_dim_sample describes a data sample, which will be compared to the
> +data sample stored in struct net_dim in order to decide on the algorithm's next
> +step. The sample should include bytes, packets and interrupts, measured by
> +the driver.
> +
> +In order to use Net DIM from a networking driver, the driver needs to call the
> +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

(continuing my question from above:)
or on each interrupt.  But the hardware could also be doing interrupt mitigation,
so each interrupt doesn't always correlate to anything specific.

> +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
> +struct net_dim to the net_dim() function call. It is advised for each entity
> +using Net DIM to hold a struct net_dim as part of its data structure and use it
> +as the main Net DIM API object. The struct net_dim_sample should hold the latest
> +bytes, packets and interrupts count. No need to perform any calculations, just
> +include the raw data.
> +
> +The net_dim() call itself does not return anything. Instead Net DIM relies on
> +the driver to provide a callback function, which is called when the algorithm
> +decides to make a change in the interrupt moderation parameters. This callback
> +will be scheduled and run in a separate thread in order not to add overhead to
> +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.
> +
> +
> +Part IV: Example
> +=================
> +
> +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.
> +
> +my_driver.c:
> +
> +#include <linux/net_dim.h>
> +
> +/* Callback for net DIM to schedule on a decision to change moderation */
> +void my_driver_do_dim_work(struct work_struct *work)
> +{
> +	/* Get struct net_dim from struct work_struct */
> +	struct net_dim *dim = container_of(work, struct net_dim,
> +					   work);
> +	/* Do interrupt moderation related stuff */
> +	...
> +
> +	/* Signal net DIM work is done and it should move to next iteration */
> +	dim->state = NET_DIM_START_MEASURE;
> +}
> +
> +/* My driver's interrupt handler */
> +int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...)
> +{
> +	...
> +	/* A struct to hold current measured data */
> +	struct net_dim_sample dim_sample;
> +	...
> +	/* Initiate data sample struct with current data */
> +	net_dim_sample(my_entity->events,
> +		       my_entity->packets,
> +		       my_entity->bytes,
> +		       &dim_sample);
> +	/* Call net DIM */
> +	net_dim(&my_entity->dim, dim_sample);
> +	...
> +}
> +
> +/* My entity's initialization function (my_entity was already allocated) */
> +int my_driver_init_my_entity(struct my_driver_entity *my_entity, ...)
> +{
> +	...
> +	/* Initiate struct work_struct with my driver's callback function */
> +	INIT_WORK(&my_entity->dim.work, my_driver_do_dim_work);
> +	...
> +}
> 

Reviewed-by: Randy Dunlap <rdunlap@infradead.org>

thanks,
-- 
~Randy

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next V2] Documentation/networking: Add net DIM documentation
  2018-03-21 19:37 ` Randy Dunlap
@ 2018-03-21 19:44   ` Florian Fainelli
  2018-03-21 20:30     ` Marcelo Ricardo Leitner
  0 siblings, 1 reply; 8+ messages in thread
From: Florian Fainelli @ 2018-03-21 19:44 UTC (permalink / raw)
  To: Randy Dunlap, Tal Gilboa, David S. Miller; +Cc: netdev, Tariq Toukan

On 03/21/2018 12:37 PM, Randy Dunlap wrote:
> On 03/21/2018 11:33 AM, Tal Gilboa wrote:
>> Net DIM is a generic algorithm, purposed for dynamically
>> optimizing network devices interrupt moderation. This
>> document describes how it works and how to use it.
>>
>> Signed-off-by: Tal Gilboa <talgi@mellanox.com>
>> ---
>>  Documentation/networking/net_dim.txt | 174 +++++++++++++++++++++++++++++++++++
>>  1 file changed, 174 insertions(+)
>>  create mode 100644 Documentation/networking/net_dim.txt
>>
>> diff --git a/Documentation/networking/net_dim.txt b/Documentation/networking/net_dim.txt
>> new file mode 100644
>> index 0000000..9cb31c5
>> --- /dev/null
>> +++ b/Documentation/networking/net_dim.txt
>> @@ -0,0 +1,174 @@
>> +Net DIM - Generic Network Dynamic Interrupt Moderation
>> +======================================================
>> +
>> +Author:
>> +	Tal Gilboa <talgi@mellanox.com>
>> +
>> +
>> +Contents
>> +=========
>> +
>> +- Assumptions
>> +- Introduction
>> +- The Net DIM Algorithm
>> +- Registering a Network Device to DIM
>> +- Example
>> +
>> +Part 0: Assumptions
>> +======================
>> +
>> +This document assumes the reader has basic knowledge in network drivers
>> +and in general interrupt moderation.
>> +
>> +
>> +Part I: Introduction
>> +======================
>> +
>> +Dynamic Interrupt Moderation (DIM) (in networking) refers to changing the
>> +interrupt moderation configuration of a channel in order to optimize packet
>> +processing. The mechanism includes an algorithm which decides if and how to
>> +change moderation parameters for a channel, usually by performing an analysis on
>> +runtime data sampled from the system. Net DIM is such a mechanism. In each
>> +iteration of the algorithm, it analyses a given sample of the data, compares it
>> +to the previous sample and if required, it can decide to change some of the
>> +interrupt moderation configuration fields. The data sample is composed of data
>> +bandwidth, the number of packets and the number of events. The time between
>> +samples is also measured. Net DIM compares the current and the previous data and
>> +returns an adjusted interrupt moderation configuration object. In some cases,
>> +the algorithm might decide not to change anything. The configuration fields are
>> +the minimum duration (microseconds) allowed between events and the maximum
>> +number of wanted packets per event. The Net DIM algorithm ascribes importance to
>> +increase bandwidth over reducing interrupt rate.
>> +
>> +
>> +Part II: The Net DIM Algorithm
>> +===============================
>> +
>> +Each iteration of the Net DIM algorithm follows these steps:
>> +1. Calculates new data sample.
>> +2. Compares it to previous sample.
>> +3. Makes a decision - suggests interrupt moderation configuration fields.
>> +4. Applies a schedule work function, which applies suggested configuration.
>> +
>> +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 to the previous iteration. The comparison step checks the difference
>> +between the new and previous data and decides on the result of the last step.
>> +A step would result as "better" if bandwidth increases and as "worse" if
>> +bandwidth reduces. If there is no change in bandwidth, the packet rate is
>> +compared in a similar fashion - increase == "better" and decrease == "worse".
>> +In case there is no change in the packet rate as well, the interrupt rate is
>> +compared. Here the algorithm tries to optimize for lower interrupt rate so an
>> +increase in the interrupt rate is considered "worse" and a decrease is
>> +considered "better". Step #2 has an optimization for avoiding false results: it
>> +only considers a difference between samples as valid if it is greater than a
>> +certain percentage. Also, since Net DIM does not measure anything by itself, it
>> +assumes the data provided by the driver is valid.
>> +
>> +Step #3 decides on the suggested configuration based on the result from step #2
>> +and the internal state of the algorithm. The states reflect the "direction" of
>> +the algorithm: is it going left (reducing moderation), right (increasing
>> +moderation) or standing still. Another optimization is that if a decision
>> +to stay still is made multiple times, the interval between iterations of the
>> +algorithm would increase in order to reduce calculation overhead. Also, after
>> +"parking" on one of the most left or most right decisions, the algorithm may
>> +decide to verify this decision by taking a step in the other direction. This is
>> +done in order to avoid getting stuck in a "deep sleep" scenario. Once a
>> +decision is made, an interrupt moderation configuration is selected from
>> +the predefined profiles.
> 
> I think a short description of the predefined profiles could help.

Agreed it would help if the different modes
(NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE,
NET_DIM_CQ_PERIOD_MODE_START_FROM_CQE) were expanded a bit further. The
whole term QE sounds very much Ethernet converged adapter to me...

> 
>> +
>> +The last step is to notify the registered driver that it should apply the
>> +suggested configuration. This is done by scheduling a work function, defined by
>> +the Net DIM API and provided by the registered driver.
>> +
>> +As you can see, Net DIM itself does not actively interact with the system. It
>> +would have trouble making the correct decisions if the wrong data is supplied to
>> +it and it would be useless if the work function would not apply the suggested
>> +configuration. This does, however, allow the registered driver some room for
>> +manoeuvre as it may provide partial data or ignore the algorithm suggestion
>> +under some conditions.
>> +
>> +
>> +Part III: Registering a Network Device to DIM
>> +==============================================
>> +
>> +Net DIM API exposes the main function net_dim(struct net_dim *dim,
>> +struct net_dim_sample end_sample). 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
>> +it should change interrupt moderation parameters. The driver should provide two
> 
> Is it completely up to the driver to decide when to call net_dim()?
> So it could be based on TX traffic, RX traffic, time, queue depths, etc.?
> 
>> +data structures: struct net_dim and struct net_dim_sample. Struct net_dim
>> +describes the state of DIM for a specific object (RX queue, TX queue,
>> +other queues, etc.). This includes the current selected profile, previous data
>> +samples, the callback function provided by the driver and more.
>> +Struct net_dim_sample describes a data sample, which will be compared to the
>> +data sample stored in struct net_dim in order to decide on the algorithm's next
>> +step. The sample should include bytes, packets and interrupts, measured by
>> +the driver.
>> +
>> +In order to use Net DIM from a networking driver, the driver needs to call the
>> +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
> 
> (continuing my question from above:)
> or on each interrupt.  But the hardware could also be doing interrupt mitigation,
> so each interrupt doesn't always correlate to anything specific.
> 
>> +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
>> +struct net_dim to the net_dim() function call. It is advised for each entity
>> +using Net DIM to hold a struct net_dim as part of its data structure and use it
>> +as the main Net DIM API object. The struct net_dim_sample should hold the latest
>> +bytes, packets and interrupts count. No need to perform any calculations, just
>> +include the raw data.
>> +
>> +The net_dim() call itself does not return anything. Instead Net DIM relies on
>> +the driver to provide a callback function, which is called when the algorithm
>> +decides to make a change in the interrupt moderation parameters. This callback
>> +will be scheduled and run in a separate thread in order not to add overhead to
>> +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.
>> +
>> +
>> +Part IV: Example
>> +=================
>> +
>> +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.
>> +
>> +my_driver.c:
>> +
>> +#include <linux/net_dim.h>
>> +
>> +/* Callback for net DIM to schedule on a decision to change moderation */
>> +void my_driver_do_dim_work(struct work_struct *work)
>> +{
>> +	/* Get struct net_dim from struct work_struct */
>> +	struct net_dim *dim = container_of(work, struct net_dim,
>> +					   work);
>> +	/* Do interrupt moderation related stuff */
>> +	...
>> +
>> +	/* Signal net DIM work is done and it should move to next iteration */
>> +	dim->state = NET_DIM_START_MEASURE;
>> +}
>> +
>> +/* My driver's interrupt handler */
>> +int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...)
>> +{
>> +	...
>> +	/* A struct to hold current measured data */
>> +	struct net_dim_sample dim_sample;
>> +	...
>> +	/* Initiate data sample struct with current data */
>> +	net_dim_sample(my_entity->events,
>> +		       my_entity->packets,
>> +		       my_entity->bytes,
>> +		       &dim_sample);
>> +	/* Call net DIM */
>> +	net_dim(&my_entity->dim, dim_sample);
>> +	...
>> +}
>> +
>> +/* My entity's initialization function (my_entity was already allocated) */
>> +int my_driver_init_my_entity(struct my_driver_entity *my_entity, ...)
>> +{
>> +	...
>> +	/* Initiate struct work_struct with my driver's callback function */
>> +	INIT_WORK(&my_entity->dim.work, my_driver_do_dim_work);
>> +	...
>> +}
>>
> 
> Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
> 
> thanks,
> 


-- 
Florian

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next V2] Documentation/networking: Add net DIM documentation
  2018-03-21 19:44   ` Florian Fainelli
@ 2018-03-21 20:30     ` Marcelo Ricardo Leitner
  0 siblings, 0 replies; 8+ messages in thread
From: Marcelo Ricardo Leitner @ 2018-03-21 20:30 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Randy Dunlap, Tal Gilboa, David S. Miller, netdev, Tariq Toukan

On Wed, Mar 21, 2018 at 12:44:29PM -0700, Florian Fainelli wrote:
> On 03/21/2018 12:37 PM, Randy Dunlap wrote:
> > On 03/21/2018 11:33 AM, Tal Gilboa wrote:
> >> Net DIM is a generic algorithm, purposed for dynamically
> >> optimizing network devices interrupt moderation. This
> >> document describes how it works and how to use it.
> >>
> >> Signed-off-by: Tal Gilboa <talgi@mellanox.com>
> >> ---
> >>  Documentation/networking/net_dim.txt | 174 +++++++++++++++++++++++++++++++++++
> >>  1 file changed, 174 insertions(+)
> >>  create mode 100644 Documentation/networking/net_dim.txt
> >>
> >> diff --git a/Documentation/networking/net_dim.txt b/Documentation/networking/net_dim.txt
> >> new file mode 100644
> >> index 0000000..9cb31c5
> >> --- /dev/null
> >> +++ b/Documentation/networking/net_dim.txt
> >> @@ -0,0 +1,174 @@
> >> +Net DIM - Generic Network Dynamic Interrupt Moderation
> >> +======================================================
> >> +
> >> +Author:
> >> +	Tal Gilboa <talgi@mellanox.com>
> >> +
> >> +
> >> +Contents
> >> +=========
> >> +
> >> +- Assumptions
> >> +- Introduction
> >> +- The Net DIM Algorithm
> >> +- Registering a Network Device to DIM
> >> +- Example
> >> +
> >> +Part 0: Assumptions
> >> +======================
> >> +
> >> +This document assumes the reader has basic knowledge in network drivers
> >> +and in general interrupt moderation.
> >> +
> >> +
> >> +Part I: Introduction
> >> +======================
> >> +
> >> +Dynamic Interrupt Moderation (DIM) (in networking) refers to changing the
> >> +interrupt moderation configuration of a channel in order to optimize packet
> >> +processing. The mechanism includes an algorithm which decides if and how to
> >> +change moderation parameters for a channel, usually by performing an analysis on
> >> +runtime data sampled from the system. Net DIM is such a mechanism. In each
> >> +iteration of the algorithm, it analyses a given sample of the data, compares it
> >> +to the previous sample and if required, it can decide to change some of the
> >> +interrupt moderation configuration fields. The data sample is composed of data
> >> +bandwidth, the number of packets and the number of events. The time between
> >> +samples is also measured. Net DIM compares the current and the previous data and
> >> +returns an adjusted interrupt moderation configuration object. In some cases,
> >> +the algorithm might decide not to change anything. The configuration fields are
> >> +the minimum duration (microseconds) allowed between events and the maximum
> >> +number of wanted packets per event. The Net DIM algorithm ascribes importance to
> >> +increase bandwidth over reducing interrupt rate.
> >> +
> >> +
> >> +Part II: The Net DIM Algorithm
> >> +===============================
> >> +
> >> +Each iteration of the Net DIM algorithm follows these steps:
> >> +1. Calculates new data sample.
> >> +2. Compares it to previous sample.
> >> +3. Makes a decision - suggests interrupt moderation configuration fields.
> >> +4. Applies a schedule work function, which applies suggested configuration.
> >> +
> >> +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 to the previous iteration. The comparison step checks the difference
> >> +between the new and previous data and decides on the result of the last step.
> >> +A step would result as "better" if bandwidth increases and as "worse" if
> >> +bandwidth reduces. If there is no change in bandwidth, the packet rate is
> >> +compared in a similar fashion - increase == "better" and decrease == "worse".
> >> +In case there is no change in the packet rate as well, the interrupt rate is
> >> +compared. Here the algorithm tries to optimize for lower interrupt rate so an
> >> +increase in the interrupt rate is considered "worse" and a decrease is
> >> +considered "better". Step #2 has an optimization for avoiding false results: it
> >> +only considers a difference between samples as valid if it is greater than a
> >> +certain percentage. Also, since Net DIM does not measure anything by itself, it
> >> +assumes the data provided by the driver is valid.
> >> +
> >> +Step #3 decides on the suggested configuration based on the result from step #2
> >> +and the internal state of the algorithm. The states reflect the "direction" of
> >> +the algorithm: is it going left (reducing moderation), right (increasing
> >> +moderation) or standing still. Another optimization is that if a decision
> >> +to stay still is made multiple times, the interval between iterations of the
> >> +algorithm would increase in order to reduce calculation overhead. Also, after
> >> +"parking" on one of the most left or most right decisions, the algorithm may
> >> +decide to verify this decision by taking a step in the other direction. This is
> >> +done in order to avoid getting stuck in a "deep sleep" scenario. Once a
> >> +decision is made, an interrupt moderation configuration is selected from
> >> +the predefined profiles.
> > 
> > I think a short description of the predefined profiles could help.
> 
> Agreed it would help if the different modes
> (NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE,
> NET_DIM_CQ_PERIOD_MODE_START_FROM_CQE) were expanded a bit further. The

Speaking of these, I just had to edit the email and adjust the
alignment to notice the single letter difference between both out of
36 chars.

NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE
NET_DIM_CQ_PERIOD_MODE_START_FROM_CQE

Would be nice if the readability could be improved somehow.

> whole term QE sounds very much Ethernet converged adapter to me...
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next V2] Documentation/networking: Add net DIM documentation
  2018-03-21 18:33 [PATCH net-next V2] Documentation/networking: Add net DIM documentation Tal Gilboa
                   ` (2 preceding siblings ...)
  2018-03-21 19:37 ` Randy Dunlap
@ 2018-03-22 18:51 ` David Miller
  2018-03-26 23:28   ` Tal Gilboa
  3 siblings, 1 reply; 8+ messages in thread
From: David Miller @ 2018-03-22 18:51 UTC (permalink / raw)
  To: talgi; +Cc: netdev, tariqt

From: Tal Gilboa <talgi@mellanox.com>
Date: Wed, 21 Mar 2018 20:33:45 +0200

> Net DIM is a generic algorithm, purposed for dynamically
> optimizing network devices interrupt moderation. This
> document describes how it works and how to use it.
> 
> Signed-off-by: Tal Gilboa <talgi@mellanox.com>

Applied, although several improvements have been suggested.

Please handle that as follow-ups.

Thank you.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next V2] Documentation/networking: Add net DIM documentation
  2018-03-22 18:51 ` David Miller
@ 2018-03-26 23:28   ` Tal Gilboa
  0 siblings, 0 replies; 8+ messages in thread
From: Tal Gilboa @ 2018-03-26 23:28 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, tariqt

On 3/22/2018 8:51 PM, David Miller wrote:
> From: Tal Gilboa <talgi@mellanox.com>
> Date: Wed, 21 Mar 2018 20:33:45 +0200
> 
>> Net DIM is a generic algorithm, purposed for dynamically
>> optimizing network devices interrupt moderation. This
>> document describes how it works and how to use it.
>>
>> Signed-off-by: Tal Gilboa <talgi@mellanox.com>
> 
> Applied, although several improvements have been suggested.
> 
> Please handle that as follow-ups.
> 
> Thank you.
> 
Will do ASAP. Thanks all for the feedback.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-03-26 23:28 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-21 18:33 [PATCH net-next V2] Documentation/networking: Add net DIM documentation Tal Gilboa
2018-03-21 19:23 ` Marcelo Ricardo Leitner
2018-03-21 19:33 ` Florian Fainelli
2018-03-21 19:37 ` Randy Dunlap
2018-03-21 19:44   ` Florian Fainelli
2018-03-21 20:30     ` Marcelo Ricardo Leitner
2018-03-22 18:51 ` David Miller
2018-03-26 23:28   ` Tal Gilboa

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).