Netdev List
 help / color / mirror / Atom feed
* Re: PATCHv3 2.6.17-rc5 tulip free_irq() called too late
From: Jeff Garzik @ 2006-06-14 15:03 UTC (permalink / raw)
  To: Grant Grundler; +Cc: Valerie Henson, Andrew Morton, netdev
In-Reply-To: <20060614044412.GA30552@colo.lackof.org>

Grant Grundler wrote:
> On Tue, Jun 13, 2006 at 08:33:22PM -0400, Jeff Garzik wrote:
>> Grant Grundler wrote:
>>> o tulip_stop_rxtx() has to be called _after_ free_irq().
>>>  ie. v2 patch didn't fix the original race condition
>>>  and when under test, dies about as fast as the original code.
>> You made the race window smaller, but it's still there.  The chip's DMA 
>> engines should be stopped before you unregister the interrupt handler.
> 
> Switching the order to be:
>         tulip_stop_rxtx(tp);            /* Stop DMA */
>         free_irq (dev->irq, dev);       /* no more races after this */
> 
> still leaves us open to IRQs being delivered _after_ we've stopped DMA.

Correct.  And that is the preferred, natural, logical, obvious order:

1) Turn things off.
2) Wait for activity to cease.


> That in turn allows the interrupt handler to re-enable DMA again.

Then that would be a problem to solve...  Some interrupt handlers will 
test netif_running() or a driver-specific shutting-down flag, 
specifically to avoid such behaviors.

	Jeff




^ permalink raw reply

* Re: [PATCH 0/2] NET: Accurate packet scheduling for ATM/ADSL
From: Jesper Dangaard Brouer @ 2006-06-14 15:08 UTC (permalink / raw)
  To: Phillip Susi; +Cc: netdev, russell-tcatm, hawk
In-Reply-To: <44901CC1.60403@cfl.rr.com>

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

On Wed, 2006-06-14 at 10:27 -0400, Phillip Susi wrote:
> Jesper Dangaard Brouer wrote:
> > The Linux traffic's control engine inaccurately calculates
> > transmission times for packets sent over ADSL links.  For
> > some packet sizes the error rises to over 50%.  This occurs
> > because ADSL uses ATM as its link layer transport, and ATM
> > transmits packets in fixed sized 53 byte cells.
> > 
> 
> I could have sworn that DSL uses its own framing protocol that is 
> similar to the frame/superframe structure of HDSL ( T1 ) lines and over 
> that you can run ATM or ethernet.  Or is it typically ethernet -> ATM -> 
> HDSL?

Nope, not according to the ADSL standards G.992.1 and G.992.2.

> In any case, why does the kernel care about the exact time that the IP 
> packet has been received and reassembled on the headend?

I think you have misunderstood what the rate table does...
(There is an explaination in the thesis page 57 section 6.1.2)
http://www.adsl-optimizer.dk/thesis/

-- 
Med venlig hilsen / Best regards
  Jesper Brouer
  ComX Networks A/S
  Linux Network developer
  Cand. Scient Datalog / MSc.
  Author of http://adsl-optimizer.dk


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: Refactor Netlink connector?
From: James Morris @ 2006-06-14 15:19 UTC (permalink / raw)
  To: jamal
  Cc: Stephen Smalley, David S. Miller, netdev, Evgeniy Polyakov,
	Thomas Graf
In-Reply-To: <1150288564.5233.31.camel@jzny2>

On Wed, 14 Jun 2006, jamal wrote:

> 
> So whats the resolution on this? I actually have some cycles this coming
> weekend that i was hopping to spend updating the doc instead.

Haven't had a chance to look at it since.

-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply

* Re: [RFC/PATCH 1/2] in-kernel sockets API
From: Harald Welte @ 2006-06-14 15:26 UTC (permalink / raw)
  To: Erik Mouw
  Cc: Daniel Phillips, bidulock, Stephen Hemminger, Sridhar Samudrala,
	netdev, linux-kernel
In-Reply-To: <20060614142903.GI11542@harddisk-recovery.com>

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

On Wed, Jun 14, 2006 at 04:29:04PM +0200, Erik Mouw wrote:
> On Wed, Jun 14, 2006 at 03:30:22PM +0200, Harald Welte wrote:
> > On Tue, Jun 13, 2006 at 02:12:41PM -0700, Daniel Phillips wrote:
> >  
> > > This has the makings of a nice stable internal kernel api.  Why do we want
> > > to provide this nice stable internal api to proprietary modules?
> > 
> > because there is IMHO legally nothing we can do about it anyway.  Use of
> > an industry-standard API that is provided in multiple operating system
> > is one of the clearest idnication of some program _not_ being a
> > derivative work.
> 
> IMHO there is no industry-standard API for in-kernel use of sockets.
> There is however one for user space.

it doesn't matter in what space you are.  If the API really is similar
enough, then any piece of code (no matter where it was originally
intended to run) will be able to work with any such socket API.

The whole point of this is: Where is the derivation of an existing work?
I can write a program against some BSD socket api somewhere, and I can
easily make it use the proposed in-kernel sockets API.  No derivation of
anything that is inside the kernel and GPL licensed.

> (IANAL, etc)

Neither am I, but I'm constantly dealing with legal questions related to
the GPL while running gpl-violations.org.

-- 
- Harald Welte <laforge@gnumonks.org>          	        http://gnumonks.org/
============================================================================
We all know Linux is great...it does infinite loops in 5 seconds. -- Linus

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

^ permalink raw reply

* Re: [PATCH 0/2] NET: Accurate packet scheduling for ATM/ADSL
From: Andy Furniss @ 2006-06-14 15:32 UTC (permalink / raw)
  To: hadi
  Cc: Jesper Dangaard Brouer, hawk, russell-tcatm, lartc, netdev,
	Stephen Hemminger
In-Reply-To: <1150286766.5233.15.camel@jzny2>

jamal wrote:
> I have taken linux-kernel off the list.
> 
> Russell's site is inaccessible to me (I actually think this is related
> to some DNS issues i may be having) and your masters is too long to
> spend 2 minutes and glean it; so heres a question or two for you:
> 
> - Have you tried to do a long-lived session such as a large FTP and 
> seen how far off the deviation was? That would provide some interesting
> data point.
> - To be a devil's advocate (and not claim there is no issue), where do
> you draw the line with "overhead"? 

Me and many others have run a smilar hack for years, there is also a 
userspace project still alive which does the same.

The difference is that without it I would need to sacrifice almost half 
my 288kbit atm/dsl showtime bandwidth to be sure of control.

With the modification I can run at 286kbit / 288 and know I will never 
have jitter worse than the bitrate latency of a mtu packet. The 286 
figure was choses to allow a full buffer to drain/ allow for timer 
innaccuracy etc. On a p200 with tsc, 2.6.12 it's never gone over for me 
- though talking of timers I notice on my desktop 2.6.16 I gain 2 
minutes a day now.

Andy.

^ permalink raw reply

* [PATCH] bcm43xx: use softmac-suggested TX rate
From: Michael Buesch @ 2006-06-14 15:51 UTC (permalink / raw)
  To: John W. Linville; +Cc: netdev, bcm43xx-dev, Daniel Drake

Hi John,

Sorry, took a little bit longer than expected, but here it is. :)
Please queue for 2.6.18.

--

From: Daniel Drake <dsd@gentoo.org>

Use Softmac-suggested TX ratecode:
ieee80211softmac_suggest_txrate()

Signed-off-by: Daniel Drake <dsd@gentoo.org>
Signed-off-by: Michael Buesch <mb@bu3sch.de>

Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
===================================================================
--- wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c	2006-06-14 16:53:50.000000000 +0200
+++ wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c	2006-06-14 17:44:23.000000000 +0200
@@ -296,11 +296,14 @@
 	u16 control = 0;
 	u16 wsec_rate = 0;
 	u16 encrypt_frame;
+	const u16 ftype = WLAN_FC_GET_TYPE(le16_to_cpu(wireless_header->frame_ctl));
+	const int is_mgt = (ftype == IEEE80211_FTYPE_MGMT);
 
 	/* Now construct the TX header. */
 	memset(txhdr, 0, sizeof(*txhdr));
 
-	bitrate = bcm->softmac->txrates.default_rate;
+	bitrate = ieee80211softmac_suggest_txrate(bcm->softmac,
+		is_multicast_ether_addr(wireless_header->addr1), is_mgt);
 	ofdm_modulation = !(ieee80211_is_cck_rate(bitrate));
 	fallback_bitrate = bcm43xx_calc_fallback_rate(bitrate);
 	fallback_ofdm_modulation = !(ieee80211_is_cck_rate(fallback_bitrate));

-- 
Greetings Michael.

^ permalink raw reply

* Re: [openib-general] [PATCH v2 1/2] iWARP Connection Manager.
From: Steve Wise @ 2006-06-14 16:11 UTC (permalink / raw)
  To: Sean Hefty; +Cc: Andrew Morton, netdev, rdreier, linux-kernel, openib-general
