gianfar: Pack struct gfar_priv_grp into three cachelines
authorClaudiu Manoil <claudiu.manoil@freescale.com>
Tue, 29 Jan 2013 03:55:12 +0000 (03:55 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 29 Jan 2013 20:22:02 +0000 (15:22 -0500)
* remove unused members(!): imask, ievent
* move space consuming interrupt name strings (int_name_* members) to
external structures, unessential for the driver's hot path
* keep high priority hot path data within the first 2 cache lines

This reduces struct gfar_priv_grp from 6 to 3 cache lines.
(Also fixed checkpatch warnings for the old code, in the process.)

Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/freescale/gianfar.c
drivers/net/ethernet/freescale/gianfar.h

index fdb8080..19c54a0 100644 (file)
@@ -544,6 +544,19 @@ static void unmap_group_regs(struct gfar_private *priv)
                        iounmap(priv->gfargrp[i].regs);
 }
 
+static void free_gfar_dev(struct gfar_private *priv)
+{
+       int i, j;
+
+       for (i = 0; i < priv->num_grps; i++)
+               for (j = 0; j < GFAR_NUM_IRQS; j++) {
+                       kfree(priv->gfargrp[i].irqinfo[j]);
+                       priv->gfargrp[i].irqinfo[j] = NULL;
+               }
+
+       free_netdev(priv->ndev);
+}
+
 static void disable_napi(struct gfar_private *priv)
 {
        int i;
@@ -565,20 +578,36 @@ static int gfar_parse_group(struct device_node *np,
 {
        struct gfar_priv_grp *grp = &priv->gfargrp[priv->num_grps];
        u32 *queue_mask;
+       int i;
+
+       if (priv->mode == MQ_MG_MODE) {
+               for (i = 0; i < GFAR_NUM_IRQS; i++) {
+                       grp->irqinfo[i] = kzalloc(sizeof(struct gfar_irqinfo),
+                                                 GFP_KERNEL);
+                       if (!grp->irqinfo[i])
+                               return -ENOMEM;
+               }
+       } else {
+               grp->irqinfo[GFAR_TX] = kzalloc(sizeof(struct gfar_irqinfo),
+                                               GFP_KERNEL);
+               if (!grp->irqinfo[GFAR_TX])
+                       return -ENOMEM;
+               grp->irqinfo[GFAR_RX] = grp->irqinfo[GFAR_ER] = NULL;
+       }
 
        grp->regs = of_iomap(np, 0);
        if (!grp->regs)
                return -ENOMEM;
 
-       grp->interruptTransmit = irq_of_parse_and_map(np, 0);
+       gfar_irq(grp, TX)->irq = irq_of_parse_and_map(np, 0);
 
        /* If we aren't the FEC we have multiple interrupts */
        if (model && strcasecmp(model, "FEC")) {
-               grp->interruptReceive = irq_of_parse_and_map(np, 1);
-               grp->interruptError =   irq_of_parse_and_map(np, 2);
-               if (grp->interruptTransmit == NO_IRQ ||
-                   grp->interruptReceive  == NO_IRQ ||
-                   grp->interruptError    == NO_IRQ)
+               gfar_irq(grp, RX)->irq = irq_of_parse_and_map(np, 1);
+               gfar_irq(grp, ER)->irq = irq_of_parse_and_map(np, 2);
+               if (gfar_irq(grp, TX)->irq == NO_IRQ ||
+                   gfar_irq(grp, RX)->irq == NO_IRQ ||
+                   gfar_irq(grp, ER)->irq == NO_IRQ)
                        return -EINVAL;
        }
 
@@ -779,7 +808,7 @@ tx_alloc_failed:
        free_tx_pointers(priv);
 err_grp_init:
        unmap_group_regs(priv);
-       free_netdev(dev);
+       free_gfar_dev(priv);
        return err;
 }
 
@@ -1184,15 +1213,16 @@ static int gfar_probe(struct platform_device *ofdev)
 
        /* fill out IRQ number and name fields */
        for (i = 0; i < priv->num_grps; i++) {
+               struct gfar_priv_grp *grp = &priv->gfargrp[i];
                if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
-                       sprintf(priv->gfargrp[i].int_name_tx, "%s%s%c%s",
+                       sprintf(gfar_irq(grp, TX)->name, "%s%s%c%s",
                                dev->name, "_g", '0' + i, "_tx");
-                       sprintf(priv->gfargrp[i].int_name_rx, "%s%s%c%s",
+                       sprintf(gfar_irq(grp, RX)->name, "%s%s%c%s",
                                dev->name, "_g", '0' + i, "_rx");
-                       sprintf(priv->gfargrp[i].int_name_er, "%s%s%c%s",
+                       sprintf(gfar_irq(grp, ER)->name, "%s%s%c%s",
                                dev->name, "_g", '0' + i, "_er");
                } else
-                       strcpy(priv->gfargrp[i].int_name_tx, dev->name);
+                       strcpy(gfar_irq(grp, TX)->name, dev->name);
        }
 
        /* Initialize the filer table */
@@ -1225,7 +1255,7 @@ register_fail:
                of_node_put(priv->phy_node);
        if (priv->tbi_node)
                of_node_put(priv->tbi_node);
-       free_netdev(dev);
+       free_gfar_dev(priv);
        return err;
 }
 
@@ -1242,7 +1272,7 @@ static int gfar_remove(struct platform_device *ofdev)
 
        unregister_netdev(priv->ndev);
        unmap_group_regs(priv);
-       free_netdev(priv->ndev);
+       free_gfar_dev(priv);
 
        return 0;
 }
@@ -1650,9 +1680,9 @@ void gfar_halt(struct net_device *dev)
 
 static void free_grp_irqs(struct gfar_priv_grp *grp)
 {
-       free_irq(grp->interruptError, grp);
-       free_irq(grp->interruptTransmit, grp);
-       free_irq(grp->interruptReceive, grp);
+       free_irq(gfar_irq(grp, TX)->irq, grp);
+       free_irq(gfar_irq(grp, RX)->irq, grp);
+       free_irq(gfar_irq(grp, ER)->irq, grp);
 }
 
 void stop_gfar(struct net_device *dev)
@@ -1681,7 +1711,7 @@ void stop_gfar(struct net_device *dev)
                        free_grp_irqs(&priv->gfargrp[i]);
        } else {
                for (i = 0; i < priv->num_grps; i++)
-                       free_irq(priv->gfargrp[i].interruptTransmit,
+                       free_irq(gfar_irq(&priv->gfargrp[i], TX)->irq,
                                 &priv->gfargrp[i]);
        }
 
@@ -1856,32 +1886,34 @@ static int register_grp_irqs(struct gfar_priv_grp *grp)
                /* Install our interrupt handlers for Error,
                 * Transmit, and Receive
                 */
-               if ((err = request_irq(grp->interruptError, gfar_error,
-                                      0, grp->int_name_er, grp)) < 0) {
+               err = request_irq(gfar_irq(grp, ER)->irq, gfar_error, 0,
+                                 gfar_irq(grp, ER)->name, grp);
+               if (err < 0) {
                        netif_err(priv, intr, dev, "Can't get IRQ %d\n",
-                                 grp->interruptError);
+                                 gfar_irq(grp, ER)->irq);
 
                        goto err_irq_fail;
                }
-
-               if ((err = request_irq(grp->interruptTransmit, gfar_transmit,
-                                      0, grp->int_name_tx, grp)) < 0) {
+               err = request_irq(gfar_irq(grp, TX)->irq, gfar_transmit, 0,
+                                 gfar_irq(grp, TX)->name, grp);
+               if (err < 0) {
                        netif_err(priv, intr, dev, "Can't get IRQ %d\n",
-                                 grp->interruptTransmit);
+                                 gfar_irq(grp, TX)->irq);
                        goto tx_irq_fail;
                }
-
-               if ((err = request_irq(grp->interruptReceive, gfar_receive,
-                                      0, grp->int_name_rx, grp)) < 0) {
+               err = request_irq(gfar_irq(grp, RX)->irq, gfar_receive, 0,
+                                 gfar_irq(grp, RX)->name, grp);
+               if (err < 0) {
                        netif_err(priv, intr, dev, "Can't get IRQ %d\n",
-                                 grp->interruptReceive);
+                                 gfar_irq(grp, RX)->irq);
                        goto rx_irq_fail;
                }
        } else {
-               if ((err = request_irq(grp->interruptTransmit, gfar_interrupt,
-                                      0, grp->int_name_tx, grp)) < 0) {
+               err = request_irq(gfar_irq(grp, TX)->irq, gfar_interrupt, 0,
+                                 gfar_irq(grp, TX)->name, grp);
+               if (err < 0) {
                        netif_err(priv, intr, dev, "Can't get IRQ %d\n",
-                                 grp->interruptTransmit);
+                                 gfar_irq(grp, TX)->irq);
                        goto err_irq_fail;
                }
        }
@@ -1889,9 +1921,9 @@ static int register_grp_irqs(struct gfar_priv_grp *grp)
        return 0;
 
 rx_irq_fail:
-       free_irq(grp->interruptTransmit, grp);
+       free_irq(gfar_irq(grp, TX)->irq, grp);
 tx_irq_fail:
-       free_irq(grp->interruptError, grp);
+       free_irq(gfar_irq(grp, ER)->irq, grp);
 err_irq_fail:
        return err;
 
index 045c0d2..71793f4 100644 (file)
@@ -996,18 +996,25 @@ struct gfar_priv_rx_q {
        unsigned long rxic;
 };
 
+enum gfar_irqinfo_id {
+       GFAR_TX = 0,
+       GFAR_RX = 1,
+       GFAR_ER = 2,
+       GFAR_NUM_IRQS = 3
+};
+
+struct gfar_irqinfo {
+       unsigned int irq;
+       char name[GFAR_INT_NAME_MAX];
+};
+
 /**
  *     struct gfar_priv_grp - per group structure
  *     @napi: the napi poll function
  *     @priv: back pointer to the priv structure
  *     @regs: the ioremapped register space for this group
  *     @grp_id: group id for this group
- *     @interruptTransmit: The TX interrupt number for this group
- *     @interruptReceive: The RX interrupt number for this group
- *     @interruptError: The ERROR interrupt number for this group
- *     @int_name_tx: tx interrupt name for this group
- *     @int_name_rx: rx interrupt name for this group
- *     @int_name_er: er interrupt name for this group
+ *     @irqinfo: TX/RX/ER irq data for this group
  */
 
 struct gfar_priv_grp {
@@ -1016,23 +1023,20 @@ struct gfar_priv_grp {
        struct gfar_private *priv;
        struct gfar __iomem *regs;
        unsigned int grp_id;
-       unsigned long rx_bit_map;
-       unsigned long tx_bit_map;
-       unsigned long num_tx_queues;
        unsigned long num_rx_queues;
+       unsigned long rx_bit_map;
+       /* cacheline 3 */
        unsigned int rstat;
        unsigned int tstat;
-       unsigned int imask;
-       unsigned int ievent;
-       unsigned int interruptTransmit;
-       unsigned int interruptReceive;
-       unsigned int interruptError;
-
-       char int_name_tx[GFAR_INT_NAME_MAX];
-       char int_name_rx[GFAR_INT_NAME_MAX];
-       char int_name_er[GFAR_INT_NAME_MAX];
+       unsigned long num_tx_queues;
+       unsigned long tx_bit_map;
+
+       struct gfar_irqinfo *irqinfo[GFAR_NUM_IRQS];
 };
 
+#define gfar_irq(grp, ID) \
+       ((grp)->irqinfo[GFAR_##ID])
+
 enum gfar_errata {
        GFAR_ERRATA_74          = 0x01,
        GFAR_ERRATA_76          = 0x02,