staging: fsl-dpaa2/eth: Use affine DPIO services
authorIoana Radulescu <ruxandra.radulescu@nxp.com>
Fri, 5 Jan 2018 11:04:32 +0000 (05:04 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 8 Jan 2018 15:47:23 +0000 (16:47 +0100)
Use the newly added DPIO service API to map cpu-affine DPIO services
to channels.

The DPAA2 Ethernet driver already had mappings of frame queues and
channels to cpus, but had no control over the DPIOs used. We can
now ensure full affinity of hotpath hardware resources to cores,
which improves performance and almost eliminates some resource
contentions (e.g. enqueue/dequeue busy counters should be close to
zero from now on).

Making the pull channel operation core affine brings the most
significant benefits. This ensures the same DPIO service will be
used for all dequeue commands issued for a certain frame queue,
which is in line with the way hardware is optimized.

Additionally, we also use affine DPIOs for the frame enqueue and
buffer release operations in order to avoid resource contention.
dpaa2_io_service_register() and dpaa2_io_service_rearm()
functions receive an affine DPIO as argument mostly for uniformity,
but this doesn't change the previous functionality.

Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h

index 824c4ad7b4b4daf474b69bdddb3548b0f9bcf239..2817e67df3d5f0b0c225d5247c11ff00102e8669 100644 (file)
@@ -597,7 +597,8 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev)
        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,
+               err = dpaa2_io_service_enqueue_qd(fq->channel->dpio,
+                                                 priv->tx_qdid, 0,
                                                  fq->tx_qdbin, &fd);
                if (err != -EBUSY)
                        break;
@@ -719,7 +720,8 @@ static void free_bufs(struct dpaa2_eth_priv *priv, u64 *buf_array, int count)
 /* Perform a single release command to add buffers
  * to the specified buffer pool
  */
-static int add_bufs(struct dpaa2_eth_priv *priv, u16 bpid)
+static int add_bufs(struct dpaa2_eth_priv *priv,
+                   struct dpaa2_eth_channel *ch, u16 bpid)
 {
        struct device *dev = priv->net_dev->dev.parent;
        u64 buf_array[DPAA2_ETH_BUFS_PER_CMD];
@@ -753,7 +755,7 @@ static int add_bufs(struct dpaa2_eth_priv *priv, u16 bpid)
 
 release_bufs:
        /* In case the portal is busy, retry until successful */
-       while ((err = dpaa2_io_service_release(NULL, bpid,
+       while ((err = dpaa2_io_service_release(ch->dpio, bpid,
                                               buf_array, i)) == -EBUSY)
                cpu_relax();
 
@@ -794,7 +796,7 @@ static int seed_pool(struct dpaa2_eth_priv *priv, u16 bpid)
        for (j = 0; j < priv->num_channels; j++) {
                for (i = 0; i < DPAA2_ETH_NUM_BUFS;
                     i += DPAA2_ETH_BUFS_PER_CMD) {
-                       new_count = add_bufs(priv, bpid);
+                       new_count = add_bufs(priv, priv->channel[j], bpid);
                        priv->channel[j]->buf_count += new_count;
 
                        if (new_count < DPAA2_ETH_BUFS_PER_CMD) {
@@ -852,7 +854,7 @@ static int refill_pool(struct dpaa2_eth_priv *priv,
                return 0;
 
        do {
-               new_count = add_bufs(priv, bpid);
+               new_count = add_bufs(priv, ch, bpid);
                if (unlikely(!new_count)) {
                        /* Out of memory; abort for now, we'll try later on */
                        break;
@@ -873,7 +875,8 @@ static int pull_channel(struct dpaa2_eth_channel *ch)
 
        /* Retry while portal is busy */
        do {
-               err = dpaa2_io_service_pull_channel(NULL, ch->ch_id, ch->store);
+               err = dpaa2_io_service_pull_channel(ch->dpio, ch->ch_id,
+                                                   ch->store);
                dequeues++;
                cpu_relax();
        } while (err == -EBUSY);
@@ -923,7 +926,7 @@ static int dpaa2_eth_poll(struct napi_struct *napi, int budget)
        if (cleaned < budget && napi_complete_done(napi, cleaned)) {
                /* Re-enable data available notifications */
                do {
-                       err = dpaa2_io_service_rearm(NULL, &ch->nctx);
+                       err = dpaa2_io_service_rearm(ch->dpio, &ch->nctx);
                        cpu_relax();
                } while (err == -EBUSY);
                WARN_ONCE(err, "CDAN notifications rearm failed on core %d",
@@ -1531,7 +1534,8 @@ static int setup_dpio(struct dpaa2_eth_priv *priv)
                nctx->desired_cpu = i;
 
                /* Register the new context */
-               err = dpaa2_io_service_register(NULL, nctx);
+               channel->dpio = dpaa2_io_service_select(i);
+               err = dpaa2_io_service_register(channel->dpio, nctx);
                if (err) {
                        dev_dbg(dev, "No affine DPIO for cpu %d\n", i);
                        /* If no affine DPIO for this core, there's probably
@@ -1571,7 +1575,7 @@ static int setup_dpio(struct dpaa2_eth_priv *priv)
        return 0;
 
 err_set_cdan:
-       dpaa2_io_service_deregister(NULL, nctx);
+       dpaa2_io_service_deregister(channel->dpio, nctx);
 err_service_reg:
        free_channel(priv, channel);
 err_alloc_ch:
@@ -1594,7 +1598,7 @@ static void free_dpio(struct dpaa2_eth_priv *priv)
        /* deregister CDAN notifications and free channels */
        for (i = 0; i < priv->num_channels; i++) {
                ch = priv->channel[i];
-               dpaa2_io_service_deregister(NULL, &ch->nctx);
+               dpaa2_io_service_deregister(ch->dpio, &ch->nctx);
                free_channel(priv, ch);
        }
 }
index fb8fb5c073435fbd9f24928f06574f8e07591242..e577410fdf4fbcffb3b58b9bc8e1c3803d2dbf7a 100644 (file)
@@ -288,6 +288,7 @@ struct dpaa2_eth_channel {
        int ch_id;
        int dpio_id;
        struct napi_struct napi;
+       struct dpaa2_io *dpio;
        struct dpaa2_io_store *store;
        struct dpaa2_eth_priv *priv;
        int buf_count;