In-Reply-To: <1150235196.17394.91.camel@stevo-desktop>

On Tue, 2006-06-13 at 16:46 -0500, Steve Wise wrote:
> On Tue, 2006-06-13 at 14:36 -0700, Sean Hefty wrote:
> > >> Er...no. It will lose this event. Depending on the event...the carnage
> > >> varies. We'll take a look at this.
> > >>
> > >
> > >This behavior is consistent with the Infiniband CM (see
> > >drivers/infiniband/core/cm.c function cm_recv_handler()).  But I think
> > >we should at least log an error because a lost event will usually stall
> > >the rdma connection.
> > 
> > I believe that there's a difference here.  For the Infiniband CM, an allocation
> > error behaves the same as if the received MAD were lost or dropped.  Since MADs
> > are unreliable anyway, it's not so much that an IB CM event gets lost, as it
> > doesn't ever occur.  A remote CM should retry the send, which hopefully allows
> > the connection to make forward progress.
> > 
> 
> hmm.  Ok.  I see.  I misunderstood the code in cm_recv_handler().
> 
> Tom and I have been talking about what we can do to not drop the event.
> Stay tuned.

Here's a simple solution that solves the problem:  

For any given cm_id, there are a finite (and small) number of
outstanding CM events that can be posted.  So we just pre-allocate them
when the cm_id is created and keep them on a free list hanging off of
the cm_id struct.  Then the event handler function will pull from this
free list.  

The only case where there is any non-finite issue is on the passive
listening cm_id.  Each incoming connection request will consume a work
struct.  So based on client connects, we could run out of work structs.
However, the CMA has the concept of a backlog, which is defined as the
max number of pending unaccepted connection requests.  So we allocate
these work structs based on that number (or a computation based on that
number), and if we run out, we simply drop the incoming connection
request due to backlog overflow (I suggest we log the drop event too).
When a MPA connection request is dropped, the (IETF conforming) MPA
client will eventually time out the connection and the consumer can
retry.

Comments?




^ permalink raw reply

* [PATCH 6/5] rt2x00: per-queue TX flow control
From: Jiri Benc @ 2006-06-14 16:36 UTC (permalink / raw)
  To: netdev; +Cc: John W. Linville, Ivo van Doorn
In-Reply-To: <20060612211454.409884000.midnight@suse.cz>

This is a patch for rt2x00 driver to do TX flow control.

It is compile-tested only.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---
 drivers/net/wireless/d80211/rt2x00/rt2400pci.c |   26 ++++++++++++++++++-------
 drivers/net/wireless/d80211/rt2x00/rt2500pci.c |   26 ++++++++++++++++++-------
 drivers/net/wireless/d80211/rt2x00/rt2500usb.c |   18 +++++++++++++----
 drivers/net/wireless/d80211/rt2x00/rt61pci.c   |   26 ++++++++++++++++++-------
 drivers/net/wireless/d80211/rt2x00/rt73usb.c   |   18 +++++++++++++----
 5 files changed, 85 insertions(+), 29 deletions(-)

--- dscape.orig/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
+++ dscape/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
@@ -1001,7 +1001,7 @@ rt2400pci_txdone(void *data)
 	struct data_entry	*entry;
 	struct txd		*txd;
 	int			tx_status;
