* [PATCH v1 5/7] gianfar: Add support etsec2.0 registers.
From: Sandeep Gopalpet @ 2009-10-26 16:27 UTC (permalink / raw)
To: netdev; +Cc: Sandeep Gopalpet
This patch adds support for etsec2.0 regsiters
Signed-off-by: Sandeep Gopalpet <sandeep.kumar@freescale.com>
---
drivers/net/gianfar.h | 55 +++++++++++++++++++++++++++++++++++++++---------
1 files changed, 44 insertions(+), 11 deletions(-)
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index fc43cfd..70c25ce 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -566,25 +566,32 @@ struct gfar_stats {
struct gfar {
u32 tsec_id; /* 0x.000 - Controller ID register */
- u8 res1[12];
+ u32 tsec_id2; /* 0x.004 - Controller ID2 register */
+ u8 res1[8];
u32 ievent; /* 0x.010 - Interrupt Event Register */
u32 imask; /* 0x.014 - Interrupt Mask Register */
u32 edis; /* 0x.018 - Error Disabled Register */
- u8 res2[4];
+ u32 emapg; /* 0x.01c - Group Error mapping register */
u32 ecntrl; /* 0x.020 - Ethernet Control Register */
u32 minflr; /* 0x.024 - Minimum Frame Length Register */
u32 ptv; /* 0x.028 - Pause Time Value Register */
u32 dmactrl; /* 0x.02c - DMA Control Register */
u32 tbipa; /* 0x.030 - TBI PHY Address Register */
- u8 res3[88];
+ u8 res2[28];
+ u32 fifo_rx_pause; /* 0x.050 - FIFO receive pause start threshold
+ register */
+ u32 fifo_rx_pause_shutoff; /* x.054 - FIFO receive starve shutoff
+ register */
+ u32 fifo_rx_alarm; /* 0x.058 - FIFO receive alarm start threshold
+ register */
+ u32 fifo_rx_alarm_shutoff; /*0x.05c - FIFO receive alarm starve
+ shutoff register */
+ u8 res3[44];
u32 fifo_tx_thr; /* 0x.08c - FIFO transmit threshold register */
u8 res4[8];
u32 fifo_tx_starve; /* 0x.098 - FIFO transmit starve register */
u32 fifo_tx_starve_shutoff; /* 0x.09c - FIFO transmit starve shutoff register */
- u8 res5[4];
- u32 fifo_rx_pause; /* 0x.0a4 - FIFO receive pause threshold register */
- u32 fifo_rx_alarm; /* 0x.0a8 - FIFO receive alarm threshold register */
- u8 res6[84];
+ u8 res5[96];
u32 tctrl; /* 0x.100 - Transmit Control Register */
u32 tstat; /* 0x.104 - Transmit Status Register */
u32 dfvlan; /* 0x.108 - Default VLAN Control word */
@@ -635,7 +642,11 @@ struct gfar {
u8 res12[8];
u32 rxic; /* 0x.310 - Receive Interrupt Coalescing Configuration Register */
u32 rqueue; /* 0x.314 - Receive queue control register */
- u8 res13[24];
+ u32 rir0; /* 0x.318 - Ring mapping register 0 */
+ u32 rir1; /* 0x.31c - Ring mapping register 1 */
+ u32 rir2; /* 0x.320 - Ring mapping register 2 */
+ u32 rir3; /* 0x.324 - Ring mapping register 3 */
+ u8 res13[8];
u32 rbifx; /* 0x.330 - Receive bit field extract control register */
u32 rqfar; /* 0x.334 - Receive queue filing table address register */
u32 rqfcr; /* 0x.338 - Receive queue filing table control register */
@@ -684,7 +695,7 @@ struct gfar {
u32 maxfrm; /* 0x.510 - Maximum Frame Length Register */
u8 res18[12];
u8 gfar_mii_regs[24]; /* See gianfar_phy.h */
- u8 res19[4];
+ u32 ifctrl; /* 0x.538 - Interface control register */
u32 ifstat; /* 0x.53c - Interface Status Register */
u32 macstnaddr1; /* 0x.540 - Station Address Part 1 Register */
u32 macstnaddr2; /* 0x.544 - Station Address Part 2 Register */
@@ -745,8 +756,30 @@ struct gfar {
u8 res23c[248];
u32 attr; /* 0x.bf8 - Attributes Register */
u32 attreli; /* 0x.bfc - Attributes Extract Length and Extract Index Register */
- u8 res24[1024];
-
+ u8 res24[688];
+ u32 isrg0; /* 0x.eb0 - Interrupt steering group 0 register */
+ u32 isrg1; /* 0x.eb4 - Interrupt steering group 1 register */
+ u32 isrg2; /* 0x.eb8 - Interrupt steering group 2 register */
+ u32 isrg3; /* 0x.ebc - Interrupt steering group 3 register */
+ u8 res25[16];
+ u32 rxic0; /* 0x.ed0 - Ring 0 Rx interrupt coalescing */
+ u32 rxic1; /* 0x.ed4 - Ring 1 Rx interrupt coalescing */
+ u32 rxic2; /* 0x.ed8 - Ring 2 Rx interrupt coalescing */
+ u32 rxic3; /* 0x.edc - Ring 3 Rx interrupt coalescing */
+ u32 rxic4; /* 0x.ee0 - Ring 4 Rx interrupt coalescing */
+ u32 rxic5; /* 0x.ee4 - Ring 5 Rx interrupt coalescing */
+ u32 rxic6; /* 0x.ee8 - Ring 6 Rx interrupt coalescing */
+ u32 rxic7; /* 0x.eec - Ring 7 Rx interrupt coalescing */
+ u8 res26[32];
+ u32 txic0; /* 0x.f10 - Ring 0 Tx interrupt coalescing */
+ u32 txic1; /* 0x.f14 - Ring 1 Tx interrupt coalescing */
+ u32 txic2; /* 0x.f18 - Ring 2 Tx interrupt coalescing */
+ u32 txic3; /* 0x.f1c - Ring 3 Tx interrupt coalescing */
+ u32 txic4; /* 0x.f20 - Ring 4 Tx interrupt coalescing */
+ u32 txic5; /* 0x.f24 - Ring 5 Tx interrupt coalescing */
+ u32 txic6; /* 0x.f28 - Ring 6 Tx interrupt coalescing */
+ u32 txic7; /* 0x.f2c - Ring 7 Tx interrupt coalescing */
+ u8 res27[208];
};
/* Flags related to gianfar device features */
--
1.5.2.2
^ permalink raw reply related
* [PATCH v1 6/7] gianfar: Add Multiple group Support
From: Sandeep Gopalpet @ 2009-10-26 16:27 UTC (permalink / raw)
To: netdev; +Cc: Sandeep Gopalpet
This patch introduces multiple group support for etsec2.0
devices.
Multiple group support is provided by mapping the set of enabled
queues to different groups and then programming the per group
regsiters imask, ievent, rstat, tstat.
The queues corresponding to a group are indicated by programming
isrg (interrupt steering) registers.
Signed-off-by: Sandeep Gopalpet <sandeep.kumar@freescale.com>
---
drivers/net/gianfar.c | 532 +++++++++++++++++++++++++++--------------
drivers/net/gianfar.h | 29 +++-
drivers/net/gianfar_ethtool.c | 58 +++--
drivers/net/gianfar_sysfs.c | 12 +-
4 files changed, 422 insertions(+), 209 deletions(-)
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 82da5d9..a60e05f 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -241,7 +241,7 @@ static int gfar_alloc_skb_resources(struct net_device *ndev)
struct device *dev = &priv->ofdev->dev;
struct gfar_priv_tx_q *tx_queue = NULL;
struct gfar_priv_rx_q *rx_queue = NULL;
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
u32 *baddr;
priv->total_tx_ring_size = 0;
@@ -334,19 +334,13 @@ cleanup:
static void gfar_init_mac(struct net_device *ndev)
{
struct gfar_private *priv = netdev_priv(ndev);
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
u32 rctrl = 0;
u32 tctrl = 0;
u32 attrs = 0;
/* Configure the coalescing support */
- gfar_write(®s->txic, 0);
- if (priv->tx_queue[0]->txcoalescing)
- gfar_write(®s->txic, priv->tx_queue[0]->txic);
-
- gfar_write(®s->rxic, 0);
- if (priv->rx_queue[0]->rxcoalescing)
- gfar_write(®s->rxic, priv->rx_queue[0]->rxic);
+ gfar_configure_coalescing(priv, 0xFF, 0xFF);
if (priv->rx_filer_enable)
rctrl |= RCTRL_FILREN;
@@ -480,16 +474,91 @@ static void free_rx_pointers(struct gfar_private *priv)
kfree(priv->rx_queue[i]);
}
+static void unmap_group_regs(struct gfar_private *priv)
+{
+ int i = 0;
+
+ for (i = 0; i < MAXGROUPS; i++)
+ if (priv->gfargrp[i].regs)
+ iounmap(priv->gfargrp[i].regs);
+}
+
+static void disable_napi(struct gfar_private *priv)
+{
+ int i = 0;
+
+ for (i = 0; i < priv->num_grps; i++)
+ napi_disable(&priv->gfargrp[i].napi);
+}
+
+static void enable_napi(struct gfar_private *priv)
+{
+ int i = 0;
+
+ for (i = 0; i < priv->num_grps; i++)
+ napi_enable(&priv->gfargrp[i].napi);
+}
+
+static int gfar_parse_group(struct device_node *np,
+ struct gfar_private *priv, const char *model)
+{
+ u32 *queue_mask;
+ u64 addr, size;
+
+ addr = of_translate_address(np,
+ of_get_address(np, 0, &size, NULL));
+ priv->gfargrp[priv->num_grps].regs = ioremap(addr, size);
+
+ if (!priv->gfargrp[priv->num_grps].regs)
+ return -ENOMEM;
+
+ priv->gfargrp[priv->num_grps].interruptTransmit =
+ irq_of_parse_and_map(np, 0);
+
+ /* If we aren't the FEC we have multiple interrupts */
+ if (model && strcasecmp(model, "FEC")) {
+ priv->gfargrp[priv->num_grps].interruptReceive =
+ irq_of_parse_and_map(np, 1);
+ priv->gfargrp[priv->num_grps].interruptError =
+ irq_of_parse_and_map(np,2);
+ if (priv->gfargrp[priv->num_grps].interruptTransmit < 0 ||
+ priv->gfargrp[priv->num_grps].interruptReceive < 0 ||
+ priv->gfargrp[priv->num_grps].interruptError < 0) {
+ return -EINVAL;
+ }
+ }
+
+ priv->gfargrp[priv->num_grps].grp_id = priv->num_grps;
+ priv->gfargrp[priv->num_grps].priv = priv;
+ spin_lock_init(&priv->gfargrp[priv->num_grps].grplock);
+ if(priv->mode == MQ_MG_MODE) {
+ queue_mask = (u32 *)of_get_property(np,
+ "fsl,rx-bit-map", NULL);
+ priv->gfargrp[priv->num_grps].rx_bit_map =
+ queue_mask ? *queue_mask :(DEFAULT_MAPPING >> priv->num_grps);
+ queue_mask = (u32 *)of_get_property(np,
+ "fsl,tx-bit-map", NULL);
+ priv->gfargrp[priv->num_grps].tx_bit_map =
+ queue_mask ? *queue_mask : (DEFAULT_MAPPING >> priv->num_grps);
+ } else {
+ priv->gfargrp[priv->num_grps].rx_bit_map = 0xFF;
+ priv->gfargrp[priv->num_grps].tx_bit_map = 0xFF;
+ }
+ priv->num_grps++;
+
+ return 0;
+}
+
static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev)
{
const char *model;
const char *ctype;
const void *mac_addr;
- u64 addr, size;
int err = 0, i;
struct net_device *dev = NULL;
struct gfar_private *priv = NULL;
struct device_node *np = ofdev->node;
+ struct device_node *child = NULL;
const u32 *stash;
const u32 *stash_len;
const u32 *stash_idx;
@@ -533,36 +602,26 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev)
dev->real_num_tx_queues = num_tx_qs;
priv->num_tx_queues = num_tx_qs;
priv->num_rx_queues = num_rx_qs;
-
- /* get a pointer to the register memory */
- addr = of_translate_address(np, of_get_address(np, 0, &size, NULL));
- priv->gfargrp.regs = ioremap(addr, size);
-
- if (priv->gfargrp.regs == NULL) {
- err = -ENOMEM;
- goto err_out;
- }
-
- priv->gfargrp.priv = priv; /* back pointer from group to priv */
- priv->gfargrp.rx_bit_map = DEFAULT_MAPPING;
- priv->gfargrp.tx_bit_map = DEFAULT_MAPPING;
-
- priv->gfargrp.interruptTransmit = irq_of_parse_and_map(np, 0);
+ priv->num_grps = 0x0;
model = of_get_property(np, "model", NULL);
- /* If we aren't the FEC we have multiple interrupts */
- if (model && strcasecmp(model, "FEC")) {
- priv->gfargrp.interruptReceive = irq_of_parse_and_map(np, 1);
+ for (i = 0; i < MAXGROUPS; i++)
+ priv->gfargrp[i].regs = NULL;
- priv->gfargrp.interruptError = irq_of_parse_and_map(np, 2);
-
- if (priv->gfargrp.interruptTransmit < 0 ||
- priv->gfargrp.interruptReceive < 0 ||
- priv->gfargrp.interruptError < 0) {
- err = -EINVAL;
- goto err_out;
+ /* Parse and initialize group specific information */
+ if (of_device_is_compatible(np, "fsl,etsec2")) {
+ priv->mode = MQ_MG_MODE;
+ for_each_child_of_node(np, child) {
+ err = gfar_parse_group(child, priv, model);
+ if (err)
+ goto err_grp_init;
}
+ } else {
+ priv->mode = SQ_SG_MODE;
+ err = gfar_parse_group(np, priv, model);
+ if(err)
+ goto err_grp_init;
}
for (i = 0; i < priv->num_tx_queues; i++)
@@ -661,8 +720,8 @@ rx_alloc_failed:
free_rx_pointers(priv);
tx_alloc_failed:
free_tx_pointers(priv);
-err_out:
- iounmap(priv->gfargrp.regs);
+err_grp_init:
+ unmap_group_regs(priv);
free_netdev(dev);
return err;
}
@@ -701,9 +760,11 @@ static int gfar_probe(struct of_device *ofdev,
struct net_device *dev = NULL;
struct gfar_private *priv = NULL;
struct gfar __iomem *regs = NULL;
- int err = 0, i;
+ int err = 0, i, grp_idx = 0;
int len_devname;
u32 rstat = 0, tstat = 0, rqueue = 0, tqueue = 0;
+ u32 isrg = 0;
+ u32 *baddr;
err = gfar_of_init(ofdev, &dev);
@@ -716,12 +777,11 @@ static int gfar_probe(struct of_device *ofdev,
priv->node = ofdev->node;
SET_NETDEV_DEV(dev, &ofdev->dev);
- spin_lock_init(&priv->gfargrp.grplock);
spin_lock_init(&priv->bflock);
INIT_WORK(&priv->reset_task, gfar_reset_task);
dev_set_drvdata(&ofdev->dev, priv);
- regs = priv->gfargrp.regs;
+ regs = priv->gfargrp[0].regs;
/* Stop the DMA engine now, in case it was running before */
/* (The firmware could have used it, and left it running). */
@@ -754,7 +814,8 @@ static int gfar_probe(struct of_device *ofdev,
dev->ethtool_ops = &gfar_ethtool_ops;
/* Register for napi ...We are registering NAPI for each grp */
- netif_napi_add(dev, &priv->gfargrp.napi, gfar_poll, GFAR_DEV_WEIGHT);
+ for (i = 0; i < priv->num_grps; i++)
+ netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll, GFAR_DEV_WEIGHT);
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
priv->rx_csum_enable = 1;
@@ -810,25 +871,51 @@ static int gfar_probe(struct of_device *ofdev,
if (dev->features & NETIF_F_IP_CSUM)
dev->hard_header_len += GMAC_FCB_LEN;
+ /* Program the isrg regs only if number of grps > 1 */
+ if (priv->num_grps > 1) {
+ baddr = ®s->isrg0;
+ for (i = 0; i < priv->num_grps; i++) {
+ isrg |= (priv->gfargrp[i].rx_bit_map << ISRG_SHIFT_RX);
+ isrg |= (priv->gfargrp[i].tx_bit_map << ISRG_SHIFT_TX);
+ gfar_write(baddr, isrg);
+ baddr++;
+ isrg = 0x0;
+ }
+ }
+
/* Need to reverse the bit maps as bit_map's MSB is q0
* but, for_each_bit parses from right to left, which
* basically reverses the queue numbers */
- priv->gfargrp.tx_bit_map = reverse_bitmap(priv->gfargrp.tx_bit_map, MAX_TX_QS);
- priv->gfargrp.rx_bit_map = reverse_bitmap(priv->gfargrp.rx_bit_map, MAX_RX_QS);
-
- /* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values */
- for_each_bit(i, &priv->gfargrp.rx_bit_map, priv->num_rx_queues) {
- priv->gfargrp.num_rx_queues++;
- rstat = rstat | (RSTAT_CLEAR_RHALT >> i);
- rqueue = rqueue | ((RQUEUE_EN0 | RQUEUE_EX0) >> i);
- }
- for_each_bit (i, &priv->gfargrp.tx_bit_map, priv->num_tx_queues) {
- priv->gfargrp.num_tx_queues++;
- tstat = tstat | (TSTAT_CLEAR_THALT >> i);
- tqueue = tqueue | (TQUEUE_EN0 >> i);
+ for (i = 0; i< priv->num_grps; i++) {
+ priv->gfargrp[i].tx_bit_map = reverse_bitmap(
+ priv->gfargrp[i].tx_bit_map, MAX_TX_QS);
+ priv->gfargrp[i].rx_bit_map = reverse_bitmap(
+ priv->gfargrp[i].rx_bit_map, MAX_RX_QS);
+ }
+
+ /* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values,
+ * also assign queues to groups */
+ for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) {
+ priv->gfargrp[grp_idx].num_rx_queues = 0x0;
+ for_each_bit(i, &priv->gfargrp[grp_idx].rx_bit_map,
+ priv->num_rx_queues) {
+ priv->gfargrp[grp_idx].num_rx_queues++;
+ priv->rx_queue[i]->grp = &priv->gfargrp[grp_idx];
+ rstat = rstat | (RSTAT_CLEAR_RHALT >> i);
+ rqueue = rqueue | ((RQUEUE_EN0 | RQUEUE_EX0) >> i);
+ }
+ priv->gfargrp[grp_idx].num_tx_queues = 0x0;
+ for_each_bit (i, &priv->gfargrp[grp_idx].tx_bit_map,
+ priv->num_tx_queues) {
+ priv->gfargrp[grp_idx].num_tx_queues++;
+ priv->tx_queue[i]->grp = &priv->gfargrp[grp_idx];
+ tstat = tstat | (TSTAT_CLEAR_THALT >> i);
+ tqueue = tqueue | (TQUEUE_EN0 >> i);
+ }
+ priv->gfargrp[grp_idx].rstat = rstat;
+ priv->gfargrp[grp_idx].tstat = tstat;
+ rstat = tstat =0;
}
- priv->gfargrp.rstat = rstat;
- priv->gfargrp.tstat = tstat;
gfar_write(®s->rqueue, rqueue);
gfar_write(®s->tqueue, tqueue);
@@ -868,20 +955,40 @@ static int gfar_probe(struct of_device *ofdev,
/* fill out IRQ number and name fields */
len_devname = strlen(dev->name);
- strncpy(&priv->gfargrp.int_name_tx[0], dev->name, len_devname);
- if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
- strncpy(&priv->gfargrp.int_name_tx[len_devname],
- "_tx", sizeof("_tx") + 1);
-
- strncpy(&priv->gfargrp.int_name_rx[0], dev->name, len_devname);
- strncpy(&priv->gfargrp.int_name_rx[len_devname],
- "_rx", sizeof("_rx") + 1);
-
- strncpy(&priv->gfargrp.int_name_er[0], dev->name, len_devname);
- strncpy(&priv->gfargrp.int_name_er[len_devname],
- "_er", sizeof("_er") + 1);
- } else
- priv->gfargrp.int_name_tx[len_devname] = '\0';
+ for (i = 0; i < priv->num_grps; i++) {
+ strncpy(&priv->gfargrp[i].int_name_tx[0], dev->name,
+ len_devname);
+ if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
+ strncpy(&priv->gfargrp[i].int_name_tx[len_devname],
+ "_g", sizeof("_g"));
+ priv->gfargrp[i].int_name_tx[
+ strlen(priv->gfargrp[i].int_name_tx)] = i+48;
+ strncpy(&priv->gfargrp[i].int_name_tx[strlen(
+ priv->gfargrp[i].int_name_tx)],
+ "_tx", sizeof("_tx") + 1);
+
+ strncpy(&priv->gfargrp[i].int_name_rx[0], dev->name,
+ len_devname);
+ strncpy(&priv->gfargrp[i].int_name_rx[len_devname],
+ "_g", sizeof("_g"));
+ priv->gfargrp[i].int_name_rx[
+ strlen(priv->gfargrp[i].int_name_rx)] = i+48;
+ strncpy(&priv->gfargrp[i].int_name_rx[strlen(
+ priv->gfargrp[i].int_name_rx)],
+ "_rx", sizeof("_rx") + 1);
+
+ strncpy(&priv->gfargrp[i].int_name_er[0], dev->name,
+ len_devname);
+ strncpy(&priv->gfargrp[i].int_name_er[len_devname],
+ "_g", sizeof("_g"));
+ priv->gfargrp[i].int_name_er[strlen(
+ priv->gfargrp[i].int_name_er)] = i+48;
+ strncpy(&priv->gfargrp[i].int_name_er[strlen(\
+ priv->gfargrp[i].int_name_er)],
+ "_er", sizeof("_er") + 1);
+ } else
+ priv->gfargrp[i].int_name_tx[len_devname] = '\0';
+ }
/* Create all the sysfs files */
gfar_init_sysfs(dev);
@@ -902,7 +1009,7 @@ static int gfar_probe(struct of_device *ofdev,
return 0;
register_fail:
- iounmap(priv->gfargrp.regs);
+ unmap_group_regs(priv);
free_tx_pointers(priv);
free_rx_pointers(priv);
if (priv->phy_node)
@@ -925,7 +1032,7 @@ static int gfar_remove(struct of_device *ofdev)
dev_set_drvdata(&ofdev->dev, NULL);
unregister_netdev(priv->ndev);
- iounmap(priv->gfargrp.regs);
+ unmap_group_regs(priv);
free_netdev(priv->ndev);
return 0;
@@ -937,7 +1044,7 @@ static int gfar_suspend(struct device *dev)
{
struct gfar_private *priv = dev_get_drvdata(dev);
struct net_device *ndev = priv->ndev;
- struct gfar __iomem *regs = NULL;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
unsigned long flags;
u32 tempval;
@@ -945,7 +1052,6 @@ static int gfar_suspend(struct device *dev)
(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
netif_device_detach(ndev);
- regs = priv->gfargrp.regs;
if (netif_running(ndev)) {
@@ -969,7 +1075,7 @@ static int gfar_suspend(struct device *dev)
unlock_tx_qs(priv);
local_irq_restore(flags);
- napi_disable(&priv->gfargrp.napi);
+ disable_napi(priv);
if (magic_packet) {
/* Enable interrupt on Magic Packet */
@@ -991,7 +1097,7 @@ static int gfar_resume(struct device *dev)
{
struct gfar_private *priv = dev_get_drvdata(dev);
struct net_device *ndev = priv->ndev;
- struct gfar __iomem *regs = NULL;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
unsigned long flags;
u32 tempval;
int magic_packet = priv->wol_en &&
@@ -1008,8 +1114,6 @@ static int gfar_resume(struct device *dev)
/* Disable Magic Packet mode, in case something
* else woke us up.
*/
- regs = priv->gfargrp.regs;
-
local_irq_save(flags);
lock_tx_qs(priv);
lock_rx_qs(priv);
@@ -1026,7 +1130,7 @@ static int gfar_resume(struct device *dev)
netif_device_attach(ndev);
- napi_enable(&priv->gfargrp.napi);
+ enable_napi(priv);
return 0;
}
@@ -1092,10 +1196,9 @@ static int gfar_legacy_resume(struct of_device *ofdev)
static phy_interface_t gfar_get_interface(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
- struct gfar __iomem *regs = NULL;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
u32 ecntrl;
- regs = priv->gfargrp.regs;
ecntrl = gfar_read(®s->ecntrl);
if (ecntrl & ECNTRL_SGMII_MODE)
@@ -1219,14 +1322,18 @@ static void init_registers(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
struct gfar __iomem *regs = NULL;
+ int i = 0;
- regs = priv->gfargrp.regs;
- /* Clear IEVENT */
- gfar_write(®s->ievent, IEVENT_INIT_CLEAR);
+ for (i = 0; i < priv->num_grps; i++) {
+ regs = priv->gfargrp[i].regs;
+ /* Clear IEVENT */
+ gfar_write(®s->ievent, IEVENT_INIT_CLEAR);
- /* Initialize IMASK */
- gfar_write(®s->imask, IMASK_INIT_CLEAR);
+ /* Initialize IMASK */
+ gfar_write(®s->imask, IMASK_INIT_CLEAR);
+ }
+ regs = priv->gfargrp[0].regs;
/* Init hash registers to zero */
gfar_write(®s->igaddr0, 0);
gfar_write(®s->igaddr1, 0);
@@ -1267,15 +1374,20 @@ static void init_registers(struct net_device *dev)
static void gfar_halt_nodisable(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = NULL;
u32 tempval;
+ int i = 0;
- /* Mask all interrupts */
- gfar_write(®s->imask, IMASK_INIT_CLEAR);
+ for (i = 0; i < priv->num_grps; i++) {
+ regs = priv->gfargrp[i].regs;
+ /* Mask all interrupts */
+ gfar_write(®s->imask, IMASK_INIT_CLEAR);
- /* Clear all interrupts */
- gfar_write(®s->ievent, IEVENT_INIT_CLEAR);
+ /* Clear all interrupts */
+ gfar_write(®s->ievent, IEVENT_INIT_CLEAR);
+ }
+ regs = priv->gfargrp[0].regs;
/* Stop the DMA, and wait for it to stop */
tempval = gfar_read(®s->dmactrl);
if ((tempval & (DMACTRL_GRS | DMACTRL_GTS))
@@ -1293,7 +1405,7 @@ static void gfar_halt_nodisable(struct net_device *dev)
void gfar_halt(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
u32 tempval;
gfar_halt_nodisable(dev);
@@ -1304,10 +1416,18 @@ void gfar_halt(struct net_device *dev)
gfar_write(®s->maccfg1, tempval);
}
+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);
+}
+
void stop_gfar(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
unsigned long flags;
+ int i;
phy_stop(priv->phydev);
@@ -1325,11 +1445,12 @@ void stop_gfar(struct net_device *dev)
/* Free the IRQs */
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
- free_irq(priv->gfargrp.interruptError, &priv->gfargrp);
- free_irq(priv->gfargrp.interruptTransmit, &priv->gfargrp);
- free_irq(priv->gfargrp.interruptReceive, &priv->gfargrp);
+ for (i = 0; i < priv->num_grps; i++)
+ free_grp_irqs(&priv->gfargrp[i]);
} else {
- free_irq(priv->gfargrp.interruptTransmit, &priv->gfargrp);
+ for (i = 0; i < priv->num_grps; i++)
+ free_irq(priv->gfargrp[i].interruptTransmit,
+ &priv->gfargrp[i]);
}
free_skb_resources(priv);
@@ -1417,8 +1538,9 @@ static void free_skb_resources(struct gfar_private *priv)
void gfar_start(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
u32 tempval;
+ int i = 0;
/* Enable Rx and Tx in MACCFG1 */
tempval = gfar_read(®s->maccfg1);
@@ -1435,92 +1557,149 @@ void gfar_start(struct net_device *dev)
tempval &= ~(DMACTRL_GRS | DMACTRL_GTS);
gfar_write(®s->dmactrl, tempval);
- /* Clear THLT/RHLT, so that the DMA starts polling now */
- gfar_write(®s->tstat, priv->gfargrp.tstat);
- gfar_write(®s->rstat, priv->gfargrp.rstat);
-
- /* Unmask the interrupts we look for */
- gfar_write(®s->imask, IMASK_DEFAULT);
+ for (i = 0; i < priv->num_grps; i++) {
+ regs = priv->gfargrp[i].regs;
+ /* Clear THLT/RHLT, so that the DMA starts polling now */
+ gfar_write(®s->tstat, priv->gfargrp[i].tstat);
+ gfar_write(®s->rstat, priv->gfargrp[i].rstat);
+ /* Unmask the interrupts we look for */
+ gfar_write(®s->imask, IMASK_DEFAULT);
+ }
dev->trans_start = jiffies;
}
-/* Bring the controller up and running */
-int startup_gfar(struct net_device *ndev)
+void gfar_configure_coalescing(struct gfar_private *priv,
+ unsigned int tx_mask, unsigned int rx_mask)
{
- struct gfar_private *priv = netdev_priv(ndev);
- struct gfar __iomem *regs = priv->gfargrp.regs;
- int err;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
+ u32 *baddr;
+ int i = 0;
- gfar_write(®s->imask, IMASK_INIT_CLEAR);
+ /* Backward compatible case ---- even if we enable
+ * multiple queues, there's only single reg to program
+ */
+ gfar_write(®s->txic, 0);
+ if(likely(priv->tx_queue[0]->txcoalescing))
+ gfar_write(®s->txic, priv->tx_queue[0]->txic);
- err = gfar_alloc_skb_resources(ndev);
- if (err)
- return err;
+ gfar_write(®s->rxic, 0);
+ if(unlikely(priv->rx_queue[0]->rxcoalescing))
+ gfar_write(®s->rxic, priv->rx_queue[0]->rxic);
- gfar_init_mac(ndev);
+ if (priv->mode == MQ_MG_MODE) {
+ baddr = ®s->txic0;
+ for_each_bit (i, &tx_mask, priv->num_tx_queues) {
+ if (likely(priv->tx_queue[i]->txcoalescing)) {
+ gfar_write(baddr + i, 0);
+ gfar_write(baddr + i, priv->tx_queue[i]->txic);
+ }
+ }
+
+ baddr = ®s->rxic0;
+ for_each_bit (i, &rx_mask, priv->num_rx_queues) {
+ if (likely(priv->rx_queue[i]->rxcoalescing)) {
+ gfar_write(baddr + i, 0);
+ gfar_write(baddr + i, priv->rx_queue[i]->rxic);
+ }
+ }
+ }
+}
+
+static int register_grp_irqs(struct gfar_priv_grp *grp)
+{
+ struct gfar_private *priv = grp->priv;
+ struct net_device *dev = priv->ndev;
+ int err;
/* If the device has multiple interrupts, register for
* them. Otherwise, only register for the one */
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
/* Install our interrupt handlers for Error,
* Transmit, and Receive */
- err = request_irq(priv->gfargrp.interruptError, gfar_error, 0,
- priv->gfargrp.int_name_er, &priv->gfargrp);
- if (err) {
+ if ((err = request_irq(grp->interruptError, gfar_error, 0,
+ grp->int_name_er,grp)) < 0) {
if (netif_msg_intr(priv))
- pr_err("%s: Can't get IRQ %d\n", ndev->name,
- priv->gfargrp.interruptError);
- goto err_irq_fail;
+ printk(KERN_ERR "%s: Can't get IRQ %d\n",
+ dev->name, grp->interruptError);
+
+ goto err_irq_fail;
}
- err = request_irq(priv->gfargrp.interruptTransmit,
- gfar_transmit, 0,
- priv->gfargrp.int_name_tx,
- &priv->gfargrp);
- if (err) {
+ if ((err = request_irq(grp->interruptTransmit, gfar_transmit,
+ 0, grp->int_name_tx, grp)) < 0) {
if (netif_msg_intr(priv))
- pr_err("%s: Can't get IRQ %d\n", ndev->name,
- priv->gfargrp.interruptTransmit);
+ printk(KERN_ERR "%s: Can't get IRQ %d\n",
+ dev->name, grp->interruptTransmit);
goto tx_irq_fail;
}
- err = request_irq(priv->gfargrp.interruptReceive,
- gfar_receive, 0,
- priv->gfargrp.int_name_rx,
- &priv->gfargrp);
- if (err) {
+ if ((err = request_irq(grp->interruptReceive, gfar_receive, 0,
+ grp->int_name_rx, grp)) < 0) {
if (netif_msg_intr(priv))
- pr_err("%s: Can't get IRQ %d (receive0)\n",
- ndev->name,
- priv->gfargrp.interruptReceive);
+ printk(KERN_ERR "%s: Can't get IRQ %d\n",
+ dev->name, grp->interruptReceive);
goto rx_irq_fail;
}
} else {
- err = request_irq(priv->gfargrp.interruptTransmit,
- gfar_interrupt, 0,
- priv->gfargrp.int_name_tx,
- &priv->gfargrp);
- if (err) {
+ if ((err = request_irq(grp->interruptTransmit, gfar_interrupt, 0,
+ grp->int_name_tx, grp)) < 0) {
if (netif_msg_intr(priv))
- pr_err("%s: Can't get IRQ %d\n", ndev->name,
- priv->gfargrp.interruptTransmit);
+ printk(KERN_ERR "%s: Can't get IRQ %d\n",
+ dev->name, grp->interruptTransmit);
goto err_irq_fail;
}
}
+ return 0;
+
+rx_irq_fail:
+ free_irq(grp->interruptTransmit, grp);
+tx_irq_fail:
+ free_irq(grp->interruptError, grp);
+err_irq_fail:
+ return err;
+
+}
+
+/* Bring the controller up and running */
+int startup_gfar(struct net_device *ndev)
+{
+ struct gfar_private *priv = netdev_priv(ndev);
+ struct gfar __iomem *regs = NULL;
+ int err, i, j;
+
+ for (i = 0; i < priv->num_grps; i++) {
+ regs= priv->gfargrp[i].regs;
+ gfar_write(®s->imask, IMASK_INIT_CLEAR);
+ }
+
+ regs= priv->gfargrp[0].regs;
+ err = gfar_alloc_skb_resources(ndev);
+ if (err)
+ return err;
+
+ gfar_init_mac(ndev);
+
+ for (i = 0; i < priv->num_grps; i++) {
+ err = register_grp_irqs(&priv->gfargrp[i]);
+ if (err) {
+ for (j = 0; j < i; j++)
+ free_grp_irqs(&priv->gfargrp[j]);
+ goto irq_fail;
+ }
+ }
+
/* Start the controller */
gfar_start(ndev);
phy_start(priv->phydev);
+ gfar_configure_coalescing(priv, 0xFF, 0xFF);
+
return 0;
-rx_irq_fail:
- free_irq(priv->gfargrp.interruptTransmit, &priv->gfargrp);
-tx_irq_fail:
- free_irq(priv->gfargrp.interruptError, &priv->gfargrp);
-err_irq_fail:
+irq_fail:
free_skb_resources(priv);
return err;
}
@@ -1532,7 +1711,7 @@ static int gfar_enet_open(struct net_device *dev)
struct gfar_private *priv = netdev_priv(dev);
int err;
- napi_enable(&priv->gfargrp.napi);
+ enable_napi(priv);
skb_queue_head_init(&priv->rx_recycle);
@@ -1544,13 +1723,13 @@ static int gfar_enet_open(struct net_device *dev)
err = init_phy(dev);
if (err) {
- napi_disable(&priv->gfargrp.napi);
+ disable_napi(priv);
return err;
}
err = startup_gfar(dev);
if (err) {
- napi_disable(&priv->gfargrp.napi);
+ disable_napi(priv);
return err;
}
@@ -1639,7 +1818,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_queue = priv->tx_queue[rq];
txq = netdev_get_tx_queue(dev, rq);
base = tx_queue->tx_bd_base;
- regs = priv->gfargrp.regs;
+ regs = tx_queue->grp->regs;
/* make space for additional header when fcb is needed */
if (((skb->ip_summed == CHECKSUM_PARTIAL) ||
@@ -1776,7 +1955,7 @@ static int gfar_close(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
- napi_disable(&priv->gfargrp.napi);
+ disable_napi(priv);
skb_queue_purge(&priv->rx_recycle);
cancel_work_sync(&priv->reset_task);
@@ -1809,7 +1988,7 @@ static void gfar_vlan_rx_register(struct net_device *dev,
unsigned long flags;
u32 tempval;
- regs = priv->gfargrp.regs;
+ regs = priv->gfargrp[0].regs;
local_irq_save(flags);
lock_rx_qs(priv);
@@ -1853,7 +2032,7 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
{
int tempsize, tempval;
struct gfar_private *priv = netdev_priv(dev);
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
int oldsize = priv->rx_buffer_size;
int frame_size = new_mtu + ETH_HLEN;
@@ -2275,7 +2454,7 @@ static int gfar_poll(struct napi_struct *napi, int budget)
struct gfar_priv_grp *gfargrp = container_of(napi,
struct gfar_priv_grp, napi);
struct gfar_private *priv = gfargrp->priv;
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = gfargrp->regs;
struct gfar_priv_tx_q *tx_queue = NULL;
struct gfar_priv_rx_q *rx_queue = NULL;
int rx_cleaned = 0, budget_per_queue = 0, rx_cleaned_per_queue = 0;
@@ -2334,14 +2513,8 @@ static int gfar_poll(struct napi_struct *napi, int budget)
/* If we are coalescing interrupts, update the timer */
/* Otherwise, clear it */
- if (likely(rx_queue->rxcoalescing)) {
- gfar_write(®s->rxic, 0);
- gfar_write(®s->rxic, rx_queue->rxic);
- }
- if (likely(tx_queue->txcoalescing)) {
- gfar_write(®s->txic, 0);
- gfar_write(®s->txic, tx_queue->txic);
- }
+ gfar_configure_coalescing(priv,
+ gfargrp->rx_bit_map, gfargrp->tx_bit_map);
}
return rx_cleaned;
@@ -2356,20 +2529,26 @@ static int gfar_poll(struct napi_struct *napi, int budget)
static void gfar_netpoll(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
+ int i = 0;
/* If the device has multiple interrupts, run tx/rx */
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
- disable_irq(priv->gfargrp.interruptTransmit);
- disable_irq(priv->gfargrp.interruptReceive);
- disable_irq(priv->gfargrp.interruptError);
- gfar_interrupt(priv->gfargrp.interruptTransmit, &priv->gfargrp);
- enable_irq(priv->gfargrp.interruptError);
- enable_irq(priv->gfargrp.interruptReceive);
- enable_irq(priv->gfargrp.interruptTransmit);
+ for (i = 0; i < priv->num_grps; i++) {
+ disable_irq(priv->gfargrp[i].interruptTransmit);
+ disable_irq(priv->gfargrp[i].interruptReceive);
+ disable_irq(priv->gfargrp[i].interruptError);
+ gfar_interrupt(priv->gfargrp[i].interruptTransmit,
+ &priv->gfargrp[i]);
+ enable_irq(priv->gfargrp[i].interruptError);
+ enable_irq(priv->gfargrp[i].interruptReceive);
+ enable_irq(priv->gfargrp[i].interruptTransmit);
+ }
} else {
- disable_irq(priv->gfargrp.interruptTransmit);
- gfar_interrupt(priv->gfargrp.interruptTransmit, &priv->gfargrp);
- enable_irq(priv->gfargrp.interruptTransmit);
+ for (i = 0; i < priv->num_grps; i++) {
+ disable_irq(priv->gfargrp[i].interruptTransmit);
+ gfar_interrupt(priv->gfargrp[i].interruptTransmit,
+ &priv->gfargrp[i]);
+ enable_irq(priv->gfargrp[i].interruptTransmit);
}
}
#endif
@@ -2406,7 +2585,7 @@ static irqreturn_t gfar_interrupt(int irq, void *grp_id)
static void adjust_link(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
unsigned long flags;
struct phy_device *phydev = priv->phydev;
int new_state = 0;
@@ -2490,7 +2669,7 @@ static void gfar_set_multi(struct net_device *dev)
{
struct dev_mc_list *mc_ptr;
struct gfar_private *priv = netdev_priv(dev);
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
u32 tempval;
if (dev->flags & IFF_PROMISC) {
@@ -2623,7 +2802,7 @@ static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr)
static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr)
{
struct gfar_private *priv = netdev_priv(dev);
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
int idx;
char tmpbuf[MAC_ADDR_LEN];
u32 tempval;
@@ -2727,6 +2906,9 @@ static struct of_device_id gfar_match[] =
.type = "network",
.compatible = "gianfar",
},
+ {
+ .compatible = "fsl,etsec2",
+ },
{},
};
MODULE_DEVICE_TABLE(of, gfar_match);
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 70c25ce..a43b238 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -79,6 +79,9 @@ extern const char gfar_driver_version[];
#define MAX_TX_QS 0x8
#define MAX_RX_QS 0x8
+/* MAXIMUM NUMBER OF GROUPS SUPPORTED */
+#define MAXGROUPS 0x2
+
/* These need to be powers of 2 for this driver */
#define DEFAULT_TX_RING_SIZE 256
#define DEFAULT_RX_RING_SIZE 256
@@ -795,7 +798,24 @@ struct gfar {
#define FSL_GIANFAR_DEV_HAS_BD_STASHING 0x00000200
#define FSL_GIANFAR_DEV_HAS_BUF_STASHING 0x00000400
+#if (MAXGROUPS == 2)
+#define DEFAULT_MAPPING 0xAA
+#else
#define DEFAULT_MAPPING 0xFF
+#endif
+
+#define ISRG_SHIFT_TX 0x10
+#define ISRG_SHIFT_RX 0x18
+
+/* The same driver can operate in two modes */
+/* SQ_SG_MODE: Single Queue Single Group Mode
+ * (Backward compatible mode)
+ * MQ_MG_MODE: Multi Queue Multi Group mode
+ */
+enum {
+ SQ_SG_MODE = 0,
+ MQ_MG_MODE
+};
/**
* struct gfar_priv_tx_q - per tx queue structure
@@ -825,6 +845,7 @@ struct gfar_priv_tx_q {
struct txbd8 *cur_tx;
struct txbd8 *dirty_tx;
struct net_device *dev;
+ struct gfar_priv_grp *grp;
u16 skb_curtx;
u16 skb_dirtytx;
u16 qindex;
@@ -857,6 +878,7 @@ struct gfar_priv_rx_q {
struct rxbd8 *rx_bd_base;
struct rxbd8 *cur_rx;
struct net_device *dev;
+ struct gfar_priv_grp *grp;
u16 skb_currx;
u16 qindex;
unsigned int rx_ring_size;
@@ -884,6 +906,7 @@ struct gfar_priv_grp {
struct napi_struct napi;
struct gfar_private *priv;
struct gfar __iomem *regs;
+ unsigned int grp_id;
unsigned int rx_bit_map;
unsigned int tx_bit_map;
unsigned int num_tx_queues;
@@ -915,6 +938,8 @@ struct gfar_private {
/* Indicates how many tx, rx queues are enabled */
unsigned int num_tx_queues;
unsigned int num_rx_queues;
+ unsigned int num_grps;
+ unsigned int mode;
/* The total tx and rx ring size for the enabled queues */
unsigned int total_tx_ring_size;
@@ -924,7 +949,7 @@ struct gfar_private {
struct net_device *ndev;
struct of_device *ofdev;
- struct gfar_priv_grp gfargrp;
+ struct gfar_priv_grp gfargrp[MAXGROUPS];
struct gfar_priv_tx_q *tx_queue[MAX_TX_QS];
struct gfar_priv_rx_q *rx_queue[MAX_RX_QS];
@@ -998,6 +1023,8 @@ extern void stop_gfar(struct net_device *dev);
extern void gfar_halt(struct net_device *dev);
extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
int enable, u32 regnum, u32 read);
+extern void gfar_configure_coalescing(struct gfar_private *priv,
+ unsigned int tx_mask, unsigned int rx_mask);
void gfar_init_sysfs(struct net_device *dev);
extern const struct ethtool_ops gfar_ethtool_ops;
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index d3d2623..562f6c2 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -137,7 +137,7 @@ static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
{
int i;
struct gfar_private *priv = netdev_priv(dev);
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
u64 *extra = (u64 *) & priv->extra_stats;
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
@@ -226,7 +226,7 @@ static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, voi
{
int i;
struct gfar_private *priv = netdev_priv(dev);
- u32 __iomem *theregs = (u32 __iomem *) priv->gfargrp.regs;
+ u32 __iomem *theregs = (u32 __iomem *) priv->gfargrp[0].regs;
u32 *buf = (u32 *) regbuf;
for (i = 0; i < sizeof (struct gfar) / sizeof (u32); i++)
@@ -352,22 +352,23 @@ static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
{
struct gfar_private *priv = netdev_priv(dev);
- struct gfar __iomem *regs = priv->gfargrp.regs;
- struct gfar_priv_tx_q *tx_queue = NULL;
- struct gfar_priv_rx_q *rx_queue = NULL;
+ int i = 0;
if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
return -EOPNOTSUPP;
- tx_queue = priv->tx_queue[0];
- rx_queue = priv->rx_queue[0];
-
/* Set up rx coalescing */
+ /* As of now, we will enable/disable coalescing for all
+ * queues together in case of eTSEC2, this will be modified
+ * along with the ethtool interface */
if ((cvals->rx_coalesce_usecs == 0) ||
- (cvals->rx_max_coalesced_frames == 0))
- rx_queue->rxcoalescing = 0;
- else
- rx_queue->rxcoalescing = 1;
+ (cvals->rx_max_coalesced_frames == 0)) {
+ for (i = 0; i < priv->num_rx_queues; i++)
+ priv->rx_queue[i]->rxcoalescing = 0;
+ } else {
+ for (i = 0; i < priv->num_rx_queues; i++)
+ priv->rx_queue[i]->rxcoalescing = 1;
+ }
if (NULL == priv->phydev)
return -ENODEV;
@@ -385,15 +386,21 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
return -EINVAL;
}
- rx_queue->rxic = mk_ic_value(cvals->rx_max_coalesced_frames,
- gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs));
+ for (i = 0; i < priv->num_rx_queues; i++) {
+ priv->rx_queue[i]->rxic = mk_ic_value(
+ cvals->rx_max_coalesced_frames,
+ gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs));
+ }
/* Set up tx coalescing */
if ((cvals->tx_coalesce_usecs == 0) ||
- (cvals->tx_max_coalesced_frames == 0))
- tx_queue->txcoalescing = 0;
- else
- tx_queue->txcoalescing = 1;
+ (cvals->tx_max_coalesced_frames == 0)) {
+ for (i = 0; i < priv->num_tx_queues; i++)
+ priv->tx_queue[i]->txcoalescing = 0;
+ } else {
+ for (i = 0; i < priv->num_tx_queues; i++)
+ priv->tx_queue[i]->txcoalescing = 1;
+ }
/* Check the bounds of the values */
if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
@@ -408,16 +415,13 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
return -EINVAL;
}
- tx_queue->txic = mk_ic_value(cvals->tx_max_coalesced_frames,
- gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs));
-
- gfar_write(®s->rxic, 0);
- if (rx_queue->rxcoalescing)
- gfar_write(®s->rxic, rx_queue->rxic);
+ for (i = 0; i < priv->num_tx_queues; i++) {
+ priv->tx_queue[i]->txic = mk_ic_value(
+ cvals->tx_max_coalesced_frames,
+ gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs));
+ }
- gfar_write(®s->txic, 0);
- if (tx_queue->txcoalescing)
- gfar_write(®s->txic, tx_queue->txic);
+ gfar_configure_coalescing(priv, 0xFF, 0xFF);
return 0;
}
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c
index 4b726f6..3724835 100644
--- a/drivers/net/gianfar_sysfs.c
+++ b/drivers/net/gianfar_sysfs.c
@@ -50,7 +50,7 @@ static ssize_t gfar_set_bd_stash(struct device *dev,
const char *buf, size_t count)
{
struct gfar_private *priv = netdev_priv(to_net_dev(dev));
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
int new_setting = 0;
u32 temp;
unsigned long flags;
@@ -105,7 +105,7 @@ static ssize_t gfar_set_rx_stash_size(struct device *dev,
const char *buf, size_t count)
{
struct gfar_private *priv = netdev_priv(to_net_dev(dev));
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
unsigned int length = simple_strtoul(buf, NULL, 0);
u32 temp;
unsigned long flags;
@@ -164,7 +164,7 @@ static ssize_t gfar_set_rx_stash_index(struct device *dev,
const char *buf, size_t count)
{
struct gfar_private *priv = netdev_priv(to_net_dev(dev));
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
unsigned short index = simple_strtoul(buf, NULL, 0);
u32 temp;
unsigned long flags;
@@ -212,7 +212,7 @@ static ssize_t gfar_set_fifo_threshold(struct device *dev,
const char *buf, size_t count)
{
struct gfar_private *priv = netdev_priv(to_net_dev(dev));
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
unsigned int length = simple_strtoul(buf, NULL, 0);
u32 temp;
unsigned long flags;
@@ -252,7 +252,7 @@ static ssize_t gfar_set_fifo_starve(struct device *dev,
const char *buf, size_t count)
{
struct gfar_private *priv = netdev_priv(to_net_dev(dev));
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
unsigned int num = simple_strtoul(buf, NULL, 0);
u32 temp;
unsigned long flags;
@@ -293,7 +293,7 @@ static ssize_t gfar_set_fifo_starve_off(struct device *dev,
const char *buf, size_t count)
{
struct gfar_private *priv = netdev_priv(to_net_dev(dev));
- struct gfar __iomem *regs = priv->gfargrp.regs;
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
unsigned int num = simple_strtoul(buf, NULL, 0);
u32 temp;
unsigned long flags;
--
1.5.2.2
^ permalink raw reply related
* [PATCH v1 7/7] gianfar: Basic Support for programming hash rules
From: Sandeep Gopalpet @ 2009-10-26 16:27 UTC (permalink / raw)
To: netdev; +Cc: Sandeep Gopalpet
This patch provides basic hash rules programming via the ethtool
interface.
Signed-off-by: Sandeep Gopalpet <sandeep.kumar@freescale.com>
---
drivers/net/gianfar.c | 73 +++++++++++++
drivers/net/gianfar.h | 93 ++++++++++++++++
drivers/net/gianfar_ethtool.c | 236 +++++++++++++++++++++++++++++++++++++++++
include/linux/ethtool.h | 2 +
4 files changed, 404 insertions(+), 0 deletions(-)
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index a60e05f..c9179d7 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -416,6 +416,9 @@ static const struct net_device_ops gfar_netdev_ops = {
#endif
};
+unsigned int ftp_rqfpr[MAX_FILER_IDX + 1];
+unsigned int ftp_rqfcr[MAX_FILER_IDX + 1];
+
inline void lock_rx_qs(struct gfar_private *priv)
{
int i = 0x0;
@@ -751,6 +754,73 @@ static unsigned int reverse_bitmap(unsigned int bit_map, unsigned int max_qs)
}
return new_bit_map;
}
+
+u32 cluster_entry_per_class(struct gfar_private *priv, u32 rqfar, u32 class)
+{
+ u32 rqfpr = FPR_FILER_MASK;
+ u32 rqfcr = 0x0;
+
+ rqfar--;
+ rqfcr = RQFCR_CLE | RQFCR_PID_MASK | RQFCR_CMP_EXACT;
+ ftp_rqfpr[rqfar] = rqfpr;
+ ftp_rqfcr[rqfar] = rqfcr;
+ gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
+
+ rqfar--;
+ rqfcr = RQFCR_CMP_NOMATCH;
+ ftp_rqfpr[rqfar] = rqfpr;
+ ftp_rqfcr[rqfar] = rqfcr;
+ gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
+
+ rqfar--;
+ rqfcr = RQFCR_CMP_EXACT | RQFCR_PID_PARSE | RQFCR_CLE | RQFCR_AND;
+ rqfpr = class;
+ ftp_rqfcr[rqfar] = rqfcr;
+ ftp_rqfpr[rqfar] = rqfpr;
+ gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
+
+ rqfar--;
+ rqfcr = RQFCR_CMP_EXACT | RQFCR_PID_MASK | RQFCR_AND;
+ rqfpr = class;
+ ftp_rqfcr[rqfar] = rqfcr;
+ ftp_rqfpr[rqfar] = rqfpr;
+ gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
+
+ return rqfar;
+}
+
+static void gfar_init_filer_table(struct gfar_private *priv)
+{
+ int i = 0x0;
+ u32 rqfar = MAX_FILER_IDX;
+ u32 rqfcr = 0x0;
+ u32 rqfpr = FPR_FILER_MASK;
+
+ /* Default rule */
+ rqfcr = RQFCR_CMP_MATCH;
+ ftp_rqfcr[rqfar] = rqfcr;
+ ftp_rqfpr[rqfar] = rqfpr;
+ gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
+
+ rqfar = cluster_entry_per_class(priv, rqfar, RQFPR_IPV6);
+ rqfar = cluster_entry_per_class(priv, rqfar, RQFPR_IPV6 | RQFPR_UDP);
+ rqfar = cluster_entry_per_class(priv, rqfar, RQFPR_IPV6 | RQFPR_TCP);
+ rqfar = cluster_entry_per_class(priv, rqfar, RQFPR_IPV4);
+ rqfar = cluster_entry_per_class(priv, rqfar, RQFPR_IPV4 | RQFPR_UDP);
+ rqfar = cluster_entry_per_class(priv, rqfar, RQFPR_IPV4 | RQFPR_TCP);
+
+ /* cur_filer_idx indicated the fisrt non-masked rule */
+ priv->cur_filer_idx = rqfar;
+
+ /* Rest are masked rules */
+ rqfcr = RQFCR_CMP_NOMATCH;
+ for (i = 0; i < rqfar; i++) {
+ ftp_rqfcr[i] = rqfcr;
+ ftp_rqfpr[i] = rqfpr;
+ gfar_write_filer(priv, i, rqfcr, rqfpr);
+ }
+}
+
/* Set up the ethernet device structure, private data,
* and anything else we need before we start */
static int gfar_probe(struct of_device *ofdev,
@@ -990,6 +1060,9 @@ static int gfar_probe(struct of_device *ofdev,
priv->gfargrp[i].int_name_tx[len_devname] = '\0';
}
+ /* Initialize the filer table */
+ gfar_init_filer_table(priv);
+
/* Create all the sysfs files */
gfar_init_sysfs(dev);
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index a43b238..1c9fdea 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -381,6 +381,84 @@ extern const char gfar_driver_version[];
#define BD_LFLAG(flags) ((flags) << 16)
#define BD_LENGTH_MASK 0x0000ffff
+#define CLASS_CODE_UNRECOG 0x00
+#define CLASS_CODE_DUMMY1 0x01
+#define CLASS_CODE_ETHERTYPE1 0x02
+#define CLASS_CODE_ETHERTYPE2 0x03
+#define CLASS_CODE_USER_PROG1 0x04
+#define CLASS_CODE_USER_PROG2 0x05
+#define CLASS_CODE_USER_PROG3 0x06
+#define CLASS_CODE_USER_PROG4 0x07
+#define CLASS_CODE_TCP_IPV4 0x08
+#define CLASS_CODE_UDP_IPV4 0x09
+#define CLASS_CODE_AH_ESP_IPV4 0x0a
+#define CLASS_CODE_SCTP_IPV4 0x0b
+#define CLASS_CODE_TCP_IPV6 0x0c
+#define CLASS_CODE_UDP_IPV6 0x0d
+#define CLASS_CODE_AH_ESP_IPV6 0x0e
+#define CLASS_CODE_SCTP_IPV6 0x0f
+
+#define FPR_FILER_MASK 0xFFFFFFFF
+#define MAX_FILER_IDX 0xFF
+
+/* RQFCR register bits */
+#define RQFCR_GPI 0x80000000
+#define RQFCR_HASHTBL_Q 0x00000000
+#define RQFCR_HASHTBL_0 0x00020000
+#define RQFCR_HASHTBL_1 0x00040000
+#define RQFCR_HASHTBL_2 0x00060000
+#define RQFCR_HASHTBL_3 0x00080000
+#define RQFCR_HASH 0x00010000
+#define RQFCR_CLE 0x00000200
+#define RQFCR_RJE 0x00000100
+#define RQFCR_AND 0x00000080
+#define RQFCR_CMP_EXACT 0x00000000
+#define RQFCR_CMP_MATCH 0x00000020
+#define RQFCR_CMP_NOEXACT 0x00000040
+#define RQFCR_CMP_NOMATCH 0x00000060
+
+/* RQFCR PID values */
+#define RQFCR_PID_MASK 0x00000000
+#define RQFCR_PID_PARSE 0x00000001
+#define RQFCR_PID_ARB 0x00000002
+#define RQFCR_PID_DAH 0x00000003
+#define RQFCR_PID_DAL 0x00000004
+#define RQFCR_PID_SAH 0x00000005
+#define RQFCR_PID_SAL 0x00000006
+#define RQFCR_PID_ETY 0x00000007
+#define RQFCR_PID_VID 0x00000008
+#define RQFCR_PID_PRI 0x00000009
+#define RQFCR_PID_TOS 0x0000000A
+#define RQFCR_PID_L4P 0x0000000B
+#define RQFCR_PID_DIA 0x0000000C
+#define RQFCR_PID_SIA 0x0000000D
+#define RQFCR_PID_DPT 0x0000000E
+#define RQFCR_PID_SPT 0x0000000F
+
+/* RQFPR when PID is 0x0001 */
+#define RQFPR_HDR_GE_512 0x00200000
+#define RQFPR_LERR 0x00100000
+#define RQFPR_RAR 0x00080000
+#define RQFPR_RARQ 0x00040000
+#define RQFPR_AR 0x00020000
+#define RQFPR_ARQ 0x00010000
+#define RQFPR_EBC 0x00008000
+#define RQFPR_VLN 0x00004000
+#define RQFPR_CFI 0x00002000
+#define RQFPR_JUM 0x00001000
+#define RQFPR_IPF 0x00000800
+#define RQFPR_FIF 0x00000400
+#define RQFPR_IPV4 0x00000200
+#define RQFPR_IPV6 0x00000100
+#define RQFPR_ICC 0x00000080
+#define RQFPR_ICV 0x00000040
+#define RQFPR_TCP 0x00000020
+#define RQFPR_UDP 0x00000010
+#define RQFPR_TUC 0x00000008
+#define RQFPR_TUV 0x00000004
+#define RQFPR_PER 0x00000002
+#define RQFPR_EER 0x00000001
+
/* TxBD status field bits */
#define TXBD_READY 0x8000
#define TXBD_PADCRC 0x4000
@@ -958,6 +1036,8 @@ struct gfar_private {
unsigned int rx_stash_size;
unsigned int rx_stash_index;
+ u32 cur_filer_idx;
+
struct sk_buff_head rx_recycle;
struct vlan_group *vlgrp;
@@ -1001,6 +1081,9 @@ struct gfar_private {
struct gfar_extra_stats extra_stats;
};
+extern unsigned int ftp_rqfpr[MAX_FILER_IDX + 1];
+extern unsigned int ftp_rqfcr[MAX_FILER_IDX + 1];
+
static inline u32 gfar_read(volatile unsigned __iomem *addr)
{
u32 val;
@@ -1013,6 +1096,16 @@ static inline void gfar_write(volatile unsigned __iomem *addr, u32 val)
out_be32(addr, val);
}
+static inline void gfar_write_filer(struct gfar_private *priv,
+ unsigned int far, unsigned int fcr, unsigned int fpr)
+{
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
+
+ gfar_write(®s->rqfar, far);
+ gfar_write(®s->rqfcr, fcr);
+ gfar_write(®s->rqfpr, fpr);
+}
+
extern inline void lock_rx_qs(struct gfar_private *priv);
extern inline void lock_tx_qs(struct gfar_private *priv);
extern inline void unlock_rx_qs(struct gfar_private *priv);
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 562f6c2..1010367 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -645,6 +645,241 @@ static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
}
#endif
+static int gfar_ethflow_to_class(int flow_type, u64 *class)
+{
+ switch (flow_type) {
+ case TCP_V4_FLOW:
+ *class = CLASS_CODE_TCP_IPV4;
+ break;
+ case UDP_V4_FLOW:
+ *class = CLASS_CODE_UDP_IPV4;
+ break;
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
+ *class = CLASS_CODE_AH_ESP_IPV4;
+ break;
+ case SCTP_V4_FLOW:
+ *class = CLASS_CODE_SCTP_IPV4;
+ break;
+ case TCP_V6_FLOW:
+ *class = CLASS_CODE_TCP_IPV6;
+ break;
+ case UDP_V6_FLOW:
+ *class = CLASS_CODE_UDP_IPV6;
+ break;
+ case AH_V6_FLOW:
+ case ESP_V6_FLOW:
+ *class = CLASS_CODE_AH_ESP_IPV6;
+ break;
+ case SCTP_V6_FLOW:
+ *class = CLASS_CODE_SCTP_IPV6;
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow)
+{
+ u32 fcr = 0x0, fpr = FPR_FILER_MASK;
+
+ if (ethflow & RXH_L2DA) {
+ fcr = RQFCR_PID_DAH |RQFCR_CMP_NOMATCH |
+ RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0;
+ ftp_rqfpr[priv->cur_filer_idx] = fpr;
+ ftp_rqfcr[priv->cur_filer_idx] = fcr;
+ gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+ priv->cur_filer_idx = priv->cur_filer_idx - 1;
+
+ fcr = RQFCR_PID_DAL | RQFCR_AND | RQFCR_CMP_NOMATCH |
+ RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0;
+ ftp_rqfpr[priv->cur_filer_idx] = fpr;
+ ftp_rqfcr[priv->cur_filer_idx] = fcr;
+ gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+ priv->cur_filer_idx = priv->cur_filer_idx - 1;
+ }
+
+ if (ethflow & RXH_VLAN) {
+ fcr = RQFCR_PID_VID | RQFCR_CMP_NOMATCH | RQFCR_HASH |
+ RQFCR_AND | RQFCR_HASHTBL_0;
+ gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+ ftp_rqfpr[priv->cur_filer_idx] = fpr;
+ ftp_rqfcr[priv->cur_filer_idx] = fcr;
+ priv->cur_filer_idx = priv->cur_filer_idx - 1;
+ }
+
+ if (ethflow & RXH_IP_SRC) {
+ fcr = RQFCR_PID_SIA | RQFCR_CMP_NOMATCH | RQFCR_HASH |
+ RQFCR_AND | RQFCR_HASHTBL_0;
+ ftp_rqfpr[priv->cur_filer_idx] = fpr;
+ ftp_rqfcr[priv->cur_filer_idx] = fcr;
+ gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+ priv->cur_filer_idx = priv->cur_filer_idx - 1;
+ }
+
+ if (ethflow & (RXH_IP_DST)) {
+ fcr = RQFCR_PID_DIA | RQFCR_CMP_NOMATCH | RQFCR_HASH |
+ RQFCR_AND | RQFCR_HASHTBL_0;
+ ftp_rqfpr[priv->cur_filer_idx] = fpr;
+ ftp_rqfcr[priv->cur_filer_idx] = fcr;
+ gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+ priv->cur_filer_idx = priv->cur_filer_idx - 1;
+ }
+
+ if (ethflow & RXH_L3_PROTO) {
+ fcr = RQFCR_PID_L4P | RQFCR_CMP_NOMATCH | RQFCR_HASH |
+ RQFCR_AND | RQFCR_HASHTBL_0;
+ ftp_rqfpr[priv->cur_filer_idx] = fpr;
+ ftp_rqfcr[priv->cur_filer_idx] = fcr;
+ gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+ priv->cur_filer_idx = priv->cur_filer_idx - 1;
+ }
+
+ if (ethflow & RXH_L4_B_0_1) {
+ fcr = RQFCR_PID_SPT | RQFCR_CMP_NOMATCH | RQFCR_HASH |
+ RQFCR_AND | RQFCR_HASHTBL_0;
+ ftp_rqfpr[priv->cur_filer_idx] = fpr;
+ ftp_rqfcr[priv->cur_filer_idx] = fcr;
+ gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+ priv->cur_filer_idx = priv->cur_filer_idx - 1;
+ }
+
+ if (ethflow & RXH_L4_B_2_3) {
+ fcr = RQFCR_PID_DPT | RQFCR_CMP_NOMATCH | RQFCR_HASH |
+ RQFCR_AND | RQFCR_HASHTBL_0;
+ ftp_rqfpr[priv->cur_filer_idx] = fpr;
+ ftp_rqfcr[priv->cur_filer_idx] = fcr;
+ gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+ priv->cur_filer_idx = priv->cur_filer_idx - 1;
+ }
+}
+
+static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u64 class)
+{
+ unsigned int last_rule_idx = priv->cur_filer_idx;
+ unsigned int cmp_rqfpr;
+ unsigned int local_rqfpr[MAX_FILER_IDX + 1];
+ unsigned int local_rqfcr[MAX_FILER_IDX + 1];
+ int i = 0x0, k = 0x0;
+ int j = MAX_FILER_IDX, l = 0x0;
+
+ switch (class) {
+ case TCP_V4_FLOW:
+ cmp_rqfpr = RQFPR_IPV4 |RQFPR_TCP;
+ break;
+ case UDP_V4_FLOW:
+ cmp_rqfpr = RQFPR_IPV4 |RQFPR_UDP;
+ break;
+ case TCP_V6_FLOW:
+ cmp_rqfpr = RQFPR_IPV6 |RQFPR_TCP;
+ break;
+ case UDP_V6_FLOW:
+ cmp_rqfpr = RQFPR_IPV6 |RQFPR_UDP;
+ break;
+ case IPV4_FLOW:
+ cmp_rqfpr = RQFPR_IPV4;
+ case IPV6_FLOW:
+ cmp_rqfpr = RQFPR_IPV6;
+ break;
+ default:
+ printk(KERN_ERR "Right now this class is not supported\n");
+ return 0;
+ }
+
+ for (i = 0; i < MAX_FILER_IDX + 1; i++) {
+ local_rqfpr[j] = ftp_rqfpr[i];
+ local_rqfcr[j] = ftp_rqfcr[i];
+ j--;
+ if ((ftp_rqfcr[i] == (RQFCR_PID_PARSE |
+ RQFCR_CLE |RQFCR_AND)) &&
+ (ftp_rqfpr[i] == cmp_rqfpr))
+ break;
+ }
+
+ if (i == MAX_FILER_IDX + 1) {
+ printk(KERN_ERR "No parse rule found, ");
+ printk(KERN_ERR "can't create hash rules\n");
+ return 0;
+ }
+
+ /* If a match was found, then it begins the starting of a cluster rule
+ * if it was already programmed, we need to overwrite these rules
+ */
+ for (l = i+1; l < MAX_FILER_IDX; l++) {
+ if ((ftp_rqfcr[l] & RQFCR_CLE) &&
+ !(ftp_rqfcr[l] & RQFCR_AND)) {
+ ftp_rqfcr[l] = RQFCR_CLE | RQFCR_CMP_EXACT |
+ RQFCR_HASHTBL_0 | RQFCR_PID_MASK;
+ ftp_rqfpr[l] = FPR_FILER_MASK;
+ gfar_write_filer(priv, l, ftp_rqfcr[l], ftp_rqfpr[l]);
+ break;
+ }
+
+ if (!(ftp_rqfcr[l] & RQFCR_CLE) && (ftp_rqfcr[l] & RQFCR_AND))
+ continue;
+ else {
+ local_rqfpr[j] = ftp_rqfpr[l];
+ local_rqfcr[j] = ftp_rqfcr[l];
+ j--;
+ }
+ }
+
+ priv->cur_filer_idx = l - 1;
+ last_rule_idx = l;
+
+ /* hash rules */
+ ethflow_to_filer_rules(priv, ethflow);
+
+ /* Write back the popped out rules again */
+ for (k = j+1; k < MAX_FILER_IDX; k++) {
+ ftp_rqfpr[priv->cur_filer_idx] = local_rqfpr[k];
+ ftp_rqfcr[priv->cur_filer_idx] = local_rqfcr[k];
+ gfar_write_filer(priv, priv->cur_filer_idx,
+ local_rqfcr[k], local_rqfpr[k]);
+ if (!priv->cur_filer_idx)
+ break;
+ priv->cur_filer_idx = priv->cur_filer_idx - 1;
+ }
+
+ return 1;
+}
+
+static int gfar_set_hash_opts(struct gfar_private *priv, struct ethtool_rxnfc *cmd)
+{
+ u64 class;
+
+ if (!gfar_ethflow_to_class(cmd->flow_type, &class))
+ return -EINVAL;
+
+ if (class < CLASS_CODE_USER_PROG1 ||
+ class > CLASS_CODE_SCTP_IPV6)
+ return -EINVAL;
+
+ /* write the filer rules here */
+ if (!gfar_ethflow_to_filer_table(priv, cmd->data, cmd->flow_type))
+ return -1;
+
+ return 0;
+}
+
+static int gfar_set_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+ int ret = 0;
+
+ switch(cmd->cmd) {
+ case ETHTOOL_SRXFH:
+ ret = gfar_set_hash_opts(priv, cmd);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
const struct ethtool_ops gfar_ethtool_ops = {
.get_settings = gfar_gsettings,
.set_settings = gfar_ssettings,
@@ -670,4 +905,5 @@ const struct ethtool_ops gfar_ethtool_ops = {
.get_wol = gfar_get_wol,
.set_wol = gfar_set_wol,
#endif
+ .set_rxnfc = gfar_set_nfc,
};
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index eb1a48d..edd03b7 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -674,6 +674,8 @@ struct ethtool_ops {
#define AH_V6_FLOW 0x0b
#define ESP_V6_FLOW 0x0c
#define IP_USER_FLOW 0x0d
+#define IPV4_FLOW 0x10
+#define IPV6_FLOW 0x11
/* L3-L4 network traffic flow hash options */
#define RXH_L2DA (1 << 1)
--
1.5.2.2
^ permalink raw reply related
* Re: [PATCH v2 8/8] Document future removal of sysctl_tcp_* options
From: Bill Fink @ 2009-10-26 15:08 UTC (permalink / raw)
To: Gilad Ben-Yossef
Cc: Eric Dumazet, William Allen Simpson, netdev, Ilpo Järvinen
In-Reply-To: <4AE5585E.5010108@codefidence.com>
On Mon, 26 Oct 2009, Gilad Ben-Yossef wrote:
> Eric Dumazet wrote:
>
> > Bill Fink a écrit :
> >
> >> On Sun, 25 Oct 2009, Gilad Ben-Yossef wrote:
> >>
> >>
> >>> Eric Dumazet wrote:
> >>>
> >>>
> >>> I still think having a global kill switch and per route options better
> >>> (basically use the exiting patch but not retire the global kill
> >>> switch|), but if you must Hgow about we leave the global sysctl as they
> >>> are and just have a two bit route option:
> >>>
> >>> 0 Use global default
> >>> 1 Off
> >>> 2 On
> >>>
> >>> It's kind of funny, because this is what the original patch from
> >>> Comsleep does and I thought it needlessly complicates things.
> >>>
> >>> So, what do you say - which will it be?
> >>>
> >> I personally feel the 2-bit settings are overkill. What i think
> >> makes the most sense is for the global options to act as they always
> >> have in the absence of any route specific settings, and for any
> >> route specific settings to override the related global settings.
> >> This is both simple and maintains backward compatibility.
> >>
> >
> > Backward compatibility is important, very important, if not the most
> > important thing. Then usability comes.
> >
> I tend to agree.
> > I know some busy servers where adding/changing a single route makes them
> > go crazy (because of ip route flush cache)
> >
> > So if a route is overriding a global conf, and the admin wants to make an
> > emergency change during peak hours, he should do it by a global setting,
> > or he wont use at all this new stuff, and stay conservative.
> >
> > Alternative would be to not trigger the flush of cache when changing
> > features flags.
> >
> >
> OK. It really sounds like we should go with my first suggestion: global
> sysctl based kill switches, just as we have now and in addition, the
> ability to kill TCP options per route. The TCP option will be used if
> and only if both kill switches (global and per route) are not set.
This wording is confusing. The global kill switch not being set
really means that the sysctl is set. And this assumes the per-route
default is not set. Correct?
> What we achieve is:
>
> 1. Global kill switches work exactly as they do now, whether you use the
> new per route options or not, so backwards compatible.
>
> 2. In addition, if the global kill switch is not in effect, you can also
> kill the options on a per route basis.
>
> I'm going to send third version of the patch to this effect, minus the
> new remote DoS possibility that Ilpo pointed out and leaving the global
> sysctl kill switches be.
>
> If you like it, please ACK ;-)
IIUC this doesn't seem right to me. I believe the global setting
should be a default and the route specific an override. Your scheme
would mean that if I set a global option to disable timestamps, then
I couldn't enable timestamps on specific routes using the per route
setting.
And it also doesn't seem to address Eric's scenario. If I understand
his concern correctly, what seems to be needed is a third global
reset value (not calling it a setting since the actual global setting
wouldn't be changed), which would reset any per-route override settings
to the global default setting.
-Bill
^ permalink raw reply
* Re: Increasing TCP initial cwnd
From: Yair Gottdenker @ 2009-10-26 15:07 UTC (permalink / raw)
To: Ilpo Järvinen, netdev
In-Reply-To: <alpine.DEB.2.00.0910261629040.19761@wel-95.cs.helsinki.fi>
Thanks,
I already had a look in it. Their changes that are related to changing
the initial cwnd (snd_cwnd) are in several places in the patch:
1. tcp_ipv4.c in function tcp_init_cwnd. since currently I am working
with no metric this is irrelevant.
2. tcp_ipv4.c: in function tcp_v4_init_sock, which I applied
3. tcp_minisocks.c - which I applied
. They patched kernel 2.6.18.8 which is very old and there were a lot
of changes since that in the kernel tcp layer. I didn't test their
patch but applying the same logic to 2.6.31.3 doesn't seems to change
initial window size.
It is clear that in order to correctly make the change to the initial
cwnd, one should apply changes to many more scenarios like setting the
initial cwnd after idle time and more. I want to proceed step by step,
first the naive changes to make it work.
On Mon, Oct 26, 2009 at 4:38 PM, Ilpo Järvinen
<ilpo.jarvinen@helsinki.fi> wrote:
> On Mon, 26 Oct 2009, Yair Gottdenker wrote:
>
>> Thanks for the response.
>> I disabled metric by: net.ipv4.tcp_no_metrics_save = 1 in sysctl.conf.
>> But just after the call to tcp_init_metrics in tcp_input.c there is
>> also a call to: tcp_init_congestion_control which calls the congestion
>> control algorithm that is in used. I created my own and in the init
>> function I set the snd_cwnd to 10 and still there is no change and
>> only 4 segments are initially sent.
>> You are right tcp_slow_start has nothing to do with the cwnd size, I
>> mistakenly thought that the initial flow enters that function.
>
> Hopefully you don't mess up anything in there.
>
> Please see from http://www.cs.helsinki.fi/research/iwtcp/kernel-patch/
> I haven't had time/interest to bring it up to date but at least there's
> very clearly shown how the initial window can be configured through a
> sysctl (though don't try to patch it to late kernels, it would just be
> a never ending pain for you :-)).
>
>> What do you mean RW? do you mean tcp read/write buffer size?
>
> RW = Restart Window (RFC2681 IIRC, nowadays also in RFC 5681 I think).
> ...It is related to slow-start after idle.
>
> --
> i.
>
^ permalink raw reply
* Re: [RFC] make per interface sysctl entries configurable
From: Denys Fedoryschenko @ 2009-10-26 15:24 UTC (permalink / raw)
To: Octavian Purdila
Cc: Eric Dumazet, Benjamin LaHaise, Stephen Hemminger, Cosmin Ratiu,
netdev
In-Reply-To: <200910251954.49700.opurdila@ixiacom.com>
I test it on pppoe with 1k customers. It works flawlessly.
When there is problem on network and i have massive users disconnect and then
login, the bottleneck is in lock somewhere in creation of sysctl(according
perf). PPPoE after 200-300 interfaces will start dying, and connection rate
will drop to 20-50 customers per minute, load average will jump to 70-100 (i
guess pppd processes waiting their turn). With this patch i am able to
sustain 200-300 customers / minute login rate and perftop is "clear" now.
Definitely this option is optional, and doesn't cut any functionality by
default, just giving more choice. And for PPP (pppoe/pptp) NAS it is very
useful.
On Sunday 25 October 2009 19:54:49 Octavian Purdila wrote:
> RFC patches are attached.
>
> Another possible approach: add an interface flag and use it to decide
> whether we want per interface sysctl entries or not.
>
> Benchmarks for creating 1000 interface (with the ndst module previously
> posted on the list, ppc750 @800Mhz machine):
>
> - without the patches:
>
> real 4m 38.27s
> user 0m 0.00s
> sys 2m 18.90s
>
> - with the patches:
>
> real 0m 0.10s
> user 0m 0.00s
> sys 0m 0.05s
>
> Thanks,
> tavi
^ permalink raw reply
* Fw: [Bug 14470] New: freez in TCP stack
From: Stephen Hemminger @ 2009-10-26 15:41 UTC (permalink / raw)
To: netdev
Begin forwarded message:
Date: Mon, 26 Oct 2009 12:47:22 GMT
From: bugzilla-daemon@bugzilla.kernel.org
To: shemminger@linux-foundation.org
Subject: [Bug 14470] New: freez in TCP stack
http://bugzilla.kernel.org/show_bug.cgi?id=14470
Summary: freez in TCP stack
Product: Networking
Version: 2.5
Kernel Version: 2.6.31
Platform: All
OS/Version: Linux
Tree: Mainline
Status: NEW
Severity: high
Priority: P1
Component: IPV4
AssignedTo: shemminger@linux-foundation.org
ReportedBy: kolo@albatani.cz
Regression: No
We are hiting kernel panics on Dell R610 servers with e1000e NICs; it apears
usualy under a high network trafic ( around 100Mbit/s) but it is not a rule it
has happened even on low trafic.
Servers are used as reverse http proxy (varnish).
On 6 equal servers this panic happens aprox 2 times a day depending on network
load. Machine completly freezes till the management watchdog reboots.
We had to put serial console on these servers to catch the oops. Is there
anything else We can do to debug this?
The RIP is always the same:
RIP: 0010:[<ffffffff814203cc>] [<ffffffff814203cc>]
tcp_xmit_retransmit_queue+0x8c/0x290
rest of the oops always differs a litle ... here is an example:
RIP: 0010:[<ffffffff814203cc>] [<ffffffff814203cc>]
tcp_xmit_retransmit_queue+0x8c/0x290
RSP: 0018:ffffc90000003a40 EFLAGS: 00010246
RAX: ffff8807e7420678 RBX: ffff8807e74205c0 RCX: 0000000000000000
RDX: 000000004598a105 RSI: 0000000000000000 RDI: ffff8807e74205c0
RBP: ffffc90000003a80 R08: 0000000000000003 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
R13: ffff8807e74205c0 R14: ffff8807e7420678 R15: 0000000000000000
FS: 0000000000000000(0000) GS:ffffc90000000000(0000) knlGS:0000000000000000
CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 0000000000000000 CR3: 0000000001001000 CR4: 00000000000006f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process swapper (pid: 0, threadinfo ffffffff81608000, task ffffffff81631440)
Stack:
ffffc90000003a60 0000000000000000 4598a105e74205c0 000000004598a101
<0> 000000000000050e ffff8807e74205c0 0000000000000003 0000000000000000
<0> ffffc90000003b40 ffffffff8141ae4a ffff8807e7420678 0000000000000000
Call Trace:
<IRQ>
[<ffffffff8141ae4a>] tcp_ack+0x170a/0x1dd0
[<ffffffff8141c362>] tcp_rcv_state_process+0x122/0xab0
[<ffffffff81422c6c>] tcp_v4_do_rcv+0xac/0x220
[<ffffffff813fd02f>] ? nf_iterate+0x5f/0x90
[<ffffffff81424b26>] tcp_v4_rcv+0x586/0x6b0
[<ffffffff813fd0c5>] ? nf_hook_slow+0x65/0xf0
[<ffffffff81406b70>] ? ip_local_deliver_finish+0x0/0x120
[<ffffffff81406bcf>] ip_local_deliver_finish+0x5f/0x120
[<ffffffff8140715b>] ip_local_deliver+0x3b/0x90
[<ffffffff81406971>] ip_rcv_finish+0x141/0x340
[<ffffffff8140701f>] ip_rcv+0x24f/0x350
[<ffffffff813e7ced>] netif_receive_skb+0x20d/0x2f0
[<ffffffff813e7e90>] napi_skb_finish+0x40/0x50
[<ffffffff813e82f4>] napi_gro_receive+0x34/0x40
[<ffffffff8133e0c8>] e1000_receive_skb+0x48/0x60
[<ffffffff81342342>] e1000_clean_rx_irq+0xf2/0x330
[<ffffffff813410a1>] e1000_clean+0x81/0x2a0
[<ffffffff81054ce1>] ? ktime_get+0x11/0x50
[<ffffffff813eaf1c>] net_rx_action+0x9c/0x130
[<ffffffff81046940>] ? get_next_timer_interrupt+0x1d0/0x210
[<ffffffff81041bd7>] __do_softirq+0xb7/0x160
[<ffffffff8100c27c>] call_softirq+0x1c/0x30
[<ffffffff8100e04d>] do_softirq+0x3d/0x80
[<ffffffff81041b0b>] irq_exit+0x7b/0x90
[<ffffffff8100d613>] do_IRQ+0x73/0xe0
[<ffffffff8100bb13>] ret_from_intr+0x0/0xa
<EOI>
[<ffffffff81296e6c>] ? acpi_idle_enter_bm+0x245/0x271
[<ffffffff81296e62>] ? acpi_idle_enter_bm+0x23b/0x271
[<ffffffff813c7a08>] ? cpuidle_idle_call+0x98/0xf0
[<ffffffff8100a104>] ? cpu_idle+0x94/0xd0
[<ffffffff81468db6>] ? rest_init+0x66/0x70
[<ffffffff816a082f>] ? start_kernel+0x2ef/0x340
[<ffffffff8169fd54>] ? x86_64_start_reservations+0x84/0x90
[<ffffffff8169fe32>] ? x86_64_start_kernel+0xd2/0x100
Code: 00 eb 28 8b 83 d0 03 00 00 41 39 44 24 40 0f 89 00 01 00 00 41 0f b6 cd
41 bd 2f 00 00 00 83 e1 03 0f 84 fc 00 00 00 4d 8b 24 24 <49> 8b 04 24 4d 39 f4
0f 18 08 0f 84 d9 00 00 00 4c 3b a3 b8 01
RIP [<ffffffff814203cc>] tcp_xmit_retransmit_queue+0x8c/0x290
RSP <ffffc90000003a40>
CR2: 0000000000000000
---[ end trace d97d99c9ae1d52cc ]---
Kernel panic - not syncing: Fatal exception in interrupt
Pid: 0, comm: swapper Tainted: G D 2.6.31 #2
Call Trace:
<IRQ> [<ffffffff8103cab0>] panic+0xa0/0x170
[<ffffffff8100bb13>] ? ret_from_intr+0x0/0xa
[<ffffffff8103c74e>] ? print_oops_end_marker+0x1e/0x20
[<ffffffff8100f38e>] oops_end+0x9e/0xb0
[<ffffffff81025b9a>] no_context+0x15a/0x250
[<ffffffff81025e2b>] __bad_area_nosemaphore+0xdb/0x1c0
[<ffffffff813e89e9>] ? dev_hard_start_xmit+0x269/0x2f0
[<ffffffff81025fae>] bad_area_nosemaphore+0xe/0x10
[<ffffffff8102639f>] do_page_fault+0x17f/0x260
[<ffffffff8147eadf>] page_fault+0x1f/0x30
[<ffffffff814203cc>] ? tcp_xmit_retransmit_queue+0x8c/0x290
[<ffffffff8141ae4a>] tcp_ack+0x170a/0x1dd0
[<ffffffff8141c362>] tcp_rcv_state_process+0x122/0xab0
[<ffffffff81422c6c>] tcp_v4_do_rcv+0xac/0x220
[<ffffffff813fd02f>] ? nf_iterate+0x5f/0x90
[<ffffffff81424b26>] tcp_v4_rcv+0x586/0x6b0
[<ffffffff813fd0c5>] ? nf_hook_slow+0x65/0xf0
[<ffffffff81406b70>] ? ip_local_deliver_finish+0x0/0x120
[<ffffffff81406bcf>] ip_local_deliver_finish+0x5f/0x120
[<ffffffff8140715b>] ip_local_deliver+0x3b/0x90
[<ffffffff81406971>] ip_rcv_finish+0x141/0x340
[<ffffffff8140701f>] ip_rcv+0x24f/0x350
[<ffffffff813e7ced>] netif_receive_skb+0x20d/0x2f0
[<ffffffff813e7e90>] napi_skb_finish+0x40/0x50
[<ffffffff813e82f4>] napi_gro_receive+0x34/0x40
[<ffffffff8133e0c8>] e1000_receive_skb+0x48/0x60
[<ffffffff81342342>] e1000_clean_rx_irq+0xf2/0x330
[<ffffffff813410a1>] e1000_clean+0x81/0x2a0
[<ffffffff81054ce1>] ? ktime_get+0x11/0x50
[<ffffffff813eaf1c>] net_rx_action+0x9c/0x130
[<ffffffff81046940>] ? get_next_timer_interrupt+0x1d0/0x210
[<ffffffff81041bd7>] __do_softirq+0xb7/0x160
[<ffffffff8100c27c>] call_softirq+0x1c/0x30
[<ffffffff8100e04d>] do_softirq+0x3d/0x80
[<ffffffff81041b0b>] irq_exit+0x7b/0x90
[<ffffffff8100d613>] do_IRQ+0x73/0xe0
[<ffffffff8100bb13>] ret_from_intr+0x0/0xa
<EOI> [<ffffffff81296e6c>] ? acpi_idle_enter_bm+0x245/0x271
[<ffffffff81296e62>] ? acpi_idle_enter_bm+0x23b/0x271
[<ffffffff813c7a08>] ? cpuidle_idle_call+0x98/0xf0
[<ffffffff8100a104>] ? cpu_idle+0x94/0xd0
[<ffffffff81468db6>] ? rest_init+0x66/0x70
[<ffffffff816a082f>] ? start_kernel+0x2ef/0x340
[<ffffffff8169fd54>] ? x86_64_start_reservations+0x84/0x90
[<ffffffff8169fe32>] ? x86_64_start_kernel+0xd2/0x100
--
Configure bugmail: http://bugzilla.kernel.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.
--
^ permalink raw reply
* [PATCH] can: sja1000: fix bug using library functions for skb allocation
From: Wolfgang Grandegger @ 2009-10-26 15:46 UTC (permalink / raw)
To: Linux Netdev List; +Cc: Socketcan-core@lists.berlios.de, Kurt Van Dijck
Commit 7b6856a0 "can: provide library functions for skb allocation"
did not properly remove two lines of the SJA1000 driver resulting in
a 'skb_over_panic' when calling skb_put, as reported by Kurt.
Signed-off-by: Kurt Van Dijck <kurt.van.dijck@eia.be>
Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
---
drivers/net/can/sja1000/sja1000.c | 2 --
1 file changed, 2 deletions(-)
Index: net-next-2.6/drivers/net/can/sja1000/sja1000.c
===================================================================
--- net-next-2.6.orig/drivers/net/can/sja1000/sja1000.c
+++ net-next-2.6/drivers/net/can/sja1000/sja1000.c
@@ -321,8 +321,6 @@ static void sja1000_rx(struct net_device
if (fi & FI_RTR)
id |= CAN_RTR_FLAG;
- cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
- memset(cf, 0, sizeof(struct can_frame));
cf->can_id = id;
cf->can_dlc = dlc;
for (i = 0; i < dlc; i++)
^ permalink raw reply
* Re: [PATCH v2 8/8] Document future removal of sysctl_tcp_* options
From: Gilad Ben-Yossef @ 2009-10-26 15:51 UTC (permalink / raw)
To: Bill Fink; +Cc: Eric Dumazet, William Allen Simpson, netdev, Ilpo Järvinen
In-Reply-To: <20091026110855.98a19f7a.billfink@mindspring.com>
Bill Fink wrote:
>
>> OK. It really sounds like we should go with my first suggestion: global
>> sysctl based kill switches, just as we have now and in addition, the
>> ability to kill TCP options per route. The TCP option will be used if
>> and only if both kill switches (global and per route) are not set.
>>
>
> This wording is confusing. The global kill switch not being set
> really means that the sysctl is set. And this assumes the per-route
> default is not set. Correct?
>
Now it is my turn to get confused, because I didn't understand your
question :-)
What I suggest is to leave the sysctl exactly as they are now:
- You leave them be (value of 1), the respective TCP option is
supported. This is the default.
- You turn them off (write 0), the respective TCP option is not supported.
What I suggest to *add* is the following ability:
- If you have the TCP option support turned on (default, value of one),
you can turn support for the option for a specific route using a ip
route option.
Hope that made it clearer.
>
>> What we achieve is:
>>
>> 1. Global kill switches work exactly as they do now, whether you use the
>> new per route options or not, so backwards compatible.
>>
>> 2. In addition, if the global kill switch is not in effect, you can also
>> kill the options on a per route basis.
>>
>> I'm going to send third version of the patch to this effect, minus the
>> new remote DoS possibility that Ilpo pointed out and leaving the global
>> sysctl kill switches be.
>>
>> If you like it, please ACK ;-)
>>
>
> IIUC this doesn't seem right to me. I believe the global setting
> should be a default and the route specific an override. Your scheme
> would mean that if I set a global option to disable timestamps, then
> I couldn't enable timestamps on specific routes using the per route
> setting.
>
Yes. You understand my intention perfectly.
Let me try to explain why I believe this is the correct behavior to
implement:
1. This is the closest thing to what we have now. Today you write 0 to
the sysctl and that TCP option is turned off globally. Period. My
suggestion leaves this behavior as is now regardless if you've used per
route settings. The other way make a very subtle change in the meaning
of writing 0 to the sysctl.
I believe very subtle changes to meaning of long established interfaces
is bad way to go. It's better to change interfaces on users, but it is
even worse to maek something that they have long used do something just
slightly different.
2. If the per route options needs to be "default, of or off" instead of
"on or off", we'd need to move from 1 bit to store the option to, well
2s bit in theory, but probably 32 bits in practice, since we can't use
RTAX_FEATURES any longer.
Yes, we can invent RTAX_FEATURES_TWO_BITS or some such, but I'd say that
is ugly :-)
3. I believe that the scenario of needing to set the support of a TCP
option globally off and just turn it on for a specific route is not very
likely to be needed and losing it is a small price to pay for 1 + 2.
> And it also doesn't seem to address Eric's scenario. If I understand
> his concern correctly, what seems to be needed is a third global
> reset value (not calling it a setting since the actual global setting
> wouldn't be changed), which would reset any per-route override settings
> to the global default setting.
>
>
Well, I do not believe this is what Eric meant (Eric?) but if it is then
I fail to see why
to require from the per route TCP options switches what is not required
of any other
route specific option already existing, since AFAIK we don't have a
"reset to default values" to the other options already supported.
Having said all that, I have no issue with re-spinning the patch with
your suggestion.
I don't feel all that much which is the correct way- I just want to get
as much feedback as possible
since I'm suggesting to add a new user interface options and we all know
it is very hard to back peddle
on those, so I'm trying to make sure to get enough feedback to do it
right the firs time.
So any feedback from anyone regarding favorite interface? it seems each
person fancy a different one :-)
Thanks!
Gilad
--
Gilad Ben-Yossef
Chief Coffee Drinker & CTO
Codefidence Ltd.
Web: http://codefidence.com
Cell: +972-52-8260388
Skype: gilad_codefidence
Tel: +972-8-9316883 ext. 201
Fax: +972-8-9316884
Email: gilad@codefidence.com
Check out our Open Source technology and training blog - http://tuxology.net
"The biggest risk you can take it is to take no risk."
-- Mark Zuckerberg and probably others
^ permalink raw reply
* Re: [PATCH next-next-2.6] netdev: better dev_name_hash
From: Octavian Purdila @ 2009-10-26 15:52 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Krishna Kumar2, Hagen Paul Pfeifer, netdev
In-Reply-To: <4AE5B84E.8040505@gmail.com>
On Monday 26 October 2009 16:55:10 you wrote:
>
> This is because you chose a 65536 slots hash table, to store 16000 elements
>
> The ideal function should be :
>
> $ ./dev_name_hash ixunc 16000 5 16
> score 16000
>
> unsigned int dev_name_hash_new10bis(const char *name)
> {
> unsigned hash = 0;
> int len = strnlen(name, IFNAMSIZ);
> int i;
>
> for (i = 0; i < len; ++i)
> hash = 10 * hash + (name[i] - '0');
> return hash;
> }
>
Eric, thanks a lot for your help. This is turning into a very instructive
thread for me :)
10bis performs better for ixunc but interestingly performs worse for ixint
now. I also get mixed results for the two when using other names like ppp or
gtp.
2 - new10, 3 - new10bis
score 49852
$ ./dev_name_hash ixint 32000 3 14
score 53194
$ ./dev_name_hash ixunc 32000 2 14
score 55232
$ ./dev_name_hash ixunc 32000 3 14
score 48168
> But should we really care ?
I'm just testing various common cases we use here ({ixint,ixunc,gtp,ppp,gre}
{1000,16000,32000,128000} {14,16}).
Ideally we want a hash function that performs better in all cases - but I
understand that it may not be possible.
I will play more with it and see if I can come up with something better, but
in any case the new{10,10bis,17,31} performs much better than full_name_hash
and most of the time better that jhash .
^ permalink raw reply
* [PATCH]NET/KS8695: add support NAPI for Rx
From: Figo.zhang @ 2009-10-26 16:00 UTC (permalink / raw)
To: Daniel Silverstone, David S. Miller; +Cc: netdev, Vincent Sanders, Ben Dooks
Add support NAPI Rx API for KS8695NET driver.
Signed-off-by: Figo.zhang <figo1802@gmail.com>
---
drivers/net/arm/ks8695net.c | 165 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 165 insertions(+), 0 deletions(-)
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c
index 2a7b774..7f9d4bd 100644
--- a/drivers/net/arm/ks8695net.c
+++ b/drivers/net/arm/ks8695net.c
@@ -35,12 +35,16 @@
#include <mach/regs-switch.h>
#include <mach/regs-misc.h>
+#include <asm/mach/irq.h>
+#include <mach/regs-irq.h>
#include "ks8695net.h"
#define MODULENAME "ks8695_ether"
#define MODULEVERSION "1.01"
+#define KS8695NET_NAPI 1
+
/*
* Transmit and device reset timeout, default 5 seconds.
*/
@@ -152,6 +156,10 @@ struct ks8695_priv {
enum ks8695_dtype dtype;
void __iomem *io_regs;
+ #ifdef KS8695NET_NAPI
+ struct napi_struct napi;
+ #endif
+
const char *rx_irq_name, *tx_irq_name, *link_irq_name;
int rx_irq, tx_irq, link_irq;
@@ -172,6 +180,7 @@ struct ks8695_priv {
dma_addr_t rx_ring_dma;
struct ks8695_skbuff rx_buffers[MAX_RX_DESC];
int next_rx_desc_read;
+ spinlock_t rx_lock;
int msg_enable;
};
@@ -391,6 +400,155 @@ ks8695_tx_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
+#ifdef KS8695NET_NAPI
+static irqreturn_t
+ks8695_rx_irq(int irq, void *dev_id)
+{
+ struct net_device *ndev = (struct net_device *)dev_id;
+ struct ks8695_priv *ksp = netdev_priv(ndev);
+ unsigned long status;
+
+ unsigned long mask_bit = 1 << ksp->rx_irq;
+
+ spin_lock(&ksp->rx_lock);
+
+ status = __raw_readl(KS8695_IRQ_VA + KS8695_INTST);
+
+ /*clean rx status bit*/
+ __raw_writel(status | mask_bit , KS8695_IRQ_VA + KS8695_INTST);
+
+ if (status & mask_bit) {
+ if (napi_schedule_prep(&ksp->napi)) {
+ /*disable rx interrupt*/
+ status &= ~mask_bit;
+ __raw_writel(status , KS8695_IRQ_VA + KS8695_INTEN);
+ __napi_schedule(&ksp->napi);
+ }
+ }
+
+ spin_unlock(&ksp->rx_lock);
+ return IRQ_HANDLED;
+}
+
+static int ks8695_rx(struct net_device *ndev, int budget)
+{
+ struct ks8695_priv *ksp = netdev_priv(ndev);
+ struct sk_buff *skb;
+ int buff_n;
+ u32 flags;
+ int pktlen;
+ int last_rx_processed = -1;
+ int received = 0;
+
+ buff_n = ksp->next_rx_desc_read;
+ while (netif_running(ndev) && received < budget
+ && ksp->rx_buffers[buff_n].skb
+ && (!(ksp->rx_ring[buff_n].status &
+ cpu_to_le32(RDES_OWN)))) {
+ rmb();
+ flags = le32_to_cpu(ksp->rx_ring[buff_n].status);
+ /* Found an SKB which we own, this means we
+ * received a packet
+ */
+ if ((flags & (RDES_FS | RDES_LS)) !=
+ (RDES_FS | RDES_LS)) {
+ /* This packet is not the first and
+ * the last segment. Therefore it is
+ * a "spanning" packet and we can't
+ * handle it
+ */
+ goto rx_failure;
+ }
+
+ if (flags & (RDES_ES | RDES_RE)) {
+ /* It's an error packet */
+ ndev->stats.rx_errors++;
+ if (flags & RDES_TL)
+ ndev->stats.rx_length_errors++;
+ if (flags & RDES_RF)
+ ndev->stats.rx_length_errors++;
+ if (flags & RDES_CE)
+ ndev->stats.rx_crc_errors++;
+ if (flags & RDES_RE)
+ ndev->stats.rx_missed_errors++;
+
+ goto rx_failure;
+ }
+
+ pktlen = flags & RDES_FLEN;
+ pktlen -= 4; /* Drop the CRC */
+
+ /* Retrieve the sk_buff */
+ skb = ksp->rx_buffers[buff_n].skb;
+
+ /* Clear it from the ring */
+ ksp->rx_buffers[buff_n].skb = NULL;
+ ksp->rx_ring[buff_n].data_ptr = 0;
+
+ /* Unmap the SKB */
+ dma_unmap_single(ksp->dev,
+ ksp->rx_buffers[buff_n].dma_ptr,
+ ksp->rx_buffers[buff_n].length,
+ DMA_FROM_DEVICE);
+
+ /* Relinquish the SKB to the network layer */
+ skb_put(skb, pktlen);
+ skb->protocol = eth_type_trans(skb, ndev);
+ netif_receive_skb(skb);
+
+ /* Record stats */
+ ndev->stats.rx_packets++;
+ ndev->stats.rx_bytes += pktlen;
+ goto rx_finished;
+
+rx_failure:
+ /* This ring entry is an error, but we can
+ * re-use the skb
+ */
+ /* Give the ring entry back to the hardware */
+ ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN);
+rx_finished:
+ received++;
+ /* And note this as processed so we can start
+ * from here next time
+ */
+ last_rx_processed = buff_n;
+ buff_n = (buff_n + 1) & MAX_RX_DESC_MASK;
+ /*And note which RX descriptor we last did */
+ if (likely(last_rx_processed != -1))
+ ksp->next_rx_desc_read =
+ (last_rx_processed + 1) &
+ MAX_RX_DESC_MASK;
+
+ /* And refill the buffers */
+ ks8695_refill_rxbuffers(ksp);
+ }
+ return received;
+}
+
+static int ks8695_poll(struct napi_struct *napi, int budget)
+{
+ struct ks8695_priv *ksp = container_of(napi, struct ks8695_priv, napi);
+ struct net_device *dev = ksp->ndev;
+ unsigned long mask_bit = 1 << ksp->rx_irq;
+ unsigned long isr = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
+
+ unsigned long work_done = 0;
+
+ work_done = ks8695_rx(dev, budget);
+
+ if (work_done < budget) {
+ unsigned long flags;
+ spin_lock_irqsave(&ksp->rx_lock, flags);
+ /*enable rx interrupt*/
+ __raw_writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN);
+ __napi_complete(napi);
+ spin_unlock_irqrestore(&ksp->rx_lock, flags);
+ }
+ return work_done;
+}
+
+#else
/**
* ks8695_rx_irq - Receive IRQ handler
* @irq: The IRQ which went off (ignored)
@@ -503,6 +661,8 @@ rx_finished:
return IRQ_HANDLED;
}
+#endif
+
/**
* ks8695_link_irq - Link change IRQ handler
* @irq: The IRQ which went off (ignored)
@@ -1472,6 +1632,10 @@ ks8695_probe(struct platform_device *pdev)
SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
+#ifdef KS8695NET_NAPI
+ netif_napi_add(ndev, &ksp->napi, ks8695_poll, 64);
+#endif
+
/* Retrieve the default MAC addr from the chip. */
/* The bootloader should have left it in there for us. */
@@ -1505,6 +1669,7 @@ ks8695_probe(struct platform_device *pdev)
/* And initialise the queue's lock */
spin_lock_init(&ksp->txq_lock);
+ spin_lock_init(&ksp->rx_lock);
/* Specify the RX DMA ring buffer */
ksp->rx_ring = ksp->ring_base + TX_RING_DMA_SIZE;
^ permalink raw reply related
* [PATCH] vlan: allow VLAN ID 0 to be used
From: Eric Dumazet @ 2009-10-26 16:13 UTC (permalink / raw)
Cc: Benny Amorsen, Gertjan Hofman, Matt Carlson,
netdev@vger.kernel.org, Patrick McHardy, David S. Miller
In-Reply-To: <4AE563C7.5070702@gmail.com>
Eric Dumazet a écrit :
> VLAN id 0 is not usable on current kernel because we use 16 bits in skb to
> store vlan_tci, and vlan_tci = 0 means there is no VLAN tagging.
>
>
> We could use high order bit (0x8000) to tell if vlan tagging is set or not.
>
Here is the patch I cooked that permitted VLAN 0 to be used with tg3
(and other HW accelerated vlan nics I suppose)
[PATCH] vlan: allow VLAN ID 0 to be used
We currently use a 16 bit field (vlan_tci) to store VLAN ID on a skb.
0 value is used a special value, meaning VLAN ID not set.
This forbids use of VLAN ID 0
As VLAN ID is 12 bits, we can use high order bit as a flag, and
allow VLAN ID 0
Reported-by: Gertjan Hofman <gertjan_hofman@yahoo.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 7ff9af1..7dfcdb5 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -105,8 +105,9 @@ static inline void vlan_group_set_device(struct vlan_group *vg,
array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev;
}
-#define vlan_tx_tag_present(__skb) ((__skb)->vlan_tci)
-#define vlan_tx_tag_get(__skb) ((__skb)->vlan_tci)
+#define VLAN_TAG_PRESENT 0x8000
+#define vlan_tx_tag_present(__skb) ((__skb)->vlan_tci & VLAN_TAG_PRESENT)
+#define vlan_tx_tag_get(__skb) ((__skb)->vlan_tci & 0x7fff)
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
extern struct net_device *vlan_dev_real_dev(const struct net_device *dev);
@@ -231,7 +232,7 @@ static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, u16 vlan_tci)
static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb,
u16 vlan_tci)
{
- skb->vlan_tci = vlan_tci;
+ skb->vlan_tci = VLAN_TAG_PRESENT | vlan_tci;
return skb;
}
@@ -284,7 +285,7 @@ static inline int __vlan_hwaccel_get_tag(const struct sk_buff *skb,
u16 *vlan_tci)
{
if (vlan_tx_tag_present(skb)) {
- *vlan_tci = skb->vlan_tci;
+ *vlan_tci = vlan_tx_tag_get(skb);
return 0;
} else {
*vlan_tci = 0;
^ permalink raw reply related
* Re: iwl3945, after a while stops working with "No space for Tx"
From: reinette chatre @ 2009-10-26 16:25 UTC (permalink / raw)
To: Frederik Nosi
Cc: Zhu, Yi, Intel Linux Wireless, John W. Linville, Winkler, Tomas,
Kolekar, Abhijeet, linux-wireless@vger.kernel.org,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <177253.23325.qm@web53903.mail.re2.yahoo.com>
On Sat, 2009-10-24 at 06:44 -0700, Frederik Nosi wrote:
> Hi,
> first sorry if somebody is not the right contact, got the adressess from ./scripts/get_maintainer.pl -f drivers/net/wireless/iwlwifi.
> From some kernel versions now, after some time that im using this card it stops working and on messages i get this errors:
>
> Oct 24 14:38:24 kotys NetworkManager: <info> Activation (wlan0) Stage 5 of 5 (IP Configure Commit) complete.
> [snip pulseaudio's stuppid log spam warning]
> Oct 24 14:40:07 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_TX_PWR_TABLE_CMD: time out after 500ms.
> Oct 24 14:40:09 kotys pulseaudio[16469]: sap.c: sendmsg() failed: Invalid argument
> Oct 24 14:40:10 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_SCAN_CMD: time out after 500ms.
> Oct 24 14:40:11 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_TX_PWR_TABLE_CMD: time out after 500ms.
> Oct 24 14:40:11 kotys kernel: iwl3945 0000:04:00.0: Error sending POWER_TABLE_CMD: time out after 500ms.
> Oct 24 14:40:14 kotys kernel: iwl3945 0000:04:00.0: set power fail, ret = -110
> Oct 24 14:40:14 kotys kernel: No probe response from AP 00:1c:df:82:63:c9 after 500ms, disconnecting.
> Oct 24 14:40:14 kotys NetworkManager: <info> (wlan0): supplicant connection state: completed -> disconnected
> Oct 24 14:40:14 kotys NetworkManager: <info> (wlan0): supplicant connection state: disconnected -> scanning
> Oct 24 14:40:14 kotys pulseaudio[16469]: sap.c: sendmsg() failed: Invalid argument
> Oct 24 14:40:14 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_RXON: time out after 500ms.
> Oct 24 14:40:14 kotys kernel: iwl3945 0000:04:00.0: Error setting new configuration (-110).
> Oct 24 14:40:15 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_SCAN_CMD: time out after 500ms.
> Oct 24 14:40:15 kotys kernel: wlan0: direct probe to AP 00:1c:df:82:63:c9 (try 1)
> Oct 24 14:40:15 kotys NetworkManager: <info> (wlan0): supplicant connection state: scanning -> associating
> Oct 24 14:40:15 kotys kernel: wlan0: direct probe to AP 00:1c:df:82:63:c9 (try 2)
> Oct 24 14:40:15 kotys kernel: wlan0: direct probe to AP 00:1c:df:82:63:c9 (try 3)
> Oct 24 14:40:15 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_RXON: time out after 500ms.
> Oct 24 14:40:15 kotys kernel: iwl3945 0000:04:00.0: Error setting new configuration (-110).
> Oct 24 14:40:15 kotys kernel: wlan0: direct probe to AP 00:1c:df:82:63:c9 timed out
> Oct 24 14:40:16 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_TX_PWR_TABLE_CMD: time out after 500ms.
> Oct 24 14:40:16 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_RXON: time out after 500ms.
> Oct 24 14:40:16 kotys kernel: iwl3945 0000:04:00.0: Error setting new configuration (-110).
>
>
> When this happens i am able to use the card only after reloading the related modules, iwl3945 ecc. But the problem happens again after some minutes that im connected.
>
> Kernel is 2.6.32-rc5 but his started happening around 2.6.31, not sure exactly what version as i update kernel often. Firmware is iwl3945-ucode-15.32.2.9.
>
> Every other info that you need just ask. I hope i dont have to bisect as this is the laptop i use for work too, but if it's needed i'll do.
>
> I'm not subscribed on any ML, so in case please cc me.
>
We currently have a bug open for this issue. Could you please add this
information to
http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=1944 ?
Thank you
Reinette
^ permalink raw reply
* Re: [PATCH v3 4/7] Add the no SACK route option feature
From: William Allen Simpson @ 2009-10-26 16:38 UTC (permalink / raw)
To: Gilad Ben-Yossef; +Cc: netdev, ori
In-Reply-To: <1256544393-12450-5-git-send-email-gilad@codefidence.com>
Gilad Ben-Yossef wrote:
> Implement querying and acting upon the no sack bit in the features
> field.
>
> Signed-off-by: Gilad Ben-Yossef <gilad@codefidence.com>
> Sigend-off-by: Ori Finkelman <ori@comsleep.com>
> Sigend-off-by: Yony Amit <yony@comsleep.com>
>
Please explain how this code turns SACK on when it is off globally?
As both Eric and I asked?
^ permalink raw reply
* Re: [RFC] [PATCH] udp: Don't save dst in udpv6_sendmsg()
From: Rick Jones @ 2009-10-26 16:45 UTC (permalink / raw)
To: David Miller; +Cc: krkumar2, netdev
In-Reply-To: <20091024.064010.145864194.davem@davemloft.net>
David Miller wrote:
> From: Krishna Kumar <krkumar2@in.ibm.com>
> Date: Fri, 23 Oct 2009 16:43:36 +0530
>
>
>>Performance: I ran netperf UDPv6 RR to use connected sockets.
>>Tested with a 70 min run, aggregate of 5 netperf runs for
>>each result.
>
>
> Who actually uses connected UDP sockets? :-)
Somebody must, they sent me patches to optionally connect() the endpoints in a
UDP_RR test :)
rick jones
trying to decide if he should by default set SO_DONTROUTE on UDP sockets to
cover the backsides of testers who cause link-down events on devices under test
with systems connected to their employer's site lans with the default route
pointing at same...
^ permalink raw reply
* Re: [PATCH]NET/KS8695: add support NAPI for Rx
From: Daniel Silverstone @ 2009-10-26 16:27 UTC (permalink / raw)
To: Figo.zhang; +Cc: David S. Miller, netdev, Vincent Sanders, Ben Dooks
In-Reply-To: <1256572828.2148.5.camel@myhost>
On Tue, Oct 27, 2009 at 12:00:28AM +0800, Figo.zhang wrote:
> +#ifdef KS8695NET_NAPI
> +static irqreturn_t
> +ks8695_rx_irq(int irq, void *dev_id)
This routine lacks its documentation comment. This driver is fully documented
in order to serve as a good example for others. Indeed this lack of
documentation comments continues through your patch, I won't bring up each
instance, instead trusting you to go back over your patch and sort them out.
> + status = __raw_readl(KS8695_IRQ_VA + KS8695_INTST);
[snip]
> + __raw_writel(status | mask_bit , KS8695_IRQ_VA + KS8695_INTST);
[snip]
> + __raw_writel(status , KS8695_IRQ_VA + KS8695_INTEN);
[snip]
> + unsigned long isr = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
[snip]
> + __raw_writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN);
Please don't use __raw_readl or __raw_writel. This driver was nice and clean,
don't ruin it.
Also, as an aside, you seem to add a spinlock (rx_lock) which afaict is only
used by NAPI related routines, and yet you include it regardless of NAPI being
enabled or not. Did I misread your patch, or is this an oversight?
Regards,
Daniel.
--
Daniel Silverstone http://www.simtec.co.uk/
^ permalink raw reply
* Re: [PATCH]NET/KS8695: add support NAPI for Rx
From: Ben Hutchings @ 2009-10-26 16:49 UTC (permalink / raw)
To: Figo.zhang
Cc: Daniel Silverstone, David S. Miller, netdev, Vincent Sanders,
Ben Dooks
In-Reply-To: <1256572828.2148.5.camel@myhost>
On Tue, 2009-10-27 at 00:00 +0800, Figo.zhang wrote:
> Add support NAPI Rx API for KS8695NET driver.
>
> Signed-off-by: Figo.zhang <figo1802@gmail.com>
> ---
> drivers/net/arm/ks8695net.c | 165 +++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 165 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c
> index 2a7b774..7f9d4bd 100644
> --- a/drivers/net/arm/ks8695net.c
> +++ b/drivers/net/arm/ks8695net.c
> @@ -35,12 +35,16 @@
>
> #include <mach/regs-switch.h>
> #include <mach/regs-misc.h>
> +#include <asm/mach/irq.h>
> +#include <mach/regs-irq.h>
>
> #include "ks8695net.h"
>
> #define MODULENAME "ks8695_ether"
> #define MODULEVERSION "1.01"
I think this merits a version bump.
> +#define KS8695NET_NAPI 1
> +
> /*
> * Transmit and device reset timeout, default 5 seconds.
> */
> @@ -152,6 +156,10 @@ struct ks8695_priv {
> enum ks8695_dtype dtype;
> void __iomem *io_regs;
>
> + #ifdef KS8695NET_NAPI
> + struct napi_struct napi;
> + #endif
> +
NAPI is well-established and there should be no need to make it
optional. So far as I'm aware, all other drivers that had it as an
option now use it unconditionally.
> const char *rx_irq_name, *tx_irq_name, *link_irq_name;
> int rx_irq, tx_irq, link_irq;
>
> @@ -172,6 +180,7 @@ struct ks8695_priv {
> dma_addr_t rx_ring_dma;
> struct ks8695_skbuff rx_buffers[MAX_RX_DESC];
> int next_rx_desc_read;
> + spinlock_t rx_lock;
>
> int msg_enable;
> };
> @@ -391,6 +400,155 @@ ks8695_tx_irq(int irq, void *dev_id)
> return IRQ_HANDLED;
> }
>
> +#ifdef KS8695NET_NAPI
> +static irqreturn_t
> +ks8695_rx_irq(int irq, void *dev_id)
> +{
> + struct net_device *ndev = (struct net_device *)dev_id;
> + struct ks8695_priv *ksp = netdev_priv(ndev);
> + unsigned long status;
> +
> + unsigned long mask_bit = 1 << ksp->rx_irq;
> +
> + spin_lock(&ksp->rx_lock);
> +
> + status = __raw_readl(KS8695_IRQ_VA + KS8695_INTST);
> +
> + /*clean rx status bit*/
> + __raw_writel(status | mask_bit , KS8695_IRQ_VA + KS8695_INTST);
> +
> + if (status & mask_bit) {
> + if (napi_schedule_prep(&ksp->napi)) {
> + /*disable rx interrupt*/
> + status &= ~mask_bit;
> + __raw_writel(status , KS8695_IRQ_VA + KS8695_INTEN);
> + __napi_schedule(&ksp->napi);
> + }
> + }
> +
> + spin_unlock(&ksp->rx_lock);
> + return IRQ_HANDLED;
> +}
The interrupt register manipulation here looks wrong, but I don't have
specific knowledge of this platform.
Since the interrupt control registers appear to be shared with other
devices, this needs to be serialised with manipulation by other drivers.
> +static int ks8695_rx(struct net_device *ndev, int budget)
> +{
> + struct ks8695_priv *ksp = netdev_priv(ndev);
> + struct sk_buff *skb;
> + int buff_n;
> + u32 flags;
> + int pktlen;
> + int last_rx_processed = -1;
> + int received = 0;
> +
> + buff_n = ksp->next_rx_desc_read;
> + while (netif_running(ndev) && received < budget
netif_running() is quite redundant here.
> + && ksp->rx_buffers[buff_n].skb
> + && (!(ksp->rx_ring[buff_n].status &
> + cpu_to_le32(RDES_OWN)))) {
> + rmb();
> + flags = le32_to_cpu(ksp->rx_ring[buff_n].status);
> + /* Found an SKB which we own, this means we
> + * received a packet
> + */
> + if ((flags & (RDES_FS | RDES_LS)) !=
> + (RDES_FS | RDES_LS)) {
> + /* This packet is not the first and
> + * the last segment. Therefore it is
> + * a "spanning" packet and we can't
> + * handle it
> + */
> + goto rx_failure;
> + }
> +
> + if (flags & (RDES_ES | RDES_RE)) {
> + /* It's an error packet */
> + ndev->stats.rx_errors++;
> + if (flags & RDES_TL)
> + ndev->stats.rx_length_errors++;
> + if (flags & RDES_RF)
> + ndev->stats.rx_length_errors++;
> + if (flags & RDES_CE)
> + ndev->stats.rx_crc_errors++;
> + if (flags & RDES_RE)
> + ndev->stats.rx_missed_errors++;
> +
> + goto rx_failure;
> + }
> +
> + pktlen = flags & RDES_FLEN;
> + pktlen -= 4; /* Drop the CRC */
> +
> + /* Retrieve the sk_buff */
> + skb = ksp->rx_buffers[buff_n].skb;
> +
> + /* Clear it from the ring */
> + ksp->rx_buffers[buff_n].skb = NULL;
> + ksp->rx_ring[buff_n].data_ptr = 0;
> +
> + /* Unmap the SKB */
> + dma_unmap_single(ksp->dev,
> + ksp->rx_buffers[buff_n].dma_ptr,
> + ksp->rx_buffers[buff_n].length,
> + DMA_FROM_DEVICE);
> +
> + /* Relinquish the SKB to the network layer */
> + skb_put(skb, pktlen);
> + skb->protocol = eth_type_trans(skb, ndev);
> + netif_receive_skb(skb);
> +
> + /* Record stats */
> + ndev->stats.rx_packets++;
> + ndev->stats.rx_bytes += pktlen;
> + goto rx_finished;
> +
> +rx_failure:
> + /* This ring entry is an error, but we can
> + * re-use the skb
> + */
> + /* Give the ring entry back to the hardware */
> + ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN);
> +rx_finished:
> + received++;
> + /* And note this as processed so we can start
> + * from here next time
> + */
> + last_rx_processed = buff_n;
> + buff_n = (buff_n + 1) & MAX_RX_DESC_MASK;
> + /*And note which RX descriptor we last did */
> + if (likely(last_rx_processed != -1))
> + ksp->next_rx_desc_read =
> + (last_rx_processed + 1) &
> + MAX_RX_DESC_MASK;
> +
> + /* And refill the buffers */
> + ks8695_refill_rxbuffers(ksp);
> + }
> + return received;
> +}
> +
> +static int ks8695_poll(struct napi_struct *napi, int budget)
> +{
> + struct ks8695_priv *ksp = container_of(napi, struct ks8695_priv, napi);
> + struct net_device *dev = ksp->ndev;
> + unsigned long mask_bit = 1 << ksp->rx_irq;
> + unsigned long isr = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
This is surely the wrong place to be reading this register.
> + unsigned long work_done = 0;
Pointless initialisation.
> +
> + work_done = ks8695_rx(dev, budget);
> +
> + if (work_done < budget) {
> + unsigned long flags;
> + spin_lock_irqsave(&ksp->rx_lock, flags);
> + /*enable rx interrupt*/
> + __raw_writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN);
> + __napi_complete(napi);
> + spin_unlock_irqrestore(&ksp->rx_lock, flags);
> + }
> + return work_done;
> +}
> +
> +#else
> /**
> * ks8695_rx_irq - Receive IRQ handler
> * @irq: The IRQ which went off (ignored)
> @@ -503,6 +661,8 @@ rx_finished:
> return IRQ_HANDLED;
> }
>
> +#endif
> +
> /**
> * ks8695_link_irq - Link change IRQ handler
> * @irq: The IRQ which went off (ignored)
> @@ -1472,6 +1632,10 @@ ks8695_probe(struct platform_device *pdev)
> SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
> ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
>
> +#ifdef KS8695NET_NAPI
> + netif_napi_add(ndev, &ksp->napi, ks8695_poll, 64);
> +#endif
> +
> /* Retrieve the default MAC addr from the chip. */
> /* The bootloader should have left it in there for us. */
>
> @@ -1505,6 +1669,7 @@ ks8695_probe(struct platform_device *pdev)
>
> /* And initialise the queue's lock */
> spin_lock_init(&ksp->txq_lock);
> + spin_lock_init(&ksp->rx_lock);
>
> /* Specify the RX DMA ring buffer */
> ksp->rx_ring = ksp->ring_base + TX_RING_DMA_SIZE;
You're missing a netif_napi_del() on removal.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH next-next-2.6] netdev: better dev_name_hash
From: Stephen Hemminger @ 2009-10-26 16:55 UTC (permalink / raw)
To: Octavian Purdila; +Cc: Eric Dumazet, Krishna Kumar2, Hagen Paul Pfeifer, netdev
In-Reply-To: <200910261752.51784.opurdila@ixiacom.com>
Added more algorithms to test...
Time is in seconds for 10000000 entries with hashbits = 8
Ratio is number of probes / ideal hash probes
Result sorted by distribution:
Algorithm Time Ratio Max StdDev
string10 1.434087 1.00 39064 0.01
SuperFastHash 1.469511 1.00 40497 2.17
string_hash17 1.472544 1.00 39497 1.50
jhash_string 1.501508 1.00 39669 1.04
crc 2.826795 1.00 39088 0.07
md5_string 3.608253 1.00 39605 0.98
djb2 1.462722 1.15 60681 76.16
string_hash31 1.457253 1.21 64950 91.12
sdbm 1.566174 2.38 129900 232.22
pjw 1.527306 2.45 99990 237.86
elf 1.576096 2.45 99990 237.86
kr_hash 1.400072 7.80 468451 515.52
fletcher 1.449671 7.80 468451 515.52
full_name_hash 1.487707 13.09 562501 687.24
xor 1.400403 13.36 583189 694.98
lastchar 1.348798 25.60 1000000 980.27
Another run sorted by speed:
Algorithm Time Ratio Max StdDev
lastchar 1.338545 25.60 1000000 980.27
kr_hash 1.398453 7.80 468451 515.52
xor 1.398843 13.36 583189 694.98
string10 1.432756 1.00 39064 0.01
fletcher 1.448499 7.80 468451 515.52
string_hash31 1.457524 1.21 64950 91.12
string_hash17 1.462548 1.00 39497 1.50
djb2 1.462956 1.15 60681 76.16
SuperFastHash 1.469907 1.00 40497 2.17
full_name_hash 1.486465 13.09 562501 687.24
jhash_string 1.500959 1.00 39669 1.04
pjw 1.526097 2.45 99990 237.86
sdbm 1.566533 2.38 129900 232.22
elf 1.576470 2.45 99990 237.86
crc 2.811210 1.00 39088 0.07
md5_string 3.604675 1.00 39605 0.98
^ permalink raw reply
* Re: [PATCH v3 1/7] Only parse time stamp TCP option in time wait sock
From: William Allen Simpson @ 2009-10-26 16:56 UTC (permalink / raw)
To: Gilad Ben-Yossef; +Cc: netdev, ori, Yony Amit
In-Reply-To: <1256544393-12450-2-git-send-email-gilad@codefidence.com>
Gilad Ben-Yossef wrote:
> Since we only use tcp_parse_options here to check for the exietence
> of TCP timestamp option in the header, it is better to call with
> the "established" flag on.
>
Please explain how this patch is required for the other patches?
And more importantly, why it is better to call with established on?
And most importantly, what end cases you considered, and how this
interacts with the proposed rfc1323bis changes, especially on reset?
^ permalink raw reply
* Re: iwl3945, after a while stops working with "No space for Tx"
From: Fredi @ 2009-10-26 17:04 UTC (permalink / raw)
To: reinette chatre
Cc: YiZhu, Intel Linux Wireless, John W. Linville, TomasWinkler,
AbhijeetKolekar, linux-wireless@vger.kernel.org,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <1256574352.21134.7591.camel@rc-desk>
Hi
first thanks for your reply,
--- On Mon, 26/10/09, reinette chatre <reinette.chatre@intel.com> wrote:
> From: reinette chatre <reinette.chatre@intel.com>
> Subject: Re: iwl3945, after a while stops working with "No space for Tx"
> To: "Frederik Nosi" <fredin77@yahoo.com>
> Cc: "Zhu, Yi" <yi.zhu@intel.com>, "Intel Linux Wireless" <ilw@linux.intel.com>, "John W. Linville" <linville@tuxdriver.com>, "Winkler, Tomas" <tomas.winkler@intel.com>, "Kolekar, Abhijeet" <abhijeet.kolekar@intel.com>, "linux-wireless@vger.kernel.org" <linux-wireless@vger.kernel.org>, "netdev@vger.kernel.org" <netdev@vger.kernel.org>, "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
> Date: Monday, 26 October, 2009, 5:25 PM
> On Sat, 2009-10-24 at 06:44 -0700,
> Frederik Nosi wrote:
> > Hi,
> > first sorry if somebody is not the right contact, got
> the adressess from ./scripts/get_maintainer.pl -f
> drivers/net/wireless/iwlwifi.
> > From some kernel versions now, after some time that im
> using this card it stops working and on messages i get this
> errors:
> >
> > Oct 24 14:38:24 kotys NetworkManager:
> <info> Activation (wlan0) Stage 5 of 5 (IP
> Configure Commit) complete.
> > [snip pulseaudio's stuppid log spam warning]
> > Oct 24 14:40:07 kotys kernel: iwl3945 0000:04:00.0:
> Error sending REPLY_TX_PWR_TABLE_CMD: time out after 500ms.
> > Oct 24 14:40:09 kotys pulseaudio[16469]: sap.c:
> sendmsg() failed: Invalid argument
> > Oct 24 14:40:10 kotys kernel: iwl3945 0000:04:00.0:
> Error sending REPLY_SCAN_CMD: time out after 500ms.
> > Oct 24 14:40:11 kotys kernel: iwl3945 0000:04:00.0:
> Error sending REPLY_TX_PWR_TABLE_CMD: time out after 500ms.
> > Oct 24 14:40:11 kotys kernel: iwl3945 0000:04:00.0:
> Error sending POWER_TABLE_CMD: time out after 500ms.
> > Oct 24 14:40:14 kotys kernel: iwl3945 0000:04:00.0:
> set power fail, ret = -110
> > Oct 24 14:40:14 kotys kernel: No probe response from
> AP 00:1c:df:82:63:c9 after 500ms, disconnecting.
> > Oct 24 14:40:14 kotys NetworkManager:
> <info> (wlan0): supplicant connection
> state: completed -> disconnected
> > Oct 24 14:40:14 kotys NetworkManager:
> <info> (wlan0): supplicant connection
> state: disconnected -> scanning
> > Oct 24 14:40:14 kotys pulseaudio[16469]: sap.c:
> sendmsg() failed: Invalid argument
> > Oct 24 14:40:14 kotys kernel: iwl3945 0000:04:00.0:
> Error sending REPLY_RXON: time out after 500ms.
> > Oct 24 14:40:14 kotys kernel: iwl3945 0000:04:00.0:
> Error setting new configuration (-110).
> > Oct 24 14:40:15 kotys kernel: iwl3945 0000:04:00.0:
> Error sending REPLY_SCAN_CMD: time out after 500ms.
> > Oct 24 14:40:15 kotys kernel: wlan0: direct probe to
> AP 00:1c:df:82:63:c9 (try 1)
> > Oct 24 14:40:15 kotys NetworkManager:
> <info> (wlan0): supplicant connection
> state: scanning -> associating
> > Oct 24 14:40:15 kotys kernel: wlan0: direct probe to
> AP 00:1c:df:82:63:c9 (try 2)
> > Oct 24 14:40:15 kotys kernel: wlan0: direct probe to
> AP 00:1c:df:82:63:c9 (try 3)
> > Oct 24 14:40:15 kotys kernel: iwl3945 0000:04:00.0:
> Error sending REPLY_RXON: time out after 500ms.
> > Oct 24 14:40:15 kotys kernel: iwl3945 0000:04:00.0:
> Error setting new configuration (-110).
> > Oct 24 14:40:15 kotys kernel: wlan0: direct probe to
> AP 00:1c:df:82:63:c9 timed out
> > Oct 24 14:40:16 kotys kernel: iwl3945 0000:04:00.0:
> Error sending REPLY_TX_PWR_TABLE_CMD: time out after 500ms.
> > Oct 24 14:40:16 kotys kernel: iwl3945 0000:04:00.0:
> Error sending REPLY_RXON: time out after 500ms.
> > Oct 24 14:40:16 kotys kernel: iwl3945 0000:04:00.0:
> Error setting new configuration (-110).
> >
> >
> > When this happens i am able to use the card only after
> reloading the related modules, iwl3945 ecc. But the problem
> happens again after some minutes that im connected.
> >
> > Kernel is 2.6.32-rc5 but his started happening around
> 2.6.31, not sure exactly what version as i update kernel
> often. Firmware is iwl3945-ucode-15.32.2.9.
> >
> > Every other info that you need just ask. I hope i dont
> have to bisect as this is the laptop i use for work too, but
> if it's needed i'll do.
> >
> > I'm not subscribed on any ML, so in case please cc
> me.
> >
>
> We currently have a bug open for this issue. Could you
> please add this
>
> information to
> http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=1944
> ?
Done, noticed that there's a patch for this issue. Will try and tell the results. And noticed the link on how to report possible firmware problems, will follow that procedure and post the results of that too.
> Thank you
Thaks for pointing me on the right direction!
> Reinette
>
>
Frederik
^ permalink raw reply
* Re: [PATCH 0/5] Candidate fix for increased number of GFP_ATOMIC failures V2
From: Tobias Oetiker @ 2009-10-26 17:37 UTC (permalink / raw)
To: Mel Gorman
Cc: Frans Pop, Jiri Kosina, Sven Geggus, Karol Lewandowski,
Rafael J. Wysocki, David Miller, Reinette Chatre, Kalle Valo,
David Rientjes, KOSAKI Motohiro, Mohamed Abbas, Jens Axboe,
John W. Linville, Pekka Enberg, Bartlomiej Zolnierkiewicz,
Greg Kroah-Hartman, Stephan von Krawczynski, Kernel Testers List,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org\"
In-Reply-To: <1256221356-26049-1-git-send-email-mel-wPRd99KPJ+uzQB+pC5nmwQ@public.gmane.org>
Hi Mel,
I have no done additional tests ... and can report the following
Thursday Mel Gorman wrote:
> 1/5 page allocator: Always wake kswapd when restarting an allocation attempt after direct reclaim failed
> 2/5 page allocator: Do not allow interrupts to use ALLOC_HARDER
>
>
> These patches correct problems introduced by me during the 2.6.31-rc1
> merge window. The patches were not meant to introduce any functional
> changes but two were missed.
>
> If your problem goes away with just these two patches applied,
> please tell me.
1+2 do not help
> Test 3: If you are getting allocation failures, try with the following patch
>
> 3/5 vmscan: Force kswapd to take notice faster when high-order watermarks are being hit
>
> This is a functional change that causes kswapd to notice sooner
> when high-order watermarks have been hit. There have been a number
> of changes in page reclaim since 2.6.30 that might have delayed
> when kswapd kicks in for higher orders
>
> If your problem goes away with these three patches applied, please
> tell me
1+2+3 do not help either
> Test 4: If you are still getting failures, apply the following
> 4/5 page allocator: Pre-emptively wake kswapd when high-order watermarks are hit
>
> This patch is very heavy handed and pre-emptively kicks kswapd when
> watermarks are hit. It should only be necessary if there has been
> significant changes in the timing and density of page allocations
> from an unknown source. Tobias, this patch is largely aimed at you.
> You reported that with patches 3+4 applied that your problems went
> away. I need to know if patch 3 on its own is enough or if both
> are required
>
> If your problem goes away with these four patches applied, please
> tell me
3 allone does not help
3+4 does ...
cheers
tobi
--
Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
http://it.oetiker.ch tobi-7K0TWYW2a3pyDzI6CaY1VQ@public.gmane.org ++41 62 775 9902 / sb: -9900
^ permalink raw reply
* Re: [PATCH next-next-2.6] netdev: better dev_name_hash
From: Stephen Hemminger @ 2009-10-26 17:45 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Octavian Purdila, Eric Dumazet, Krishna Kumar2,
Hagen Paul Pfeifer, netdev
In-Reply-To: <20091026095516.02f1cb49@nehalam>
Another algorithm that scores well in my tests.
http://isthe.com/chongo/tech/comp/fnv/
Algorithm Time Ratio Max StdDev
string10 1.433267 1.00 39064 0.01
string_hash17 1.461422 1.00 39497 1.50
fnv1a 1.472216 1.00 39895 2.25
jhash_string 1.482494 1.00 39669 1.04
static unsigned int fnv32(const unsigned char *key, unsigned int len)
{
uint32_t hval = 2166136261;
unsigned int i;
for (i = 0; i < len; i++) {
hval ^= key[i];
/* optimized multiply by 0x01000193 */
hval += (hval<<1) + (hval<<4) + (hval<<7)
+ (hval<<8) + (hval<<24);
}
return hval;
}
^ permalink raw reply
* Re: [PATCH] virtio-net: fix data corruption with OOM
From: Michael S. Tsirkin @ 2009-10-26 18:42 UTC (permalink / raw)
To: Rusty Russell; +Cc: virtualization, kvm, netdev
In-Reply-To: <200910261211.52148.rusty@rustcorp.com.au>
On Mon, Oct 26, 2009 at 12:11:51PM +1030, Rusty Russell wrote:
> On Mon, 26 Oct 2009 03:33:40 am Michael S. Tsirkin wrote:
> > virtio net used to unlink skbs from send queues on error,
> > but ever since 48925e372f04f5e35fec6269127c62b2c71ab794
> > we do not do this. This causes guest data corruption and crashes
> > with vhost since net core can requeue the skb or free it without
> > it being taken off the list.
> >
> > This patch fixes this by queueing the skb after successfull
> > transmit.
>
> I originally thought that this was racy: as soon as we do add_buf, we need to
> make sure we're ready for the callback (for virtio_pci, it's ->kick, but we
> shouldn't rely on that).
Modified the guest slightly, and I am getting crashes again.
I didn't have time to debug this, but based on previous experience,
I reverted 48925e372f04f5e35fec6269127c62b2c71ab794,
and the crash went away.
Rusty, what do you say we just revert 48925e372f04f5e35fec6269127c62b2c71ab794
for now?
How to reproduce: I used my vhost trees, and modified drivers/vhost/vhost.c :
- vhost_workqueue = create_workqueue("vhost");
+ vhost_workqueue = create_singlethread_workqueue("vhost");
My guess is this modifies timing and uncovers more races,
but of course there is a possibility that the bug is in vhost.
Still, the fact that 2.6.31 and 48925e372f04f5e35fec6269127c62b2c71ab794
as a guest are both fine, this is a strong hint that
48925e372f04f5e35fec6269127c62b2c71ab794 is to blame.
[ 24.555691] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
[ 24.556658] IP: [<ffffffffa003f1b1>] free_old_xmit_skbs+0x66/0xcd [virtio_net]
[ 24.556658] PGD 3e9ee067 PUD 3f38d067 PMD 0
[ 24.556658] Thread overran stack, or stack corrupted
[ 24.556658] Oops: 0002 [#1] SMP
[ 24.556658] last sysfs file: /sys/devices/virtual/input/input1/capabilities/sw
[ 24.556658] CPU 0
[ 24.556658] Modules linked in: virtio_net virtio_blk virtio_pci virtio_ring virtio af_packet aacraid [last unloaded: scsi_wait_scan]
[ 24.556658] Pid: 0, comm: swapper Tainted: G W 2.6.32-rc4-net #6
[ 24.556658] RIP: 0010:[<ffffffffa003f1b1>] [<ffffffffa003f1b1>] free_old_xmit_skbs+0x66/0xcd [virtio_net]
[ 24.556658] RSP: 0018:ffff880001c03d70 EFLAGS: 00010202
[ 24.556658] RAX: ffff88003e951418 RBX: ffff88003e953398 RCX: 0000000000000000
[ 24.556658] RDX: 0000000000000000 RSI: ffff880001c03d84 RDI: ffff88003e953398
[ 24.556658] RBP: ffff880001c03db0 R08: ffff88003e2c949c R09: 00000000ffffffff
[ 24.556658] R10: ffff880001c03f78 R11: 00000000fffbcc57 R12: ffff88003e65cdc0
[ 24.556658] R13: 0000000000000000 R14: 2000000000000000 R15: ffff880001c03d84
[ 24.556658] FS: 0000000000000000(0000) GS:ffff880001c00000(0000) knlGS:0000000000000000
[ 24.556658] CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
[ 24.556658] CR2: 0000000000000008 CR3: 000000003eee4000 CR4: 00000000000006b0
[ 24.556658] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 24.556658] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 24.556658] Process swapper (pid: 0, threadinfo ffffffff8174e000, task ffffffff817c09f0)
[ 24.556658] Stack:
[ 24.556658] 0000000000000002 0000000000000000 0000000000000000 ffff88003e953398
[ 24.556658] <0> ffff88003e953398 ffff88003e65cdc0 ffff88003e65c800 ffff88003e65ce70
[ 24.556658] <0> ffff880001c03df0 ffffffffa003fb35 ffff88003e65cc28 ffff88003e953398
[ 24.556658] Call Trace:
[ 24.556658] <IRQ>
[ 24.556658] [<ffffffffa003fb35>] start_xmit+0x38/0x15f [virtio_net]
[ 24.556658] [<ffffffff813ff768>] dev_hard_start_xmit+0x26c/0x2d3
[ 24.556658] [<ffffffff81412016>] sch_direct_xmit+0x5a/0x157
[ 24.556658] [<ffffffff814121cf>] __qdisc_run+0xbc/0xdd
[ 24.556658] [<ffffffff813fce1c>] net_tx_action+0xc2/0x120
[ 24.556658] [<ffffffff81047efe>] __do_softirq+0xd8/0x192
[ 24.556658] [<ffffffff8100cb3c>] call_softirq+0x1c/0x28
[ 24.556658] [<ffffffff8100ddb7>] do_softirq+0x33/0x6b
[ 24.556658] [<ffffffff81047d5c>] irq_exit+0x36/0x75
[ 24.556658] [<ffffffff8100d692>] do_IRQ+0xa8/0xbf
[ 24.556658] [<ffffffff8100c3d3>] ret_from_intr+0x0/0xa
[ 24.556658] <EOI>
[ 24.556658] [<ffffffff81011de3>] ? default_idle+0x31/0x46
[ 24.556658] [<ffffffff81011dc5>] ? default_idle+0x13/0x46
[ 24.556658] [<ffffffff8100ae53>] ? cpu_idle+0x55/0x8d
[ 24.556658] [<ffffffff814d1982>] ? rest_init+0x66/0x68
[ 24.556658] [<ffffffff818adc5d>] ? start_kernel+0x360/0x36b
[ 24.556658] [<ffffffff818ad29a>] ? x86_64_start_reservations+0xaa/0xae
[ 24.556658] [<ffffffff818ad37f>] ? x86_64_start_kernel+0xe1/0xe8
[ 24.556658] Code: fc 26 00 00 00 75 75 41 ff 8c 24 c0 00 00 00 48 89 df 48 8b 13 48 8b 43 08 48 c7 03 00 00 00 00 48 c7 43 08 00 00 00 00 48 89 10 <48> 89 42 08 49 8b 54 24 20 8b 43 68 48 01 82 98 00 00 00 49 8b
[ 24.556658] RIP [<ffffffffa003f1b1>] free_old_xmit_skbs+0x66/0xcd [virtio_net]
[ 24.556658] RSP <ffff880001c03d70>
[ 24.556658] CR2: 0000000000000008
[ 24.722629] ---[ end trace 6ac04221a0ae018b ]---
[ 24.725010] Kernel panic - not syncing: Fatal exception in interrupt
[ 24.727696] Pid: 0, comm: swapper Tainted: G D W 2.6.32-rc4-net #6
[ 24.730447] Call Trace:
[ 24.732443] <IRQ> [<ffffffff814eb553>] panic+0x75/0x127
[ 24.735097] [<ffffffff814ee350>] oops_end+0xaa/0xba
[ 24.737520] [<ffffffff81029002>] no_context+0x1ea/0x1f9
[ 24.740024] [<ffffffff810291c4>] __bad_area_nosemaphore+0x1b3/0x1d9
[ 24.742779] [<ffffffff810291f8>] bad_area_nosemaphore+0xe/0x10
[ 24.745399] [<ffffffff814ef73c>] do_page_fault+0x186/0x2c3
[ 24.748009] [<ffffffff814ed8bf>] page_fault+0x1f/0x30
[ 24.750463] [<ffffffffa003f1b1>] ? free_old_xmit_skbs+0x66/0xcd [virtio_net]
[ 24.753299] [<ffffffffa003fb35>] start_xmit+0x38/0x15f [virtio_net]
[ 24.755990] [<ffffffff813ff768>] dev_hard_start_xmit+0x26c/0x2d3
[ 24.758635] [<ffffffff81412016>] sch_direct_xmit+0x5a/0x157
[ 24.761204] [<ffffffff814121cf>] __qdisc_run+0xbc/0xdd
[ 24.763693] [<ffffffff813fce1c>] net_tx_action+0xc2/0x120
[ 24.766236] [<ffffffff81047efe>] __do_softirq+0xd8/0x192
[ 24.768754] [<ffffffff8100cb3c>] call_softirq+0x1c/0x28
[ 24.771326] [<ffffffff8100ddb7>] do_softirq+0x33/0x6b
[ 24.773793] [<ffffffff81047d5c>] irq_exit+0x36/0x75
[ 24.776241] [<ffffffff8100d692>] do_IRQ+0xa8/0xbf
[ 24.778705] [<ffffffff8100c3d3>] ret_from_intr+0x0/0xa
[ 24.781191] <EOI> [<ffffffff81011de3>] ? default_idle+0x31/0x46
[ 24.783961] [<ffffffff81011dc5>] ? default_idle+0x13/0x46
[ 24.786487] [<ffffffff8100ae53>] ? cpu_idle+0x55/0x8d
[ 24.788967] [<ffffffff814d1982>] ? rest_init+0x66/0x68
[ 24.791448] [<ffffffff818adc5d>] ? start_kernel+0x360/0x36b
[ 24.794014] [<ffffffff818ad29a>] ? x86_64_start_reservations+0xaa/0xae
[ 24.796747] [<ffffffff818ad37f>] ? x86_64_start_kernel+0xe1/0xe8
^ permalink raw reply
* 2.6.32-rc5-git3: Reported regressions from 2.6.31
From: Rafael J. Wysocki @ 2009-10-26 18:45 UTC (permalink / raw)
To: Linux Kernel Mailing List
Cc: Adrian Bunk, Andrew Morton, Linus Torvalds, Natalie Protasevich,
Kernel Testers List, Network Development, Linux ACPI,
Linux PM List, Linux SCSI List, Linux Wireless List, DRI
This message contains a list of some regressions from 2.6.31, for which there
are no fixes in the mainline I know of. If any of them have been fixed already,
please let me know.
If you know of any other unresolved regressions from 2.6.31, please let me know
either and I'll add them to the list. Also, please let me know if any of the
entries below are invalid.
Each entry from the list will be sent additionally in an automatic reply to
this message with CCs to the people involved in reporting and handling the
issue.
Listed regressions statistics:
Date Total Pending Unresolved
----------------------------------------
2009-10-26 66 42 37
2009-10-12 48 31 27
2009-10-02 22 15 9
Unresolved regressions
----------------------
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14485
Subject : System lockup running "cat /sys/kernel/debug/dri/0/i915_regs"
Submitter : Miles Lane <miles.lane-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2009-10-26 4:00 (1 days old)
References : http://marc.info/?l=linux-kernel&m=125652968117713&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14484
Subject : no video output after suspend
Submitter : Riccardo Magliocchetti <riccardo.magliocchetti-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2009-10-25 20:57 (2 days old)
References : http://marc.info/?l=linux-kernel&m=125650430123713&w=4
Handled-By : Jesse Barnes <jbarnes-Y1mF5jBUw70BENJcbMCuUQ@public.gmane.org>
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14483
Subject : WARNING: at drivers/base/sys.c:353 __sysdev_resume+0x54/0xca()
Submitter : Justin Mattock <justinmattock-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2009-10-25 19:58 (2 days old)
References : http://marc.info/?l=linux-kernel&m=125650070420168&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14482
Subject : kernel BUG at fs/dcache.c:670 +lvm +md +ext3
Submitter : Alexander Clouter <alex-L4GPcECwBoDe9xe1eoZjHA@public.gmane.org>
Date : 2009-10-23 10:30 (4 days old)
References : http://lkml.org/lkml/2009/10/23/50
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14481
Subject : umount blocked for more than 120 seconds after USB drive removal
Submitter : Robert Hancock <hancockrwd-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2009-10-21 5:26 (6 days old)
References : http://marc.info/?l=linux-kernel&m=125610280532245&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14479
Subject : nfs oops
Submitter : Egon Alter <egon.alter-hi6Y0CQ0nG0@public.gmane.org>
Date : 2009-10-19 16:03 (8 days old)
References : http://marc.info/?l=linux-kernel&m=125596822630410&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14477
Subject : possible circular locking dependency in ISDN PPP
Submitter : Tilman Schmidt <tilman-ZTO5kqT2PaM@public.gmane.org>
Date : 2009-10-18 22:16 (9 days old)
References : http://marc.info/?l=linux-kernel&m=125590423416087&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14473
Subject : ATA related kernel warning after resume
Submitter : Tino Keitel <tino.keitel-rAwCM5oiXHA@public.gmane.org>
Date : 2009-10-14 6:55 (13 days old)
References : http://marc.info/?l=linux-kernel&m=125550466624678&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14472
Subject : EXT4 corruption
Submitter : Shawn Starr <shawn.starr-bJEeYj9oJeDQT0dZR+AlfA@public.gmane.org>
Date : 2009-10-13 2:07 (14 days old)
References : http://marc.info/?l=linux-kernel&m=125539997508256&w=4
Handled-By : Theodore Tso <tytso-3s7WtUTddSA@public.gmane.org>
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14467
Subject : Linker errors on ia64 with NR_CPUS=4096
Submitter : Jeff Mahoney <jeffm-IBi9RG/b67k@public.gmane.org>
Date : 2009-10-18 22:28 (9 days old)
First-Bad-Commit: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=34d76c41554a05425613d16efebb3069c4c545f0
References : http://marc.info/?l=linux-kernel&m=125590493116720&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14466
Subject : EFI boot on x86 fails in .32
Submitter : Matthew Garrett <mjg59-1xO5oi07KQx4cg9Nei1l7Q@public.gmane.org>
Date : 2009-10-20 0:34 (7 days old)
First-Bad-Commit: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=7bd867dfb4e0357e06a3211ab2bd0e714110def3
References : http://marc.info/?l=linux-kernel&m=125599887314290&w=4
Handled-By : Feng Tang <feng.tang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14442
Subject : resume after hibernate: /dev/sdb drops and returns as /dev/sde
Submitter : Duncan <1i5t5.duncan-j9pdmedNgrk@public.gmane.org>
Date : 2009-10-20 01:52 (7 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14430
Subject : sync() hangs in bdi_sched_wait
Submitter : Petr Vandrovec <petr-vPk2MGR0e28uaRcfnNAh7A@public.gmane.org>
Date : 2009-10-17 19:14 (10 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14415
Subject : Reboot on kernel load
Submitter : Brian Beardall <brian-sVkzCUl/XCrR7s880joybQ@public.gmane.org>
Date : 2009-10-15 23:57 (12 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14408
Subject : sysctl check failed
Submitter : Peter Teoh <htmldeveloper-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2009-10-14 22:59 (13 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14406
Subject : uvcvideo stopped work on Toshiba
Submitter : okias <d.okias-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2009-10-14 19:08 (13 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14390
Subject : "bind" a device to a driver doesn't not work anymore
Submitter : Éric Piel <Eric.Piel-VkQ1JFuSMpfAbQlEx87xDw@public.gmane.org>
Date : 2009-10-11 0:04 (16 days old)
References : http://marc.info/?l=linux-kernel&m=125521979921241&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14389
Subject : Build system issue
Submitter : Peter Zijlstra <peterz-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
Date : 2009-10-09 8:58 (18 days old)
First-Bad-Commit: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=575543347b5baed0ca927cb90ba8807396fe9cc9
References : http://marc.info/?l=linux-kernel&m=125507914909152&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14387
Subject : deadlock with fallocate
Submitter : Thomas Neumann <tneumann-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
Date : 2009-10-07 3:00 (20 days old)
References : http://marc.info/?l=linux-kernel&m=125488495526471&w=4
Handled-By : Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14384
Subject : tbench regression with 2.6.32-rc1
Submitter : Zhang, Yanmin <yanmin_zhang-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Date : 2009-10-09 9:51 (18 days old)
First-Bad-Commit: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=59abf02644c45f1591e1374ee7bb45dc757fcb88
References : http://marc.info/?l=linux-kernel&m=125508216713138&w=4
Handled-By : Peter Zijlstra <a.p.zijlstra-/NLkJaSkS4VmR6Xm/wNWPw@public.gmane.org>
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14383
Subject : hackbench regression with kernel 2.6.32-rc1
Submitter : Zhang, Yanmin <yanmin_zhang-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Date : 2009-10-09 9:19 (18 days old)
First-Bad-Commit: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=29cd8bae396583a2ee9a3340db8c5102acf9f6fd
References : http://marc.info/?l=linux-kernel&m=125508007510274&w=4
Handled-By : Peter Zijlstra <a.p.zijlstra-/NLkJaSkS4VmR6Xm/wNWPw@public.gmane.org>
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14381
Subject : iwlagn lost connection after s2ram (with warnings)
Submitter : Carlos R. Mafra <crmafra2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2009-10-07 14:20 (20 days old)
References : http://marc.info/?l=linux-kernel&m=125492569119947&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14378
Subject : Problems with net/core/skbuff.c
Submitter : Massimo Cetra <mcetra-BBpJ+9iBSNKonA0d6jMUrA@public.gmane.org>
Date : 2009-10-08 14:51 (19 days old)
References : http://marc.info/?l=linux-kernel&m=125501488220358&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14376
Subject : Kernel NULL pointer dereference/ kvm subsystem
Submitter : Don Dupuis <dondster-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2009-10-06 14:38 (21 days old)
References : http://marc.info/?l=linux-kernel&m=125484025021737&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14373
Subject : Task blocked for more than 120 seconds
Submitter : Zeno Davatz <zdavatz-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2009-10-02 10:16 (25 days old)
References : http://marc.info/?l=linux-kernel&m=125447858618412&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14372
Subject : ath5k wireless not working after suspend-resume - eeepc
Submitter : Fabio Comolli <fabio.comolli-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2009-10-03 15:36 (24 days old)
References : http://lkml.org/lkml/2009/10/3/91
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14355
Subject : USB serial regression after 2.6.31.1 with Huawei E169 GSM modem
Submitter : Benjamin Herrenschmidt <benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org>
Date : 2009-10-10 03:07 (17 days old)
References : http://marc.info/?l=linux-kernel&m=125513456327542&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14354
Subject : Bad corruption with 2.6.32-rc1 and upwards
Submitter : Holger Freyther <zecke-MQnelBtSfJRAfugRpC6u6w@public.gmane.org>
Date : 2009-10-09 15:42 (18 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14353
Subject : BUG: sleeping function called from invalid context at kernel/mutex.c:280
Submitter : Miles Lane <miles.lane-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2009-10-05 3:39 (22 days old)
References : http://marc.info/?l=linux-kernel&m=125471432208671&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14352
Subject : WARNING: at net/mac80211/scan.c:267
Submitter : Maciej Rutecki <maciej.rutecki-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2009-10-08 00:30 (19 days old)
References : http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2089#c7
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14334
Subject : pcmcia suspend regression from 2.6.31.1 to 2.6.31.2 - Dell Inspiron 600m
Submitter : Jose Marino <braket-PkbjNfxxIARBDgjK7y7TUQ@public.gmane.org>
Date : 2009-10-06 15:44 (21 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14331
Subject : Radeon XPRESS 200M: System hang with radeon DRI and Fedora 10 userspace unless DRI=off
Submitter : Alex Villacis Lasso <avillaci-x0m+Mc+nT7uljOmnV8AmnkElSqmLX1BE@public.gmane.org>
Date : 2009-10-06 00:29 (21 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14299
Subject : oops in wireless, iwl3945 related?
Submitter : Pavel Machek <pavel-+ZI9xUNit7I@public.gmane.org>
Date : 2009-09-29 17:12 (28 days old)
References : http://marc.info/?l=linux-kernel&m=125424439725743&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14298
Subject : warning at manage.c:361 (set_irq_wake), matrix-keypad related?
Submitter : Pavel Machek <pavel-+ZI9xUNit7I@public.gmane.org>
Date : 2009-09-30 20:07 (27 days old)
References : http://marc.info/?l=linux-kernel&m=125434130703538&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14297
Subject : console resume broken since ba15ab0e8d
Submitter : Sascha Hauer <s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Date : 2009-09-30 15:11 (27 days old)
References : http://marc.info/?l=linux-kernel&m=125432349404060&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14296
Subject : spitz boots but suspend/resume is broken
Submitter : Pavel Machek <pavel-+ZI9xUNit7I@public.gmane.org>
Date : 2009-09-30 12:06 (27 days old)
References : http://marc.info/?l=linux-kernel&m=125431244516449&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14277
Subject : Caught 8-bit read from freed memory in b43 driver at association
Submitter : Christian Casteyde <casteyde.christian-GANU6spQydw@public.gmane.org>
Date : 2009-09-30 18:06 (27 days old)
Regressions with patches
------------------------
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14480
Subject : 2 locks held by cat -- running "find /sys | head -c 4" --> system hang
Submitter : Miles Lane <miles.lane-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2009-10-20 16:11 (7 days old)
References : http://marc.info/?l=linux-kernel&m=125605511728088&w=4
Handled-By : Chris Wilson <chris-Y6uKTt2uX1cEflXRtASbqLVCufUGDwFn@public.gmane.org>
Patch : http://patchwork.kernel.org/patch/54974/
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14380
Subject : Video tearing/glitching with T400 laptops
Submitter : Theodore Ts'o <tytso-3s7WtUTddSA@public.gmane.org>
Date : 2009-10-02 22:40 (25 days old)
References : http://marc.info/?l=linux-kernel&m=125452324520623&w=4
Handled-By : Jesse Barnes <jbarnes-Y1mF5jBUw70BENJcbMCuUQ@public.gmane.org>
Patch : http://marc.info/?l=linux-kernel&m=125591495325000&w=4
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14379
Subject : ACPI Warning for _SB_.BAT0._BIF: Converted Buffer to expected String
Submitter : Justin Mattock <justinmattock-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2009-10-08 21:46 (19 days old)
First-Bad-Commit: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=d9adc2e031bd22d5d9607a53a8d3b30e0b675f39
References : http://marc.info/?l=linux-kernel&m=125504031328941&w=4
Handled-By : Alexey Starikovskiy <astarikovskiy-l3A5Bk7waGM@public.gmane.org>
Patch : http://bugzilla.kernel.org/attachment.cgi?id=23347
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14375
Subject : Intel(R) I/OAT DMA Engine init failed
Submitter : Alexander Beregalov <a.beregalov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2009-10-02 9:46 (25 days old)
References : http://marc.info/?l=linux-kernel&m=125447680016160&w=4
Handled-By : Dan Williams <dan.j.williams-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Patch : http://patchwork.kernel.org/patch/51808/
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=14302
Subject : Kernel panic on i386 machine when booting with profile=2
Submitter : Shi, Alex <alex.shi-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Date : 2009-10-01 3:23 (26 days old)
References : http://marc.info/?l=linux-kernel&m=125436749607199&w=4
Handled-By : Alex Shi <alex.shi-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Patch : http://patchwork.kernel.org/patch/50813/
For details, please visit the bug entries and follow the links given in
references.
As you can see, there is a Bugzilla entry for each of the listed regressions.
There also is a Bugzilla entry used for tracking the regressions from 2.6.31,
unresolved as well as resolved, at:
http://bugzilla.kernel.org/show_bug.cgi?id=14230
Please let me know if there are any Bugzilla entries that should be added to
the list in there.
Thanks,
Rafael
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* performance regression in virtio-net in 2.6.32-rc4
From: Michael S. Tsirkin @ 2009-10-26 18:48 UTC (permalink / raw)
To: Rusty Russell; +Cc: virtualization, kvm, netdev
Hi!
I noticed a performance regression in virtio net: going from
2.6.31 to 2.6.32-rc4 I see this, for guest to host communication:
[mst@tuck ~]$ ssh robin sh streamtest1
TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 11.0.0.3
(11.0.0.3) port 0 AF_INET : demo
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 10.20 7806.48
[mst@tuck ~]$ ssh robin sh streamtest1
TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 11.0.0.3
(11.0.0.3) port 0 AF_INET : demo
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 10.00 6814.60
Note: I had to revert 48925e372f04f5e35fec6269127c62b2c71ab794,
and I applied a patch
virtio-pci: fix per-vq MSI-X request logic
which fixes a bug introduced by f68d24082e22ccee3077d11aeb6dc5354f0ca7f1.
Any tips on debugging this?
--
MST
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox