提交 ee873fda 编写于 作者: C Claudiu Manoil 提交者: David S. Miller

gianfar: Pack struct gfar_priv_grp into three cachelines

* 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: NClaudiu Manoil <claudiu.manoil@freescale.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 5fedcc14
...@@ -544,6 +544,19 @@ static void unmap_group_regs(struct gfar_private *priv) ...@@ -544,6 +544,19 @@ static void unmap_group_regs(struct gfar_private *priv)
iounmap(priv->gfargrp[i].regs); 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) static void disable_napi(struct gfar_private *priv)
{ {
int i; int i;
...@@ -565,20 +578,36 @@ static int gfar_parse_group(struct device_node *np, ...@@ -565,20 +578,36 @@ static int gfar_parse_group(struct device_node *np,
{ {
struct gfar_priv_grp *grp = &priv->gfargrp[priv->num_grps]; struct gfar_priv_grp *grp = &priv->gfargrp[priv->num_grps];
u32 *queue_mask; 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); grp->regs = of_iomap(np, 0);
if (!grp->regs) if (!grp->regs)
return -ENOMEM; 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 we aren't the FEC we have multiple interrupts */
if (model && strcasecmp(model, "FEC")) { if (model && strcasecmp(model, "FEC")) {
grp->interruptReceive = irq_of_parse_and_map(np, 1); gfar_irq(grp, RX)->irq = irq_of_parse_and_map(np, 1);
grp->interruptError = irq_of_parse_and_map(np, 2); gfar_irq(grp, ER)->irq = irq_of_parse_and_map(np, 2);
if (grp->interruptTransmit == NO_IRQ || if (gfar_irq(grp, TX)->irq == NO_IRQ ||
grp->interruptReceive == NO_IRQ || gfar_irq(grp, RX)->irq == NO_IRQ ||
grp->interruptError == NO_IRQ) gfar_irq(grp, ER)->irq == NO_IRQ)
return -EINVAL; return -EINVAL;
} }
...@@ -779,7 +808,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) ...@@ -779,7 +808,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
free_tx_pointers(priv); free_tx_pointers(priv);
err_grp_init: err_grp_init:
unmap_group_regs(priv); unmap_group_regs(priv);
free_netdev(dev); free_gfar_dev(priv);
return err; return err;
} }
...@@ -1184,15 +1213,16 @@ static int gfar_probe(struct platform_device *ofdev) ...@@ -1184,15 +1213,16 @@ static int gfar_probe(struct platform_device *ofdev)
/* fill out IRQ number and name fields */ /* fill out IRQ number and name fields */
for (i = 0; i < priv->num_grps; i++) { 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) { 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"); 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"); 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"); dev->name, "_g", '0' + i, "_er");
} else } else
strcpy(priv->gfargrp[i].int_name_tx, dev->name); strcpy(gfar_irq(grp, TX)->name, dev->name);
} }
/* Initialize the filer table */ /* Initialize the filer table */
...@@ -1225,7 +1255,7 @@ static int gfar_probe(struct platform_device *ofdev) ...@@ -1225,7 +1255,7 @@ static int gfar_probe(struct platform_device *ofdev)
of_node_put(priv->phy_node); of_node_put(priv->phy_node);
if (priv->tbi_node) if (priv->tbi_node)
of_node_put(priv->tbi_node); of_node_put(priv->tbi_node);
free_netdev(dev); free_gfar_dev(priv);
return err; return err;
} }
...@@ -1242,7 +1272,7 @@ static int gfar_remove(struct platform_device *ofdev) ...@@ -1242,7 +1272,7 @@ static int gfar_remove(struct platform_device *ofdev)
unregister_netdev(priv->ndev); unregister_netdev(priv->ndev);
unmap_group_regs(priv); unmap_group_regs(priv);
free_netdev(priv->ndev); free_gfar_dev(priv);
return 0; return 0;
} }
...@@ -1650,9 +1680,9 @@ void gfar_halt(struct net_device *dev) ...@@ -1650,9 +1680,9 @@ void gfar_halt(struct net_device *dev)
static void free_grp_irqs(struct gfar_priv_grp *grp) static void free_grp_irqs(struct gfar_priv_grp *grp)
{ {
free_irq(grp->interruptError, grp); free_irq(gfar_irq(grp, TX)->irq, grp);
free_irq(grp->interruptTransmit, grp); free_irq(gfar_irq(grp, RX)->irq, grp);
free_irq(grp->interruptReceive, grp); free_irq(gfar_irq(grp, ER)->irq, grp);
} }
void stop_gfar(struct net_device *dev) void stop_gfar(struct net_device *dev)
...@@ -1681,7 +1711,7 @@ void stop_gfar(struct net_device *dev) ...@@ -1681,7 +1711,7 @@ void stop_gfar(struct net_device *dev)
free_grp_irqs(&priv->gfargrp[i]); free_grp_irqs(&priv->gfargrp[i]);
} else { } else {
for (i = 0; i < priv->num_grps; i++) 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]); &priv->gfargrp[i]);
} }
...@@ -1856,32 +1886,34 @@ static int register_grp_irqs(struct gfar_priv_grp *grp) ...@@ -1856,32 +1886,34 @@ static int register_grp_irqs(struct gfar_priv_grp *grp)
/* Install our interrupt handlers for Error, /* Install our interrupt handlers for Error,
* Transmit, and Receive * Transmit, and Receive
*/ */
if ((err = request_irq(grp->interruptError, gfar_error, err = request_irq(gfar_irq(grp, ER)->irq, gfar_error, 0,
0, grp->int_name_er, grp)) < 0) { gfar_irq(grp, ER)->name, grp);
if (err < 0) {
netif_err(priv, intr, dev, "Can't get IRQ %d\n", netif_err(priv, intr, dev, "Can't get IRQ %d\n",
grp->interruptError); gfar_irq(grp, ER)->irq);
goto err_irq_fail; goto err_irq_fail;
} }
err = request_irq(gfar_irq(grp, TX)->irq, gfar_transmit, 0,
if ((err = request_irq(grp->interruptTransmit, gfar_transmit, gfar_irq(grp, TX)->name, grp);
0, grp->int_name_tx, grp)) < 0) { if (err < 0) {
netif_err(priv, intr, dev, "Can't get IRQ %d\n", netif_err(priv, intr, dev, "Can't get IRQ %d\n",
grp->interruptTransmit); gfar_irq(grp, TX)->irq);
goto tx_irq_fail; goto tx_irq_fail;
} }
err = request_irq(gfar_irq(grp, RX)->irq, gfar_receive, 0,
if ((err = request_irq(grp->interruptReceive, gfar_receive, gfar_irq(grp, RX)->name, grp);
0, grp->int_name_rx, grp)) < 0) { if (err < 0) {
netif_err(priv, intr, dev, "Can't get IRQ %d\n", netif_err(priv, intr, dev, "Can't get IRQ %d\n",
grp->interruptReceive); gfar_irq(grp, RX)->irq);
goto rx_irq_fail; goto rx_irq_fail;
} }
} else { } else {
if ((err = request_irq(grp->interruptTransmit, gfar_interrupt, err = request_irq(gfar_irq(grp, TX)->irq, gfar_interrupt, 0,
0, grp->int_name_tx, grp)) < 0) { gfar_irq(grp, TX)->name, grp);
if (err < 0) {
netif_err(priv, intr, dev, "Can't get IRQ %d\n", netif_err(priv, intr, dev, "Can't get IRQ %d\n",
grp->interruptTransmit); gfar_irq(grp, TX)->irq);
goto err_irq_fail; goto err_irq_fail;
} }
} }
...@@ -1889,9 +1921,9 @@ static int register_grp_irqs(struct gfar_priv_grp *grp) ...@@ -1889,9 +1921,9 @@ static int register_grp_irqs(struct gfar_priv_grp *grp)
return 0; return 0;
rx_irq_fail: rx_irq_fail:
free_irq(grp->interruptTransmit, grp); free_irq(gfar_irq(grp, TX)->irq, grp);
tx_irq_fail: tx_irq_fail:
free_irq(grp->interruptError, grp); free_irq(gfar_irq(grp, ER)->irq, grp);
err_irq_fail: err_irq_fail:
return err; return err;
......
...@@ -996,18 +996,25 @@ struct gfar_priv_rx_q { ...@@ -996,18 +996,25 @@ struct gfar_priv_rx_q {
unsigned long rxic; 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 * struct gfar_priv_grp - per group structure
* @napi: the napi poll function * @napi: the napi poll function
* @priv: back pointer to the priv structure * @priv: back pointer to the priv structure
* @regs: the ioremapped register space for this group * @regs: the ioremapped register space for this group
* @grp_id: group id for this group * @grp_id: group id for this group
* @interruptTransmit: The TX interrupt number for this group * @irqinfo: TX/RX/ER irq data 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
*/ */
struct gfar_priv_grp { struct gfar_priv_grp {
...@@ -1016,23 +1023,20 @@ struct gfar_priv_grp { ...@@ -1016,23 +1023,20 @@ struct gfar_priv_grp {
struct gfar_private *priv; struct gfar_private *priv;
struct gfar __iomem *regs; struct gfar __iomem *regs;
unsigned int grp_id; 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 num_rx_queues;
unsigned long rx_bit_map;
/* cacheline 3 */
unsigned int rstat; unsigned int rstat;
unsigned int tstat; unsigned int tstat;
unsigned int imask; unsigned long num_tx_queues;
unsigned int ievent; unsigned long tx_bit_map;
unsigned int interruptTransmit;
unsigned int interruptReceive; struct gfar_irqinfo *irqinfo[GFAR_NUM_IRQS];
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];
}; };
#define gfar_irq(grp, ID) \
((grp)->irqinfo[GFAR_##ID])
enum gfar_errata { enum gfar_errata {
GFAR_ERRATA_74 = 0x01, GFAR_ERRATA_74 = 0x01,
GFAR_ERRATA_76 = 0x02, GFAR_ERRATA_76 = 0x02,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册