-	int			ack;
+	int			ack, wake, queue;
 
 	while (!rt2x00_ring_empty(ring)) {
 		entry = rt2x00_get_data_entry_done(ring);
@@ -1048,7 +1048,11 @@ rt2400pci_txdone(void *data)
 		rt2x00_set_field32(&txd->word0, TXD_W0_VALID, 0);
 		entry->skb = NULL;
 
+		wake = rt2x00_ring_full(ring);
+		queue = entry->tx_status.control.queue;
 		rt2x00_ring_index_done_inc(ring);
+		if (wake)
+			ieee80211_wake_queue(ring->net_dev, queue);
 	}
 
 	/*
@@ -1541,24 +1545,31 @@ rt2400pci_tx(struct net_device *net_dev,
 		ERROR("Attempt to send packet over invalid queue %d.\n"
 			"Please file bug report to %s.\n",
 			control->queue, DRV_PROJECT);
-		return NET_XMIT_DROP;
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
 	}
 
-	if (rt2x00_ring_full(ring))
-		return NET_XMIT_DROP;
+	if (rt2x00_ring_full(ring)) {
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
 
 	entry = rt2x00_get_data_entry(ring);
 	txd = entry->desc_addr;
 
-	if (rt2x00_get_field32(txd->word0, TXD_W0_OWNER_NIC)
-	|| rt2x00_get_field32(txd->word0, TXD_W0_VALID))
-		return NET_XMIT_DROP;
+	if (rt2x00_get_field32(txd->word0, TXD_W0_OWNER_NIC) ||
+	    rt2x00_get_field32(txd->word0, TXD_W0_VALID)) {
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
 
 	memcpy(entry->data_addr, skb->data, skb->len);
 	rt2400pci_write_tx_desc(rt2x00pci, txd, skb, control);
 	entry->skb = skb;
 
 	rt2x00_ring_index_inc(ring);
+	if (rt2x00_ring_full(ring))
+		ieee80211_stop_queue(net_dev, control->queue);
 
 	rt2x00_register_read(rt2x00pci, TXCSR0, &reg);
 	if (control->queue == IEEE80211_TX_QUEUE_DATA0)
@@ -1668,6 +1679,7 @@ rt2400pci_open(struct net_device *net_de
 	rt2x00_register_write(rt2x00pci, CSR8, reg);
 
 	SET_FLAG(rt2x00pci, RADIO_ENABLED);
+	ieee80211_start_queues(net_dev);
 
 	return 0;
 
--- dscape.orig/drivers/net/wireless/d80211/rt2x00/rt2500pci.c
+++ dscape/drivers/net/wireless/d80211/rt2x00/rt2500pci.c
@@ -1089,7 +1089,7 @@ rt2500pci_txdone(void *data)
 	struct data_entry	*entry;
 	struct txd		*txd;
 	int			tx_status;
-	int			ack;
+	int			ack, wake, queue;
 
 	while (!rt2x00_ring_empty(ring)) {
 		entry = rt2x00_get_data_entry_done(ring);
@@ -1136,7 +1136,11 @@ rt2500pci_txdone(void *data)
 		rt2x00_set_field32(&txd->word0, TXD_W0_VALID, 0);
 		entry->skb = NULL;
 
+		wake = rt2x00_ring_full(ring);
+		queue = entry->tx_status.control.queue;
 		rt2x00_ring_index_done_inc(ring);
+		if (wake)
+			ieee80211_wake_queue(ring->net_dev, queue);
 	}
 
 	/*
@@ -1664,24 +1668,31 @@ rt2500pci_tx(struct net_device *net_dev,
 		ERROR("Attempt to send packet over invalid queue %d.\n"
 			"Please file bug report to %s.\n",
 			control->queue, DRV_PROJECT);
-		return NET_XMIT_DROP;
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
 	}
 
-	if (rt2x00_ring_full(ring))
-		return NET_XMIT_DROP;
+	if (rt2x00_ring_full(ring)) {
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
 
 	entry = rt2x00_get_data_entry(ring);
 	txd = entry->desc_addr;
 
-	if (rt2x00_get_field32(txd->word0, TXD_W0_OWNER_NIC)
-	|| rt2x00_get_field32(txd->word0, TXD_W0_VALID))
-		return NET_XMIT_DROP;
+	if (rt2x00_get_field32(txd->word0, TXD_W0_OWNER_NIC) ||
+	    rt2x00_get_field32(txd->word0, TXD_W0_VALID)) {
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
 
 	memcpy(entry->data_addr, skb->data, skb->len);
 	rt2500pci_write_tx_desc(rt2x00pci, txd, skb, control);
 	entry->skb = skb;
 
 	rt2x00_ring_index_inc(ring);
+	if (rt2x00_ring_full(ring))
+		ieee80211_stop_queue(net_dev, control->queue);
 
 	rt2x00_register_read(rt2x00pci, TXCSR0, &reg);
 	if (control->queue == IEEE80211_TX_QUEUE_DATA0)
@@ -1791,6 +1802,7 @@ rt2500pci_open(struct net_device *net_de
 	rt2x00_register_write(rt2x00pci, CSR8, reg);
 
 	SET_FLAG(rt2x00pci, RADIO_ENABLED);
+	ieee80211_start_queues(net_dev);
 
 	return 0;
 
--- dscape.orig/drivers/net/wireless/d80211/rt2x00/rt2500usb.c
+++ dscape/drivers/net/wireless/d80211/rt2x00/rt2500usb.c
@@ -929,7 +929,7 @@ rt2500usb_txdone(void *data)
 		ieee80211_dev_hw_data(ring->net_dev);
 	struct data_entry	*entry;
 	struct txd		*txd;
-	int			ack;
+	int			ack, wake, queue;
 
 	 while (!rt2x00_ring_empty(ring)) {
 		entry = rt2x00_get_data_entry_done(ring);
@@ -968,7 +968,11 @@ rt2500usb_txdone(void *data)
 	
 		entry->skb = NULL;
 	
+		wake = rt2x00_ring_full(ring);
+		queue = entry->tx_status.control.queue;
 		rt2x00_ring_index_done_inc(entry->ring);
+		if (wake)
+			ieee80211_wake_queue(ring->net_dev, queue);
 	}
 
 	/*
@@ -1376,11 +1380,14 @@ rt2500usb_tx(struct net_device *net_dev,
 		ERROR("Attempt to send packet over invalid queue %d.\n"
 			"Please file bug report to %s.\n",
 			control->queue, DRV_PROJECT);
-		return NET_XMIT_DROP;
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_BUSY;
 	}
 
-	if (rt2x00_ring_full(ring))
-		return NET_XMIT_DROP;
+	if (rt2x00_ring_full(ring)) {
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
 
 	entry = rt2x00_get_data_entry(ring);
 	txd = rt2x00usb_txdesc_addr(entry);
@@ -1401,6 +1408,8 @@ rt2500usb_tx(struct net_device *net_dev,
 	usb_submit_urb(entry->urb, GFP_ATOMIC);
 
 	rt2x00_ring_index_inc(ring);
+	if (rt2x00_ring_full(ring))
+		ieee80211_stop_queue(net_dev, control->queue);
 
 	return 0;
 }
@@ -1468,6 +1477,7 @@ rt2500usb_open(struct net_device *net_de
 	rt2500usb_enable_led(rt2x00usb);
 
 	SET_FLAG(rt2x00usb, RADIO_ENABLED);
+	ieee80211_start_queues(net_dev);
 
 	return 0;
 
--- dscape.orig/drivers/net/wireless/d80211/rt2x00/rt61pci.c
+++ dscape/drivers/net/wireless/d80211/rt2x00/rt61pci.c
@@ -1351,7 +1351,7 @@ rt61pci_txdone(void *data)
 	struct data_entry	*entry;
 	struct txd		*txd;
 	int			tx_status;
-	int			ack;
+	int			ack, wake, queue;
 	int			reg;
 
 	while (!rt2x00_ring_empty(ring)) {
@@ -1402,7 +1402,11 @@ rt61pci_txdone(void *data)
 		rt2x00_set_field32(&txd->word0, TXD_W0_VALID, 0);
 		entry->skb = NULL;
 
+		wake = rt2x00_ring_full(ring);
+		queue = entry->tx_status.control.queue;
 		rt2x00_ring_index_done_inc(ring);
+		if (wake)
+			ieee80211_wake_queue(ring->net_dev, queue);
 	}
 
 	/*
@@ -2100,24 +2104,31 @@ rt61pci_tx(struct net_device *net_dev,
 		ERROR("Attempt to send packet over invalid queue %d.\n"
 			"Please file bug report to %s.\n",
 			control->queue, DRV_PROJECT);
-		return NET_XMIT_DROP;
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
 	}
 
-	if (rt2x00_ring_full(ring))
-		return NET_XMIT_DROP;
+	if (rt2x00_ring_full(ring)) {
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
 
 	entry = rt2x00_get_data_entry(ring);
 	txd = entry->desc_addr;
 
-	if (rt2x00_get_field32(txd->word0, TXD_W0_OWNER_NIC)
-	|| rt2x00_get_field32(txd->word0, TXD_W0_VALID))
-		return NET_XMIT_DROP;
+	if (rt2x00_get_field32(txd->word0, TXD_W0_OWNER_NIC) ||
+	    rt2x00_get_field32(txd->word0, TXD_W0_VALID)) {
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
 
 	memcpy(entry->data_addr, skb->data, skb->len);
 	rt61pci_write_tx_desc(rt2x00pci, txd, skb, control);
 	entry->skb = skb;
 
 	rt2x00_ring_index_inc(ring);
+	if (rt2x00_ring_full(ring))
+		ieee80211_stop_queue(net_dev, control->queue);
 
 	rt2x00_register_read(rt2x00pci, TX_CNTL_CSR, &reg);
 	if (control->queue == IEEE80211_TX_QUEUE_DATA0)
@@ -2248,6 +2259,7 @@ rt61pci_open(struct net_device *net_dev)
 	rt2x00_register_write(rt2x00pci, INT_SOURCE_CSR, reg);
 
 	SET_FLAG(rt2x00pci, RADIO_ENABLED);
+	ieee80211_start_queues(net_dev);
 
 	return 0;
 
--- dscape.orig/drivers/net/wireless/d80211/rt2x00/rt73usb.c
+++ dscape/drivers/net/wireless/d80211/rt2x00/rt73usb.c
@@ -1093,7 +1093,7 @@ rt73usb_txdone(void *data)
 		ieee80211_dev_hw_data(ring->net_dev);
 	struct data_entry	*entry;
 	struct txd		*txd;
-	int			ack;
+	int			ack, wake, queue;
 
 	while (!rt2x00_ring_empty(ring)) {
 		entry = rt2x00_get_data_entry_done(ring);
@@ -1132,7 +1132,11 @@ rt73usb_txdone(void *data)
 
 		entry->skb = NULL;
 
+		wake = rt2x00_ring_full(ring);
+		queue = entry->tx_status.control.queue;
 		rt2x00_ring_index_done_inc(entry->ring);
+		if (wake)
+			ieee80211_wake_queue(ring->net_dev, queue);
 	}
 
 	/*
@@ -1668,11 +1672,14 @@ rt73usb_tx(struct net_device *net_dev,
 		ERROR("Attempt to send packet over invalid queue %d.\n"
 			"Please file bug report to %s.\n",
 			control->queue, DRV_PROJECT);
-		return NET_XMIT_DROP;
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
 	}
 
-	if (rt2x00_ring_full(ring))
-		return NET_XMIT_DROP;
+	if (rt2x00_ring_full(ring)) {
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
 
 	entry = rt2x00_get_data_entry(ring);
 	txd = rt2x00usb_txdesc_addr(entry);
@@ -1693,6 +1700,8 @@ rt73usb_tx(struct net_device *net_dev,
 	usb_submit_urb(entry->urb, GFP_ATOMIC);
 
 	rt2x00_ring_index_inc(ring);
+	if (rt2x00_ring_full(ring))
+		ieee80211_stop_queue(net_dev, control->queue);
 
 	return 0;
 }
@@ -1765,6 +1774,7 @@ rt73usb_open(struct net_device *net_dev)
 	rt73usb_enable_led(rt2x00usb);
 
 	SET_FLAG(rt2x00usb, RADIO_ENABLED);
+	ieee80211_start_queues(net_dev);
 
 	return 0;
 

^ permalink raw reply

* Re: tcp_slow_start_after_idle
From: Rick Jones @ 2006-06-14 16:46 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, zach.brown, jheffner
In-Reply-To: <20060613.223538.24611602.davem@davemloft.net>

> +tcp_slow_start_after_idle - BOOLEAN
> +	If set, provide RFC2861 behavior and time out the congestion
> +	window after an idle period.  An idle period is defined at
> +	the current RTO.  If unset, the congestion window will not
> +	be timed out after an idle period.
> +	Default: 1

Did you mean "defined as" rather than "defined at?"

Also, does the congestion window "time out" or does it decay?

Perhaps:

tcp_slow_start_after_idle - BOOLEAN
      If set, provide RFC2861 behavior and decay the congestion
      window after the connection has been idle for the connection's
      current RTO.  If unset, the congestion window will not decay
      when the connection has been idle.
      Default: 1

> diff --git a/include/net/tcp.h b/include/net/tcp.h
> index de88c54..bfc71f9 100644
> --- a/include/net/tcp.h
> +++ b/include/net/tcp.h
> @@ -227,6 +227,7 @@ extern int sysctl_tcp_abc;
>  extern int sysctl_tcp_mtu_probing;
>  extern int sysctl_tcp_base_mss;
>  extern int sysctl_tcp_workaround_signed_windows;
> +extern int sysctl_tcp_slow_start_after_idle;

> diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
> index 743016b..be6d929 100644
> --- a/net/ipv4/tcp_output.c
> +++ b/net/ipv4/tcp_output.c
> @@ -59,6 +59,9 @@ int sysctl_tcp_tso_win_divisor = 3;
>  int sysctl_tcp_mtu_probing = 0;
>  int sysctl_tcp_base_mss = 512;
>  
> +/* By default, RFC2861 behavior.  */
> +int sysctl_tcp_slow_start_after_idle = 1;
> +

Is this a candidate for "readmostly?"

rick jones

^ permalink raw reply

* Re: tcp_slow_start_after_idle
From: Zach Brown @ 2006-06-14 17:09 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, jheffner
In-Reply-To: <20060613.223538.24611602.davem@davemloft.net>

David Miller wrote:
> Bringing back up this old topic:
> 
> 	http://marc.theaimsgroup.com/?l=linux-netdev&m=114564962420171&w=2
> 
> I've decided to add this tunable to the net-2.6.18 tree, patch below.

