Linux Archive

Linux Archive (http://www.linux-archive.org/)
-   Debian Kernel (http://www.linux-archive.org/debian-kernel/)
-   -   Bug#590582: abot vortex problem (http://www.linux-archive.org/debian-kernel/617895-bug-590582-abot-vortex-problem.html)

Karol Szkudlarek 01-06-2012 08:38 AM

Bug#590582: abot vortex problem
 
Hello,

No..., I'm not tried 3.x kernel from sid or experimental becuase problem
considers my home router/server which is need 24h/day...


But I could try for example backported patched a module driver 3c95x for
my 2.6.32 current debian squeeze version. For me it will be safe
solution which I can easily revert.
As I wrote before problem is easy to reproduce if you try copying
(through scp, wire connection or wireless connection where access point
is connected to 3c95x port) a file from one PC to server which contains
3c95x network card. After copying for example 200/600MB/1GB (its not a
constant amount) copying stalled and network interface on destination
doesn't responding (ping,telnet....)


I hope it helps a little,
Regards,

--
Karol Szkudlarek



--
To UNSUBSCRIBE, email to debian-kernel-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Archive: 4F06C12E.6070200@mikronika.com.pl">http://lists.debian.org/4F06C12E.6070200@mikronika.com.pl

Jonathan Nieder 03-19-2012 05:41 AM

Bug#590582: abot vortex problem
 
Hi Karol,

Karol Szkudlarek wrote:

> No..., I'm not tried 3.x kernel from sid or experimental becuase
> problem considers my home router/server which is need 24h/day...
>
> But I could try for example backported patched a module driver 3c95x
> for my 2.6.32 current debian squeeze version. For me it will be safe
> solution which I can easily revert.

Ok, makes sense.

I've attached a patch to try, following instructions from [1]. The
result should be ABI-compatible with a squeeze kernel, so if all goes
well and you have kept a copy of the unpatched 3c95x driver, you can
unload the patched 3c95x driver and reload the standard one after
testing. (Of course, it is always possible that testing could go
poorly and e.g. hang the system.)

Hope that helps,
Jonathan

[1] http://kernel-handbook.alioth.debian.org/ch-common-tasks.html#s-common-official
or the corresponding page in the debian-kernel-handbook package
From: Jonathan Nieder <jrnieder@gmail.com>
Date: Mon, 19 Mar 2012 01:31:49 -0500
Subject: debugging patch for bug#590582

This patch basically updates the 3c59x driver in squeeze to the
version in the longterm 3.0.y tree. Some commits making cosmetic
changes have been skipped to make the changes more minimal and
therefore easier to understand.
---
drivers/net/3c59x.c | 84 +++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 71 insertions(+), 13 deletions(-)

diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 447b04a43c89..534f287f7e7b 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -633,7 +633,11 @@ struct vortex_private {
open:1,
medialock:1,
must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */
- large_frames:1; /* accept large frames */
+ large_frames:1, /* accept large frames */
+ handling_irq:1; /* private in_irq indicator */
+ /* {get|set}_wol operations are already serialized by rtnl.
+ * no additional locking is required for the enable_wol and acpi_set_WOL()
+ */
int drv_flags;
u16 status_enable;
u16 intr_enable;
@@ -695,7 +699,8 @@ DEFINE_WINDOW_IO(32)
#define DEVICE_PCI(dev) NULL
#endif

-#define VORTEX_PCI(vp) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL)
+#define VORTEX_PCI(vp)
+ ((struct pci_dev *) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL))

#ifdef CONFIG_EISA
#define DEVICE_EISA(dev) (((dev)->bus == &eisa_bus_type) ? to_eisa_device((dev)) : NULL)
@@ -703,7 +708,8 @@ DEFINE_WINDOW_IO(32)
#define DEVICE_EISA(dev) NULL
#endif

-#define VORTEX_EISA(vp) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL)
+#define VORTEX_EISA(vp)
+ ((struct eisa_device *) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL))

/* The action to take with a media selection timer tick.
Note that we deviate from the 3Com order by checking 10base2 before AUI.
@@ -1020,10 +1026,16 @@ static int __devinit vortex_init_one(struct pci_dev *pdev,
ioaddr = pci_iomap(pdev, pci_bar, 0);
if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */
ioaddr = pci_iomap(pdev, 0, 0);
+ if (!ioaddr) {
+ pci_disable_device(pdev);
+ rc = -ENOMEM;
+ goto out;
+ }

rc = vortex_probe1(&pdev->dev, ioaddr, pdev->irq,
ent->driver_data, unit);
if (rc < 0) {
+ pci_iounmap(pdev, ioaddr);
pci_disable_device(pdev);
goto out;
}
@@ -1830,7 +1842,7 @@ vortex_timer(unsigned long data)
ok = 1;
}

