Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ef38e38 authored by Jason Gunthorpe's avatar Jason Gunthorpe
Browse files

Merge tag 'blk-dim-v2' into rdma.git for-next



Generic DIM

From: Tal Gilboa and Yamin Fridman

Implement net DIM over a generic DIM library, add RDMA DIM

dim.h lib exposes an implementation of the DIM algorithm for
dynamically-tuned interrupt moderation for networking interfaces.

We want a similar functionality for other protocols, which might need to
optimize interrupts differently. Main motivation here is DIM for NVMf
storage protocol.

Current DIM implementation prioritizes reducing interrupt overhead over
latency. Also, in order to reduce DIM's own overhead, the algorithm might
take some time to identify it needs to change profiles. While this is
acceptable for networking, it might not work well on other scenarios.

Here we propose a new structure to DIM. The idea is to allow a slightly
modified functionality without the risk of breaking Net DIM behavior for
netdev. We verified there are no degradations in current DIM behavior with
the modified solution.

Suggested solution:
- Common logic is implemented in lib/dim/dim.c
- Net DIM (existing) logic is implemented in lib/dim/net_dim.c, which uses
  the common logic in dim.c
- Any new DIM logic will be implemented in "lib/dim/new_dim.c".
  This new implementation will expose modified versions of profiles,
  dim_step() and dim_decision().
- DIM API is declared in include/linux/dim.h for all implementations.

Pros for this solution are:
- Zero impact on existing net_dim implementation and usage
- Relatively more code reuse (compared to two separate solutions)
- Increased extensibility

Required for dependencies in the next series.

Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parents 89705e92 398c2b05
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -5600,7 +5600,8 @@ F: include/linux/dynamic_debug.h
DYNAMIC INTERRUPT MODERATION
DYNAMIC INTERRUPT MODERATION
M:	Tal Gilboa <talgi@mellanox.com>
M:	Tal Gilboa <talgi@mellanox.com>
S:	Maintained
S:	Maintained
F:	include/linux/net_dim.h
F:	include/linux/dim.h
F:	lib/dim/


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>
+1 −0
Original line number Original line Diff line number Diff line
@@ -8,6 +8,7 @@ config NET_VENDOR_BROADCOM
	default y
	default y
	depends on (SSB_POSSIBLE && HAS_DMA) || PCI || BCM63XX || \
	depends on (SSB_POSSIBLE && HAS_DMA) || PCI || BCM63XX || \
		   SIBYTE_SB1xxx_SOC
		   SIBYTE_SB1xxx_SOC
	select DIMLIB
	---help---
	---help---
	  If you have a network (Ethernet) chipset belonging to this class,
	  If you have a network (Ethernet) chipset belonging to this class,
	  say Y.
	  say Y.
+10 −10
Original line number Original line Diff line number Diff line
@@ -609,7 +609,7 @@ static int bcm_sysport_set_coalesce(struct net_device *dev,
				    struct ethtool_coalesce *ec)
				    struct ethtool_coalesce *ec)
{
{
	struct bcm_sysport_priv *priv = netdev_priv(dev);
	struct bcm_sysport_priv *priv = netdev_priv(dev);
	struct net_dim_cq_moder moder;
	struct dim_cq_moder moder;
	u32 usecs, pkts;
	u32 usecs, pkts;
	unsigned int i;
	unsigned int i;


@@ -992,7 +992,7 @@ static int bcm_sysport_poll(struct napi_struct *napi, int budget)
{
{
	struct bcm_sysport_priv *priv =
	struct bcm_sysport_priv *priv =
		container_of(napi, struct bcm_sysport_priv, napi);
		container_of(napi, struct bcm_sysport_priv, napi);
	struct net_dim_sample dim_sample;
	struct dim_sample dim_sample;
	unsigned int work_done = 0;
	unsigned int work_done = 0;


	work_done = bcm_sysport_desc_rx(priv, budget);
	work_done = bcm_sysport_desc_rx(priv, budget);
@@ -1016,7 +1016,7 @@ static int bcm_sysport_poll(struct napi_struct *napi, int budget)
	}
	}


	if (priv->dim.use_dim) {
	if (priv->dim.use_dim) {
		net_dim_sample(priv->dim.event_ctr, priv->dim.packets,
		dim_update_sample(priv->dim.event_ctr, priv->dim.packets,
				  priv->dim.bytes, &dim_sample);
				  priv->dim.bytes, &dim_sample);
		net_dim(&priv->dim.dim, dim_sample);
		net_dim(&priv->dim.dim, dim_sample);
	}
	}
@@ -1087,16 +1087,16 @@ static void bcm_sysport_resume_from_wol(struct bcm_sysport_priv *priv)


static void bcm_sysport_dim_work(struct work_struct *work)
static void bcm_sysport_dim_work(struct work_struct *work)
{
{
	struct net_dim *dim = container_of(work, struct net_dim, work);
	struct dim *dim = container_of(work, struct dim, work);
	struct bcm_sysport_net_dim *ndim =
	struct bcm_sysport_net_dim *ndim =
			container_of(dim, struct bcm_sysport_net_dim, dim);
			container_of(dim, struct bcm_sysport_net_dim, dim);
	struct bcm_sysport_priv *priv =
	struct bcm_sysport_priv *priv =
			container_of(ndim, struct bcm_sysport_priv, dim);
			container_of(ndim, struct bcm_sysport_priv, dim);
	struct net_dim_cq_moder cur_profile =
	struct dim_cq_moder cur_profile = net_dim_get_rx_moderation(dim->mode,
			net_dim_get_rx_moderation(dim->mode, dim->profile_ix);
								    dim->profile_ix);


	bcm_sysport_set_rx_coalesce(priv, cur_profile.usec, cur_profile.pkts);
	bcm_sysport_set_rx_coalesce(priv, cur_profile.usec, cur_profile.pkts);
	dim->state = NET_DIM_START_MEASURE;
	dim->state = DIM_START_MEASURE;
}
}


/* RX and misc interrupt routine */
/* RX and misc interrupt routine */
@@ -1437,7 +1437,7 @@ static void bcm_sysport_init_dim(struct bcm_sysport_priv *priv,
	struct bcm_sysport_net_dim *dim = &priv->dim;
	struct bcm_sysport_net_dim *dim = &priv->dim;


	INIT_WORK(&dim->dim.work, cb);
	INIT_WORK(&dim->dim.work, cb);
	dim->dim.mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE;
	dim->dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
	dim->event_ctr = 0;
	dim->event_ctr = 0;
	dim->packets = 0;
	dim->packets = 0;
	dim->bytes = 0;
	dim->bytes = 0;
@@ -1446,7 +1446,7 @@ static void bcm_sysport_init_dim(struct bcm_sysport_priv *priv,
static void bcm_sysport_init_rx_coalesce(struct bcm_sysport_priv *priv)
static void bcm_sysport_init_rx_coalesce(struct bcm_sysport_priv *priv)
{
{
	struct bcm_sysport_net_dim *dim = &priv->dim;
	struct bcm_sysport_net_dim *dim = &priv->dim;
	struct net_dim_cq_moder moder;
	struct dim_cq_moder moder;
	u32 usecs, pkts;
	u32 usecs, pkts;


	usecs = priv->rx_coalesce_usecs;
	usecs = priv->rx_coalesce_usecs;
+2 −2
Original line number Original line Diff line number Diff line
@@ -11,7 +11,7 @@
#include <linux/bitmap.h>
#include <linux/bitmap.h>
#include <linux/ethtool.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/if_vlan.h>
#include <linux/net_dim.h>
#include <linux/dim.h>


/* Receive/transmit descriptor format */
/* Receive/transmit descriptor format */
#define DESC_ADDR_HI_STATUS_LEN	0x00
#define DESC_ADDR_HI_STATUS_LEN	0x00
@@ -702,7 +702,7 @@ struct bcm_sysport_net_dim {
	u16			event_ctr;
	u16			event_ctr;
	unsigned long		packets;
	unsigned long		packets;
	unsigned long		bytes;
	unsigned long		bytes;
	struct net_dim		dim;
	struct dim		dim;
};
};


/* Software view of the TX ring */
/* Software view of the TX ring */
+6 −6
Original line number Original line Diff line number Diff line
@@ -2130,9 +2130,9 @@ static int bnxt_poll(struct napi_struct *napi, int budget)
		}
		}
	}
	}
	if (bp->flags & BNXT_FLAG_DIM) {
	if (bp->flags & BNXT_FLAG_DIM) {
		struct net_dim_sample dim_sample;
		struct dim_sample dim_sample;


		net_dim_sample(cpr->event_ctr,
		dim_update_sample(cpr->event_ctr,
				  cpr->rx_packets,
				  cpr->rx_packets,
				  cpr->rx_bytes,
				  cpr->rx_bytes,
				  &dim_sample);
				  &dim_sample);
@@ -7813,7 +7813,7 @@ static void bnxt_enable_napi(struct bnxt *bp)


		if (bp->bnapi[i]->rx_ring) {
		if (bp->bnapi[i]->rx_ring) {
			INIT_WORK(&cpr->dim.work, bnxt_dim_work);
			INIT_WORK(&cpr->dim.work, bnxt_dim_work);
			cpr->dim.mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE;
			cpr->dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
		}
		}
		napi_enable(&bp->bnapi[i]->napi);
		napi_enable(&bp->bnapi[i]->napi);
	}
	}
Loading