Nice, thanks for the heads-up.  I'll pass the notice on to the guys who
were asking about this in that thread.

- z

^ permalink raw reply

* Interrupt handling on SMP system
From: Majid Khan @ 2006-06-14 17:20 UTC (permalink / raw)
  To: netdev

Hi all,
  I had a few question regarding how interrupt handling work on linux
within a SMP systems.

1. Which processor gets the interrupt when a new packet arrives? Is
there any policy mechanism which can guide the interrupt to the idle
processor etc? Do the processors share an interrupt line and an
interrupt controller assign it to a specific processor?

2. When a soft IRQ is scheduled by the driver and picked up by a
ksoftirqd thread, does it get processed entirely on the same
processor? Does ksoftirqd/i thread processes the packets in the ith
processor queue only?

Regards,
Majid

^ permalink raw reply

* Re: [RFC/PATCH 1/2] in-kernel sockets API
From: Daniel Phillips @ 2006-06-14 17:48 UTC (permalink / raw)
  To: Harald Welte
  Cc: bidulock, Stephen Hemminger, Sridhar Samudrala, netdev,
	linux-kernel
In-Reply-To: <20060614133022.GU11863@sunbeam.de.gnumonks.org>

Hi Harald,

You wrote:
> On Tue, Jun 13, 2006 at 02:12:41PM -0700, I wrote:
> 
>>This has the makings of a nice stable internal kernel api.  Why do we want
>>to provide this nice stable internal api to proprietary modules?
> 
> because there is IMHO legally nothing we can do about it anyway.

Speaking as a former member of a "grey market" binary module vendor that
came in from the cold I can assure you that the distinction between EXPORT
and EXPORT_GPL _is_ meaningful.  That tainted flag makes it extremely
difficult to do deals with mainstream Linux companies and there is always
the fear that it will turn into a legal problem.  The latter bit tends to
make venture capitalists nervous.

That said, the EXPORT_GPL issue is not about black and white legal issues,
it is about gentle encouragement.  In this case we are offering a clumsy,
on-the-metal, guaranteed-to-change-and-make-you-edit-code interface to
non-GPL-compatible modules and a decent, stable (in the deserves to live
sense) interface for the pure of heart.  Gentle encouragement at exactly
the right level.

Did we settle the question of whether these particular exports should be
EXPORT_SYMBOL_GPL?

Regards,

Daniel

^ permalink raw reply

* Re: [RFC/PATCH 1/2] in-kernel sockets API
From: Brian F. G. Bidulock @ 2006-06-14 18:03 UTC (permalink / raw)
  To: Daniel Phillips
  Cc: Harald Welte, Stephen Hemminger, Sridhar Samudrala, netdev,
	linux-kernel
In-Reply-To: <44904C08.6020307@google.com>

Daniel,

On Wed, 14 Jun 2006, Daniel Phillips wrote:
> 
> Speaking as a former member of a "grey market" binary module vendor that
> came in from the cold I can assure you that the distinction between EXPORT
> and EXPORT_GPL _is_ meaningful.  That tainted flag makes it extremely
> difficult to do deals with mainstream Linux companies and there is always
> the fear that it will turn into a legal problem.  The latter bit tends to
> make venture capitalists nervous.
> 

EXPORT_SYMBOL_GPL and the Tainted flag have nothing to do with each other.


^ permalink raw reply

* RE: [openib-general] [PATCH v2 1/2] iWARP Connection Manager.
From: Caitlin Bestler @ 2006-06-14 18:06 UTC (permalink / raw)
  To: Steve Wise, Sean Hefty
  Cc: Andrew Morton, netdev, rdreier, linux-kernel, openib-general

netdev-owner@vger.kernel.org wrote:
> On Tue, 2006-06-13 at 16:46 -0500, Steve Wise wrote:
>> On Tue, 2006-06-13 at 14:36 -0700, Sean Hefty wrote:
>>>>> Er...no. It will lose this event. Depending on the event...the
>>>>> carnage varies. We'll take a look at this.
>>>>> 
>>>> 
>>>> This behavior is consistent with the Infiniband CM (see
>>>> drivers/infiniband/core/cm.c function cm_recv_handler()).  But I
>>>> think we should at least log an error because a lost event will
>>>> usually stall the rdma connection.
>>> 
>>> I believe that there's a difference here.  For the Infiniband CM, an
>>> allocation error behaves the same as if the received MAD were lost
>>> or dropped.  Since MADs are unreliable anyway, it's not so much that
>>> an IB CM event gets lost, as it doesn't ever occur.  A remote CM
>>> should retry the send, which hopefully allows the
> connection to make forward progress.
>>> 
>> 
>> hmm.  Ok.  I see.  I misunderstood the code in cm_recv_handler().
>> 
>> Tom and I have been talking about what we can do to not drop the
>> event. Stay tuned.
> 
> Here's a simple solution that solves the problem:
> 
> For any given cm_id, there are a finite (and small) number of
> outstanding CM events that can be posted.  So we just
> pre-allocate them when the cm_id is created and keep them on
> a free list hanging off of the cm_id struct.  Then the event
> handler function will pull from this free list.
> 
> The only case where there is any non-finite issue is on the
> passive listening cm_id.  Each incoming connection request
> will consume a work struct.  So based on client connects, we
> could run out of work structs.
> However, the CMA has the concept of a backlog, which is
> defined as the max number of pending unaccepted connection
> requests.  So we allocate these work structs based on that
> number (or a computation based on that number), and if we run
> out, we simply drop the incoming connection request due to
> backlog overflow (I suggest we log the drop event too).
> When a MPA connection request is dropped, the (IETF
> conforming) MPA client will eventually time out the
> connection and the consumer can retry.
> 
> Comments?
> 

If the IWCM cannot accept a Connection Request event from
the driver then *someone* should generate a non-peer reject
MPA Response frame. Since the IWCM does not have the resources
to relay the event, it probably does not have the resources
to generate the MPA Response frame either. So simply returning
an "I'm Busy" error and expecting the driver to handle it
makes sense to me.


^ permalink raw reply

* Re: PATCHv3 2.6.17-rc5 tulip free_irq() called too late
From: Grant Grundler @ 2006-06-14 18:14 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Grant Grundler, Valerie Henson, Andrew Morton, netdev
In-Reply-To: <44902554.7010703@pobox.com>

On Wed, Jun 14, 2006 at 11:03:48AM -0400, Jeff Garzik wrote:
> Grant Grundler wrote:
> >Switching the order to be:
> >        tulip_stop_rxtx(tp);            /* Stop DMA */
> >        free_irq (dev->irq, dev);       /* no more races after this */
> >
> >still leaves us open to IRQs being delivered _after_ we've stopped DMA.
> 
> Correct.  And that is the preferred, natural, logical, obvious order:
> 
> 1) Turn things off.
> 2) Wait for activity to cease.

Patch v3 does this in two stages:
1) turn off tulip interrupts
2) free_irq() calls syncronize_irq() to handle pending IRQs

then calls tulip_stop_rxtx() which:
1) tells tulip to stop DMA
2) poll until DMA completes

After this we can free remaining resources.

> >That in turn allows the interrupt handler to re-enable DMA again.
> 
> Then that would be a problem to solve...  Some interrupt handlers will 
> test netif_running() or a driver-specific shutting-down flag, 
> specifically to avoid such behaviors.

I'm not keen on adding more code to tulip_interrupt() routine
for something that rarely happens (compared to IRQs) and is handled
outside the interrupt routine.  I'm pretty sure stopping interrupts
before stopping DMA is sufficient.
Can you show an example where it doesn't work?

This is important since I'm going to propose a new Documentation/pci.txt
based on this experience.

thanks,
grant

^ permalink raw reply

* Re: [PATCH 6/5] rt2x00: per-queue TX flow control
From: Ivo van Doorn @ 2006-06-14 18:35 UTC (permalink / raw)
  To: Jiri Benc; +Cc: netdev, John W. Linville
In-Reply-To: <20060614183635.546d3346@griffin.suse.cz>

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

Hi,

On Wednesday 14 June 2006 18:36, Jiri Benc wrote:
> This is a patch for rt2x00 driver to do TX flow control.
> 
> It is compile-tested only.
>
> Signed-off-by: Jiri Benc <jbenc@suse.cz>

I'll put my comments for the rt2400pci driver only,
since the same changes are made for each rt2x00 driver.

> --- dscape.orig/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
> +++ dscape/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
> @@ -1001,7 +1001,7 @@ rt2400pci_txdone(void *data)
>  	struct data_entry	*entry;
>  	struct txd		*txd;
>  	int			tx_status;
> -	int			ack;
> +	int			ack, wake, queue;
>  
>  	while (!rt2x00_ring_empty(ring)) {
>  		entry = rt2x00_get_data_entry_done(ring);
> @@ -1048,7 +1048,11 @@ rt2400pci_txdone(void *data)
>  		rt2x00_set_field32(&txd->word0, TXD_W0_VALID, 0);
>  		entry->skb = NULL;
>  
> +		wake = rt2x00_ring_full(ring);
> +		queue = entry->tx_status.control.queue;
>  		rt2x00_ring_index_done_inc(ring);
> +		if (wake)
> +			ieee80211_wake_queue(ring->net_dev, queue);
>  	}

This will not give the correct result I fear, and it would cause (unwanted)
overhead of checking if the queue was full.
Queue_full can be checked when the loop starts, and the
waking of the queue can best be done after freeing all entries
and after the second check if the queue is still not full. (There is no guarentee
the while() loop will end while there are free entries in the queue)

>  	/*
> @@ -1541,24 +1545,31 @@ rt2400pci_tx(struct net_device *net_dev,
>  		ERROR("Attempt to send packet over invalid queue %d.\n"
>  			"Please file bug report to %s.\n",
>  			control->queue, DRV_PROJECT);
> -		return NET_XMIT_DROP;
> +		dev_kfree_skb_any(skb);
> +		return NETDEV_TX_OK;
>  	}
>  
> -	if (rt2x00_ring_full(ring))
> -		return NET_XMIT_DROP;
> +	if (rt2x00_ring_full(ring)) {
> +		ieee80211_stop_queue(net_dev, control->queue);
> +		return NETDEV_TX_BUSY;
> +	}
>  
>  	entry = rt2x00_get_data_entry(ring);
>  	txd = entry->desc_addr;
>  
> -	if (rt2x00_get_field32(txd->word0, TXD_W0_OWNER_NIC)
> -	|| rt2x00_get_field32(txd->word0, TXD_W0_VALID))
> -		return NET_XMIT_DROP;
> +	if (rt2x00_get_field32(txd->word0, TXD_W0_OWNER_NIC) ||
> +	    rt2x00_get_field32(txd->word0, TXD_W0_VALID)) {
> +		ieee80211_stop_queue(net_dev, control->queue);
> +		return NETDEV_TX_BUSY;
> +	}

Not sure if I am happy with this one. When this check is made,
it occurs after the ring_full check. This means that when this statement
is true, the queue is not full. Instead it has more of a meaning that something
has gone wrong with the queue and this should not have happened.

But this is not really a problem in the patch itself, just a problem I only
now recognize thanks to your patch. ;)

For the time being I'll add a debug message, but I need to find a method
to clean up the ring if this occurs.
This check currently does not happen in the rt2570 and rt73 USB drivers,
but it is safer to add them in there as well.

>  	memcpy(entry->data_addr, skb->data, skb->len);
>  	rt2400pci_write_tx_desc(rt2x00pci, txd, skb, control);
>  	entry->skb = skb;
>  
>  	rt2x00_ring_index_inc(ring);
> +	if (rt2x00_ring_full(ring))
> +		ieee80211_stop_queue(net_dev, control->queue);
>  
>  	rt2x00_register_read(rt2x00pci, TXCSR0, &reg);
>  	if (control->queue == IEEE80211_TX_QUEUE_DATA0)
> @@ -1668,6 +1679,7 @@ rt2400pci_open(struct net_device *net_de
>  	rt2x00_register_write(rt2x00pci, CSR8, reg);
>  
>  	SET_FLAG(rt2x00pci, RADIO_ENABLED);
> +	ieee80211_start_queues(net_dev);
>  
>  	return 0;

Based on Jiri's patch for rt2x00 driver to do TX flow control.

Signed-off-by Ivo van Doorn <IvDoorn@gmail.com>

---

diff --git a/drivers/net/wireless/d80211/rt2x00/rt2400pci.c b/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
index 8b856dd..946cf86 100644
--- a/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
@@ -1002,6 +1002,12 @@ rt2400pci_txdone(void *data)
 	struct txd		*txd;
 	int			tx_status;
 	int			ack;
+	int			ring_full;
+
+	/*
+	 * Store the current status of the ring.
+	 */
+	ring_full = rt2x00_ring_full(ring);
 
 	while (!rt2x00_ring_empty(ring)) {
 		entry = rt2x00_get_data_entry_done(ring);
@@ -1062,6 +1068,16 @@ rt2400pci_txdone(void *data)
 		rt2x00pci->scan->status = SCANNING_READY;
 		complete(&rt2x00pci->scan->completion);
 	}
+
+	/*
+	 * If the data ring was full before the txdone handler
+	 * we must make sure the packet queue in the d80211 stack
+	 * is reenabled when the txdone handler has finished.
+	 */
+	entry = ring->entry;
+	if (ring_full && !rt2x00_ring_full(ring))
+		ieee80211_wake_queue(ring->net_dev,
+			entry->tx_status.control.queue);
 }
 
 static irqreturn_t
@@ -1541,18 +1557,26 @@ rt2400pci_tx(struct net_device *net_dev,
 		ERROR("Attempt to send packet over invalid queue %d.\n"
 			"Please file bug report to %s.\n",
 			control->queue, DRV_PROJECT);
-		return NET_XMIT_DROP;
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
 	}
 
-	if (rt2x00_ring_full(ring))
-		return NET_XMIT_DROP;
+	if (rt2x00_ring_full(ring)) {
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
 
 	entry = rt2x00_get_data_entry(ring);
 	txd = entry->desc_addr;
 
 	if (rt2x00_get_field32(txd->word0, TXD_W0_OWNER_NIC)
-	|| rt2x00_get_field32(txd->word0, TXD_W0_VALID))
-		return NET_XMIT_DROP;
+	|| rt2x00_get_field32(txd->word0, TXD_W0_VALID)) {
+		ERROR("Arrived at non-free entry in the non-full queue %d.\n"
+			"Please file bug report to %s.\n",
+			control->queue, DRV_PROJECT);
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
 
 	memcpy(entry->data_addr, skb->data, skb->len);
 	rt2400pci_write_tx_desc(rt2x00pci, txd, skb, control);
@@ -1560,6 +1584,9 @@ rt2400pci_tx(struct net_device *net_dev,
 
 	rt2x00_ring_index_inc(ring);
 
+	if (rt2x00_ring_full(ring))
+		ieee80211_stop_queue(net_dev, control->queue);
+
 	rt2x00_register_read(rt2x00pci, TXCSR0, &reg);
 	if (control->queue == IEEE80211_TX_QUEUE_DATA0)
 		rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, 1);
@@ -1569,7 +1596,7 @@ rt2400pci_tx(struct net_device *net_dev,
 		rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, 1);
 	rt2x00_register_write(rt2x00pci, TXCSR0, reg);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int
@@ -1669,6 +1696,8 @@ rt2400pci_open(struct net_device *net_de
 
 	SET_FLAG(rt2x00pci, RADIO_ENABLED);
 
+	ieee80211_start_queues(net_dev);
+
 	return 0;
 
 exit_fail:
diff --git a/drivers/net/wireless/d80211/rt2x00/rt2500pci.c b/drivers/net/wireless/d80211/rt2x00/rt2500pci.c
index 6aeaf1a..ca0edd5 100644
--- a/drivers/net/wireless/d80211/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/d80211/rt2x00/rt2500pci.c
@@ -1090,6 +1090,12 @@ rt2500pci_txdone(void *data)
 	struct txd		*txd;
 	int			tx_status;
 	int			ack;
+	int			ring_full;
+
+	/*
+	 * Store the current status of the ring.
+	 */
+	ring_full = rt2x00_ring_full(ring);
 
 	while (!rt2x00_ring_empty(ring)) {
 		entry = rt2x00_get_data_entry_done(ring);
@@ -1150,6 +1156,16 @@ rt2500pci_txdone(void *data)
 		rt2x00pci->scan->status = SCANNING_READY;
 		complete(&rt2x00pci->scan->completion);
 	}
+
+	/*
+	 * If the data ring was full before the txdone handler
+	 * we must make sure the packet queue in the d80211 stack
+	 * is reenabled when the txdone handler has finished.
+	 */
+	entry = ring->entry;
+	if (ring_full && !rt2x00_ring_full(ring))
+		ieee80211_wake_queue(ring->net_dev,
+			entry->tx_status.control.queue);
 }
 
 static irqreturn_t
@@ -1664,18 +1680,26 @@ rt2500pci_tx(struct net_device *net_dev,
 		ERROR("Attempt to send packet over invalid queue %d.\n"
 			"Please file bug report to %s.\n",
 			control->queue, DRV_PROJECT);
-		return NET_XMIT_DROP;
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
 	}
 
-	if (rt2x00_ring_full(ring))
-		return NET_XMIT_DROP;
+	if (rt2x00_ring_full(ring)) {
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
 
 	entry = rt2x00_get_data_entry(ring);
 	txd = entry->desc_addr;
 
 	if (rt2x00_get_field32(txd->word0, TXD_W0_OWNER_NIC)
-	|| rt2x00_get_field32(txd->word0, TXD_W0_VALID))
-		return NET_XMIT_DROP;
+	|| rt2x00_get_field32(txd->word0, TXD_W0_VALID)) {
+		ERROR("Arrived at non-free entry in the non-full queue %d.\n"
+			"Please file bug report to %s.\n",
+			control->queue, DRV_PROJECT);
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
 
 	memcpy(entry->data_addr, skb->data, skb->len);
 	rt2500pci_write_tx_desc(rt2x00pci, txd, skb, control);
@@ -1683,6 +1707,9 @@ rt2500pci_tx(struct net_device *net_dev,
 
 	rt2x00_ring_index_inc(ring);
 
+	if (rt2x00_ring_full(ring))
+		ieee80211_stop_queue(net_dev, control->queue);
+
 	rt2x00_register_read(rt2x00pci, TXCSR0, &reg);
 	if (control->queue == IEEE80211_TX_QUEUE_DATA0)
 		rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, 1);
@@ -1692,7 +1719,7 @@ rt2500pci_tx(struct net_device *net_dev,
 		rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, 1);
 	rt2x00_register_write(rt2x00pci, TXCSR0, reg);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int
@@ -1792,6 +1819,8 @@ rt2500pci_open(struct net_device *net_de
 
 	SET_FLAG(rt2x00pci, RADIO_ENABLED);
 
+	ieee80211_start_queues(net_dev);
+
 	return 0;
 
 exit_fail:
diff --git a/drivers/net/wireless/d80211/rt2x00/rt2500usb.c b/drivers/net/wireless/d80211/rt2x00/rt2500usb.c
index 1193e60..76c3a68 100644
--- a/drivers/net/wireless/d80211/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/d80211/rt2x00/rt2500usb.c
@@ -930,6 +930,12 @@ rt2500usb_txdone(void *data)
 	struct data_entry	*entry;
 	struct txd		*txd;
 	int			ack;
+	int			ring_full;
+
+	/*
+	 * Store the current status of the ring.
+	 */
+	ring_full = rt2x00_ring_full(ring);
 
 	 while (!rt2x00_ring_empty(ring)) {
 		entry = rt2x00_get_data_entry_done(ring);
@@ -982,6 +988,16 @@ rt2500usb_txdone(void *data)
 		rt2x00usb->scan->status = SCANNING_READY;
 		complete(&rt2x00usb->scan->completion);
 	}
+
+	/*
+	 * If the data ring was full before the txdone handler
+	 * we must make sure the packet queue in the d80211 stack
+	 * is reenabled when the txdone handler has finished.
+	 */
+	entry = ring->entry;
+	if (ring_full && !rt2x00_ring_full(ring))
+		ieee80211_wake_queue(ring->net_dev,
+			entry->tx_status.control.queue);
 }
 
 static void
@@ -1376,15 +1392,26 @@ rt2500usb_tx(struct net_device *net_dev,
 		ERROR("Attempt to send packet over invalid queue %d.\n"
 			"Please file bug report to %s.\n",
 			control->queue, DRV_PROJECT);
-		return NET_XMIT_DROP;
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
 	}
 
-	if (rt2x00_ring_full(ring))
-		return NET_XMIT_DROP;
+	if (rt2x00_ring_full(ring)) {
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
 
 	entry = rt2x00_get_data_entry(ring);
 	txd = rt2x00usb_txdesc_addr(entry);
 
+	if (GET_FLAG(entry, ENTRY_OWNER_NIC)) {
+		ERROR("Arrived at non-free entry in the non-full queue %d.\n"
+			"Please file bug report to %s.\n",
+			control->queue, DRV_PROJECT);
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
+
 	memcpy(rt2x00usb_txdata_addr(entry), skb->data, skb->len);
 	rt2500usb_write_tx_desc(rt2x00usb, txd, skb, control);
 	entry->skb = skb;
@@ -1402,7 +1429,10 @@ rt2500usb_tx(struct net_device *net_dev,
 
 	rt2x00_ring_index_inc(ring);
 
-	return 0;
+	if (rt2x00_ring_full(ring))
+		ieee80211_stop_queue(net_dev, control->queue);
+
+	return NETDEV_TX_OK;
 }
 
 static inline void
@@ -1469,6 +1499,8 @@ rt2500usb_open(struct net_device *net_de
 
 	SET_FLAG(rt2x00usb, RADIO_ENABLED);
 
+	ieee80211_start_queues(net_dev);
+
 	return 0;
 
 exit_fail:
diff --git a/drivers/net/wireless/d80211/rt2x00/rt61pci.c b/drivers/net/wireless/d80211/rt2x00/rt61pci.c
index fdbfa60..0799f9f 100644
--- a/drivers/net/wireless/d80211/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/d80211/rt2x00/rt61pci.c
@@ -1353,6 +1353,12 @@ rt61pci_txdone(void *data)
 	int			tx_status;
 	int			ack;
 	int			reg;
+	int			ring_full;
+
+	/*
+	 * Store the current status of the ring.
+	 */
+	ring_full = rt2x00_ring_full(ring);
 
 	while (!rt2x00_ring_empty(ring)) {
 		entry = rt2x00_get_data_entry_done(ring);
@@ -1418,6 +1424,16 @@ rt61pci_txdone(void *data)
 		rt2x00pci->scan->status = SCANNING_READY;
 		complete(&rt2x00pci->scan->completion);
 	}
+
+	/*
+	 * If the data ring was full before the txdone handler
+	 * we must make sure the packet queue in the d80211 stack
+	 * is reenabled when the txdone handler has finished.
+	 */
+	entry = ring->entry;
+	if (ring_full && !rt2x00_ring_full(ring))
+		ieee80211_wake_queue(ring->net_dev,
+			entry->tx_status.control.queue);
 }
 
 static irqreturn_t
@@ -2100,18 +2116,26 @@ rt61pci_tx(struct net_device *net_dev,
 		ERROR("Attempt to send packet over invalid queue %d.\n"
 			"Please file bug report to %s.\n",
 			control->queue, DRV_PROJECT);
-		return NET_XMIT_DROP;
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
 	}
 
-	if (rt2x00_ring_full(ring))
-		return NET_XMIT_DROP;
+	if (rt2x00_ring_full(ring)) {
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
 
 	entry = rt2x00_get_data_entry(ring);
 	txd = entry->desc_addr;
 
 	if (rt2x00_get_field32(txd->word0, TXD_W0_OWNER_NIC)
-	|| rt2x00_get_field32(txd->word0, TXD_W0_VALID))
-		return NET_XMIT_DROP;
+	|| rt2x00_get_field32(txd->word0, TXD_W0_VALID)) {
+		ERROR("Arrived at non-free entry in the non-full queue %d.\n"
+			"Please file bug report to %s.\n",
+			control->queue, DRV_PROJECT);
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
 
 	memcpy(entry->data_addr, skb->data, skb->len);
 	rt61pci_write_tx_desc(rt2x00pci, txd, skb, control);
@@ -2119,6 +2143,9 @@ rt61pci_tx(struct net_device *net_dev,
 
 	rt2x00_ring_index_inc(ring);
 
+	if (rt2x00_ring_full(ring))
+		ieee80211_stop_queue(net_dev, control->queue);
+
 	rt2x00_register_read(rt2x00pci, TX_CNTL_CSR, &reg);
 	if (control->queue == IEEE80211_TX_QUEUE_DATA0)
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, 1);
@@ -2132,7 +2159,7 @@ rt61pci_tx(struct net_device *net_dev,
 		rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_MGMT, 1);
 	rt2x00_register_write(rt2x00pci, TX_CNTL_CSR, reg);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int
@@ -2249,6 +2276,8 @@ rt61pci_open(struct net_device *net_dev)
 
 	SET_FLAG(rt2x00pci, RADIO_ENABLED);
 
+	ieee80211_start_queues(net_dev);
+
 	return 0;
 
 exit_fail:
diff --git a/drivers/net/wireless/d80211/rt2x00/rt73usb.c b/drivers/net/wireless/d80211/rt2x00/rt73usb.c
index 48e9917..1871204 100644
--- a/drivers/net/wireless/d80211/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/d80211/rt2x00/rt73usb.c
@@ -1094,6 +1094,12 @@ rt73usb_txdone(void *data)
 	struct data_entry	*entry;
 	struct txd		*txd;
 	int			ack;
+	int			ring_full;
+
+	/*
+	 * Store the current status of the ring.
+	 */
+	ring_full = rt2x00_ring_full(ring);
 
 	while (!rt2x00_ring_empty(ring)) {
 		entry = rt2x00_get_data_entry_done(ring);
@@ -1148,6 +1154,16 @@ rt73usb_txdone(void *data)
 		rt2x00usb->scan->status = SCANNING_READY;
 		complete(&rt2x00usb->scan->completion);
 	}
+
+	/*
+	 * If the data ring was full before the txdone handler
+	 * we must make sure the packet queue in the d80211 stack
+	 * is reenabled when the txdone handler has finished.
+	 */
+	entry = ring->entry;
+	if (ring_full && !rt2x00_ring_full(ring))
+		ieee80211_wake_queue(ring->net_dev,
+			entry->tx_status.control.queue);
 }
 
 static void
@@ -1668,15 +1684,26 @@ rt73usb_tx(struct net_device *net_dev,
 		ERROR("Attempt to send packet over invalid queue %d.\n"
 			"Please file bug report to %s.\n",
 			control->queue, DRV_PROJECT);
-		return NET_XMIT_DROP;
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
 	}
 
-	if (rt2x00_ring_full(ring))
-		return NET_XMIT_DROP;
+	if (rt2x00_ring_full(ring)) {
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
 
 	entry = rt2x00_get_data_entry(ring);
 	txd = rt2x00usb_txdesc_addr(entry);
 
+	if (GET_FLAG(entry, ENTRY_OWNER_NIC)) {
+		ERROR("Arrived at non-free entry in the non-full queue %d.\n"
+			"Please file bug report to %s.\n",
+			control->queue, DRV_PROJECT);
+		ieee80211_stop_queue(net_dev, control->queue);
+		return NETDEV_TX_BUSY;
+	}
+
 	memcpy(rt2x00usb_txdata_addr(entry), skb->data, skb->len);
 	rt73usb_write_tx_desc(rt2x00usb, txd, skb, control);
 	entry->skb = skb;
@@ -1694,7 +1721,10 @@ rt73usb_tx(struct net_device *net_dev,
 
 	rt2x00_ring_index_inc(ring);
 
-	return 0;
+	if (rt2x00_ring_full(ring))
+		ieee80211_stop_queue(net_dev, control->queue);
+
+	return NETDEV_TX_OK;
 }
 
 static inline void
@@ -1766,6 +1796,8 @@ rt73usb_open(struct net_device *net_dev)
 
 	SET_FLAG(rt2x00usb, RADIO_ENABLED);
 
+	ieee80211_start_queues(net_dev);
+
 	return 0;
 
 exit_fail:

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

^ permalink raw reply related

* Re: Remove Prism II support from Orinoco
From: Mike Kershaw @ 2006-06-14 19:09 UTC (permalink / raw)
  To: Jar; +Cc: netdev
In-Reply-To: <448F02F1.3070001@pcuf.fi>

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

On Tue, Jun 13, 2006 at 09:24:49PM +0300, Jar wrote:
> It always loads itself with or without blacklist. That's why I have to 
> do 'rm -f orinoco*.* && depmod -a' when the new kernel arrives. Seems 
> that users are directed to use unsecure orinoco (wep) driver rather than 
> secure hostap (wpa/wpa2,tkip,aes) driver for their prism2 hardware.

The hostap drivers are also much better behaved for rfmon than the
orinoco drivers for prism2.

-m

-- 
Mike Kershaw/Dragorn <dragorn@kismetwireless.net>
GPG Fingerprint: 3546 89DF 3C9D ED80 3381  A661 D7B2 8822 738B BDB1

Bus Error at 008BE426 while reading byte from DEADBEEF in User data space


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

^ permalink raw reply

* [patch] ipv4: fix lock usage in udp_ioctl
From: Heiko Carstens @ 2006-06-14 19:43 UTC (permalink / raw)
  To: David S. Miller, Jeff Garzik, Andrew Morton
  Cc: linux-kernel, netdev, Ingo Molnar, Frank Pavlic

From: Heiko Carstens <heiko.carstens@de.ibm.com>

Fix lock usage in udp_ioctl().

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---

udp_poll() seems to have the same problem, right?

As reported by the lock validator:

============================
[ BUG: illegal lock usage! ]
----------------------------
illegal {in-hardirq-W} -> {hardirq-on-W} usage.
syslogd/739 [HC0[0]:SC0[1]:HE1:SE0] takes:
 (&list->lock){++..}, at: [<002e36d6>] udp_ioctl+0x96/0x100
{in-hardirq-W} state was registered at:
  [<00062128>] lock_acquire+0x9c/0xc0
  [<0036209e>] _spin_lock_irqsave+0x66/0x84
  [<002912ce>] skb_dequeue+0x32/0xb0
  [<00263160>] qeth_qdio_output_handler+0x3e8/0xf8c
  [<00219fdc>] tiqdio_thinint_handler+0xde0/0x2234
  [<0020448c>] do_adapter_IO+0x5c/0xa8
  [<0020842c>] do_IRQ+0x13c/0x18c
  [<000208a2>] io_no_vtime+0x16/0x1c
  [<0001978c>] cpu_idle+0x1d0/0x20c
irq event stamp: 1694
hardirqs last  enabled at (1693): [<003629c2>] _spin_unlock_irqrestore+0x92/0xa8
hardirqs last disabled at (1692): [<00362074>] _spin_lock_irqsave+0x3c/0x84
softirqs last  enabled at (1682): [<0028c7c4>] release_sock+0xe4/0xf4
softirqs last disabled at (1694): [<00361f7e>] _spin_lock_bh+0x2e/0x70

other info that might help us debug this:
no locks held by syslogd/739.

stack backtrace:
000000000fd6c148 000000000de2f960 0000000000000002 0000000000000000 
       000000000de2fa00 000000000de2f978 000000000de2f978 000000000001737c 
       0000000000000000 0000000000000000 0000000000000000 0000000000000000 
       000000000de2f960 000000000000000c 000000000de2f960 000000000de2f9d0 
       000000000036fe70 000000000001737c 000000000de2f960 000000000de2f9b0 
Call Trace:
([<000000000001730a>] show_trace+0x166/0x16c)
 [<00000000000173d6>] show_stack+0xc6/0xf8
 [<0000000000017436>] dump_stack+0x2e/0x3c
 [<000000000005f978>] print_usage_bug+0x23c/0x250
 [<00000000000607cc>] mark_lock+0x594/0x714
 [<00000000000613be>] __lock_acquire+0x252/0xf20
 [<0000000000062128>] lock_acquire+0x9c/0xc0
 [<0000000000361fa8>] _spin_lock_bh+0x58/0x70
 [<00000000002e36d6>] udp_ioctl+0x96/0x100
 [<00000000002eadd6>] inet_ioctl+0x72/0x11c
 [<00000000002893f2>] sock_ioctl+0x1ca/0x2c0
 [<00000000000c13ee>] do_ioctl+0x56/0xe0
 [<00000000000c14f2>] vfs_ioctl+0x7a/0x384
 [<00000000000c184e>] sys_ioctl+0x52/0x84
 [<00000000000e80a2>] do_ioctl32_pointer+0x2a/0x3c
 [<00000000000e55c8>] compat_sys_ioctl+0x168/0x378
 [<0000000000020338>] sysc_noemu+0x10/0x16

diffstat:
 net/ipv4/udp.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 3f93292..b15a17b 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -740,7 +740,7 @@ int udp_ioctl(struct sock *sk, int cmd, 
 			unsigned long amount;
 
 			amount = 0;
-			spin_lock_bh(&sk->sk_receive_queue.lock);
+			spin_lock_irq(&sk->sk_receive_queue.lock);
 			skb = skb_peek(&sk->sk_receive_queue);
 			if (skb != NULL) {
 				/*
@@ -750,7 +750,7 @@ int udp_ioctl(struct sock *sk, int cmd, 
 				 */
 				amount = skb->len - sizeof(struct udphdr);
 			}
-			spin_unlock_bh(&sk->sk_receive_queue.lock);
+			spin_unlock_irq(&sk->sk_receive_queue.lock);
 			return put_user(amount, (int __user *)arg);
 		}
 

^ permalink raw reply related

* Re: PATCHv3 2.6.17-rc5 tulip free_irq() called too late
From: Jeff Garzik @ 2006-06-14 19:51 UTC (permalink / raw)
  To: Grant Grundler; +Cc: Valerie Henson, Andrew Morton, netdev
In-Reply-To: <20060614181419.GA10365@colo.lackof.org>

Grant Grundler wrote:
> On Wed, Jun 14, 2006 at 11:03:48AM -0400, Jeff Garzik wrote:
>> Grant Grundler wrote:
>>> Switching the order to be:
>>>        tulip_stop_rxtx(tp);            /* Stop DMA */
>>>        free_irq (dev->irq, dev);       /* no more races after this */
>>>
>>> still leaves us open to IRQs being delivered _after_ we've stopped DMA.
>> Correct.  And that is the preferred, natural, logical, obvious order:
>>
>> 1) Turn things off.
>> 2) Wait for activity to cease.
> 
> Patch v3 does this in two stages:
> 1) turn off tulip interrupts
> 2) free_irq() calls syncronize_irq() to handle pending IRQs
> 
> then calls tulip_stop_rxtx() which:
> 1) tells tulip to stop DMA
> 2) poll until DMA completes
> 
> After this we can free remaining resources.

You need to turn off the thing that generates work (DMA engine), before 
turning off the thing that reaps work (irq handler).


>>> That in turn allows the interrupt handler to re-enable DMA again.
>> Then that would be a problem to solve...  Some interrupt handlers will 
>> test netif_running() or a driver-specific shutting-down flag, 
>> specifically to avoid such behaviors.
> 
> I'm not keen on adding more code to tulip_interrupt() routine
> for something that rarely happens (compared to IRQs) and is handled
> outside the interrupt routine.  I'm pretty sure stopping interrupts
> before stopping DMA is sufficient.
> Can you show an example where it doesn't work?

It should be completely obvious that the chip is still generating 
work...  You don't want to leave the hardware in a position where it has 
unacknowledged events.

	Jeff



^ permalink raw reply

* Re: [PATCH 1/2] e1000: fix netpoll with NAPI
From: Neil Horman @ 2006-06-14 20:41 UTC (permalink / raw)
  To: Mitch Williams
  Cc: Jeff Moyer, Kok, Auke-jan H, Matt Mackall, Garzik, Jeff, netdev,
	Brandeburg, Jesse, Kok, Auke
In-Reply-To: <20060612180600.GB3790@hmsreliant.homelinux.net>

On Mon, Jun 12, 2006 at 02:06:00PM -0400, Neil Horman wrote:
> On Mon, Jun 12, 2006 at 09:42:14AM -0700, Mitch Williams wrote:
> > On Sun, 2006-06-11 at 17:13 -0700, Neil Horman wrote:
> > > Any further thoughts on this guys?  I still think my last solution
> > > solves all of
> > > the netpoll problems, and isn't going to have any noticable impact on
> > > performance.
> > > 
> > I haven't had time to evaluate performance on your patch (sorry!), but
> > after thinking about it, I agree that it should not have any noticeable
> > impact.  OTOH, performance tuning is a funny thing, and things you think
> > won't cause problems often do.
> > 
> Thats ok, I just didn't hear out of anyone on friday, so I was curious as to
> where we were on this.  I don't have the ability to do any real world
> performance testing here, but I'll try to record the run time of the interrupt
> routine on a limited number of frames here.
> 

