Netdev List
 help / color / mirror / Atom feed
* Re: [e1000 debug] KERNEL: assertion (!sk_forward_alloc) failed...
From: David S. Miller @ 2006-04-14 23:53 UTC (permalink / raw)
  To: jesse.brandeburg
  Cc: bb, herbert, kernel, nipsy, jrlundgren, cat, djani22,
	yoseph.basri, mykleb, olel, michal, chris, netdev,
	jesse.brandeburg, E1000-devel, ak, jgarzik
In-Reply-To: <Pine.WNT.4.63.0604141553210.2116@jbrandeb-desk.amr.corp.intel.com>

From: Jesse Brandeburg <jesse.brandeburg@intel.com>
Date: Fri, 14 Apr 2006 15:55:10 -0700 (Pacific Daylight Time)

> I'm trying to isolate more of a reproduction case, I'll be sure to
> post if I can find anything with more detail.

I think I see the bug.

If tbench with large numbers of clients is part of what helps
reproduce it, the key might be hitting the memory limits in tcp_mem[]
and friends, or something to do with concurrent access to
sk->sk_forward_alloc.

I bet there is some race in there.

A lot of the action is in net/core/stream.c  We modify
sk->sk_forward_alloc non-atomically but that should be ok
since we ought to be holding all of the correct locks when
we hit these accesses.  But it is the first thing to audit.

Let's look at sk_stream_rfree() as that is invoked from SKB
freeing callbacks and is the most likely suspect for these
kinds of problems.

It is hooked up to the skb->destructor by sk_stream_set_owner_r() and
then invoked via __kfree_skb().

Nothing here takes any locks, and as stated above we modify
sk->sk_forward_alloc non-atomically, and this is therefore the bug.

Shit.

I'll think of how to fix this in the least invasive manner.  I also
want to search the changelog history to see if this race was always
present or if it was "introduced".

Making sk->sk_forward_alloc an atomic_t would be incredibly expensive
so I'll try to find a way to avoid that.  We may be able to just do
a bh_lock_sock()/bh_unlock_sock() around the body of sk_stream_rfree()
to fix this.

^ permalink raw reply

* fixing sk_stream_rfree()
From: David S. Miller @ 2006-04-15  3:59 UTC (permalink / raw)
  To: netdev; +Cc: herbert


Herbert, as you may have noticed we found some missing
locking in sk_stream_rfree().  It could explain the
"!sk_forward_alloc" BUG() we thought was caused by e1000's
TSO implementation and the Intel folks have provided enough
datapoints to prove that it is indeed not an e1000 specific
problem.

sk_stream_rfree() modifies sk->sk_forward_alloc without holding any
locks from the __kfree_skb() callback.

Now, _most_ of the time it is OK because we're being invoked with the
socket lock held as ACKs come back to liberate the transmit queue or
during socket shutdown which also holds the socket locked.  (I did
audit this, but I may have missed something, please double check this
assertion)

However, if skb->users is incremented or similar, that entity could
end up being the context in which the skb is freed up and that will
not necessarily have the socket locked correctly when the
skb->destructor callback invokes sk_stream_rfree().  Consider tcpdump
or similar.

But we're stuck if we try to cure this:

1) We can't take bh_lock_sock().  Well, we could if we disabled
   BH explicitly first but even then if the socket is locked
   by the user we can't tell if that's the current cpu and there
   is no easy way to handle deferring this work.

   We really can't consider using a workqueue or something like
   that to handle this, that's way too heavy handed.

2) We can't turn sk_forward_alloc easily into an atomic_t.  The
   masking operation in __sk_stream_mem_reclaim() does not translate
   readily into an atomic_t op:

		sk->sk_forward_alloc &= SK_STREAM_MEM_QUANTUM - 1;

   That line has always driven me nuts, but I know that it is there
   to handle partial page allocations existing when that function
   is called.

I guess for #2 we could change those two lines into:

		int n = atomic_read(&sk->sk_forward_alloc) /
				SK_STREAM_MEM_QUANTUM;

		atomic_sub(n, sk->sk_prot->memory_allocated);
		sk->sk_forward_alloc -= n * SK_STREAM_MEM_QUANTUM;

in order to make it "atomic_t op" translatable.

But even if we did this with sk->sk_forward_alloc as an atomic_t
it would have the same kinds of races we're trying to cure here,
namely that we test the value and then act upon it while an unlocked
asynchronous context can modify the value in another thread of
execution in between the test and the action.

Any ideas?  Come to think of it, __sk_stream_mem_reclaim() looks
really racey even as-is.

^ permalink raw reply

* Re: [patch] ipv4: initialize arp_tbl rw lock
From: Heiko Carstens @ 2006-04-15  7:27 UTC (permalink / raw)
  To: David S. Miller
  Cc: shemminger, jgarzik, akpm, netdev, linux-kernel, fpavlic, davem
In-Reply-To: <20060408.031404.111884281.davem@davemloft.net>

> > Ok, so the problem seems to be that inet_init gets called after qeth_init.
> > Looking at the top level Makefile this seems to be true for all network
> > drivers in drivers/net/ and drivers/s390/net/ since we have
> > 
> > vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
> > 
> > The patch below works for me... I guess there must be a better way to make
> > sure that any networking driver's initcall is made before inet_init?
> > 
> > Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
> 
> We could make inet_init() a subsystem init but I vaguely recall
> that we were doing that at one point and it broke things for
> some reason.
> 
> Perhaps fs_initcall() would work better.  Or if that causes
> problems we could create a net_initcall() that sits between
> fs_initcall() and device_initcall().
> 
> Or any other ideas?

Tried to figure out what is causing the delays I experienced when I replaced
module_init() in af_inet.c with fs_initcall(). After all it turned out that
synchronize_net() which is basicically nothing else than synchronize_rcu()
sometimes takes several seconds to complete?! No idea why that is...

callchain: inet_init() -> inet_register_protosw() -> synchronize_net()

^ permalink raw reply

* Re: [patch] ipv4: initialize arp_tbl rw lock
From: David S. Miller @ 2006-04-15  7:34 UTC (permalink / raw)
  To: heiko.carstens
  Cc: shemminger, jgarzik, akpm, netdev, linux-kernel, fpavlic, davem
In-Reply-To: <20060415072745.GA17011@osiris.boeblingen.de.ibm.com>

From: Heiko Carstens <heiko.carstens@de.ibm.com>
Date: Sat, 15 Apr 2006 09:27:45 +0200

> Tried to figure out what is causing the delays I experienced when I replaced
> module_init() in af_inet.c with fs_initcall(). After all it turned out that
> synchronize_net() which is basicically nothing else than synchronize_rcu()
> sometimes takes several seconds to complete?! No idea why that is...
> 
> callchain: inet_init() -> inet_register_protosw() -> synchronize_net()

The problem can't be rcu_init(), that gets done very early
in init/main.c

Maybe it's some timer or something else specific to s390?

It could also be that there's perhaps nothing to context
switch to, thus the RCU takes forever to "happen".

^ permalink raw reply

* Re: fixing sk_stream_rfree()
From: David S. Miller @ 2006-04-15  8:23 UTC (permalink / raw)
  To: netdev; +Cc: herbert
In-Reply-To: <20060414.205927.13626300.davem@davemloft.net>

From: "David S. Miller" <davem@davemloft.net>
Date: Fri, 14 Apr 2006 20:59:27 -0700 (PDT)

> Any ideas?  Come to think of it, __sk_stream_mem_reclaim() looks
> really racey even as-is.

I came up with one more possible approach, it goes something like
this:

1) Get rid of the skb->destructor callback for TCP receive
   data.

2) Adjust sk_rmem_alloc and sk_forward_alloc explicitly when we add
   packets to sk_receive_queue/out_of_order_queue, and when we unlink
   them from sk_receive_queue and __kfree_skb() them up.

I think this would work and get rid of the unlocked accesses to
sk_forward_alloc.  And it would do so without adding new overheads
(the other two ideas did, by adding locks or turning sk_forward_alloc
into an atomic_t).

The implementation needs a bit of thinking in order to not mess up all
the nice abstractions Arnaldo has created for stream sockets and the
interfaces we share between TCP and DCCP.

But actually DCCP needs this fix too, since it also uses
sk_forward_alloc, so building the solution into the shared interfaces
is desirable.

Too bad this will take a little bit of time to implement, I really
want to be able to cook up a much simpler test patch that the people
who can reproduce the BUG() can try out.

^ permalink raw reply

* Re: fixing sk_stream_rfree()
From: David S. Miller @ 2006-04-15  9:03 UTC (permalink / raw)
  To: netdev; +Cc: herbert
In-Reply-To: <20060415.012327.68977713.davem@davemloft.net>

From: "David S. Miller" <davem@davemloft.net>
Date: Sat, 15 Apr 2006 01:23:27 -0700 (PDT)

> I came up with one more possible approach, it goes something like
> this:
> 
> 1) Get rid of the skb->destructor callback for TCP receive
>    data.
> 
> 2) Adjust sk_rmem_alloc and sk_forward_alloc explicitly when we add
>    packets to sk_receive_queue/out_of_order_queue, and when we unlink
>    them from sk_receive_queue and __kfree_skb() them up.

It turns out DCCP doesn't use the sk_forward_alloc memory
scheduling at least not for receive.

So, as food for thought, below is a comile-tested-only
implementation of the above idea.  The basic transformations
are:

1) sk_eat_skb --> sk_stream_eat_skb which does the sk_forward_alloc
   et al. accounting by hand which would have been done by the
   skb->destructor sk_stream_rfree()

2) __skb_queue_purge --> sk_stream_eat_queue

3) sk_stream_set_owner_r --> sk_stream_charge_r which does
   the accounting for a new receive skb but does not hook up
   the destructor

4) unlink and free SKB not received to userspace yet -->
   sk_stream_eat_skb()

... and then I noticed that ip_rcv() unshares the SKB, so
skb->users should always be 1 and therefore it is impossible
for sk_stream_rfree() to be called from a non socket locked
context.

And all of this was a wild goose chase, oh well :-)
So the BUG_ON(!sk_forward_alloc) problem is elsewhere. :-/

diff --git a/arch/x86_64/kernel/functionlist b/arch/x86_64/kernel/functionlist
index 2bcebdc..da3379a 100644
--- a/arch/x86_64/kernel/functionlist
+++ b/arch/x86_64/kernel/functionlist
@@ -751,7 +751,6 @@
 *(.text.strcmp)
 *(.text.steal_locks)
 *(.text.sock_create)
-*(.text.sk_stream_rfree)
 *(.text.sk_stream_mem_schedule)
 *(.text.skip_atoi)
 *(.text.sk_alloc)
diff --git a/include/net/sock.h b/include/net/sock.h
index af2b054..54d5a2f 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -442,14 +442,56 @@ static inline int sk_stream_memory_free(
 	return sk->sk_wmem_queued < sk->sk_sndbuf;
 }
 
-extern void sk_stream_rfree(struct sk_buff *skb);
-
-static inline void sk_stream_set_owner_r(struct sk_buff *skb, struct sock *sk)
+/* Charge SKB as receive queue memory to SK.  The socket must be locked
+ * when we get here.
+ */
+static inline void sk_stream_charge_r(struct sk_buff *skb, struct sock *sk)
 {
-	skb->sk = sk;
-	skb->destructor = sk_stream_rfree;
 	atomic_add(skb->truesize, &sk->sk_rmem_alloc);
 	sk->sk_forward_alloc -= skb->truesize;
+}
+
+/* Release SKB as receive queue memory from SK.  The socket must be
+ * locked when we get here.
+ */
+static inline void sk_stream_release_r(struct sk_buff *skb, struct sock *sk)
+{
+	atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
+	sk->sk_forward_alloc += skb->truesize;
+}
+
+/**
+ * sk_stream_eat_skb - Release a skb if it is no longer needed
+ * @sk: socket to eat this skb from
+ * @skb: socket buffer to eat
+ * @queue: skb queue to unlink from
+ *
+ * This routine must be called with interrupts disabled or with the socket
+ * locked so that the sk_buff queue operation is ok.
+ */
+static inline void sk_stream_eat_skb(struct sk_buff *skb, struct sock *sk, struct sk_buff_head *queue)
+{
+	__skb_unlink(skb, queue);
+	sk_stream_release_r(skb, sk);
+	__kfree_skb(skb);
+}
+
+/*
+ * sk_stream_eat_queue - Release an entire queue of skbs, when no longer needed
+ * @sk: socket to eat these skbs from
+ * @queue: queue of skbs to eat
+ *
+ * This routine must be called with interrupts disabled or with the socket
+ * locked so that the sk_buff queue operation is ok.
+ */
+static inline void sk_stream_eat_queue(struct sock *sk, struct sk_buff_head *queue)
+{
+	struct sk_buff *skb;
+
+	while ((skb = __skb_dequeue(queue)) != NULL) {
+		sk_stream_release_r(skb, sk);
+		__kfree_skb(skb);
+	}
 }
 
 static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb)
diff --git a/net/core/stream.c b/net/core/stream.c
index 35e2525..a034f2d 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -172,16 +172,6 @@ do_interrupted:
 
 EXPORT_SYMBOL(sk_stream_wait_memory);
 
-void sk_stream_rfree(struct sk_buff *skb)
-{
-	struct sock *sk = skb->sk;
-
-	atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
-	sk->sk_forward_alloc += skb->truesize;
-}
-
-EXPORT_SYMBOL(sk_stream_rfree);
-
 int sk_stream_error(struct sock *sk, int flags, int err)
 {
 	if (err == -EPIPE)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 87f68e7..c45a9c2 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1072,11 +1072,11 @@ int tcp_read_sock(struct sock *sk, read_
 				break;
 		}
 		if (skb->h.th->fin) {
-			sk_eat_skb(sk, skb);
+			sk_stream_eat_skb(skb, sk, &sk->sk_receive_queue);
 			++seq;
 			break;
 		}
-		sk_eat_skb(sk, skb);
+		sk_stream_eat_skb(skb, sk, &sk->sk_receive_queue);
 		if (!desc->count)
 			break;
 	}
@@ -1355,15 +1355,17 @@ skip_copy:
 
 		if (skb->h.th->fin)
 			goto found_fin_ok;
-		if (!(flags & MSG_PEEK))
-			sk_eat_skb(sk, skb);
+		if (!(flags & MSG_PEEK)) {
+			sk_stream_eat_skb(skb, sk, &sk->sk_receive_queue);
+		}
 		continue;
 
 	found_fin_ok:
 		/* Process the FIN. */
 		++*seq;
-		if (!(flags & MSG_PEEK))
-			sk_eat_skb(sk, skb);
+		if (!(flags & MSG_PEEK)) {
+			sk_stream_eat_skb(skb, sk, &sk->sk_receive_queue);
+		}
 		break;
 	} while (len > 0);
 
@@ -1489,6 +1491,7 @@ void tcp_close(struct sock *sk, long tim
 		u32 len = TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq -
 			  skb->h.th->fin;
 		data_was_unread += len;
+		sk_stream_release_r(skb, sk);
 		__kfree_skb(skb);
 	}
 
@@ -1650,9 +1653,9 @@ int tcp_disconnect(struct sock *sk, int 
 		sk->sk_err = ECONNRESET;
 
 	tcp_clear_xmit_timers(sk);
-	__skb_queue_purge(&sk->sk_receive_queue);
+	sk_stream_eat_queue(sk, &sk->sk_receive_queue);
 	sk_stream_writequeue_purge(sk);
-	__skb_queue_purge(&tp->out_of_order_queue);
+	sk_stream_eat_queue(sk, &tp->out_of_order_queue);
 
 	inet->dport = 0;
 
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 9f0cca4..5a30648 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2875,7 +2875,7 @@ static void tcp_fin(struct sk_buff *skb,
 	/* It _is_ possible, that we have something out-of-order _after_ FIN.
 	 * Probably, we should reset in this case. For now drop them.
 	 */
-	__skb_queue_purge(&tp->out_of_order_queue);
+	sk_stream_eat_queue(sk, &tp->out_of_order_queue);
 	if (tp->rx_opt.sack_ok)
 		tcp_sack_reset(&tp->rx_opt);
 	sk_stream_mem_reclaim(sk);
@@ -3093,8 +3093,7 @@ static void tcp_ofo_queue(struct sock *s
 
 		if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) {
 			SOCK_DEBUG(sk, "ofo packet was already received \n");
-			__skb_unlink(skb, &tp->out_of_order_queue);
-			__kfree_skb(skb);
+			sk_stream_eat_skb(skb, sk, &tp->out_of_order_queue);
 			continue;
 		}
 		SOCK_DEBUG(sk, "ofo requeuing : rcv_next %X seq %X - %X\n",
@@ -3166,7 +3165,7 @@ queue_and_out:
 				    !sk_stream_rmem_schedule(sk, skb))
 					goto drop;
 			}
-			sk_stream_set_owner_r(skb, sk);
+			sk_stream_charge_r(skb, sk);
 			__skb_queue_tail(&sk->sk_receive_queue, skb);
 		}
 		tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