- if (!netif_carrier_ok(dev))
+ if (dev->flags & IFF_SLAVE || !netif_carrier_ok(dev))
next_tick = 5*HZ;

if (vp->medialock)
@@ -1881,7 +1893,6 @@ leave_media_alone:
mod_timer(&vp->timer, RUN_AT(next_tick));
if (vp->deferred)
iowrite16(FakeIntr, ioaddr + EL3_CMD);
- return;
}

static void vortex_tx_timeout(struct net_device *dev)
@@ -1942,7 +1953,7 @@ static void vortex_tx_timeout(struct net_device *dev)

/* Issue Tx Enable */
iowrite16(TxEnable, ioaddr + EL3_CMD);
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
}

/*
@@ -2087,7 +2098,6 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
}

- dev->trans_start = jiffies;

/* Clear the Tx status stack. */
{
@@ -2128,6 +2138,15 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->name, vp->cur_tx);
}

+ /*
+ * We can't allow a recursion from our interrupt handler back into the
+ * tx routine, as they take the same spin lock, and that causes
+ * deadlock. Just return NETDEV_TX_BUSY and let the stack try again in
+ * a bit
+ */
+ if (vp->handling_irq)
+ return NETDEV_TX_BUSY;
+
if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) {
if (vortex_debug > 0)
pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.
",
@@ -2153,8 +2172,8 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
int i;

vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
- skb->len-skb->data_len, PCI_DMA_TODEVICE));
- vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb->len-skb->data_len);
+ skb_headlen(skb), PCI_DMA_TODEVICE));
+ vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb_headlen(skb));

for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -2198,7 +2217,6 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
iowrite16(DownUnstall, ioaddr + EL3_CMD);
spin_unlock_irqrestore(&vp->lock, flags);
- dev->trans_start = jiffies;
return NETDEV_TX_OK;
}

@@ -2336,11 +2354,13 @@ boomerang_interrupt(int irq, void *dev_id)

ioaddr = vp->ioaddr;

+
/*
* It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout
* and boomerang_start_xmit
*/
spin_lock(&vp->lock);
+ vp->handling_irq = 1;

status = ioread16(ioaddr + EL3_STATUS);

@@ -2448,6 +2468,7 @@ boomerang_interrupt(int irq, void *dev_id)
pr_debug("%s: exiting interrupt, status %4.4x.
",
dev->name, status);
handler_exit:
+ vp->handling_irq = 0;
spin_unlock(&vp->lock);
return IRQ_HANDLED;
}
@@ -2594,7 +2615,7 @@ boomerang_rx(struct net_device *dev)
struct sk_buff *skb;
entry = vp->dirty_rx % RX_RING_SIZE;
if (vp->rx_skbuff[entry] == NULL) {
- skb = netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN);
+ skb = netdev_alloc_skb_ip_align(dev, PKT_BUF_SZ);
if (skb == NULL) {
static unsigned long last_jif;
if (time_after(jiffies, last_jif + 10 * HZ)) {
@@ -2606,7 +2627,6 @@ boomerang_rx(struct net_device *dev)
break; /* Bad news! */
}

- skb_reserve(skb, NET_IP_ALIGN);
vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
vp->rx_skbuff[entry] = skb;
}
@@ -2920,6 +2940,39 @@ static void vortex_get_drvinfo(struct net_device *dev,
}
}

