netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] sky2: version 1.2
@ 2006-04-25 17:58 Stephen Hemminger
  2006-04-25 17:58 ` [PATCH 1/5] sky2: reschedule if irq still pending Stephen Hemminger
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Stephen Hemminger @ 2006-04-25 17:58 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev

Update to sky2 driver. Mostly fixes to try and handle users
stuck with edge-triggered interrupts. Also, some minor cleanups.

Patches apply onto 1.1 version in 2.6.17-rc2

--


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/5] sky2: reschedule if irq still pending
  2006-04-25 17:58 [PATCH 0/5] sky2: version 1.2 Stephen Hemminger
@ 2006-04-25 17:58 ` Stephen Hemminger
  2006-04-26 10:20   ` Jeff Garzik
  2006-04-25 17:58 ` [PATCH 2/5] sky2: add fake idle irq timer Stephen Hemminger
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Stephen Hemminger @ 2006-04-25 17:58 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev

[-- Attachment #1: sky2-edge.patch --]
[-- Type: text/plain, Size: 2676 bytes --]

This is a workaround for the case edge-triggered irq's. Several users
seem to have broken configurations sharing edge-triggered irq's. To avoid
losing IRQ's, reshedule if more work arrives.

The changes to netdevice.h are to extract the part that puts device
back in list into separate inline.

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>


--- sky2-2.6.17.orig/drivers/net/sky2.c	2006-04-25 10:48:44.000000000 -0700
+++ sky2-2.6.17/drivers/net/sky2.c	2006-04-25 10:48:47.000000000 -0700
@@ -2093,6 +2093,7 @@
 	int work_done = 0;
 	u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
 
+ restart_poll:
 	if (unlikely(status & ~Y2_IS_STAT_BMU)) {
 		if (status & Y2_IS_HW_ERR)
 			sky2_hw_intr(hw);
@@ -2123,7 +2124,7 @@
 	}
 
 	if (status & Y2_IS_STAT_BMU) {
-		work_done = sky2_status_intr(hw, work_limit);
+		work_done += sky2_status_intr(hw, work_limit - work_done);
 		*budget -= work_done;
 		dev0->quota -= work_done;
 
@@ -2133,9 +2134,22 @@
 		sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
 	}
 
-	netif_rx_complete(dev0);
+	local_irq_disable();
+	__netif_rx_complete(dev0);
 
 	status = sky2_read32(hw, B0_Y2_SP_LISR);
+
+	if (unlikely(status)) {
+		/* More work pending, try and keep going */
+		if (__netif_rx_schedule_prep(dev0)) {
+			__netif_rx_reschedule(dev0, work_done);
+			status = sky2_read32(hw, B0_Y2_SP_EISR);
+			local_irq_enable();
+			goto restart_poll;
+		}
+	}
+
+	local_irq_enable();
 	return 0;
 }
 
@@ -2153,8 +2167,6 @@
 	prefetch(&hw->st_le[hw->st_idx]);
 	if (likely(__netif_rx_schedule_prep(dev0)))
 		__netif_rx_schedule(dev0);
-	else
-		printk(KERN_DEBUG PFX "irq race detected\n");
 
 	return IRQ_HANDLED;
 }
--- sky2-2.6.17.orig/include/linux/netdevice.h	2006-04-25 10:48:44.000000000 -0700
+++ sky2-2.6.17/include/linux/netdevice.h	2006-04-25 10:48:47.000000000 -0700
@@ -829,19 +829,21 @@
 		__netif_rx_schedule(dev);
 }
 
-/* Try to reschedule poll. Called by dev->poll() after netif_rx_complete().
- * Do not inline this?
- */
+
+static inline void  __netif_rx_reschedule(struct net_device *dev, int undo)
+{
+	dev->quota += undo;
+	list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);
+	__raise_softirq_irqoff(NET_RX_SOFTIRQ);
+}
+
+/* Try to reschedule poll. Called by dev->poll() after netif_rx_complete(). */
 static inline int netif_rx_reschedule(struct net_device *dev, int undo)
 {
 	if (netif_rx_schedule_prep(dev)) {
 		unsigned long flags;
-
-		dev->quota += undo;
-
 		local_irq_save(flags);
-		list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);
-		__raise_softirq_irqoff(NET_RX_SOFTIRQ);
+		__netif_rx_reschedule(dev, undo);
 		local_irq_restore(flags);
 		return 1;
 	}

--


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 2/5] sky2: add fake idle irq timer
  2006-04-25 17:58 [PATCH 0/5] sky2: version 1.2 Stephen Hemminger
  2006-04-25 17:58 ` [PATCH 1/5] sky2: reschedule if irq still pending Stephen Hemminger
@ 2006-04-25 17:58 ` Stephen Hemminger
  2006-04-25 21:23   ` Francois Romieu
  2006-04-25 17:58 ` [PATCH 3/5] sky2: use ALIGN() macro Stephen Hemminger
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Stephen Hemminger @ 2006-04-25 17:58 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev

[-- Attachment #1: sky2-idle-timer.patch --]
[-- Type: text/plain, Size: 1943 bytes --]

Add an fake NAPI schedule once a second. This is an attempt to work around
for broken configurations with edge-triggered interrupts.

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>

--- sky2-2.6.17.orig/drivers/net/sky2.c	2006-04-25 10:48:47.000000000 -0700
+++ sky2-2.6.17/drivers/net/sky2.c	2006-04-25 10:53:32.000000000 -0700
@@ -2086,6 +2086,20 @@
 	}
 }
 
+/* If idle then force a fake soft NAPI poll once a second
+ * to work around cases where sharing an edge triggered interrupt.
+ */
+static void sky2_idle(unsigned long arg)
+{
+	struct net_device *dev = (struct net_device *) arg;
+
+	local_irq_disable();
+	if (__netif_rx_schedule_prep(dev))
+		__netif_rx_schedule(dev);
+	local_irq_enable();
+}
+
+
 static int sky2_poll(struct net_device *dev0, int *budget)
 {
 	struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
@@ -2134,6 +2148,8 @@
 		sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
 	}
 
+	mod_timer(&hw->idle_timer, jiffies + HZ);
+
 	local_irq_disable();
 	__netif_rx_complete(dev0);
 
@@ -3288,6 +3304,8 @@
 
 	sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
 
+	setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) dev);
+
 	pci_set_drvdata(pdev, hw);
 
 	return 0;
@@ -3323,13 +3341,15 @@
 	if (!hw)
 		return;
 
+	del_timer_sync(&hw->idle_timer);
+
+	sky2_write32(hw, B0_IMSK, 0);
 	dev0 = hw->dev[0];
 	dev1 = hw->dev[1];
 	if (dev1)
 		unregister_netdev(dev1);
 	unregister_netdev(dev0);
 
-	sky2_write32(hw, B0_IMSK, 0);
 	sky2_set_power_state(hw, PCI_D3hot);
 	sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
 	sky2_write8(hw, B0_CTST, CS_RST_SET);
--- sky2-2.6.17.orig/drivers/net/sky2.h	2006-04-25 10:48:42.000000000 -0700
+++ sky2-2.6.17/drivers/net/sky2.h	2006-04-25 10:51:33.000000000 -0700
@@ -1880,6 +1880,8 @@
 	struct sky2_status_le *st_le;
 	u32		     st_idx;
 	dma_addr_t   	     st_dma;
+
+	struct timer_list    idle_timer;
 	int		     msi_detected;
 	wait_queue_head_t    msi_wait;
 };

--


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 3/5] sky2: use ALIGN() macro
  2006-04-25 17:58 [PATCH 0/5] sky2: version 1.2 Stephen Hemminger
  2006-04-25 17:58 ` [PATCH 1/5] sky2: reschedule if irq still pending Stephen Hemminger
  2006-04-25 17:58 ` [PATCH 2/5] sky2: add fake idle irq timer Stephen Hemminger
@ 2006-04-25 17:58 ` Stephen Hemminger
  2006-04-25 17:58 ` [PATCH 4/5] sky2: reset function can be devinit Stephen Hemminger
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Stephen Hemminger @ 2006-04-25 17:58 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev

[-- Attachment #1: sky2-align.patch --]
[-- Type: text/plain, Size: 995 bytes --]

The ALIGN() macro in kernel.h does the same math that the
sky2 driver was using for padding.

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>

--- sky2-2.6.17.orig/drivers/net/sky2.c	2006-04-25 10:47:03.000000000 -0700
+++ sky2-2.6.17/drivers/net/sky2.c	2006-04-25 10:47:28.000000000 -0700
@@ -925,8 +925,7 @@
 	skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask);
 	if (likely(skb)) {
 		unsigned long p	= (unsigned long) skb->data;
-		skb_reserve(skb,
-			((p + RX_SKB_ALIGN - 1) & ~(RX_SKB_ALIGN - 1)) - p);
+		skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p);
 	}
 
 	return skb;
@@ -1686,13 +1685,12 @@
 }
 
 
-#define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
 /* Want receive buffer size to be multiple of 64 bits
  * and incl room for vlan and truncation
  */
 static inline unsigned sky2_buf_size(int mtu)
 {
-	return roundup(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8;
+	return ALIGN(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8;
 }
 
 static int sky2_change_mtu(struct net_device *dev, int new_mtu)

--


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 4/5] sky2: reset function can be devinit
  2006-04-25 17:58 [PATCH 0/5] sky2: version 1.2 Stephen Hemminger
                   ` (2 preceding siblings ...)
  2006-04-25 17:58 ` [PATCH 3/5] sky2: use ALIGN() macro Stephen Hemminger
@ 2006-04-25 17:58 ` Stephen Hemminger
  2006-04-25 17:58 ` [PATCH 5/5] sky2: version 1.2 Stephen Hemminger
  2006-04-29 18:15 ` [PATCH 0/5] " Bertrand Jacquin
  5 siblings, 0 replies; 12+ messages in thread
From: Stephen Hemminger @ 2006-04-25 17:58 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev

[-- Attachment #1: sky2-devinit.patch --]
[-- Type: text/plain, Size: 488 bytes --]

The sky2_reset function only called from sky2_probe.
Maybe the compiler was smart enough to figure this out already.

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>


--- sky2-2.6.17.orig/drivers/net/sky2.c	2006-04-25 10:53:37.000000000 -0700
+++ sky2-2.6.17/drivers/net/sky2.c	2006-04-25 10:54:57.000000000 -0700
@@ -2219,7 +2219,7 @@
 }
 
 
-static int sky2_reset(struct sky2_hw *hw)
+static int __devinit sky2_reset(struct sky2_hw *hw)
 {
 	u16 status;
 	u8 t8, pmd_type;

--


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 5/5] sky2: version 1.2
  2006-04-25 17:58 [PATCH 0/5] sky2: version 1.2 Stephen Hemminger
                   ` (3 preceding siblings ...)
  2006-04-25 17:58 ` [PATCH 4/5] sky2: reset function can be devinit Stephen Hemminger
@ 2006-04-25 17:58 ` Stephen Hemminger
  2006-04-29 18:15 ` [PATCH 0/5] " Bertrand Jacquin
  5 siblings, 0 replies; 12+ messages in thread
From: Stephen Hemminger @ 2006-04-25 17:58 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev

[-- Attachment #1: sky2-1.2.patch --]
[-- Type: text/plain, Size: 387 bytes --]

Update to version 1.2

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>


--- sky2-2.6.17.orig/drivers/net/sky2.c	2006-04-25 10:54:57.000000000 -0700
+++ sky2-2.6.17/drivers/net/sky2.c	2006-04-25 10:55:51.000000000 -0700
@@ -51,7 +51,7 @@
 #include "sky2.h"
 
 #define DRV_NAME		"sky2"
-#define DRV_VERSION		"1.1"
+#define DRV_VERSION		"1.2"
 #define PFX			DRV_NAME " "
 
 /*

--


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/5] sky2: add fake idle irq timer
  2006-04-25 17:58 ` [PATCH 2/5] sky2: add fake idle irq timer Stephen Hemminger
@ 2006-04-25 21:23   ` Francois Romieu
  2006-04-25 21:30     ` Stephen Hemminger
  0 siblings, 1 reply; 12+ messages in thread
From: Francois Romieu @ 2006-04-25 21:23 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Jeff Garzik, netdev

Stephen Hemminger <shemminger@osdl.org> :
[...]
> --- sky2-2.6.17.orig/drivers/net/sky2.c	2006-04-25 10:48:47.000000000 -0700
> +++ sky2-2.6.17/drivers/net/sky2.c	2006-04-25 10:53:32.000000000 -0700
> @@ -2086,6 +2086,20 @@
>  	}
>  }
>  
> +/* If idle then force a fake soft NAPI poll once a second
> + * to work around cases where sharing an edge triggered interrupt.
> + */
> +static void sky2_idle(unsigned long arg)
> +{
> +	struct net_device *dev = (struct net_device *) arg;
> +
> +	local_irq_disable();
> +	if (__netif_rx_schedule_prep(dev))
> +		__netif_rx_schedule(dev);
> +	local_irq_enable();
> +}
> +
> +
>  static int sky2_poll(struct net_device *dev0, int *budget)
>  {
>  	struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
> @@ -2134,6 +2148,8 @@
>  		sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
>  	}
>  
> +	mod_timer(&hw->idle_timer, jiffies + HZ);
> +
>  	local_irq_disable();
>  	__netif_rx_complete(dev0);


Any objection against moving mod_timer() from sky2_poll() to sky2_idle()
so as to keep poll() path unmodified ?

-- 
Ueimor

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/5] sky2: add fake idle irq timer
  2006-04-25 21:23   ` Francois Romieu
@ 2006-04-25 21:30     ` Stephen Hemminger
  2006-04-25 22:39       ` Francois Romieu
  0 siblings, 1 reply; 12+ messages in thread
From: Stephen Hemminger @ 2006-04-25 21:30 UTC (permalink / raw)
  To: Francois Romieu; +Cc: Jeff Garzik, netdev

On Tue, 25 Apr 2006 23:23:29 +0200
Francois Romieu <romieu@fr.zoreil.com> wrote:

> Stephen Hemminger <shemminger@osdl.org> :
> [...]
> > --- sky2-2.6.17.orig/drivers/net/sky2.c	2006-04-25 10:48:47.000000000 -0700
> > +++ sky2-2.6.17/drivers/net/sky2.c	2006-04-25 10:53:32.000000000 -0700
> > @@ -2086,6 +2086,20 @@
> >  	}
> >  }
> >  
> > +/* If idle then force a fake soft NAPI poll once a second
> > + * to work around cases where sharing an edge triggered interrupt.
> > + */
> > +static void sky2_idle(unsigned long arg)
> > +{
> > +	struct net_device *dev = (struct net_device *) arg;
> > +
> > +	local_irq_disable();
> > +	if (__netif_rx_schedule_prep(dev))
> > +		__netif_rx_schedule(dev);
> > +	local_irq_enable();
> > +}
> > +
> > +
> >  static int sky2_poll(struct net_device *dev0, int *budget)
> >  {
> >  	struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
> > @@ -2134,6 +2148,8 @@
> >  		sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
> >  	}
> >  
> > +	mod_timer(&hw->idle_timer, jiffies + HZ);
> > +
> >  	local_irq_disable();
> >  	__netif_rx_complete(dev0);
> 
> 
> Any objection against moving mod_timer() from sky2_poll() to sky2_idle()
> so as to keep poll() path unmodified ?
> 

If traffic is moving, then I want the timer to keep getting rescheduled
farther out.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/5] sky2: add fake idle irq timer
  2006-04-25 21:30     ` Stephen Hemminger
@ 2006-04-25 22:39       ` Francois Romieu
  2006-04-25 22:45         ` Stephen Hemminger
  0 siblings, 1 reply; 12+ messages in thread
From: Francois Romieu @ 2006-04-25 22:39 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Jeff Garzik, netdev

Stephen Hemminger <shemminger@osdl.org> :
[...]
> > Any objection against moving mod_timer() from sky2_poll() to sky2_idle()
> > so as to keep poll() path unmodified ?
> > 
> 
> If traffic is moving, then I want the timer to keep getting rescheduled
> farther out.

If my version of the driver is not stale, the timer will not be
rescheduled when work_done >= work_limit. I.e. the optimization
tends to vanish when the load goes up. Before this point is reached,
the long path of mod_timer() can be taken up to HZ per second.

I have no idea which balance works best.

-- 
Ueimor

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/5] sky2: add fake idle irq timer
  2006-04-25 22:39       ` Francois Romieu
@ 2006-04-25 22:45         ` Stephen Hemminger
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Hemminger @ 2006-04-25 22:45 UTC (permalink / raw)
  To: Francois Romieu; +Cc: Jeff Garzik, netdev

On Wed, 26 Apr 2006 00:39:00 +0200
Francois Romieu <romieu@fr.zoreil.com> wrote:

> Stephen Hemminger <shemminger@osdl.org> :
> [...]
> > > Any objection against moving mod_timer() from sky2_poll() to sky2_idle()
> > > so as to keep poll() path unmodified ?
> > > 
> > 
> > If traffic is moving, then I want the timer to keep getting rescheduled
> > farther out.
> 
> If my version of the driver is not stale, the timer will not be
> rescheduled when work_done >= work_limit.

I am trying to work around possible lost IRQ's, not netdev scheduler
screw up's.  If workdone >= work_limit, then it will already be
called back later when it return's 1.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/5] sky2: reschedule if irq still pending
  2006-04-25 17:58 ` [PATCH 1/5] sky2: reschedule if irq still pending Stephen Hemminger
@ 2006-04-26 10:20   ` Jeff Garzik
  0 siblings, 0 replies; 12+ messages in thread
From: Jeff Garzik @ 2006-04-26 10:20 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

Stephen Hemminger wrote:
> This is a workaround for the case edge-triggered irq's. Several users
> seem to have broken configurations sharing edge-triggered irq's. To avoid
> losing IRQ's, reshedule if more work arrives.
> 
> The changes to netdevice.h are to extract the part that puts device
> back in list into separate inline.
> 
> Signed-off-by: Stephen Hemminger <shemminger@osdl.org>

applied 1-5 to #upstream-fixes



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/5] sky2: version 1.2
  2006-04-25 17:58 [PATCH 0/5] sky2: version 1.2 Stephen Hemminger
                   ` (4 preceding siblings ...)
  2006-04-25 17:58 ` [PATCH 5/5] sky2: version 1.2 Stephen Hemminger
@ 2006-04-29 18:15 ` Bertrand Jacquin
  5 siblings, 0 replies; 12+ messages in thread
From: Bertrand Jacquin @ 2006-04-29 18:15 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: jgarzik, netdev

[-- Attachment #1: Type: text/plain, Size: 476 bytes --]

Le Tue, 25 Apr 2006 10:58:49 -0700, Stephen Hemminger <shemminger@osdl.org> m'a avoué:

> Update to sky2 driver. Mostly fixes to try and handle users
> stuck with edge-triggered interrupts. Also, some minor cleanups.
> 
> Patches apply onto 1.1 version in 2.6.17-rc2

Hi,

I've just testing patches and I get still the same bug.

-- 
/* Beber : beber (AT) gna (DOT) org
 * http://guybrush.ath.cx, irc://irc.freenode.net/#{e.fr,gentoofr}
 * Guybrush @ Melee */

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2006-04-29 18:15 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-04-25 17:58 [PATCH 0/5] sky2: version 1.2 Stephen Hemminger
2006-04-25 17:58 ` [PATCH 1/5] sky2: reschedule if irq still pending Stephen Hemminger
2006-04-26 10:20   ` Jeff Garzik
2006-04-25 17:58 ` [PATCH 2/5] sky2: add fake idle irq timer Stephen Hemminger
2006-04-25 21:23   ` Francois Romieu
2006-04-25 21:30     ` Stephen Hemminger
2006-04-25 22:39       ` Francois Romieu
2006-04-25 22:45         ` Stephen Hemminger
2006-04-25 17:58 ` [PATCH 3/5] sky2: use ALIGN() macro Stephen Hemminger
2006-04-25 17:58 ` [PATCH 4/5] sky2: reset function can be devinit Stephen Hemminger
2006-04-25 17:58 ` [PATCH 5/5] sky2: version 1.2 Stephen Hemminger
2006-04-29 18:15 ` [PATCH 0/5] " Bertrand Jacquin

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).