@@ -3248,7 +3247,7 @@ drop:
 	SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n",
 		   tp->rcv_nxt, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);
 
-	sk_stream_set_owner_r(skb, sk);
+	sk_stream_charge_r(skb, sk);
 
 	if (!skb_peek(&tp->out_of_order_queue)) {
 		/* Initial out of order segment, build 1 SACK. */
@@ -3290,6 +3289,7 @@ drop:
 		    before(seq, TCP_SKB_CB(skb1)->end_seq)) {
 			if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
 				/* All the bits are present. Drop. */
+				sk_stream_release_r(skb, sk);
 				__kfree_skb(skb);
 				tcp_dsack_set(tp, seq, end_seq);
 				goto add_sack;
@@ -3311,9 +3311,8 @@ drop:
 			       tcp_dsack_extend(tp, TCP_SKB_CB(skb1)->seq, end_seq);
 			       break;
 		       }
-		       __skb_unlink(skb1, &tp->out_of_order_queue);
 		       tcp_dsack_extend(tp, TCP_SKB_CB(skb1)->seq, TCP_SKB_CB(skb1)->end_seq);
-		       __kfree_skb(skb1);
+		       sk_stream_eat_skb(skb1, sk, &tp->out_of_order_queue);
 		}
 
 add_sack:
@@ -3340,8 +3339,7 @@ tcp_collapse(struct sock *sk, struct sk_
 		/* No new bits? It is possible on ofo queue. */
 		if (!before(start, TCP_SKB_CB(skb)->end_seq)) {
 			struct sk_buff *next = skb->next;
-			__skb_unlink(skb, list);
-			__kfree_skb(skb);
+			sk_stream_eat_skb(skb, sk, list);
 			NET_INC_STATS_BH(LINUX_MIB_TCPRCVCOLLAPSED);
 			skb = next;
 			continue;
@@ -3387,7 +3385,7 @@ tcp_collapse(struct sock *sk, struct sk_
 		memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
 		TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(nskb)->end_seq = start;
 		__skb_insert(nskb, skb->prev, skb, list);
-		sk_stream_set_owner_r(nskb, sk);
+		sk_stream_charge_r(nskb, sk);
 
 		/* Copy data, releasing collapsed skbs. */
 		while (copy > 0) {
@@ -3405,8 +3403,7 @@ tcp_collapse(struct sock *sk, struct sk_
 			}
 			if (!before(start, TCP_SKB_CB(skb)->end_seq)) {
 				struct sk_buff *next = skb->next;
-				__skb_unlink(skb, list);
-				__kfree_skb(skb);
+				sk_stream_eat_skb(skb, sk, list);
 				NET_INC_STATS_BH(LINUX_MIB_TCPRCVCOLLAPSED);
 				skb = next;
 				if (skb == tail || skb->h.th->syn || skb->h.th->fin)
@@ -3494,7 +3491,7 @@ static int tcp_prune_queue(struct sock *
 	/* First, purge the out_of_order queue. */
 	if (!skb_queue_empty(&tp->out_of_order_queue)) {
 		NET_INC_STATS_BH(LINUX_MIB_OFOPRUNED);
-		__skb_queue_purge(&tp->out_of_order_queue);
+		sk_stream_eat_queue(sk, &tp->out_of_order_queue);
 
 		/* Reset SACK state.  A conforming SACK implementation will
 		 * do the same at a timeout based retransmit.  When a connection
@@ -3703,10 +3700,8 @@ static void tcp_check_urg(struct sock * 
 	    tp->copied_seq != tp->rcv_nxt) {
 		struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
 		tp->copied_seq++;
-		if (skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq)) {
-			__skb_unlink(skb, &sk->sk_receive_queue);
-			__kfree_skb(skb);
-		}
+		if (skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq))
+			sk_stream_eat_skb(skb, sk, &sk->sk_receive_queue);
 	}
 
 	tp->urg_data   = TCP_URG_NOTYET;
@@ -3950,7 +3945,7 @@ int tcp_rcv_established(struct sock *sk,
 				/* Bulk data transfer: receiver */
 				__skb_pull(skb,tcp_header_len);
 				__skb_queue_tail(&sk->sk_receive_queue, skb);
-				sk_stream_set_owner_r(skb, sk);
+				sk_stream_charge_r(skb, sk);
 				tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
 			}
 
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 672950e..e518d97 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1294,7 +1294,7 @@ int tcp_v4_destroy_sock(struct sock *sk)
   	sk_stream_writequeue_purge(sk);
 
 	/* Cleans up our, hopefully empty, out_of_order_queue. */
-  	__skb_queue_purge(&tp->out_of_order_queue);
+	sk_stream_eat_queue(sk, &tp->out_of_order_queue);
 
 	/* Clean prequeue, it must be empty really */
 	__skb_queue_purge(&tp->ucopy.prequeue);

^ permalink raw reply related

* Re: [RFC: 2.6 patch] net/irda/irias_object.c: remove unused exports
From: Samuel Ortiz @ 2006-04-15  8:56 UTC (permalink / raw)
  To: ext Adrian Bunk; +Cc: Jean Tourrilhes, netdev, linux-kernel
In-Reply-To: <20060414172326.GA15022@stusta.de>

On Fri, 14 Apr 2006, ext Adrian Bunk wrote:

> On Fri, Apr 14, 2006 at 09:42:03AM -0700, Jean Tourrilhes wrote:
>
> > 	Hi,
>
> Hi Jean,
>
> > 	You now need to send those patches to :
> > 		Samuel.Ortiz@nokia.com
>
> Samuel, please send a patch to update MAINTAINERS.
Will do.

>
> > 	Personally, I don't see what this patch buy us...
>
> It makes the kernel image smaller.
It's not a lot, but it does make the kernel image smaller.
Those 3 symbols do not need to be exported as they are not used anywhere
in the modularized parts of the IrDA stack. So, the patch looks good to
me.

Cheers,
Samuel.

> > 	Jean
>
> cu
> Adrian
>
> --
>
>        "Is there not promise of rain?" Ling Tan asked suddenly out
>         of the darkness. There had been need of rain for many days.
>        "Only a promise," Lao Er said.
>                                        Pearl S. Buck - Dragon Seed
>
>


^ permalink raw reply

* Re: [RFC: 2.6 patch] net/irda/irias_object.c: remove unused exports
From: Samuel Ortiz @ 2006-04-15  8:58 UTC (permalink / raw)
  To: ext Adrian Bunk; +Cc: Jean Tourrilhes, netdev, linux-kernel
In-Reply-To: <20060414114446.GL4162@stusta.de>

On Fri, 14 Apr 2006, ext Adrian Bunk wrote:

> This patch removes the following unused EXPORT_SYMBOL's:
> - irias_find_attrib
> - irias_new_string_value
> - irias_new_octseq_value
>
> Signed-off-by: Adrian Bunk <bunk@stusta.de>
Looks good to me.

Signed-off-by: Samuel Ortiz <samuel.ortiz@nokia.com>


> ---
>
>  net/irda/irias_object.c |    3 ---
>  1 file changed, 3 deletions(-)
>
> --- linux-2.6.17-rc1-mm2-full/net/irda/irias_object.c.old	2006-04-14 12:37:49.000000000 +0200
> +++ linux-2.6.17-rc1-mm2-full/net/irda/irias_object.c	2006-04-14 12:39:26.000000000 +0200
> @@ -257,7 +257,6 @@
>  	/* Unsafe (locking), attrib might change */
>  	return attrib;
>  }
> -EXPORT_SYMBOL(irias_find_attrib);
>
>  /*
>   * Function irias_add_attribute (obj, attrib)
> @@ -484,7 +483,6 @@
>
>  	return value;
>  }
> -EXPORT_SYMBOL(irias_new_string_value);
>
>  /*
>   * Function irias_new_octseq_value (octets, len)
> @@ -519,7 +517,6 @@
>  	memcpy(value->t.oct_seq, octseq , len);
>  	return value;
>  }
> -EXPORT_SYMBOL(irias_new_octseq_value);
>
>  struct ias_value *irias_new_missing_value(void)
>  {
>
> -
> 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
>


^ permalink raw reply

* Re: [RFC: 2.6 patch] net/irda/irias_object.c: remove unused exports
From: David S. Miller @ 2006-04-15  9:27 UTC (permalink / raw)
  To: samuel.ortiz; +Cc: bunk, jt, netdev, linux-kernel
In-Reply-To: <Pine.LNX.4.58.0604151157320.1032@irie>

From: Samuel Ortiz <samuel.ortiz@nokia.com>
Date: Sat, 15 Apr 2006 11:58:21 +0300 (EEST)

> On Fri, 14 Apr 2006, ext Adrian Bunk wrote:
> 
> > This patch removes the following unused EXPORT_SYMBOL's:
> > - irias_find_attrib
> > - irias_new_string_value
> > - irias_new_octseq_value
> >
> > Signed-off-by: Adrian Bunk <bunk@stusta.de>
> Looks good to me.
> 
> Signed-off-by: Samuel Ortiz <samuel.ortiz@nokia.com>

Sam, just add this to your IRDA queue.  Ok?

^ permalink raw reply

* [PATCH-2.6] e1000: fix media_type <-> phy_type thinko
From: Willy TARREAU @ 2006-04-15 11:00 UTC (permalink / raw)
  To: jesse.brandeburg, netdev, linux-kernel; +Cc: rol


Recent patch cb764326dff0ee51aca0d450e1a292de65661055 introduced
a thinko in e1000_main.c : e1000_media_type_copper is compared
to hw.phy_type instead of hw.media_type. Original patch proposed
by Jesse Brandeburg was correct, but what has been merged is not.

---

 drivers/net/e1000/e1000_main.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

3df8a180d50c89a72c28abf37151e38ffda75f39
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index add8dc4..590a456 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -4156,7 +4156,7 @@ e1000_mii_ioctl(struct net_device *netde
 			spin_unlock_irqrestore(&adapter->stats_lock, flags);
 			return -EIO;
 		}
-		if (adapter->hw.phy_type == e1000_media_type_copper) {
+		if (adapter->hw.media_type == e1000_media_type_copper) {
 			switch (data->reg_num) {
 			case PHY_CTRL:
 				if (mii_reg & MII_CR_POWER_DOWN)
-- 
1.2.4


^ permalink raw reply related

* skb diet
From: Hisham Kotry @ 2006-04-15 11:17 UTC (permalink / raw)
  To: netdev

Hi,

I just read David S. Miller's skb redundancy page and in it he seems to suggest
taking an approach similar to that of BSD's mbufs to reduce the skb's
size. I was going to do some janitor work on the network stack and I
thought that maybe I could start by adding a tag list to the skb
similar to BSD's mbuf tags and change the code to store its private
variables in tags rather than in skb->cb. That should save 40 bytes
per skb and maybe later the tc and nf related variables could go in
tags too. The transition shouldn't be hard for the most part, many
users of skb->cb use macros like FRAG_CB(skb) so I could redefine
those macros to search the tag-list for the appropriate tag and return
its contents. Is this approach acceptable or is there a consensus on
another approach?

^ permalink raw reply

* RE: Fw: Openswan, iptables (fiaif) and 2.6.16 kernel
From: Marco Berizzi @ 2006-04-15 13:00 UTC (permalink / raw)
  To: akpm; +Cc: netdev, lcaron
In-Reply-To: <20060414105917.0db022d9.akpm@osdl.org>

Andrew Morton wrote:

>Begin forwarded message:
>
>Date: Fri, 14 Apr 2006 14:32:39 +0200
>From: Laurent CARON <lcaron@apartia.fr>
>To: linux-kernel@vger.kernel.org
>Subject: Openswan, iptables (fiaif) and 2.6.16 kernel
>
>
>Hi,
>
>I'm running an openswan gateway for quite a long time now.
>
>I have used 2.4.X and 2.6.X kernels without any problem until i decided
>to upgrade to 2.6.16 kernel.
>
>Summary of problem:
>
>Under 2.6.15 everything is fine
>
>Under 2.6.16 my tunnels establish well, but i can't even ping a single
>computer located on the other end of the tunnel when the firewall is up.
>Disabling the firewall solves the problem (but is not an option for me).
>
>$ cat ip_conntrack | grep 192.168.10
>icmp     1 8 src=192.168.0.192 dst=192.168.10.1 type=8 code=0 id=793
>packets=4 bytes=116 [UNREPLIED] src=192.168.10.1 dst=XXX.XXX.XXX.XXX
>type=0 code=0 id=793 packets=0 bytes=0 mark=0 use=1
>
>192.168.0.0/24 is my lan subnet (natted so that lan computers can access
>the internet through the public ip address)
>192.168.0.192 is a workstation on my lan
>192.168.10.0/24 is the other subnet
>XXX.XXX.XXX.XXX is my public ip address
>
>
>If i disable the nat of 192.168.0.0/24, i can ping the other end.
>
>Re-enabling the nat however disables the ability to ping the other end.
>
>Seems iptables is trying to nat packets the wrong way :$, or that I
>missed a major change in 2.6.16.
>
>Do anyone have any clue about this weiredness?
>
>Thanks
>
>Laurent

I have replied to Laurent and to openswan list:
http://lists.openswan.org/pipermail/users/2006-April/009070.html



^ permalink raw reply

* [2.6 patch] fix the AU1000_FIR dependencies
From: Adrian Bunk @ 2006-04-15 14:23 UTC (permalink / raw)
  To: Samuel.Ortiz; +Cc: netdev, linux-kernel, ralf, linux-mips, Jean-Luc Leger

This patrch fixes the AU1000_FIR dependencies.

Spotted by Jean-Luc Leger.

Signed-off-by: Adrian Bunk <bunk@stusta.de>

--- linux-2.6.17-rc1-mm2-full/drivers/net/irda/Kconfig.old	2006-04-15 16:17:36.000000000 +0200
+++ linux-2.6.17-rc1-mm2-full/drivers/net/irda/Kconfig	2006-04-15 16:18:06.000000000 +0200
@@ -350,7 +350,7 @@
 
 config AU1000_FIR
 	tristate "Alchemy Au1000 SIR/FIR"
-	depends on MIPS_AU1000 && IRDA
+	depends on SOC_AU1000 && IRDA
 
 config SMC_IRCC_FIR
 	tristate "SMSC IrCC (EXPERIMENTAL)"


^ permalink raw reply

* [PATCH] wireless/airo: minimal WPA awareness
From: Dan Williams @ 2006-04-15 16:26 UTC (permalink / raw)
  To: netdev; +Cc: John W. Linville, matthieu castet, Javier Achirica,
	Jean Tourrilhes

airo cards with firmware versions of 5.30.17 and higher support WPA.
This patch recognizes WPA-capable firmware versions and adds support for
retrieving the WPA and RSN information elements from the card's scan
results.  The JOB and FLAG fields are now independent, since there was
no space left in the FLAG field for FLAG_WPA_CAPABLE.

Signed-off-by: matthieu castet <castet.matthieu@free.fr>
Signed-off-by: Dan Williams <dcbw@redhat.com>

--- a/drivers/net/wireless/airo.c	2006-04-04 09:59:43.000000000 -0400
+++ b/drivers/net/wireless/airo.c	2006-04-15 12:16:21.000000000 -0400
@@ -47,6 +47,7 @@
 #include <linux/ioport.h>
 #include <linux/pci.h>
 #include <asm/uaccess.h>
+#include <net/ieee80211.h>
 
 #include "airo.h"
 
@@ -467,6 +468,8 @@
 #define RID_ECHOTEST_RESULTS 0xFF71
 #define RID_BSSLISTFIRST 0xFF72
 #define RID_BSSLISTNEXT  0xFF73
+#define RID_WPA_BSSLISTFIRST 0xFF74
+#define RID_WPA_BSSLISTNEXT  0xFF75
 
 typedef struct {
 	u16 cmd;
@@ -739,6 +742,14 @@
 	u16 extSoftCap;
 } CapabilityRid;
 
+
+/* Only present on firmware >= 5.30.17 */
+typedef struct {
+  u16 unknown[4];
+  u8 fixed[12]; /* WLAN management frame */
+  u8 iep[624];
+} BSSListRidExtra;
+
 typedef struct {
   u16 len;
   u16 index; /* First is 0 and 0xffff means end of list */
@@ -767,6 +778,9 @@
   } fh;
   u16 dsChannel;
   u16 atimWindow;
+
+  /* Only present on firmware >= 5.30.17 */
+  BSSListRidExtra extra;
 } BSSListRid;
 
 typedef struct {
@@ -1140,8 +1154,6 @@
 	char defindex; // Used with auto wep
 	struct proc_dir_entry *proc_entry;
         spinlock_t aux_lock;
-        unsigned long flags;
-#define FLAG_PROMISC	8	/* IFF_PROMISC 0x100 - include/linux/if.h */
 #define FLAG_RADIO_OFF	0	/* User disabling of MAC */
 #define FLAG_RADIO_DOWN	1	/* ifup/ifdown disabling of MAC */
 #define FLAG_RADIO_MASK 0x03
@@ -1151,6 +1163,7 @@
 #define FLAG_UPDATE_MULTI 5
 #define FLAG_UPDATE_UNI 6
 #define FLAG_802_11	7
+#define FLAG_PROMISC	8	/* IFF_PROMISC 0x100 - include/linux/if.h */
 #define FLAG_PENDING_XMIT 9
 #define FLAG_PENDING_XMIT11 10
 #define FLAG_MPI	11
@@ -1158,17 +1171,19 @@
 #define FLAG_COMMIT	13
 #define FLAG_RESET	14
 #define FLAG_FLASHING	15
-#define JOB_MASK	0x2ff0000
-#define JOB_DIE		16
-#define JOB_XMIT	17
-#define JOB_XMIT11	18
-#define JOB_STATS	19
-#define JOB_PROMISC	20
-#define JOB_MIC		21
-#define JOB_EVENT	22
-#define JOB_AUTOWEP	23
-#define JOB_WSTATS	24
-#define JOB_SCAN_RESULTS  25
+#define FLAG_WPA_CAPABLE	16
+	unsigned long flags;
+#define JOB_DIE	0
+#define JOB_XMIT	1
+#define JOB_XMIT11	2
+#define JOB_STATS	3
+#define JOB_PROMISC	4
+#define JOB_MIC	5
+#define JOB_EVENT	6
+#define JOB_AUTOWEP	7
+#define JOB_WSTATS	8
+#define JOB_SCAN_RESULTS  9
+	unsigned long jobs;
 	int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen,
 			int whichbap);
 	unsigned short *flash;
@@ -1208,6 +1223,11 @@
 #define	PCI_SHARED_LEN		2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE
 	char			proc_name[IFNAMSIZ];
 
+	/* WPA-related stuff */
+	unsigned int bssListFirst;
+	unsigned int bssListNext;
+	unsigned int bssListRidLen;
+
 	struct list_head network_list;
 	struct list_head network_free_list;
 	BSSListElement *networks;
@@ -1264,7 +1284,7 @@
 {
 	MICRid mic_rid;
 
-	clear_bit(JOB_MIC, &ai->flags);
+	clear_bit(JOB_MIC, &ai->jobs);
 	PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0);
 	up(&ai->sem);
 
@@ -1705,24 +1725,24 @@
 static int readBSSListRid(struct airo_info *ai, int first,
 		      BSSListRid *list) {
 	int rc;
-			Cmd cmd;
-			Resp rsp;
+	Cmd cmd;
+	Resp rsp;
 
 	if (first == 1) {
-			if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
-			memset(&cmd, 0, sizeof(cmd));
-			cmd.cmd=CMD_LISTBSS;
-			if (down_interruptible(&ai->sem))
-				return -ERESTARTSYS;
-			issuecommand(ai, &cmd, &rsp);
-			up(&ai->sem);
-			/* Let the command take effect */
-			ai->task = current;
-			ssleep(3);
-			ai->task = NULL;
-		}
-	rc = PC4500_readrid(ai, first ? RID_BSSLISTFIRST : RID_BSSLISTNEXT,
-			    list, sizeof(*list), 1);
+		if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
+		memset(&cmd, 0, sizeof(cmd));
+		cmd.cmd=CMD_LISTBSS;
+		if (down_interruptible(&ai->sem))
+			return -ERESTARTSYS;
+		issuecommand(ai, &cmd, &rsp);
+		up(&ai->sem);
+		/* Let the command take effect */
+		ai->task = current;
+		ssleep(3);
+		ai->task = NULL;
+	}
+	rc = PC4500_readrid(ai, first ? ai->bssListFirst : ai->bssListNext,
+			    list, ai->bssListRidLen, 1);
 
 	list->len = le16_to_cpu(list->len);
 	list->index = le16_to_cpu(list->index);
@@ -2112,7 +2132,7 @@
 	int fid = priv->xmit.fid;
 	u32 *fids = priv->fids;
 
-	clear_bit(JOB_XMIT, &priv->flags);
+	clear_bit(JOB_XMIT, &priv->jobs);
 	clear_bit(FLAG_PENDING_XMIT, &priv->flags);
 	status = transmit_802_3_packet (priv, fids[fid], skb->data);
 	up(&priv->sem);
@@ -2162,7 +2182,7 @@
 	if (down_trylock(&priv->sem) != 0) {
 		set_bit(FLAG_PENDING_XMIT, &priv->flags);
 		netif_stop_queue(dev);
-		set_bit(JOB_XMIT, &priv->flags);
+		set_bit(JOB_XMIT, &priv->jobs);
 		wake_up_interruptible(&priv->thr_wait);
 	} else
 		airo_end_xmit(dev);
@@ -2177,7 +2197,7 @@
 	int fid = priv->xmit11.fid;
 	u32 *fids = priv->fids;
 
-	clear_bit(JOB_XMIT11, &priv->flags);
+	clear_bit(JOB_XMIT11, &priv->jobs);
 	clear_bit(FLAG_PENDING_XMIT11, &priv->flags);
 	status = transmit_802_11_packet (priv, fids[fid], skb->data);
 	up(&priv->sem);
@@ -2233,7 +2253,7 @@
 	if (down_trylock(&priv->sem) != 0) {
 		set_bit(FLAG_PENDING_XMIT11, &priv->flags);
 		netif_stop_queue(dev);
-		set_bit(JOB_XMIT11, &priv->flags);
+		set_bit(JOB_XMIT11, &priv->jobs);
 		wake_up_interruptible(&priv->thr_wait);
 	} else
 		airo_end_xmit11(dev);
@@ -2244,7 +2264,7 @@
 	StatsRid stats_rid;
 	u32 *vals = stats_rid.vals;
 
-	clear_bit(JOB_STATS, &ai->flags);
+	clear_bit(JOB_STATS, &ai->jobs);
 	if (ai->power.event) {
 		up(&ai->sem);
 		return;
@@ -2272,10 +2292,10 @@
 {
 	struct airo_info *local =  dev->priv;
 
-	if (!test_bit(JOB_STATS, &local->flags)) {
+	if (!test_bit(JOB_STATS, &local->jobs)) {
 		/* Get stats out of the card if available */
 		if (down_trylock(&local->sem) != 0) {
-			set_bit(JOB_STATS, &local->flags);
+			set_bit(JOB_STATS, &local->jobs);
 			wake_up_interruptible(&local->thr_wait);
 		} else
 			airo_read_stats(local);
@@ -2290,7 +2310,7 @@
 
 	memset(&cmd, 0, sizeof(cmd));
 	cmd.cmd=CMD_SETMODE;
-	clear_bit(JOB_PROMISC, &ai->flags);
+	clear_bit(JOB_PROMISC, &ai->jobs);
 	cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC;
 	issuecommand(ai, &cmd, &rsp);
 	up(&ai->sem);
@@ -2302,7 +2322,7 @@
 	if ((dev->flags ^ ai->flags) & IFF_PROMISC) {
 		change_bit(FLAG_PROMISC, &ai->flags);
 		if (down_trylock(&ai->sem) != 0) {
-			set_bit(JOB_PROMISC, &ai->flags);
+			set_bit(JOB_PROMISC, &ai->jobs);
 			wake_up_interruptible(&ai->thr_wait);
 		} else
 			airo_set_promisc(ai);
@@ -2380,7 +2400,7 @@
 		}
 		clear_bit(FLAG_REGISTERED, &ai->flags);
 	}
-	set_bit(JOB_DIE, &ai->flags);
+	set_bit(JOB_DIE, &ai->jobs);
 	kill_proc(ai->thr_pid, SIGTERM, 1);
 	wait_for_completion(&ai->thr_exited);
 
@@ -2701,14 +2721,14 @@
 	return 0;
 }
 
-#define MAX_NETWORK_COUNT	64
+#define AIRO_MAX_NETWORK_COUNT	64
 static int airo_networks_allocate(struct airo_info *ai)
 {
 	if (ai->networks)
 		return 0;
 
 	ai->networks =
-	    kzalloc(MAX_NETWORK_COUNT * sizeof(BSSListElement),
+	    kzalloc(AIRO_MAX_NETWORK_COUNT * sizeof(BSSListElement),
 		    GFP_KERNEL);
 	if (!ai->networks) {
 		airo_print_warn(ai->dev->name, "Out of memory allocating beacons");
@@ -2732,11 +2752,33 @@
 
 	INIT_LIST_HEAD(&ai->network_free_list);
 	INIT_LIST_HEAD(&ai->network_list);
-	for (i = 0; i < MAX_NETWORK_COUNT; i++)
+	for (i = 0; i < AIRO_MAX_NETWORK_COUNT; i++)
 		list_add_tail(&ai->networks[i].list,
 			      &ai->network_free_list);
 }
 
+static int airo_test_wpa_capable(struct airo_info *ai)
+{
+	int status;
+	CapabilityRid cap_rid;
+	const char *name = ai->dev->name;
+
+	status = readCapabilityRid(ai, &cap_rid, 1);
+	if (status != SUCCESS) return 0;
+
+	/* Only firmware versions 5.30.17 or better can do WPA */
+	if ((cap_rid.softVer > 0x530)
+	  || ((cap_rid.softVer == 0x530) && (cap_rid.softSubVer >= 0x17))) {
+		airo_print_info(name, "WPA is supported.");
+		return 1;
+	}
+
+	/* No WPA support */
+	airo_print_info(name, "WPA unsupported (only firmware versions 5.30.17"
+		" and greater support WPA.  Detected %s)", cap_rid.prodVer);
+	return 0;
+}
+
 static struct net_device *_init_airo_card( unsigned short irq, int port,
 					   int is_pcmcia, struct pci_dev *pci,
 					   struct device *dmdev )
@@ -2759,6 +2801,7 @@
 	ai = dev->priv;
 	ai->wifidev = NULL;
 	ai->flags = 0;
+	ai->jobs = 0;
 	ai->dev = dev;
 	if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) {
 		airo_print_dbg(dev->name, "Found an MPI350 card");
@@ -2838,6 +2881,18 @@
 		set_bit(FLAG_FLASHING, &ai->flags);
 	}
 
+	/* Test for WPA support */
+	if (airo_test_wpa_capable(ai)) {
+		set_bit(FLAG_WPA_CAPABLE, &ai->flags);
+		ai->bssListFirst = RID_WPA_BSSLISTFIRST;
+		ai->bssListNext = RID_WPA_BSSLISTNEXT;
+		ai->bssListRidLen = sizeof(BSSListRid);
+	} else {
+		ai->bssListFirst = RID_BSSLISTFIRST;
+		ai->bssListNext = RID_BSSLISTNEXT;
+		ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra);
+	}
+
 	rc = register_netdev(dev);
 	if (rc) {
 		airo_print_err(dev->name, "Couldn't register_netdev");
@@ -2875,7 +2930,7 @@
 err_out_unlink:
 	del_airo_dev(dev);
 err_out_thr:
-	set_bit(JOB_DIE, &ai->flags);
+	set_bit(JOB_DIE, &ai->jobs);
 	kill_proc(ai->thr_pid, SIGTERM, 1);
 	wait_for_completion(&ai->thr_exited);
 err_out_free:
@@ -2933,7 +2988,7 @@
 	union iwreq_data wrqu;
 	StatusRid status_rid;
 
-	clear_bit(JOB_EVENT, &ai->flags);
+	clear_bit(JOB_EVENT, &ai->jobs);
 	PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0);
 	up(&ai->sem);
 	wrqu.data.length = 0;
@@ -2947,7 +3002,7 @@
 
 static void airo_process_scan_results (struct airo_info *ai) {
 	union iwreq_data	wrqu;
-	BSSListRid BSSList;
+	BSSListRid bss;
 	int rc;
 	BSSListElement * loop_net;
 	BSSListElement * tmp_net;
@@ -2960,15 +3015,15 @@
 	}
 
 	/* Try to read the first entry of the scan result */
-	rc = PC4500_readrid(ai, RID_BSSLISTFIRST, &BSSList, sizeof(BSSList), 0);
-	if((rc) || (BSSList.index == 0xffff)) {
+	rc = PC4500_readrid(ai, ai->bssListFirst, &bss, ai->bssListRidLen, 0);
+	if((rc) || (bss.index == 0xffff)) {
 		/* No scan results */
 		goto out;
 	}
 
 	/* Read and parse all entries */
 	tmp_net = NULL;
-	while((!rc) && (BSSList.index != 0xffff)) {
+	while((!rc) && (bss.index != 0xffff)) {
 		/* Grab a network off the free list */
 		if (!list_empty(&ai->network_free_list)) {
 			tmp_net = list_entry(ai->network_free_list.next,
@@ -2977,19 +3032,19 @@
 		}
 
 		if (tmp_net != NULL) {
-			memcpy(tmp_net, &BSSList, sizeof(tmp_net->bss));
+			memcpy(tmp_net, &bss, sizeof(tmp_net->bss));
 			list_add_tail(&tmp_net->list, &ai->network_list);
 			tmp_net = NULL;
 		}
 
 		/* Read next entry */
-		rc = PC4500_readrid(ai, RID_BSSLISTNEXT,
-				    &BSSList, sizeof(BSSList), 0);
+		rc = PC4500_readrid(ai, ai->bssListNext,
+				    &bss, ai->bssListRidLen, 0);
 	}
 
 out:
 	ai->scan_timeout = 0;
-	clear_bit(JOB_SCAN_RESULTS, &ai->flags);
+	clear_bit(JOB_SCAN_RESULTS, &ai->jobs);
 	up(&ai->sem);
 
 	/* Send an empty event to user space.
@@ -3019,10 +3074,10 @@
 		/* make swsusp happy with our thread */
 		try_to_freeze();
 
-		if (test_bit(JOB_DIE, &ai->flags))
+		if (test_bit(JOB_DIE, &ai->jobs))
 			break;
 
-		if (ai->flags & JOB_MASK) {
+		if (ai->jobs) {
 			locked = down_interruptible(&ai->sem);
 		} else {
 			wait_queue_t wait;
@@ -3031,16 +3086,16 @@
 			add_wait_queue(&ai->thr_wait, &wait);
 			for (;;) {
 				set_current_state(TASK_INTERRUPTIBLE);
-				if (ai->flags & JOB_MASK)
+				if (ai->jobs)
 					break;
 				if (ai->expires || ai->scan_timeout) {
 					if (ai->scan_timeout &&
 							time_after_eq(jiffies,ai->scan_timeout)){
-						set_bit(JOB_SCAN_RESULTS,&ai->flags);
+						set_bit(JOB_SCAN_RESULTS, &ai->jobs);
 						break;
 					} else if (ai->expires &&
 							time_after_eq(jiffies,ai->expires)){
-						set_bit(JOB_AUTOWEP,&ai->flags);
+						set_bit(JOB_AUTOWEP, &ai->jobs);
 						break;
 					}
 					if (!signal_pending(current)) {
@@ -3069,7 +3124,7 @@
 		if (locked)
 			continue;
 
-		if (test_bit(JOB_DIE, &ai->flags)) {
+		if (test_bit(JOB_DIE, &ai->jobs)) {
 			up(&ai->sem);
 			break;
 		}
@@ -3079,23 +3134,23 @@
 			continue;
 		}
 
-		if (test_bit(JOB_XMIT, &ai->flags))
+		if (test_bit(JOB_XMIT, &ai->jobs))
 			airo_end_xmit(dev);
-		else if (test_bit(JOB_XMIT11, &ai->flags))
+		else if (test_bit(JOB_XMIT11, &ai->jobs))
 			airo_end_xmit11(dev);
-		else if (test_bit(JOB_STATS, &ai->flags))
+		else if (test_bit(JOB_STATS, &ai->jobs))
 			airo_read_stats(ai);
-		else if (test_bit(JOB_WSTATS, &ai->flags))
+		else if (test_bit(JOB_WSTATS, &ai->jobs))
 			airo_read_wireless_stats(ai);
-		else if (test_bit(JOB_PROMISC, &ai->flags))
+		else if (test_bit(JOB_PROMISC, &ai->jobs))
 			airo_set_promisc(ai);
-		else if (test_bit(JOB_MIC, &ai->flags))
+		else if (test_bit(JOB_MIC, &ai->jobs))
 			micinit(ai);
-		else if (test_bit(JOB_EVENT, &ai->flags))
+		else if (test_bit(JOB_EVENT, &ai->jobs))
 			airo_send_event(dev);
-		else if (test_bit(JOB_AUTOWEP, &ai->flags))
+		else if (test_bit(JOB_AUTOWEP, &ai->jobs))
 			timer_func(dev);
-		else if (test_bit(JOB_SCAN_RESULTS, &ai->flags))
+		else if (test_bit(JOB_SCAN_RESULTS, &ai->jobs))
 			airo_process_scan_results(ai);
 		else  /* Shouldn't get here, but we make sure to unlock */
 			up(&ai->sem);
@@ -3133,7 +3188,7 @@
 		if ( status & EV_MIC ) {
 			OUT4500( apriv, EVACK, EV_MIC );
 			if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) {
-				set_bit(JOB_MIC, &apriv->flags);
+				set_bit(JOB_MIC, &apriv->jobs);
 				wake_up_interruptible(&apriv->thr_wait);
 			}
 		}
@@ -3187,7 +3242,7 @@
 				set_bit(FLAG_UPDATE_MULTI, &apriv->flags);
 
 				if (down_trylock(&apriv->sem) != 0) {
-					set_bit(JOB_EVENT, &apriv->flags);
+					set_bit(JOB_EVENT, &apriv->jobs);
 					wake_up_interruptible(&apriv->thr_wait);
 				} else
 					airo_send_event(dev);
@@ -5485,7 +5540,7 @@
 	up(&apriv->sem);
 
 /* Schedule check to see if the change worked */
-	clear_bit(JOB_AUTOWEP, &apriv->flags);
+	clear_bit(JOB_AUTOWEP, &apriv->jobs);
 	apriv->expires = RUN_AT(HZ*3);
 }
 
@@ -6876,7 +6931,7 @@
 	}
 	range->num_txpower = i;
 	range->txpower_capa = IW_TXPOW_MWATT;
-	range->we_version_source = 12;
+	range->we_version_source = 19;
 	range->we_version_compiled = WIRELESS_EXT;
 	range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
 	range->retry_flags = IW_RETRY_LIMIT;
@@ -7152,6 +7207,7 @@
 	u16			capabilities;
 	char *			current_val;	/* For rates */
 	int			i;
+	char *		buf;
 
 	/* First entry *MUST* be the AP MAC address */
 	iwe.cmd = SIOCGIWAP;
@@ -7238,8 +7294,69 @@
 	if((current_val - current_ev) > IW_EV_LCP_LEN)
 		current_ev = current_val;
 
-	/* The other data in the scan result are not really
-	 * interesting, so for now drop it - Jean II */
+	/* Beacon interval */
+	buf = kmalloc(30, GFP_KERNEL);
+	if (buf) {
+		iwe.cmd = IWEVCUSTOM;
+		sprintf(buf, "bcn_int=%d", bss->beaconInterval);
+		iwe.u.data.length = strlen(buf);
+		current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
+		kfree(buf);
+	}
+
+	/* Put WPA/RSN Information Elements into the event stream */
+	if (test_bit(FLAG_WPA_CAPABLE, &ai->flags)) {
+		unsigned int num_null_ies = 0;
+		u16 length = sizeof (bss->extra.iep);
+		struct ieee80211_info_element *info_element =
+			(struct ieee80211_info_element *) &bss->extra.iep;
+
+		while ((length >= sizeof(*info_element)) && (num_null_ies < 2)) {
+			if (sizeof(*info_element) + info_element->len > length) {
+				/* Invalid element, don't continue parsing IE */
+				break;
+			}
+
+			switch (info_element->id) {
+			case MFIE_TYPE_SSID:
+				/* Two zero-length SSID elements
+				 * mean we're done parsing elements */
+				if (!info_element->len)
+					num_null_ies++;
+				break;
+
+			case MFIE_TYPE_GENERIC:
+				if (info_element->len >= 4 &&
+				    info_element->data[0] == 0x00 &&
+				    info_element->data[1] == 0x50 &&
+				    info_element->data[2] == 0xf2 &&
+				    info_element->data[3] == 0x01) {
+					iwe.cmd = IWEVGENIE;
+					iwe.u.data.length = min(info_element->len + 2,
+								  MAX_WPA_IE_LEN);
+					current_ev = iwe_stream_add_point(current_ev, end_buf,
+							&iwe, (char *) info_element);
+				}
+				break;
+
+			case MFIE_TYPE_RSN:
+				iwe.cmd = IWEVGENIE;
+				iwe.u.data.length = min(info_element->len + 2,
+							  MAX_WPA_IE_LEN);
+				current_ev = iwe_stream_add_point(current_ev, end_buf,
+						&iwe, (char *) info_element);
+				break;
+
+			default:
+				break;
+			}
+
+			length -= sizeof(*info_element) + info_element->len;
+			info_element =
+			    (struct ieee80211_info_element *)&info_element->
+			    data[info_element->len];
+		}
+	}
 	return current_ev;
 }
 
@@ -7521,7 +7638,7 @@
 	u32 *vals = stats_rid.vals;
 
 	/* Get stats out of the card */
-	clear_bit(JOB_WSTATS, &local->flags);
+	clear_bit(JOB_WSTATS, &local->jobs);
 	if (local->power.event) {
 		up(&local->sem);
 		return;
@@ -7565,10 +7682,10 @@
 {
 	struct airo_info *local =  dev->priv;
 
-	if (!test_bit(JOB_WSTATS, &local->flags)) {
+	if (!test_bit(JOB_WSTATS, &local->jobs)) {
 		/* Get stats out of the card if available */
 		if (down_trylock(&local->sem) != 0) {
-			set_bit(JOB_WSTATS, &local->flags);
+			set_bit(JOB_WSTATS, &local->jobs);
 			wake_up_interruptible(&local->thr_wait);
 		} else
 			airo_read_wireless_stats(local);



^ permalink raw reply

* Re: [PATCH] sir: switch to a workqueue
From: Christoph Hellwig @ 2006-04-15 16:37 UTC (permalink / raw)
  To: Martin Diehl; +Cc: Christoph Hellwig, Jean Tourrilhes, netdev
In-Reply-To: <Pine.LNX.4.44.0604151444521.19061-100000@notebook.home.mdiehl.de>

On Sat, Apr 15, 2006 at 04:24:15PM +0200, Martin Diehl wrote:
> 
> My only concern with this patch is this:

<..>

> Hm, queue_work might fail (like it was possible with irda_queue_request), 
> if work->pending is set. In that case, chances are we have a partially 
> configured irda device dangling around. The idea was to (re-)enable rx and 
> restore the xmit queue state on netdev so we can rely on the upper layers 
> to recover. I think without the fallback the netdev might become unuseable 
> until ifdown/ifup-cycle, if queue_work would ever fail.

queue_work doesn't fail if work->pending, it just noticed this
particular work_Struct is already beeing serviced and tells you that.
In the sir code that can't happen because the work_struct has ben
allocated and initialized a few lines above, so there's zero chance for
someone else to call queue_work on it concurrently.


^ permalink raw reply

* Re: [RFC] Geographical/regulatory information for ieee80211
From: Faidon Liambotis @ 2006-04-15 17:07 UTC (permalink / raw)
  To: netdev
In-Reply-To: <20060414152715.GC29461@instant802.com>

Jouni Malinen wrote:
> The maximum power would be quite useful--I would say required--part of
> regulatory domain information.. In other words, I would like to see the
> groups created in a way that would take differences in power limits into
> account. Without this, the groups will need to be re-created at some
> point in the future when IEEE 802.11d and IEEE 802.11h would like to use
> the same table.. In addition, flag of specifying indoor/outdoor/both
> would be a nice addition.
Speaking of 802.11h, for the table to be complete, it should specify
which protocol is allowed on a given channel.
EU members allow 802.11h (DFS/TPC) but not 802.11a. This is an important
distinction that, IMHO, should be included in a regulatory information
table.

Regards,
Faidon


^ permalink raw reply

* Re: [RFC] Geographical/regulatory information for ieee80211
From: Christoph Hellwig @ 2006-04-15 17:47 UTC (permalink / raw)
  To: Larry Finger; +Cc: netdev, jeffl
In-Reply-To: <443EF3E9.7050303@lwfinger.net>

On Thu, Apr 13, 2006 at 07:59:21PM -0500, Larry Finger wrote:
> I am planning on writing a new routine to be added to 
> net/ieee80211/ieee80211_geo.c that will populate an ieee80211_geo object 
> given a country code. The new routine will eliminate the need for each 
> driver to do their own.

This sounds like a generally good idea, but the question is:  do we want
this inside a kernel module or in userspace, either like the regulartory
daemon intel has (unfortunately in binary only form) or as a simple init
script.  I really don't want to recompile my kernel just because regulations
changed, and they seems to do that quite often.


^ permalink raw reply

* Re: skb diet
From: Andi Kleen @ 2006-04-15 19:22 UTC (permalink / raw)
  To: Hisham Kotry; +Cc: netdev
In-Reply-To: <baebb9a00604150417h1ffb3f97g102253dca0b3a53e@mail.gmail.com>

On Saturday 15 April 2006 13:17, Hisham Kotry wrote:
> I just read David S. Miller's skb redundancy page and in it he seems to suggest
> taking an approach similar to that of BSD's mbufs to reduce the skb's
> size. I was going to do some janitor work on the network stack and I
> thought that maybe I could start by adding a tag list to the skb
> similar to BSD's mbuf tags and change the code to store its private
> variables in tags rather than in skb->cb. That should save 40 bytes
> per skb and maybe later the tc and nf related variables could go in
> tags too. The transition shouldn't be hard for the most part, many
> users of skb->cb use macros like FRAG_CB(skb) so I could redefine
> those macros to search the tag-list for the appropriate tag and return
> its contents. Is this approach acceptable or is there a consensus on
> another approach?

Where would that tag list be stored if you want to remove the 
40 bytes of ->cb?

In general I don't think it will help much even if you find
a magic way to store it without using memory @) because
->cb is already private to each layer, so it's only the single 40 bytes
which is reused as needed.

You seem to think they accumulate which is not the case.

Linux 2.0 did something like this, but that was removed for good 
reasons. Now TCP always clones skbs before sending it out.

And optimizing for uncommon cases (not TCP) doesn't seem too useful.

-Andi

^ permalink raw reply

* Re: [patch 1/3] softmac: return -EAGAIN from getscan while scanning
From: Johannes Berg @ 2006-04-15 19:24 UTC (permalink / raw)
  To: jt; +Cc: Dan Williams, Pete Zaitcev, netdev, softmac-dev
In-Reply-To: <20060413161359.GA21074@bougret.hpl.hp.com>

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

On Thu, 2006-04-13 at 09:13 -0700, Jean Tourrilhes wrote:

> 	Yes, Dan is 100% correct.

Right, slightly later I posted a patch to do it that way. After everyone
else has discussed, do we agree to leave the patches as they are now?

johannes

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

^ permalink raw reply

* Re: [RFC PATCH] softmac: (v2) send WEXT assoc/disassoc events to userspace
From: Johannes Berg @ 2006-04-15 19:25 UTC (permalink / raw)
  To: Hans Fugal
  Cc: Larry Finger, netdev, softmac-dev, David Woodhouse, Dan Williams,
	bcm43xx-dev
In-Reply-To: <20060414010545.GA10636@falcon.fugal.net>

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

On Thu, 2006-04-13 at 19:05 -0600, Hans Fugal wrote:
> With the patch, wpa_supplicant is able to work properly for WEP and
> plaintext as tested with my bcm4306 (iBook), and the latest git.

Thanks, great. I have network-manager up and running too now (finally!)

> However, and this may not be related, I still must issue an 
> 
>     ip link set up eth1
> 
> after loading the bcm43xx module but before starting wpa_supplicant or
> it will not work. 

Right, that is expected behaviour right now until we come up with how to
handle this properly.

johannes

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

^ permalink raw reply

* Re: [RFC: 2.6 patch] net/irda/irias_object.c: remove unused exports
From: Samuel Ortiz @ 2006-04-15 19:35 UTC (permalink / raw)
  To: ext David S. Miller; +Cc: bunk, ext Jean Tourrilhes, netdev, linux-kernel
In-Reply-To: <20060415.022702.120267858.davem@davemloft.net>

On Sat, 15 Apr 2006, ext David S. Miller wrote:

> From: Samuel Ortiz <samuel.ortiz@nokia.com>
> Date: Sat, 15 Apr 2006 11:58:21 +0300 (EEST)
>
> > On Fri, 14 Apr 2006, ext Adrian Bunk wrote:
> >
> > > This patch removes the following unused EXPORT_SYMBOL's:
> > > - irias_find_attrib
> > > - irias_new_string_value
> > > - irias_new_octseq_value
> > >
> > > Signed-off-by: Adrian Bunk <bunk@stusta.de>
> > Looks good to me.
> >
> > Signed-off-by: Samuel Ortiz <samuel.ortiz@nokia.com>
>
> Sam, just add this to your IRDA queue.  Ok?
Sure, I will.

^ permalink raw reply

* r8169 locks up in 2.6.16.5
From: Thomas A. Oehser @ 2006-04-15 20:47 UTC (permalink / raw)
  To: netdev


Hi,

The r8169 driver seems not to be able to handle high loads?

On a dual Athlon 2600+ MP with 2GB RAM, and nothing else running.

I'm doing:

	nc -l -p 12345|buffer|cpio -iuvmdB

On the other machine, also with a gigabit card, I'm doing:

	find .|cpio -o -Hnewc -B|nc 192.168.111.1 12345

It works fine- for about 10 minutes- then, suddenly one of 3 things happens-
even if I stop the high-throughput transfer and quiescse everything.....

- Pings to the router take 9000ms instead of <1 ms (ifconfig down/up fixes it)
- or, it completely stops working, but ifconfig down/up makes it work again
- or, if iptables is natting, sometimes itg completely crashdump oopses

None of these problems occurs using the other NIC, an eepro100 or something.

Should I just give these cards away and forget I ever heard of RealTeK?

Is it known that this driver, or this card, or the comgination, is unstable?

Note, I have another machine using r8169, with some other OS- it doesn't fail.


-Tom

-- 
May 4, 1970: Alison Krause, Jeffrey Miller, Sandra Scheuer, William Schroeder.

^ permalink raw reply

* Re: [patch 1/3] softmac: return -EAGAIN from getscan while scanning
From: Dan Williams @ 2006-04-15 21:27 UTC (permalink / raw)
  To: Johannes Berg; +Cc: jt, Pete Zaitcev, netdev, softmac-dev
In-Reply-To: <1145129056.6560.0.camel@localhost>

On Sat, 2006-04-15 at 21:24 +0200, Johannes Berg wrote:
> On Thu, 2006-04-13 at 09:13 -0700, Jean Tourrilhes wrote:
> 
> > 	Yes, Dan is 100% correct.
> 
> Right, slightly later I posted a patch to do it that way. After everyone
> else has discussed, do we agree to leave the patches as they are now?

Current patch set looks good to me.

Dan



^ permalink raw reply

* Re: [NFS] [RFC: 2.6 patch] net/sunrpc/: possible cleanups
From: Adrian Bunk @ 2006-04-15 21:32 UTC (permalink / raw)
  To: Lever, Charles
  Cc: David Miller, neilb, trond.myklebust, linux-kernel, nfs, netdev
In-Reply-To: <044B81DE141D7443BCE91E8F44B3C1E288E4FC@exsvl02.hq.netapp.com>

On Thu, Oct 06, 2005 at 07:13:14AM -0700, Lever, Charles wrote:

> actually, can we hold off on this change?  the RPC transport switch will
> eventually need most of those EXPORT_SYMBOLs.
>...
> > This patch was already sent on:
> > - 30 May 2005
> > - 7 May 2005
>...

One year has passed since I sent this patch the first time, and with the 
exception that it needs re-diff'ing it still applies.

Charles, are the changes you are talking about that might need them 
available in the very near future?

If not, I'd suggest to remove them and re-add them when code using them 
will be included in the kernel (reverting parts or all of my patch 
should be trivial).

This way, they'll not continue to uselessly making the kernel image 
larger.

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed


^ permalink raw reply

* Re: [patch] ipv4: initialize arp_tbl rw lock
From: Heiko Carstens @ 2006-04-15 23:00 UTC (permalink / raw)
  To: David S. Miller
  Cc: shemminger, jgarzik, akpm, netdev, linux-kernel, fpavlic, davem
In-Reply-To: <20060415.003457.103031290.davem@davemloft.net>

> > callchain: inet_init() -> inet_register_protosw() -> synchronize_net()
> 
> The problem can't be rcu_init(), that gets done very early
> in init/main.c
> 
> Maybe it's some timer or something else specific to s390?
> 
> It could also be that there's perhaps nothing to context
> switch to, thus the RCU takes forever to "happen".

Changing inet_init to fs_initcall() moves it way up the chain...
There are quite a few __initcall()s (way is this mapped to
device_initcall()?) and module_init()s in places where I would
never have expected them (e.g. kernel/).
After all the dependencies are anything but obvious to me. The
only obvious solution which fixes my problem would be to convert
qeth's module_init() to late_initcall().

^ 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