+static void vortex_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct vortex_private *vp = netdev_priv(dev);
+
+ if (!VORTEX_PCI(vp))
+ return;
+
+ wol->supported = WAKE_MAGIC;
+
+ wol->wolopts = 0;
+ if (vp->enable_wol)
+ wol->wolopts |= WAKE_MAGIC;
+}
+
+static int vortex_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct vortex_private *vp = netdev_priv(dev);
+
+ if (!VORTEX_PCI(vp))
+ return -EOPNOTSUPP;
+
+ if (wol->wolopts & ~WAKE_MAGIC)
+ return -EINVAL;
+
+ if (wol->wolopts & WAKE_MAGIC)
+ vp->enable_wol = 1;
+ else
+ vp->enable_wol = 0;
+ acpi_set_WOL(dev);
+
+ return 0;
+}
+
static const struct ethtool_ops vortex_ethtool_ops = {
.get_drvinfo = vortex_get_drvinfo,
.get_strings = vortex_get_strings,
@@ -2931,6 +2984,8 @@ static const struct ethtool_ops vortex_ethtool_ops = {
.set_settings = vortex_set_settings,
.get_link = ethtool_op_get_link,
.nway_reset = vortex_nway_reset,
+ .get_wol = vortex_get_wol,
+ .set_wol = vortex_set_wol,
};

#ifdef CONFIG_PCI
@@ -2972,7 +3027,7 @@ static void set_rx_mode(struct net_device *dev)
if (vortex_debug > 3)
pr_notice("%s: Setting promiscuous mode.
", dev->name);
new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast|RxPr om;
- } else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
+ } else if (!netdev_mc_empty(dev) || dev->flags & IFF_ALLMULTI) {
new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast;
} else
new_mode = SetRxFilter | RxStation | RxBroadcast;
@@ -3155,6 +3210,9 @@ static void acpi_set_WOL(struct net_device *dev)
return;
}

+ if (VORTEX_PCI(vp)->current_state < PCI_D3hot)
+ return;
+
/* Change the power state to D3; RxEnable doesn't take effect. */
pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot);
}
--
1.7.10.rc1

Karol Szkudlarek 03-24-2012 08:50 AM

Bug#590582: abot vortex problem
 
W dniu 19.03.2012 07:41, Jonathan Nieder pisze:

Hi Karol,

Karol Szkudlarek wrote:


No..., I'm not tried 3.x kernel from sid or experimental becuase
problem considers my home router/server which is need 24h/day...

But I could try for example backported patched a module driver 3c95x
for my 2.6.32 current debian squeeze version. For me it will be safe
solution which I can easily revert.


Ok, makes sense.

I've attached a patch to try, following instructions from [1]. The
result should be ABI-compatible with a squeeze kernel, so if all goes
well and you have kept a copy of the unpatched 3c95x driver, you can
unload the patched 3c95x driver and reload the standard one after
testing. (Of course, it is always possible that testing could go
poorly and e.g. hang the system.)

Hope that helps,
Jonathan

[1] http://kernel-handbook.alioth.debian.org/ch-common-tasks.html#s-common-official
or the corresponding page in the debian-kernel-handbook package

Jonathan,

I've succesfully applied patch and reinstall module as you suggest me in
previous e-mail (thanks for help in module reinstalling!)


{
rmmod 3c59x; insmod
/usr/src/linux-source-2.6.32/drivers/net/3c59x.ko; insmod
/lib/modules/2.6.32-5-686/kernel/drivers/net/3c59x.ko

ifdown eth0;ifup eth0;ifdown eth2;ifup eth2
} &

and I have to add ifdown/ifup for my network interfaces after it.

I've tested patched driver, but unfortunately it contains the same bug,
copying large file via eth0 stills breaks eth0 communication... :-(

Of course I've checked via lsmod different size of memory of patched
and original driver to be sure that I've loaded patched driver instead
of original.


Regards,
Karol



--
To UNSUBSCRIBE, email to debian-kernel-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Archive: 4F6D98F7.3050607@mikronika.com.pl">http://lists.debian.org/4F6D98F7.3050607@mikronika.com.pl


All times are GMT. The time now is 11:55 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.