* sky2 driver - large files upload problem
@ 2006-08-21 12:41 Jon Wikne
2006-08-21 13:18 ` Daniel Drake
0 siblings, 1 reply; 9+ messages in thread
From: Jon Wikne @ 2006-08-21 12:41 UTC (permalink / raw)
To: netdev
Hi Stephen & rest of list,
I'm having a peculiar problem with the sky2 driver.
The problem is seen on the versions in kernels 2.6.16.16,
2.6.17.8 and 2.6.18-rc4.
The problem appears when uploading large files (for instance
via scp) _from_ the system in question. Downloads work OK,
as does normal interactive traffic against the remote system.
What happens is typically this: After transeferring some
data, ranging from less than 100kB to 10MB, the upload freezes,
i.e. gets no further. Use of ping shows the connection is
effectively dead. If I do a sequence /sbin/ifdown eth0
/sbin/ifup eth0 the upload might resume, but stops again
shortly. The phenomenon seems to occur sooner if the path
to the remote system is _fast_ (low ping times).
The system in question works OK using the WLAN interface,
and also the wired connection works flawlessly in both
directions when running under (ugh!) WinXP.
# lspci
[...]
02:00.0 Ethernet controller: Marvell Technology Group Ltd. 88E8036 PCI-E
Fast Ethernet Controller (rev 10)
# cat /proc/interrupts
[...]
17: 10568 IO-APIC-level yenta, uhci_hcd:usb5, sky2,
i915@pci:0000:00:02.0
Any ideas...?
Please CC replies to wikne@cheetah.uio.no
Regards,
-- Jon Wikne
Department of Physics
University of Oslo
Norway
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: sky2 driver - large files upload problem
2006-08-21 12:41 sky2 driver - large files upload problem Jon Wikne
@ 2006-08-21 13:18 ` Daniel Drake
2006-08-21 14:21 ` Jon Wikne
0 siblings, 1 reply; 9+ messages in thread
From: Daniel Drake @ 2006-08-21 13:18 UTC (permalink / raw)
To: Jon Wikne; +Cc: netdev
Hi Jon,
Jon Wikne wrote:
> What happens is typically this: After transeferring some
> data, ranging from less than 100kB to 10MB, the upload freezes,
> i.e. gets no further. Use of ping shows the connection is
> effectively dead. If I do a sequence /sbin/ifdown eth0
> /sbin/ifup eth0 the upload might resume, but stops again
> shortly. The phenomenon seems to occur sooner if the path
> to the remote system is _fast_ (low ping times).
You can try applying this patch:
http://developer.osdl.org/shemminger/prototypes/sky2-proc-debug.patch
It will add a /proc/net/sky2/ethX file, which lists the status of the TX
and status rings. You should compare the contents of this file during
normal operation to when the interface has hung.
Daniel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: sky2 driver - large files upload problem
2006-08-21 13:18 ` Daniel Drake
@ 2006-08-21 14:21 ` Jon Wikne
2006-08-21 16:51 ` Stephen Hemminger
0 siblings, 1 reply; 9+ messages in thread
From: Jon Wikne @ 2006-08-21 14:21 UTC (permalink / raw)
To: netdev; +Cc: Daniel Drake
Daniel Drake wrote:
>
> Jon Wikne wrote:
>
>> What happens is typically this: After transeferring some
>> data, ranging from less than 100kB to 10MB, the upload freezes,
>> i.e. gets no further. Use of ping shows the connection is
>> effectively dead. If I do a sequence /sbin/ifdown eth0
>> /sbin/ifup eth0 the upload might resume, but stops again
>> shortly. The phenomenon seems to occur sooner if the path
>> to the remote system is _fast_ (low ping times).
>
> You can try applying this patch:
> http://developer.osdl.org/shemminger/prototypes/sky2-proc-debug.patch
>
> It will add a /proc/net/sky2/ethX file, which lists the status of the TX
> and status rings. You should compare the contents of this file during
> normal operation to when the interface has hung.
Thanks, Daniel. I applied the patch.
The output of 'cat /proc/net/sky2/eth0' under normal circumstances
is here:
http://puma.uio.no/sky2/sky2-status-normal.txt
After the interface hangs, 'cat /proc/net/sky2/eth0' causes the
whole computer to hang completely. No kernel oops or other
messages in the console window. Power down is the only
solution.... :-[ No log entries after reboot.
-- Jon
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: sky2 driver - large files upload problem
2006-08-21 14:21 ` Jon Wikne
@ 2006-08-21 16:51 ` Stephen Hemminger
2006-08-21 22:04 ` Jon Wikne
0 siblings, 1 reply; 9+ messages in thread
From: Stephen Hemminger @ 2006-08-21 16:51 UTC (permalink / raw)
To: Jon Wikne; +Cc: netdev, Daniel Drake
On Mon, 21 Aug 2006 16:21:07 +0200
Jon Wikne <wikne@cheetah.uio.no> wrote:
> Daniel Drake wrote:
> >
> > Jon Wikne wrote:
> >
> >> What happens is typically this: After transeferring some
> >> data, ranging from less than 100kB to 10MB, the upload freezes,
> >> i.e. gets no further. Use of ping shows the connection is
> >> effectively dead. If I do a sequence /sbin/ifdown eth0
> >> /sbin/ifup eth0 the upload might resume, but stops again
> >> shortly. The phenomenon seems to occur sooner if the path
> >> to the remote system is _fast_ (low ping times).
> >
> > You can try applying this patch:
> > http://developer.osdl.org/shemminger/prototypes/sky2-proc-debug.patch
> >
> > It will add a /proc/net/sky2/ethX file, which lists the status of the TX
> > and status rings. You should compare the contents of this file during
> > normal operation to when the interface has hung.
>
> Thanks, Daniel. I applied the patch.
>
> The output of 'cat /proc/net/sky2/eth0' under normal circumstances
> is here:
>
> http://puma.uio.no/sky2/sky2-status-normal.txt
>
> After the interface hangs, 'cat /proc/net/sky2/eth0' causes the
> whole computer to hang completely. No kernel oops or other
> messages in the console window. Power down is the only
> solution.... :-[ No log entries after reboot.
>
It could be the code in the debug patch is walking off into space.
The smaller version of the same patch, doesn't walk but just reports
the index values.
--- sky2.orig/drivers/net/sky2.c 2006-08-16 15:17:53.000000000 -0700
+++ sky2/drivers/net/sky2.c 2006-08-16 15:19:42.000000000 -0700
@@ -38,6 +38,7 @@
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/if_vlan.h>
+#include <linux/proc_fs.h>
#include <linux/prefetch.h>
#include <linux/mii.h>
@@ -1005,6 +1006,7 @@
re->mapaddr = pci_map_single(hw->pdev, re->skb->data,
sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
+ re->ridx = sky2->rx_put;
sky2_rx_add(sky2, re->mapaddr);
}
@@ -1890,6 +1892,7 @@
skb_put(skb, length);
resubmit:
re->skb->ip_summed = CHECKSUM_NONE;
+ re->ridx = sky2->rx_put;
sky2_rx_add(sky2, re->mapaddr);
return skb;
@@ -3088,6 +3091,49 @@
.get_perm_addr = ethtool_op_get_perm_addr,
};
+
+static struct proc_dir_entry *sky2_proc;
+
+static int sky2_seq_show(struct seq_file *seq, void *v)
+{
+ struct net_device *dev = seq->private;
+ const struct sky2_port *sky2 = netdev_priv(dev);
+ const struct sky2_hw *hw = sky2->hw;
+ unsigned last;
+
+ last = sky2_read16(hw, STAT_PUT_IDX);
+
+ if (hw->st_idx == last)
+ seq_puts(seq, "Status ring (empty)\n");
+ else
+ seq_printf(seq, "Status ring %d...%d\n", last, hw->st_idx);
+
+ if (sky2->tx_cons == sky2->tx_prod)
+ seq_puts(seq, "Tx ring (empty)\n");
+ else
+ seq_printf(seq, "Tx ring %d..%d\n", sky2->tx_cons, sky2->tx_prod);
+
+ seq_printf(seq, "Rx pending hw get=%d put=%d last=%d\n",
+ sky2_read16(hw, Y2_QADDR(rxqaddr[sky2->port], PREF_UNIT_GET_IDX)),
+ sky2_read16(hw, Y2_QADDR(rxqaddr[sky2->port], PREF_UNIT_PUT_IDX)),
+ sky2_read16(hw, Y2_QADDR(rxqaddr[sky2->port], PREF_UNIT_LAST_IDX)));
+
+ return 0;
+}
+
+static int sky2_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, sky2_seq_show, PDE(inode)->data);
+}
+
+static const struct file_operations sky2_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = sky2_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/* Initialize network device */
static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
unsigned port, int highmem)
@@ -3178,6 +3224,15 @@
dev->name,
dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+
+ if (sky2_proc) {
+ struct proc_dir_entry *res;
+ res = create_proc_entry(dev->name, S_IRUGO, sky2_proc);
+ if (res) {
+ res->proc_fops = &sky2_proc_fops;
+ res->data = dev;
+ }
+ }
}
/* Handle software interrupt used during MSI test */
@@ -3417,8 +3472,11 @@
dev0 = hw->dev[0];
dev1 = hw->dev[1];
- if (dev1)
+ if (dev1) {
+ remove_proc_entry(dev1->name, sky2_proc);
unregister_netdev(dev1);
+ }
+ remove_proc_entry(dev0->name, sky2_proc);
unregister_netdev(dev0);
sky2_set_power_state(hw, PCI_D3hot);
@@ -3519,12 +3577,14 @@
static int __init sky2_init_module(void)
{
+ sky2_proc = proc_mkdir("sky2", proc_net);
return pci_register_driver(&sky2_driver);
}
static void __exit sky2_cleanup_module(void)
{
pci_unregister_driver(&sky2_driver);
+ proc_net_remove("sky2");
}
module_init(sky2_init_module);
--- sky2.orig/drivers/net/sky2.h 2006-08-16 15:19:29.000000000 -0700
+++ sky2/drivers/net/sky2.h 2006-08-16 15:19:42.000000000 -0700
@@ -1827,6 +1827,7 @@
struct ring_info {
struct sk_buff *skb;
dma_addr_t mapaddr;
+ u16 ridx;
};
struct sky2_port {
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: sky2 driver - large files upload problem
2006-08-21 16:51 ` Stephen Hemminger
@ 2006-08-21 22:04 ` Jon Wikne
2006-08-21 23:36 ` Stephen Hemminger
2006-08-22 22:38 ` [RFT] sky2: transmit complete alternative Stephen Hemminger
0 siblings, 2 replies; 9+ messages in thread
From: Jon Wikne @ 2006-08-21 22:04 UTC (permalink / raw)
To: netdev; +Cc: Stephen Hemminger, Daniel Drake
Stephen Hemminger wrote:
> On Mon, 21 Aug 2006 16:21:07 +0200
> Jon Wikne <wikne@cheetah.uio.no> wrote:
>
>>Daniel Drake wrote:
>>
>>>Jon Wikne wrote:
>>>
>>>>What happens is typically this: After transeferring some
>>>>data, ranging from less than 100kB to 10MB, the upload freezes,
>>>>i.e. gets no further. Use of ping shows the connection is
>>>>effectively dead. If I do a sequence /sbin/ifdown eth0
>>>>/sbin/ifup eth0 the upload might resume, but stops again
>>>>shortly. The phenomenon seems to occur sooner if the path
>>>>to the remote system is _fast_ (low ping times).
>>>
>>>You can try applying this patch:
>>>http://developer.osdl.org/shemminger/prototypes/sky2-proc-debug.patch
>>>
>>>It will add a /proc/net/sky2/ethX file, which lists the status of the TX
>>>and status rings. You should compare the contents of this file during
>>>normal operation to when the interface has hung.
>>
>>Thanks, Daniel. I applied the patch.
>>
>>The output of 'cat /proc/net/sky2/eth0' under normal circumstances
>>is here:
>>
>>http://puma.uio.no/sky2/sky2-status-normal.txt
>>
>>After the interface hangs, 'cat /proc/net/sky2/eth0' causes the
>>whole computer to hang completely. No kernel oops or other
>>messages in the console window. Power down is the only
>>solution.... :-[ No log entries after reboot.
>>
> It could be the code in the debug patch is walking off into space.
> The smaller version of the same patch, doesn't walk but just reports
> the index values.
[ patch ]
OK, I applied that. Part of it (5 hunks) had to be done manually, since
it appeared not to be relative to the version in 2.6.18-rc4 which I was
using.
The result is:
Normal operation:
Status ring (empty)
Tx ring (empty)
Rx pending hw get=60 put=256 last=511
Error condition:
Status ring (empty)
Tx ring 338..378
Rx pending hw get=316 put=0 last=511
-- Jon
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: sky2 driver - large files upload problem
2006-08-21 22:04 ` Jon Wikne
@ 2006-08-21 23:36 ` Stephen Hemminger
2006-08-22 9:43 ` Jon Wikne
2006-08-22 22:38 ` [RFT] sky2: transmit complete alternative Stephen Hemminger
1 sibling, 1 reply; 9+ messages in thread
From: Stephen Hemminger @ 2006-08-21 23:36 UTC (permalink / raw)
To: Jon Wikne; +Cc: netdev, Daniel Drake
On Tue, 22 Aug 2006 00:04:07 +0200
Jon Wikne <wikne@cheetah.uio.no> wrote:
> Stephen Hemminger wrote:
>
> > On Mon, 21 Aug 2006 16:21:07 +0200
> > Jon Wikne <wikne@cheetah.uio.no> wrote:
> >
> >>Daniel Drake wrote:
> >>
> >>>Jon Wikne wrote:
> >>>
> >>>>What happens is typically this: After transeferring some
> >>>>data, ranging from less than 100kB to 10MB, the upload freezes,
> >>>>i.e. gets no further. Use of ping shows the connection is
> >>>>effectively dead. If I do a sequence /sbin/ifdown eth0
> >>>>/sbin/ifup eth0 the upload might resume, but stops again
> >>>>shortly. The phenomenon seems to occur sooner if the path
> >>>>to the remote system is _fast_ (low ping times).
> >>>
> >>>You can try applying this patch:
> >>>http://developer.osdl.org/shemminger/prototypes/sky2-proc-debug.patch
> >>>
> >>>It will add a /proc/net/sky2/ethX file, which lists the status of the TX
> >>>and status rings. You should compare the contents of this file during
> >>>normal operation to when the interface has hung.
> >>
> >>Thanks, Daniel. I applied the patch.
> >>
> >>The output of 'cat /proc/net/sky2/eth0' under normal circumstances
> >>is here:
> >>
> >>http://puma.uio.no/sky2/sky2-status-normal.txt
> >>
> >>After the interface hangs, 'cat /proc/net/sky2/eth0' causes the
> >>whole computer to hang completely. No kernel oops or other
> >>messages in the console window. Power down is the only
> >>solution.... :-[ No log entries after reboot.
> >>
> > It could be the code in the debug patch is walking off into space.
> > The smaller version of the same patch, doesn't walk but just reports
> > the index values.
> [ patch ]
>
> OK, I applied that. Part of it (5 hunks) had to be done manually, since
> it appeared not to be relative to the version in 2.6.18-rc4 which I was
> using.
>
> The result is:
>
> Normal operation:
> Status ring (empty)
> Tx ring (empty)
> Rx pending hw get=60 put=256 last=511
The chip has prefetched some of the 254 frames we gave it.
> Error condition:
> Status ring (empty)
> Tx ring 338..378
40 packets waiting to send
> Rx pending hw get=316 put=0 last=511
So there are some frames waiting to be received as well.
Looks like a missed interrupt. Is there anything surprising in the
ethtool stats? (ethtool -S eth0)
In the past, when there were flow control hardware bugs
there would be suspicious statistics like "1 mac pause frame received".
>
>
> -- Jon
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Stephen Hemminger <shemminger@osdl.org>
All non-trivial abstractions, to some degree, are leaky.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: sky2 driver - large files upload problem
2006-08-21 23:36 ` Stephen Hemminger
@ 2006-08-22 9:43 ` Jon Wikne
0 siblings, 0 replies; 9+ messages in thread
From: Jon Wikne @ 2006-08-22 9:43 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Daniel Drake
Stephen Hemminger wrote:
> On Tue, 22 Aug 2006 00:04:07 +0200
> Jon Wikne <wikne@cheetah.uio.no> wrote:
>
>
>>Stephen Hemminger wrote:
>>
>>
>>>On Mon, 21 Aug 2006 16:21:07 +0200
>>>Jon Wikne <wikne@cheetah.uio.no> wrote:
>>>
>>>
>>>>Daniel Drake wrote:
>>>>
>>>>
>>>>>Jon Wikne wrote:
>>>>>
>>>>>
>>>>>>What happens is typically this: After transeferring some
>>>>>>data, ranging from less than 100kB to 10MB, the upload freezes,
>>>>>>i.e. gets no further. Use of ping shows the connection is
>>>>>>effectively dead. If I do a sequence /sbin/ifdown eth0
>>>>>>/sbin/ifup eth0 the upload might resume, but stops again
>>>>>>shortly. The phenomenon seems to occur sooner if the path
>>>>>>to the remote system is _fast_ (low ping times).
>>>>>
>>>>>You can try applying this patch:
>>>>>http://developer.osdl.org/shemminger/prototypes/sky2-proc-debug.patch
>>>>>
>>>>>It will add a /proc/net/sky2/ethX file, which lists the status of the TX
>>>>>and status rings. You should compare the contents of this file during
>>>>>normal operation to when the interface has hung.
>>>>
>>>>Thanks, Daniel. I applied the patch.
>>>>
>>>>The output of 'cat /proc/net/sky2/eth0' under normal circumstances
>>>>is here:
>>>>
>>>>http://puma.uio.no/sky2/sky2-status-normal.txt
>>>>
>>>>After the interface hangs, 'cat /proc/net/sky2/eth0' causes the
>>>>whole computer to hang completely. No kernel oops or other
>>>>messages in the console window. Power down is the only
>>>>solution.... :-[ No log entries after reboot.
>>>>
>>>
>>>It could be the code in the debug patch is walking off into space.
>>>The smaller version of the same patch, doesn't walk but just reports
>>>the index values.
>>
>>[ patch ]
>>
>>OK, I applied that. Part of it (5 hunks) had to be done manually, since
>>it appeared not to be relative to the version in 2.6.18-rc4 which I was
>>using.
>>
>>The result is:
>>
>>Normal operation:
>>Status ring (empty)
>>Tx ring (empty)
>>Rx pending hw get=60 put=256 last=511
>
>
> The chip has prefetched some of the 254 frames we gave it.
>
>
>>Error condition:
>>Status ring (empty)
>>Tx ring 338..378
>
>
> 40 packets waiting to send
>
>
>>Rx pending hw get=316 put=0 last=511
>
>
> So there are some frames waiting to be received as well.
> Looks like a missed interrupt. Is there anything surprising in the
> ethtool stats? (ethtool -S eth0)
Nothing that surprises me, anyway. The following log contains two
subsequent ethtool outputs: The first before the upload was started,
the second after the freeze occurred:
http://puma.uio.no/sky2/sky2-ethtool.txt
> In the past, when there were flow control hardware bugs
> there would be suspicious statistics like "1 mac pause frame received".
The only entries that refer to mac_pause are 0 both before and after
the freeze.
The system in question is a laptop, Toshiba Tecra A3, PTA30E-03502XNE
with serial number Z5310230K. I find no codes that are obvious to
state a date of manufacture, but it was bought in May 2006.
-- Jon
^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFT] sky2: transmit complete alternative
2006-08-21 22:04 ` Jon Wikne
2006-08-21 23:36 ` Stephen Hemminger
@ 2006-08-22 22:38 ` Stephen Hemminger
2006-08-23 10:06 ` Jon Wikne
1 sibling, 1 reply; 9+ messages in thread
From: Stephen Hemminger @ 2006-08-22 22:38 UTC (permalink / raw)
To: Jon Wikne; +Cc: netdev, Daniel Drake
Does the following get rid of the hang?
--------
Recode the transmit completion handling to avoid races between the hardware
status report mechanism and the interrupt handler. Rather than relying on
the index value in the status ring, read the chip register and cleanup
all completed transmits.
Reduce the transmit lock window smaller to allow more parallelism.
--- sky2.orig/drivers/net/sky2.c 2006-08-22 13:45:17.000000000 -0700
+++ sky2/drivers/net/sky2.c 2006-08-22 14:01:52.000000000 -0700
@@ -135,6 +135,7 @@
static const unsigned txqaddr[] = { Q_XA1, Q_XA2 };
static const unsigned rxqaddr[] = { Q_R1, Q_R2 };
static const u32 portirq_msk[] = { Y2_IS_PORT_1, Y2_IS_PORT_2 };
+static const u16 report_idx[] = { STAT_TXA1_RIDX, STAT_TXA2_RIDX };
/* This driver supports yukon2 chipset only */
static const char *yukon2_name[] = {
@@ -1189,7 +1190,6 @@
struct sky2_tx_le *le = NULL;
struct tx_ring_info *re;
unsigned i, len;
- int avail;
dma_addr_t mapping;
u32 addr64;
u16 mss;
@@ -1332,12 +1332,8 @@
re->idx = sky2->tx_prod;
le->ctrl |= EOP;
- avail = tx_avail(sky2);
- if (mss != 0 || avail < TX_MIN_PENDING) {
- le->ctrl |= FRC_STAT;
- if (avail <= MAX_SKB_TX_LE)
- netif_stop_queue(dev);
- }
+ if (tx_avail(sky2) <= MAX_SKB_TX_LE)
+ netif_stop_queue(dev);
sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);
@@ -1361,12 +1357,10 @@
u16 nxt, put;
unsigned i;
- BUG_ON(done >= TX_RING_SIZE);
-
- if (unlikely(netif_msg_tx_done(sky2)))
- printk(KERN_DEBUG "%s: tx done, up to %u\n",
- dev->name, done);
+ if (done == sky2->tx_cons)
+ return;
+ BUG_ON(done >= TX_RING_SIZE);
for (put = sky2->tx_cons; put != done; put = nxt) {
struct tx_ring_info *re = sky2->tx_ring + put;
struct sk_buff *skb = re->skb;
@@ -1391,20 +1385,26 @@
PCI_DMA_TODEVICE);
}
+ if (unlikely(netif_msg_tx_done(sky2)))
+ printk(KERN_DEBUG "%s: tx done, slot %u\n",
+ dev->name, put);
+
dev_kfree_skb(skb);
}
+ spin_lock(&sky2->tx_lock);
sky2->tx_cons = put;
if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
netif_wake_queue(dev);
+ spin_unlock(&sky2->tx_lock);
}
/* Cleanup all untransmitted buffers, assume transmitter not running */
static void sky2_tx_clean(struct sky2_port *sky2)
{
- spin_lock_bh(&sky2->tx_lock);
+ local_bh_disable();
sky2_tx_complete(sky2, sky2->tx_prod);
- spin_unlock_bh(&sky2->tx_lock);
+ local_bh_enable();
}
/* Network shutdown */
@@ -1732,7 +1732,7 @@
if (netif_msg_timer(sky2))
printk(KERN_ERR PFX "%s: tx timeout\n", dev->name);
- report = sky2_read16(hw, sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX);
+ report = sky2_read16(hw, report_idx[sky2->port]);
done = sky2_read16(hw, Q_ADDR(txq, Q_DONE));
printk(KERN_DEBUG PFX "%s: transmit ring %u .. %u report=%u done=%u\n",
@@ -1747,9 +1747,7 @@
} else if (report != sky2->tx_cons) {
printk(KERN_INFO PFX "status report lost?\n");
- spin_lock_bh(&sky2->tx_lock);
sky2_tx_complete(sky2, report);
- spin_unlock_bh(&sky2->tx_lock);
} else {
printk(KERN_INFO PFX "hardware hung? flushing\n");
@@ -1919,15 +1917,14 @@
goto resubmit;
}
-/* Transmit complete */
-static inline void sky2_tx_done(struct net_device *dev, u16 last)
+/* Transmit completion handling */
+static void sky2_tx(struct sky2_hw *hw, unsigned port)
{
- struct sky2_port *sky2 = netdev_priv(dev);
+ struct net_device *dev = hw->dev[port];
- if (netif_running(dev)) {
- spin_lock(&sky2->tx_lock);
- sky2_tx_complete(sky2, last);
- spin_unlock(&sky2->tx_lock);
+ if (dev && netif_running(dev)) {
+ u16 last = sky2_read16(hw, report_idx[port]);
+ sky2_tx_complete(netdev_priv(dev), last);
}
}
@@ -1939,6 +1936,10 @@
unsigned buf_write[2] = { 0, 0 };
u16 hwidx = sky2_read16(hw, STAT_PUT_IDX);
+ sky2_tx(hw, 0);
+ if (hw->ports > 1)
+ sky2_tx(hw, 1);
+
rmb();
while (hw->st_idx != hwidx) {
@@ -2004,13 +2005,7 @@
break;
case OP_TXINDEXLE:
- /* TX index reports status for both ports */
- BUILD_BUG_ON(TX_RING_SIZE > 0x1000);
- sky2_tx_done(hw->dev[0], status & 0xfff);
- if (hw->dev[1])
- sky2_tx_done(hw->dev[1],
- ((status >> 24) & 0xff)
- | (u16)(length & 0xf) << 8);
+ /* TX completion handled above */
break;
default:
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFT] sky2: transmit complete alternative
2006-08-22 22:38 ` [RFT] sky2: transmit complete alternative Stephen Hemminger
@ 2006-08-23 10:06 ` Jon Wikne
0 siblings, 0 replies; 9+ messages in thread
From: Jon Wikne @ 2006-08-23 10:06 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Daniel Drake
Stephen Hemminger wrote:
> Does the following get rid of the hang?
> --------
> Recode the transmit completion handling to avoid races between the hardware
> status report mechanism and the interrupt handler. Rather than relying on
> the index value in the status ring, read the chip register and cleanup
> all completed transmits.
>
> Reduce the transmit lock window smaller to allow more parallelism.
[ patch ]
I'm afraid not. :-(
1) The number of bytes before the hang occurs seems to have _decreased_
rather than the opposite. This observation is, however, a question
of statistics, and I have better such with the previous version.
2) Previously, the sequence /sbin/ifdown eth0 - /sbin/ifup eth0 made
the driver recover. Now, the latter of these commands hangs the
whole system. The recovery is now /sbin/ifdown eth0 - rmmod sky2
- modprobe sky2
-- Jon
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2006-08-23 10:06 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-21 12:41 sky2 driver - large files upload problem Jon Wikne
2006-08-21 13:18 ` Daniel Drake
2006-08-21 14:21 ` Jon Wikne
2006-08-21 16:51 ` Stephen Hemminger
2006-08-21 22:04 ` Jon Wikne
2006-08-21 23:36 ` Stephen Hemminger
2006-08-22 9:43 ` Jon Wikne
2006-08-22 22:38 ` [RFT] sky2: transmit complete alternative Stephen Hemminger
2006-08-23 10:06 ` Jon Wikne
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).