From 537336ce2e916c32eadaad1e6cc2712292eb7d65 Mon Sep 17 00:00:00 2001 From: Ioana Radulescu Date: Thu, 21 Dec 2017 06:33:20 -0600 Subject: staging: fsl-dpaa2/eth: Flow affinity for IP forwarding The driver xmit function chooses an egress FQ based on the current core id. The network stack itself sets a mapping field in the skb based on many things - the default one being a hash on packet fields, which the current driver ignores. This patch saves the ingress frame flow affinity information in the skb. In case of forwarded frames, this info will then be used for Tx and Tx confirmation hardware queue selection, ensuring all processing of the given frame is done on a single core. Signed-off-by: Bogdan Purcareata Signed-off-by: Ioana Radulescu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 16 ++++++++++------ drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h | 3 ++- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers/staging/fsl-dpaa2') diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c index 7f3e4fae6bb9..b63ae09afb1a 100644 --- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c +++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c @@ -230,7 +230,8 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv, static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, struct dpaa2_eth_channel *ch, const struct dpaa2_fd *fd, - struct napi_struct *napi) + struct napi_struct *napi, + u16 queue_id) { dma_addr_t addr = dpaa2_fd_get_addr(fd); u8 fd_format = dpaa2_fd_get_format(fd); @@ -281,6 +282,7 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, } skb->protocol = eth_type_trans(skb, priv->net_dev); + skb_record_rx_queue(skb, queue_id); percpu_stats->rx_packets++; percpu_stats->rx_bytes += dpaa2_fd_get_len(fd); @@ -325,7 +327,7 @@ static int consume_frames(struct dpaa2_eth_channel *ch) fq = (struct dpaa2_eth_fq *)dpaa2_dq_fqd_ctx(dq); fq->stats.frames++; - fq->consume(priv, ch, fd, &ch->napi); + fq->consume(priv, ch, fd, &ch->napi, fq->flowid); cleaned++; } while (!is_last); @@ -588,10 +590,11 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev) /* Tracing point */ trace_dpaa2_tx_fd(net_dev, &fd); - /* TxConf FQ selection primarily based on cpu affinity; this is - * non-migratable context, so it's safe to call smp_processor_id(). + /* TxConf FQ selection relies on queue id from the stack. + * In case of a forwarded frame from another DPNI interface, we choose + * a queue affined to the same core that processed the Rx frame */ - queue_mapping = smp_processor_id() % dpaa2_eth_queue_count(priv); + queue_mapping = skb_get_queue_mapping(skb); fq = &priv->fq[queue_mapping]; for (i = 0; i < DPAA2_ETH_ENQUEUE_RETRIES; i++) { err = dpaa2_io_service_enqueue_qd(NULL, priv->tx_qdid, 0, @@ -622,7 +625,8 @@ err_alloc_headroom: static void dpaa2_eth_tx_conf(struct dpaa2_eth_priv *priv, struct dpaa2_eth_channel *ch, const struct dpaa2_fd *fd, - struct napi_struct *napi __always_unused) + struct napi_struct *napi __always_unused, + u16 queue_id __always_unused) { struct rtnl_link_stats64 *percpu_stats; struct dpaa2_eth_drv_stats *percpu_extras; diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h index d68ac386dd0a..fb8fb5c07343 100644 --- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h +++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h @@ -276,7 +276,8 @@ struct dpaa2_eth_fq { void (*consume)(struct dpaa2_eth_priv *, struct dpaa2_eth_channel *, const struct dpaa2_fd *, - struct napi_struct *); + struct napi_struct *, + u16 queue_id); struct dpaa2_eth_fq_stats stats; }; -- cgit v1.2.3-59-g8ed1b