Commit 295711fa authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'dpaa2-irq-coalescing'



Ioana Ciornei says:

====================
dpaa2-eth: add support for IRQ coalescing

This patch set adds support for interrupts coalescing in dpaa2-eth.
The first patches add support for the hardware level configuration of
the IRQ coalescing in the dpio driver, while the ones that touch the
dpaa2-eth driver are responsible for the ethtool user interraction.

With the adaptive IRQ coalescing in place and enabled we have observed
the following changes in interrupt rates on one A72 core @2.2GHz
(LX2160A) while running a Rx TCP flow.  The TCP stream is sent on a
10Gbit link and the only cpu that does Rx is fully utilized.
                                IRQ rate (irqs / sec)
before:   4.59 Gbits/sec                24k
after:    5.67 Gbits/sec                1.3k
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f3fafbcb fc398bec
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -533,6 +533,7 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv,

	percpu_stats->rx_packets++;
	percpu_stats->rx_bytes += dpaa2_fd_get_len(fd);
	ch->stats.bytes_per_cdan += dpaa2_fd_get_len(fd);

	list_add_tail(&skb->list, ch->rx_list);

@@ -641,6 +642,7 @@ static int dpaa2_eth_consume_frames(struct dpaa2_eth_channel *ch,

	fq->stats.frames += cleaned;
	ch->stats.frames += cleaned;
	ch->stats.frames_per_cdan += cleaned;

	/* A dequeue operation only pulls frames from a single queue
	 * into the store. Return the frame queue as an out param.
@@ -1264,7 +1266,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev)

/* Tx confirmation frame processing routine */
static void dpaa2_eth_tx_conf(struct dpaa2_eth_priv *priv,
			      struct dpaa2_eth_channel *ch __always_unused,
			      struct dpaa2_eth_channel *ch,
			      const struct dpaa2_fd *fd,
			      struct dpaa2_eth_fq *fq)
{
@@ -1279,6 +1281,7 @@ static void dpaa2_eth_tx_conf(struct dpaa2_eth_priv *priv,
	percpu_extras = this_cpu_ptr(priv->percpu_extras);
	percpu_extras->tx_conf_frames++;
	percpu_extras->tx_conf_bytes += fd_len;
	ch->stats.bytes_per_cdan += fd_len;

	/* Check frame errors in the FD field */
	fd_errors = dpaa2_fd_get_ctrl(fd) & DPAA2_FD_TX_ERR_MASK;
@@ -1601,6 +1604,12 @@ static int dpaa2_eth_poll(struct napi_struct *napi, int budget)
		}
	} while (store_cleaned);

	/* Update NET DIM with the values for this CDAN */
	dpaa2_io_update_net_dim(ch->dpio, ch->stats.frames_per_cdan,
				ch->stats.bytes_per_cdan);
	ch->stats.frames_per_cdan = 0;
	ch->stats.bytes_per_cdan = 0;

	/* We didn't consume the entire budget, so finish napi and
	 * re-enable data availability notifications
	 */
+2 −0
Original line number Diff line number Diff line
@@ -384,6 +384,8 @@ struct dpaa2_eth_ch_stats {
	__u64 xdp_redirect;
	/* Must be last, does not show up in ethtool stats */
	__u64 frames;
	__u64 frames_per_cdan;
	__u64 bytes_per_cdan;
};

/* Maximum number of queues associated with a DPNI */
+58 −0
Original line number Diff line number Diff line
@@ -820,7 +820,63 @@ static int dpaa2_eth_set_tunable(struct net_device *net_dev,
	return err;
}

static int dpaa2_eth_get_coalesce(struct net_device *dev,
				  struct ethtool_coalesce *ic,
				  struct kernel_ethtool_coalesce *kernel_coal,
				  struct netlink_ext_ack *extack)
{
	struct dpaa2_eth_priv *priv = netdev_priv(dev);
	struct dpaa2_io *dpio = priv->channel[0]->dpio;

	dpaa2_io_get_irq_coalescing(dpio, &ic->rx_coalesce_usecs);
	ic->use_adaptive_rx_coalesce = dpaa2_io_get_adaptive_coalescing(dpio);

	return 0;
}

static int dpaa2_eth_set_coalesce(struct net_device *dev,
				  struct ethtool_coalesce *ic,
				  struct kernel_ethtool_coalesce *kernel_coal,
				  struct netlink_ext_ack *extack)
{
	struct dpaa2_eth_priv *priv = netdev_priv(dev);
	struct dpaa2_io *dpio;
	int prev_adaptive;
	u32 prev_rx_usecs;
	int i, j, err;

	/* Keep track of the previous value, just in case we fail */
	dpio = priv->channel[0]->dpio;
	dpaa2_io_get_irq_coalescing(dpio, &prev_rx_usecs);
	prev_adaptive = dpaa2_io_get_adaptive_coalescing(dpio);

	/* Setup new value for rx coalescing */
	for (i = 0; i < priv->num_channels; i++) {
		dpio = priv->channel[i]->dpio;

		dpaa2_io_set_adaptive_coalescing(dpio,
						 ic->use_adaptive_rx_coalesce);
		err = dpaa2_io_set_irq_coalescing(dpio, ic->rx_coalesce_usecs);
		if (err)
			goto restore_rx_usecs;
	}

	return 0;

restore_rx_usecs:
	for (j = 0; j < i; j++) {
		dpio = priv->channel[j]->dpio;

		dpaa2_io_set_irq_coalescing(dpio, prev_rx_usecs);
		dpaa2_io_set_adaptive_coalescing(dpio, prev_adaptive);
	}

	return err;
}

const struct ethtool_ops dpaa2_ethtool_ops = {
	.supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS |
				     ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
	.get_drvinfo = dpaa2_eth_get_drvinfo,
	.nway_reset = dpaa2_eth_nway_reset,
	.get_link = ethtool_op_get_link,
@@ -836,4 +892,6 @@ const struct ethtool_ops dpaa2_ethtool_ops = {
	.get_ts_info = dpaa2_eth_get_ts_info,
	.get_tunable = dpaa2_eth_get_tunable,
	.set_tunable = dpaa2_eth_set_tunable,
	.get_coalesce = dpaa2_eth_get_coalesce,
	.set_coalesce = dpaa2_eth_set_coalesce,
};
+1 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ config FSL_MC_DPIO
        tristate "QorIQ DPAA2 DPIO driver"
        depends on FSL_MC_BUS
        select SOC_BUS
        select DIMLIB
        help
	  Driver for the DPAA2 DPIO object.  A DPIO provides queue and
	  buffer management facilities for software to interact with
+3 −0
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@ struct dpio_rsp_get_attr {
	__le64 qbman_portal_ci_addr;
	/* cmd word 3 */
	__le32 qbman_version;
	__le32 pad1;
	/* cmd word 4 */
	__le32 clk;
};

struct dpio_stashing_dest {
Loading