Commit 569dac6a authored by Ioana Ciocoi Radulescu's avatar Ioana Ciocoi Radulescu Committed by David S. Miller
Browse files

dpaa2-eth: bql support



Add support for byte queue limit.

On NAPI poll, we save the total number of Tx confirmed frames/bytes
and register them with bql at the end of the poll function.

Signed-off-by: default avatarIoana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent dbcdf728
Loading
Loading
Loading
Loading
+44 −15
Original line number Diff line number Diff line
@@ -288,7 +288,7 @@ err_frame_format:
 * Observance of NAPI budget is not our concern, leaving that to the caller.
 */
static int consume_frames(struct dpaa2_eth_channel *ch,
			  enum dpaa2_eth_fq_type *type)
			  struct dpaa2_eth_fq **src)
{
	struct dpaa2_eth_priv *priv = ch->priv;
	struct dpaa2_eth_fq *fq = NULL;
@@ -322,10 +322,10 @@ static int consume_frames(struct dpaa2_eth_channel *ch,
	ch->stats.frames += cleaned;

	/* A dequeue operation only pulls frames from a single queue
	 * into the store. Return the frame queue type as an out param.
	 * into the store. Return the frame queue as an out param.
	 */
	if (type)
		*type = fq->type;
	if (src)
		*src = fq;

	return cleaned;
}
@@ -570,8 +570,10 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev)
	struct rtnl_link_stats64 *percpu_stats;
	struct dpaa2_eth_drv_stats *percpu_extras;
	struct dpaa2_eth_fq *fq;
	struct netdev_queue *nq;
	u16 queue_mapping;
	unsigned int needed_headroom;
	u32 fd_len;
	int err, i;

	percpu_stats = this_cpu_ptr(priv->percpu_stats);
@@ -643,8 +645,12 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev)
		/* Clean up everything, including freeing the skb */
		free_tx_fd(priv, &fd);
	} else {
		fd_len = dpaa2_fd_get_len(&fd);
		percpu_stats->tx_packets++;
		percpu_stats->tx_bytes += dpaa2_fd_get_len(&fd);
		percpu_stats->tx_bytes += fd_len;

		nq = netdev_get_tx_queue(net_dev, queue_mapping);
		netdev_tx_sent_queue(nq, fd_len);
	}

	return NETDEV_TX_OK;
@@ -660,10 +666,11 @@ err_alloc_headroom:
static void dpaa2_eth_tx_conf(struct dpaa2_eth_priv *priv,
			      struct dpaa2_eth_channel *ch __always_unused,
			      const struct dpaa2_fd *fd,
			      struct dpaa2_eth_fq *fq __always_unused)
			      struct dpaa2_eth_fq *fq)
{
	struct rtnl_link_stats64 *percpu_stats;
	struct dpaa2_eth_drv_stats *percpu_extras;
	u32 fd_len = dpaa2_fd_get_len(fd);
	u32 fd_errors;

	/* Tracing point */
@@ -671,7 +678,10 @@ 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 += dpaa2_fd_get_len(fd);
	percpu_extras->tx_conf_bytes += fd_len;

	fq->dq_frames++;
	fq->dq_bytes += fd_len;

	/* Check frame errors in the FD field */
	fd_errors = dpaa2_fd_get_ctrl(fd) & DPAA2_FD_TX_ERR_MASK;
@@ -932,8 +942,9 @@ static int dpaa2_eth_poll(struct napi_struct *napi, int budget)
	struct dpaa2_eth_channel *ch;
	struct dpaa2_eth_priv *priv;
	int rx_cleaned = 0, txconf_cleaned = 0;
	enum dpaa2_eth_fq_type type = 0;
	int store_cleaned;
	struct dpaa2_eth_fq *fq, *txc_fq = NULL;
	struct netdev_queue *nq;
	int store_cleaned, work_done;
	int err;

	ch = container_of(napi, struct dpaa2_eth_channel, napi);
@@ -947,18 +958,25 @@ static int dpaa2_eth_poll(struct napi_struct *napi, int budget)
		/* Refill pool if appropriate */
		refill_pool(priv, ch, priv->bpid);

		store_cleaned = consume_frames(ch, &type);
		if (type == DPAA2_RX_FQ)
		store_cleaned = consume_frames(ch, &fq);
		if (!store_cleaned)
			break;
		if (fq->type == DPAA2_RX_FQ) {
			rx_cleaned += store_cleaned;
		else
		} else {
			txconf_cleaned += store_cleaned;
			/* We have a single Tx conf FQ on this channel */
			txc_fq = fq;
		}

		/* If we either consumed the whole NAPI budget with Rx frames
		 * or we reached the Tx confirmations threshold, we're done.
		 */
		if (rx_cleaned >= budget ||
		    txconf_cleaned >= DPAA2_ETH_TXCONF_PER_NAPI)
			return budget;
		    txconf_cleaned >= DPAA2_ETH_TXCONF_PER_NAPI) {
			work_done = budget;
			goto out;
		}
	} while (store_cleaned);

	/* We didn't consume the entire budget, so finish napi and
@@ -972,7 +990,18 @@ static int dpaa2_eth_poll(struct napi_struct *napi, int budget)
	WARN_ONCE(err, "CDAN notifications rearm failed on core %d",
		  ch->nctx.desired_cpu);

	return max(rx_cleaned, 1);
	work_done = max(rx_cleaned, 1);

out:
	if (txc_fq) {
		nq = netdev_get_tx_queue(priv->net_dev, txc_fq->flowid);
		netdev_tx_completed_queue(nq, txc_fq->dq_frames,
					  txc_fq->dq_bytes);
		txc_fq->dq_frames = 0;
		txc_fq->dq_bytes = 0;
	}

	return work_done;
}

static void enable_ch_napi(struct dpaa2_eth_priv *priv)
+2 −0
Original line number Diff line number Diff line
@@ -271,6 +271,8 @@ struct dpaa2_eth_fq {
	u32 tx_qdbin;
	u16 flowid;
	int target_cpu;
	u32 dq_frames;
	u32 dq_bytes;
	struct dpaa2_eth_channel *channel;
	enum dpaa2_eth_fq_type type;