Hey, as promised, I've done some rudimentary performance benchmarking on various
ways that we have talked about to solve this problem.  As I previously mentioned
I didn't have the equipment to do any real full scale testing here, so what I
did was take a read of the real time counter at the start and end of the
e1000_intr routine with various patches applied, and I recorded the number of
ticks elapsed on the tsc during its run.  I did this on my single cpu x86_64
machine here, using the latest unpatched e1000 driver as a base, and then
comparing it to the e1000 driver using my patch and separately with a patch that
spinlocks the e1000_clean_rx_irq routine (so as to serialize the critical
section that would otherwise be subject to data corruption.  Here are my
results:

Base line: 
Avg. 8145 Ticks on the tsc.

With my patch: http://marc.theaimsgroup.com/?l=linux-netdev&m=114970807606096&w=2 
Avg. 8159 Ticks on the tsc. (+0.17% increase)

With a spinlock added to e1000_clean_rx_irq:
Avg. 8238 Ticks on the tsc. (+1.1% increase)

If you like I can send you the time stamp counter patch that I used, as well as
the patch which adds spinlocks to the clean routine.  Note that the free running
counter values will vary so you probably want to look at percentage increase.
Either way, I think either solution provides very little impact on interrupt run
time.  Given that my patch (granted using my test methodology here) is the
faster of the two, and arguably the more correct in terms of not using the poll
controller method to recieve frames, We should go with that patch.

Thoughts/opinions? 
Neil


-- 
/***************************************************
 *Neil Horman
 *Software Engineer
 *gpg keyid: 1024D / 0x92A74FA1 - http://pgp.mit.edu
 ***************************************************/

^ permalink raw reply

* Re: PATCHv3 2.6.17-rc5 tulip free_irq() called too late
From: Francois Romieu @ 2006-06-14 20:47 UTC (permalink / raw)
  To: Grant Grundler; +Cc: Jeff Garzik, Valerie Henson, Andrew Morton, netdev
In-Reply-To: <20060614181419.GA10365@colo.lackof.org>

Grant Grundler <grundler@parisc-linux.org> :
[...]
> I'm not keen on adding more code to tulip_interrupt() routine
> for something that rarely happens (compared to IRQs) and is handled
> outside the interrupt routine.  I'm pretty sure stopping interrupts
> before stopping DMA is sufficient.
> Can you show an example where it doesn't work?

Shared irq. 

The device has not quiesced, the kernel stop listening to it and the
neighbor device receives a late interruption from the network device.

-- 
Ueimor

^ permalink raw reply

* Re: [RFC/PATCH 1/2] in-kernel sockets API
From: Sridhar Samudrala @ 2006-06-14 20:52 UTC (permalink / raw)
  To: Daniel Phillips, davem
  Cc: Harald Welte, bidulock, Stephen Hemminger, netdev, linux-kernel
In-Reply-To: <44904C08.6020307@google.com>

On Wed, 2006-06-14 at 10:48 -0700, Daniel Phillips wrote:

> 
> Did we settle the question of whether these particular exports should be
> EXPORT_SYMBOL_GPL?

When i submitted this patch, i didn't really think about the different
ways to export these symbols. I simply used the EXPORT_SYMBOL() that is 
used by all the other exports in net/socket.c including kernel_sendmsg()
and kernel_recvmsg().

I am OK with either option(EXPORT_SYMBOL or EXPORT_SYMBOL_GPL) and i will
leave it to David Miller to make that decision at this point.

Thanks
Sridhar


^ permalink raw reply

* skge wake on lan failing
From: Sitsofe Wheeler @ 2006-06-14 21:10 UTC (permalink / raw)
  To: netdev

Hello,

We have a bunch of PCI D-Link System Inc DGE-530T Gigabit Ethernet cards
which use the skge driver. However, the link light for a given card goes
off at the switch during a suspend to ram or power down even though an
"ethtool -s eth0 wol g" has been issued.

Can anyone shed any light on the problem?

-- 
Sitsofe | http://sucs.org/~sits/



^ permalink raw reply

* type of sadb_x_kmprivate_reserved in pfkeyv2.h
From: Tushar Gohad @ 2006-06-14 22:13 UTC (permalink / raw)
  To: netdev

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

Hi David and folks,

In include/linux/pfkeyv2.h, is the type 'u_int32_t' for 
sadb_x_kmprivate_reserved intentional or just an error while bringing in 
the PF_KEY IPsec extensions from KAME?

struct sadb_x_kmprivate {
        uint16_t        sadb_x_kmprivate_len;
        uint16_t        sadb_x_kmprivate_exttype;
        u_int32_t       sadb_x_kmprivate_reserved;    <====
} __attribute__((packed));

This is causing erroneous ipsec-tools builds. How does the 
__BIT_TYPES_DEFINED define work? Seems like u_int32_t does not get 
defined in include/linux/types.h when building a userland program such 
as ipsec-tools.

An easy fix is to change the type to uint32_t. Patch attached.

Thanks.
- Tushar


[-- Attachment #2: common_fix_pfkeyv2_type.patch --]
[-- Type: text/x-patch, Size: 849 bytes --]

Source: MontaVista Software, Inc.
MR: 19039
Type: Defect Fix
Disposition: needs submitting to kernel.org
Signed-off-by: Tushar Gohad <tgohad@mvista.com>
Description:
    When bringing over the PF_KEY extensions for IPsec from the
KAME stack, folks probably forgot to change this only variable
to be of type uint32_t. Or otherwise. This is the easiest and 
harmless fix.

Index: linux-p4/include/linux/pfkeyv2.h
===================================================================
--- linux-p4.orig/include/linux/pfkeyv2.h
+++ linux-p4/include/linux/pfkeyv2.h
@@ -159,7 +159,7 @@ struct sadb_spirange {
 struct sadb_x_kmprivate {
 	uint16_t	sadb_x_kmprivate_len;
 	uint16_t	sadb_x_kmprivate_exttype;
-	u_int32_t	sadb_x_kmprivate_reserved;
+	uint32_t	sadb_x_kmprivate_reserved;
 } __attribute__((packed));
 /* sizeof(struct sadb_x_kmprivate) == 8 */
 

^ permalink raw reply

* Re: [patch] ipv4: fix lock usage in udp_ioctl
From: David Miller @ 2006-06-14 22:16 UTC (permalink / raw)
  To: heiko.carstens; +Cc: jgarzik, akpm, linux-kernel, netdev, mingo, fpavlic
In-Reply-To: <20060614194305.GB10391@osiris.ibm.com>

From: Heiko Carstens <heiko.carstens@de.ibm.com>
Date: Wed, 14 Jun 2006 21:43:05 +0200

> From: Heiko Carstens <heiko.carstens@de.ibm.com>
> 
> Fix lock usage in udp_ioctl().
> 
> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>

More likely the qeth driver shouldn't call into the socket code in
hardware interrupt context.  From your logs that's what it seems is
happening.

The socket receive queue should only be touched in software
interrupt context, never in hardware interrupt context.  That's
why the locking does BH disabling at best.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox