Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 1/6] bnx2: Fix excessive stack usage
From: Michael Chan @ 2005-05-24  4:29 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: davem, netdev
In-Reply-To: <429286A3.1060606@pobox.com>

On Mon, 2005-05-23 at 21:42 -0400, Jeff Garzik wrote:
> 
> memleak -- you need to free good_mbuf.
> 

Oops, here is the revised patch with kfree(). Thanks.

Fix excessive stack usage in bnx2_alloc_bad_rbuf() by replacing local
variable array with kmalloc array. Also changed function to return error
code, and changed some of the callers to check for the return code.

Spotted by Jeff Garzik.

Signed-off-by: Michael Chan <mchan@broadcom.com>

diff -Nru 10/drivers/net/bnx2.c 11/drivers/net/bnx2.c
--- 10/drivers/net/bnx2.c	2005-05-23 10:20:02.000000000 -0700
+++ 11/drivers/net/bnx2.c	2005-05-23 21:13:46.000000000 -0700
@@ -1138,13 +1138,20 @@
 	}
 }
 
-static void
+static int
 bnx2_alloc_bad_rbuf(struct bnx2 *bp)
 {
-	u16 good_mbuf[512];
+	u16 *good_mbuf;
 	u32 good_mbuf_cnt;
 	u32 val;
 
+	good_mbuf = kmalloc(512 * sizeof(u16), GFP_KERNEL);
+	if (good_mbuf == NULL) {
+		printk(KERN_ERR PFX "Failed to allocate memory in "
+				    "bnx2_alloc_bad_rbuf\n");
+		return -ENOMEM;
+	}
+
 	REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
 		BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE);
 
@@ -1178,6 +1185,8 @@
 
 		REG_WR_IND(bp, BNX2_RBUF_FW_BUF_FREE, val);
 	}
+	kfree(good_mbuf);
+	return 0;
 }
 
 static void
@@ -2710,7 +2719,7 @@
 bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
 {
 	u32 val;
-	int i;
+	int i, rc = 0;
 
 	/* Wait for the current PCI transaction to complete before
 	 * issuing a reset. */
@@ -2785,10 +2794,10 @@
 		REG_WR(bp, BNX2_MISC_VREG_CONTROL, 0x000000fa);
 
 		/* Remove bad rbuf memory from the free pool. */
-		bnx2_alloc_bad_rbuf(bp);
+		rc = bnx2_alloc_bad_rbuf(bp);
 	}
 
-	return 0;
+	return rc;
 }
 
 static int
@@ -3097,8 +3106,13 @@
 static int
 bnx2_reset_nic(struct bnx2 *bp, u32 reset_code)
 {
-	bnx2_reset_chip(bp, reset_code);
+	int rc;
+
+	rc = bnx2_reset_chip(bp, reset_code);
 	bnx2_free_skbs(bp);
+	if (rc)
+		return rc;
+
 	bnx2_init_chip(bp);
 	bnx2_init_tx_ring(bp);
 	bnx2_init_rx_ring(bp);
@@ -3108,7 +3122,11 @@
 static int
 bnx2_init_nic(struct bnx2 *bp)
 {
-	bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET);
+	int rc;
+
+	if ((rc = bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET)) != 0)
+		return rc;
+
 	bnx2_init_phy(bp);
 	bnx2_set_link(bp);
 	return 0;

^ permalink raw reply

* Re: [patch 2.6.12-rc4 1/1] tulip: add return to ULI526X clause in tulip_mdio_write
From: Jeff Garzik @ 2005-05-24  4:26 UTC (permalink / raw)
  To: John W. Linville; +Cc: netdev, Clear.Zhang
In-Reply-To: <20050518174132.GB16148@tuxdriver.com>

applied

^ permalink raw reply

* [XFRM] Call dst_check() with appropriate cookie
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2005-05-24  3:49 UTC (permalink / raw)
  To: davem; +Cc: netdev

From: Kazunori Miyazawa <kazunori@miyazawa.org>

[XFRM] Call dst_check() with appropriate cookie.

This fixes infinite loop issue with IPv6 tunnel mode.

Signed-off-by: Kazunori Miyazawa <kazunori@miyazawa.org>
Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>

diff -ruN linux-2.6.12-rc4-git7/include/net/xfrm.h linux-2.6.12-rc4-git7-ipv6ipsec/include/net/xfrm.h
--- linux-2.6.12-rc4-git7/include/net/xfrm.h	2005-05-24 00:15:26.000000000 +0900
+++ linux-2.6.12-rc4-git7-ipv6ipsec/include/net/xfrm.h	2005-05-24 00:19:24.000000000 +0900
@@ -515,6 +515,8 @@
 	struct dst_entry *route;
 	u32 route_mtu_cached;
 	u32 child_mtu_cached;
+	u32 route_cookie;
+	u32 path_cookie;
 };

 static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
diff -ruN linux-2.6.12-rc4-git7/net/ipv4/xfrm4_policy.c linux-2.6.12-rc4-git7-ipv6ipsec/net/ipv4/xfrm4_policy.c
--- linux-2.6.12-rc4-git7/net/ipv4/xfrm4_policy.c	2005-05-24 00:15:27.000000000 +0900
+++ linux-2.6.12-rc4-git7-ipv6ipsec/net/ipv4/xfrm4_policy.c	2005-05-24 00:20:29.000000000 +0900
@@ -95,6 +95,7 @@

 		xdst = (struct xfrm_dst *)dst1;
 		xdst->route = &rt->u.dst;
+		xdst->route_cookie = 0;

 		dst1->next = dst_prev;
 		dst_prev = dst1;
@@ -119,6 +120,7 @@

 	dst_prev->child = &rt->u.dst;
 	dst->path = &rt->u.dst;
+	((struct xfrm_dst*)dst)->path_cookie = 0;

 	*dst_p = dst;
 	dst = dst_prev;
diff -ruN linux-2.6.12-rc4-git7/net/ipv6/xfrm6_policy.c linux-2.6.12-rc4-git7-ipv6ipsec/net/ipv6/xfrm6_policy.c
--- linux-2.6.12-rc4-git7/net/ipv6/xfrm6_policy.c	2005-05-24 00:15:27.000000000 +0900
+++ linux-2.6.12-rc4-git7-ipv6ipsec/net/ipv6/xfrm6_policy.c	2005-05-24 00:22:15.000000000 +0900
@@ -113,6 +113,7 @@

 		xdst = (struct xfrm_dst *)dst1;
 		xdst->route = &rt->u.dst;
+		xdst->route_cookie = rt->rt6i_node->fn_sernum;

 		dst1->next = dst_prev;
 		dst_prev = dst1;
@@ -137,6 +138,7 @@

 	dst_prev->child = &rt->u.dst;
 	dst->path = &rt->u.dst;
+	((struct xfrm_dst*)dst)->path_cookie = rt->rt6i_node->fn_sernum;

 	*dst_p = dst;
 	dst = dst_prev;
diff -ruN linux-2.6.12-rc4-git7/net/xfrm/xfrm_policy.c linux-2.6.12-rc4-git7-ipv6ipsec/net/xfrm/xfrm_policy.c
--- linux-2.6.12-rc4-git7/net/xfrm/xfrm_policy.c	2005-05-24 00:15:28.000000000 +0900
+++ linux-2.6.12-rc4-git7-ipv6ipsec/net/xfrm/xfrm_policy.c	2005-05-24 00:22:57.000000000 +0900
@@ -1136,7 +1136,7 @@
 	struct xfrm_dst *last;
 	u32 mtu;

-	if (!dst_check(dst->path, 0) ||
+	if (!dst_check(dst->path, ((struct xfrm_dst*)dst)->path_cookie) ||
 	    (dst->dev && !netif_running(dst->dev)))
 		return 0;

@@ -1156,7 +1156,7 @@
 			xdst->child_mtu_cached = mtu;
 		}

-		if (!dst_check(xdst->route, 0))
+		if (!dst_check(xdst->route, xdst->route_cookie))
 			return 0;
 		mtu = dst_mtu(xdst->route);
 		if (xdst->route_mtu_cached != mtu) {

-- 
YOSHIFUJI Hideaki @ USAGI Project  <yoshfuji@linux-ipv6.org>
GPG-FP  : 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA

^ permalink raw reply

* Re: [PATCH] Super TSO v3
From: David S. Miller @ 2005-05-24  2:38 UTC (permalink / raw)
  To: herbert; +Cc: netdev
In-Reply-To: <20050524023256.GA29242@gondor.apana.org.au>

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Tue, 24 May 2005 12:32:57 +1000

> True, the Nagle algorithm itself aims to do something different
> from this function.  However, the act of turning Nagle off is
> an indication that the application wants to minimise the latency
> by sending things out ASAP.  So we should either respect that
> here by not delaying the packets to increase the TSO size, or
> we'll need a new socket option to do that for TSO.

Sure, we can check tp->nonagle to turn this deferring off.

But, I bet there are folks who want traditional Nagle turned
off, yet TSO chunking enabled.

^ permalink raw reply

* Re: [PATCH] Super TSO v3
From: Herbert Xu @ 2005-05-24  2:32 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev
In-Reply-To: <20050523.192917.48530622.davem@davemloft.net>

On Mon, May 23, 2005 at 07:29:17PM -0700, David S. Miller wrote:
>
> > Should we skip this step if the socket has Nagle turned off?
> 
> No, that Nagle is trying to achieve something different (optimize
> request/response type communication) compared to what we're doing
> here (optimizing the number of transmit calls per byte during a
> bulk transfer, without allowing the congestion window to empty
> too much).

True, the Nagle algorithm itself aims to do something different
from this function.  However, the act of turning Nagle off is
an indication that the application wants to minimise the latency
by sending things out ASAP.  So we should either respect that
here by not delaying the packets to increase the TSO size, or
we'll need a new socket option to do that for TSO.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH] Super TSO v3
From: David S. Miller @ 2005-05-24  2:29 UTC (permalink / raw)
  To: herbert; +Cc: netdev
In-Reply-To: <20050524003208.GA25778@gondor.apana.org.au>

From: Herbert Xu <herbert@gondor.apana.org.au>
Subject: Re: [PATCH] Super TSO v3
Date: Tue, 24 May 2005 10:32:08 +1000

> On Mon, May 23, 2005 at 07:19:43PM +0000, David S. Miller wrote:
> > 
> > The guts of the logic is in tcp_tso_should_defer().  And
> > when dealing with a TSO frame, tcp_write_xmit() calls
> > this instead of tcp_nagle_test().  So you can view this
> > deferral as a sort of "TSO Nagle".
> 
> Should we skip this step if the socket has Nagle turned off?

No, that Nagle is trying to achieve something different (optimize
request/response type communication) compared to what we're doing
here (optimizing the number of transmit calls per byte during a
bulk transfer, without allowing the congestion window to empty
too much).

> Also why are we doing this check in tcp_push_one? The only
> way we can get there is if the TSO goal has been reached
> or there is out-of-band stuff to send.

Good point, that copy of the test can be removed.

^ permalink raw reply

* Re: [PATCH 0/6] bnx2: Misc fixes
From: Jeff Garzik @ 2005-05-24  1:48 UTC (permalink / raw)
  To: Michael Chan; +Cc: davem, netdev
In-Reply-To: <1116892439.4908.1.camel@rh4>

Michael Chan wrote:
> These patches fix the following problems spotted by Jeff Garzik. Thanks
> Jeff.

Thanks for fixing them up.

I ACK patches #2 - #6.  Sent a comment related to #1 in a separate email.

	Jeff

^ permalink raw reply

* Re: [PATCH 1/6] bnx2: Fix excessive stack usage
From: Jeff Garzik @ 2005-05-24  1:42 UTC (permalink / raw)
  To: Michael Chan; +Cc: davem, netdev
In-Reply-To: <1116894307.4908.28.camel@rh4>

Michael Chan wrote:
> diff -Nru 10/drivers/net/bnx2.c 11/drivers/net/bnx2.c
> --- 10/drivers/net/bnx2.c	2005-05-23 10:20:02.000000000 -0700
> +++ 11/drivers/net/bnx2.c	2005-05-23 10:20:20.000000000 -0700
> @@ -1138,13 +1138,20 @@
>  	}
>  }
>  
> -static void
> +static int
>  bnx2_alloc_bad_rbuf(struct bnx2 *bp)
>  {
> -	u16 good_mbuf[512];
> +	u16 *good_mbuf;
>  	u32 good_mbuf_cnt;
>  	u32 val;
>  
> +	good_mbuf = kmalloc(512 * sizeof(u16), GFP_KERNEL);
> +	if (good_mbuf == NULL) {
> +		printk(KERN_ERR PFX "Failed to allocate memory in "
> +				    "bnx2_alloc_bad_rbuf\n");
> +		return -ENOMEM;
> +	}
> +
>  	REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
>  		BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE);
>  
> @@ -1178,6 +1185,7 @@
>  
>  		REG_WR_IND(bp, BNX2_RBUF_FW_BUF_FREE, val);
>  	}
> +	return 0;
>  }
>  
>  static void

memleak -- you need to free good_mbuf.

	Jeff

^ permalink raw reply

* [PATCH 2/2][NET] rename struct tcp_listen_opt to struct listen_sock
From: Arnaldo Carvalho de Melo @ 2005-05-24  1:17 UTC (permalink / raw)
  To: David S.Miller; +Cc: netdev

Hi David,

        Please consider pulling into your net-2.6.13 pending tree from:

rsync://rsync.kernel.org/pub/scm/linux/kernel/git/acme/net-2.6.13.git
	
Best Regards,

- Arnaldo

tree b1aabc6ec772af37643e4eab8d35a48f5ca5d799
parent a48a17a6700bb4e6eed677e25422adf478f85c4d
author Arnaldo Carvalho de Melo <acme@ghostprotocols.net> 1113624884 -0300
committer Arnaldo Carvalho de Melo <acme@ghostprotocols.net> 1116888488 -0300

[NET] rename struct tcp_listen_opt to struct listen_sock

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>

------------------------------------------------------------------------------

 include/net/request_sock.h |   16 ++++++++--------
 net/core/request_sock.c    |    4 ++--
 net/ipv4/tcp.c             |    2 +-
 net/ipv4/tcp_diag.c        |    2 +-
 net/ipv4/tcp_ipv4.c        |    4 ++--
 net/ipv4/tcp_timer.c       |    2 +-
 net/ipv6/tcp_ipv6.c        |    4 ++--
 7 files changed, 17 insertions(+), 17 deletions(-)

------------------------------------------------------------------------------

diff --git a/include/net/request_sock.h b/include/net/request_sock.h
--- a/include/net/request_sock.h
+++ b/include/net/request_sock.h
@@ -78,11 +78,11 @@ static inline void reqsk_free(struct req
 
 extern int sysctl_max_syn_backlog;
 
-/** struct tcp_listen_opt - listen state
+/** struct listen_sock - listen state
  *
  * @max_qlen_log - log_2 of maximal queued SYNs/REQUESTs
  */
-struct tcp_listen_opt {
+struct listen_sock {
 	u8			max_qlen_log;
 	/* 3 bytes hole, try to use */
 	int			qlen;
@@ -111,15 +111,15 @@ struct request_sock_queue {
 	struct request_sock	*rskq_accept_head;
 	struct request_sock	*rskq_accept_tail;
 	rwlock_t		syn_wait_lock;
-	struct tcp_listen_opt	*listen_opt;
+	struct listen_sock	*listen_opt;
 };
 
 extern int reqsk_queue_alloc(struct request_sock_queue *queue,
 			     const int nr_table_entries);
 
-static inline struct tcp_listen_opt *reqsk_queue_yank_listen_sk(struct request_sock_queue *queue)
+static inline struct listen_sock *reqsk_queue_yank_listen_sk(struct request_sock_queue *queue)
 {
-	struct tcp_listen_opt *lopt;
+	struct listen_sock *lopt;
 
 	write_lock_bh(&queue->syn_wait_lock);
 	lopt = queue->listen_opt;
@@ -203,7 +203,7 @@ static inline struct sock *reqsk_queue_g
 static inline int reqsk_queue_removed(struct request_sock_queue *queue,
 				      struct request_sock *req)
 {
-	struct tcp_listen_opt *lopt = queue->listen_opt;
+	struct listen_sock *lopt = queue->listen_opt;
 
 	if (req->retrans == 0)
 		--lopt->qlen_young;
@@ -213,7 +213,7 @@ static inline int reqsk_queue_removed(st
 
 static inline int reqsk_queue_added(struct request_sock_queue *queue)
 {
-	struct tcp_listen_opt *lopt = queue->listen_opt;
+	struct listen_sock *lopt = queue->listen_opt;
 	const int prev_qlen = lopt->qlen;
 
 	lopt->qlen_young++;
@@ -240,7 +240,7 @@ static inline void reqsk_queue_hash_req(
 					u32 hash, struct request_sock *req,
 					unsigned timeout)
 {
-	struct tcp_listen_opt *lopt = queue->listen_opt;
+	struct listen_sock *lopt = queue->listen_opt;
 
 	req->expires = jiffies + timeout;
 	req->retrans = 0;
diff --git a/net/core/request_sock.c b/net/core/request_sock.c
--- a/net/core/request_sock.c
+++ b/net/core/request_sock.c
@@ -21,9 +21,9 @@
 int reqsk_queue_alloc(struct request_sock_queue *queue,
 		      const int nr_table_entries)
 {
-	const int lopt_size = sizeof(struct tcp_listen_opt) +
+	const int lopt_size = sizeof(struct listen_sock) +
 			      nr_table_entries * sizeof(struct request_sock *);
-	struct tcp_listen_opt *lopt = kmalloc(lopt_size, GFP_KERNEL);
+	struct listen_sock *lopt = kmalloc(lopt_size, GFP_KERNEL);
 
 	if (lopt == NULL)
 		return -ENOMEM;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -499,7 +499,7 @@ int tcp_listen_start(struct sock *sk)
 static void tcp_listen_stop (struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_listen_opt *lopt;
+	struct listen_sock *lopt;
 	struct request_sock *acc_req;
 	struct request_sock *req;
 	int i;
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c
--- a/net/ipv4/tcp_diag.c
+++ b/net/ipv4/tcp_diag.c
@@ -514,7 +514,7 @@ static int tcpdiag_dump_reqs(struct sk_b
 	struct tcpdiag_entry entry;
 	struct tcpdiagreq *r = NLMSG_DATA(cb->nlh);
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_listen_opt *lopt;
+	struct listen_sock *lopt;
 	struct rtattr *bc = NULL;
 	struct inet_sock *inet = inet_sk(sk);
 	int j, s_j;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -874,7 +874,7 @@ static struct request_sock *tcp_v4_searc
 					      __u16 rport,
 					      __u32 raddr, __u32 laddr)
 {
-	struct tcp_listen_opt *lopt = tp->accept_queue.listen_opt;
+	struct listen_sock *lopt = tp->accept_queue.listen_opt;
 	struct request_sock *req, **prev;
 
 	for (prev = &lopt->syn_table[tcp_v4_synq_hash(raddr, rport, lopt->hash_rnd)];
@@ -898,7 +898,7 @@ static struct request_sock *tcp_v4_searc
 static void tcp_v4_synq_add(struct sock *sk, struct request_sock *req)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_listen_opt *lopt = tp->accept_queue.listen_opt;
+	struct listen_sock *lopt = tp->accept_queue.listen_opt;
 	u32 h = tcp_v4_synq_hash(inet_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd);
 
 	reqsk_queue_hash_req(&tp->accept_queue, h, req, TCP_TIMEOUT_INIT);
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -464,7 +464,7 @@ out_unlock:
 static void tcp_synack_timer(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_listen_opt *lopt = tp->accept_queue.listen_opt;
+	struct listen_sock *lopt = tp->accept_queue.listen_opt;
 	int max_retries = tp->syn_retries ? : sysctl_tcp_synack_retries;
 	int thresh = max_retries;
 	unsigned long now = jiffies;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -401,7 +401,7 @@ static struct request_sock *tcp_v6_searc
 					      struct in6_addr *laddr,
 					      int iif)
 {
-	struct tcp_listen_opt *lopt = tp->accept_queue.listen_opt;
+	struct listen_sock *lopt = tp->accept_queue.listen_opt;
 	struct request_sock *req, **prev;  
 
 	for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport, lopt->hash_rnd)];
@@ -1267,7 +1267,7 @@ static struct sock *tcp_v6_hnd_req(struc
 static void tcp_v6_synq_add(struct sock *sk, struct request_sock *req)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_listen_opt *lopt = tp->accept_queue.listen_opt;
+	struct listen_sock *lopt = tp->accept_queue.listen_opt;
 	u32 h = tcp_v6_synq_hash(&tcp6_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd);
 
 	reqsk_queue_hash_req(&tp->accept_queue, h, req, TCP_TIMEOUT_INIT);

^ permalink raw reply

* [PATCH 1/2][NET] Generalise tcp_listen_opt
From: Arnaldo Carvalho de Melo @ 2005-05-24  1:16 UTC (permalink / raw)
  To: David S.Miller; +Cc: netdev

Hi David,

	Please consider pulling into your net-2.6.13 pending tree from:

rsync://rsync.kernel.org/pub/scm/linux/kernel/git/acme/net-2.6.13.git

	The bksend like output below was done using this script, people
starting to use git may find it useful :-)

http://dccp.ghostprotocols.net:81/acme-git-send-changeset

Best Regards,

- Arnaldo

tree f416accfe16809dce40f34fb711d42a67aea892d
parent 0642cf1e6afa649d8d9a9d3dc7275ceebb038ae0
author Arnaldo Carvalho de Melo <acme@ghostprotocols.net> 1113623934 -0300
committer Arnaldo Carvalho de Melo <acme@ghostprotocols.net> 1116886806 -0300

[NET] Generalise tcp_listen_opt

This chunks out the accept_queue and tcp_listen_opt code and moves them to
net/core/request_sock.c and include/net/request_sock.h, to make it useful for
other transport protocols, DCCP being the first one to use it.

Next patches will rename tcp_listen_opt to accept_sock and remove the inline
tcp functions that just call a reqsk_queue_ function.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>

------------------------------------------------------------------------------

 include/linux/tcp.h        |   17 ----
 include/net/request_sock.h |  178 +++++++++++++++++++++++++++++++++++++++++++++
 include/net/tcp.h          |   46 ++---------
 net/core/Makefile          |    3 
 net/core/request_sock.c    |   48 ++++++++++++
 net/ipv4/tcp.c             |   67 +++++-----------
 net/ipv4/tcp_diag.c        |    6 -
 net/ipv4/tcp_ipv4.c        |   32 +++-----
 net/ipv4/tcp_minisocks.c   |    6 -
 net/ipv4/tcp_timer.c       |   10 --
 net/ipv6/tcp_ipv6.c        |   14 ---
 11 files changed, 281 insertions(+), 146 deletions(-)

------------------------------------------------------------------------------

diff --git a/include/linux/tcp.h b/include/linux/tcp.h
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -379,22 +379,7 @@ struct tcp_sock {
 
 	__u32	total_retrans;	/* Total retransmits for entire connection */
 
-	/* The syn_wait_lock is necessary only to avoid proc interface having
-	 * to grab the main lock sock while browsing the listening hash
-	 * (otherwise it's deadlock prone).
-	 * This lock is acquired in read mode only from listening_get_next()
-	 * and it's acquired in write mode _only_ from code that is actively
-	 * changing the syn_wait_queue. All readers that are holding
-	 * the master sock lock don't need to grab this lock in read mode
-	 * too as the syn_wait_queue writes are always protected from
-	 * the main sock lock.
-	 */
-	rwlock_t		syn_wait_lock;
-	struct tcp_listen_opt	*listen_opt;
-
-	/* FIFO of established children */
-	struct request_sock	*accept_queue;
-	struct request_sock	*accept_queue_tail;
+	struct request_sock_queue accept_queue; /* FIFO of established children */
 
 	unsigned int		keepalive_time;	  /* time before keep alive takes place */
 	unsigned int		keepalive_intvl;  /* time interval between keep alive probes */
diff --git a/include/net/request_sock.h b/include/net/request_sock.h
--- a/include/net/request_sock.h
+++ b/include/net/request_sock.h
@@ -16,7 +16,9 @@
 #define _REQUEST_SOCK_H
 
 #include <linux/slab.h>
+#include <linux/spinlock.h>
 #include <linux/types.h>
+
 #include <net/sock.h>
 
 struct request_sock;
@@ -74,4 +76,180 @@ static inline void reqsk_free(struct req
 	__reqsk_free(req);
 }
 
+extern int sysctl_max_syn_backlog;
+
+/** struct tcp_listen_opt - listen state
+ *
+ * @max_qlen_log - log_2 of maximal queued SYNs/REQUESTs
+ */
+struct tcp_listen_opt {
+	u8			max_qlen_log;
+	/* 3 bytes hole, try to use */
+	int			qlen;
+	int			qlen_young;
+	int			clock_hand;
+	u32			hash_rnd;
+	struct request_sock	*syn_table[0];
+};
+
+/** struct request_sock_queue - queue of request_socks
+ *
+ * @rskq_accept_head - FIFO head of established children
+ * @rskq_accept_tail - FIFO tail of established children
+ * @syn_wait_lock - serializer
+ *
+ * %syn_wait_lock is necessary only to avoid proc interface having to grab the main
+ * lock sock while browsing the listening hash (otherwise it's deadlock prone).
+ *
+ * This lock is acquired in read mode only from listening_get_next() seq_file
+ * op and it's acquired in write mode _only_ from code that is actively
+ * changing rskq_accept_head. All readers that are holding the master sock lock
+ * don't need to grab this lock in read mode too as rskq_accept_head. writes
+ * are always protected from the main sock lock.
+ */
+struct request_sock_queue {
+	struct request_sock	*rskq_accept_head;
+	struct request_sock	*rskq_accept_tail;
+	rwlock_t		syn_wait_lock;
+	struct tcp_listen_opt	*listen_opt;
+};
+
+extern int reqsk_queue_alloc(struct request_sock_queue *queue,
+			     const int nr_table_entries);
+
+static inline struct tcp_listen_opt *reqsk_queue_yank_listen_sk(struct request_sock_queue *queue)
+{
+	struct tcp_listen_opt *lopt;
+
+	write_lock_bh(&queue->syn_wait_lock);
+	lopt = queue->listen_opt;
+	queue->listen_opt = NULL;
+	write_unlock_bh(&queue->syn_wait_lock);
+
+	return lopt;
+}
+
+static inline void reqsk_queue_destroy(struct request_sock_queue *queue)
+{
+	kfree(reqsk_queue_yank_listen_sk(queue));
+}
+
+static inline struct request_sock *
+	reqsk_queue_yank_acceptq(struct request_sock_queue *queue)
+{
+	struct request_sock *req = queue->rskq_accept_head;
+
+	queue->rskq_accept_head = queue->rskq_accept_head = NULL;
+	return req;
+}
+
+static inline int reqsk_queue_empty(struct request_sock_queue *queue)
+{
+	return queue->rskq_accept_head == NULL;
+}
+
+static inline void reqsk_queue_unlink(struct request_sock_queue *queue,
+				      struct request_sock *req,
+				      struct request_sock **prev_req)
+{
+	write_lock(&queue->syn_wait_lock);
+	*prev_req = req->dl_next;
+	write_unlock(&queue->syn_wait_lock);
+}
+
+static inline void reqsk_queue_add(struct request_sock_queue *queue,
+				   struct request_sock *req,
+				   struct sock *parent,
+				   struct sock *child)
+{
+	req->sk = child;
+	sk_acceptq_added(parent);
+
+	if (queue->rskq_accept_head == NULL)
+		queue->rskq_accept_head = req;
+	else
+		queue->rskq_accept_tail->dl_next = req;
+
+	queue->rskq_accept_tail = req;
+	req->dl_next = NULL;
+}
+
+static inline struct request_sock *reqsk_queue_remove(struct request_sock_queue *queue)
+{
+	struct request_sock *req = queue->rskq_accept_head;
+
+	BUG_TRAP(req != NULL);
+
+	queue->rskq_accept_head = req->dl_next;
+	if (queue->rskq_accept_head == NULL)
+		queue->rskq_accept_tail = NULL;
+
+	return req;
+}
+
+static inline struct sock *reqsk_queue_get_child(struct request_sock_queue *queue,
+						 struct sock *parent)
+{
+	struct request_sock *req = reqsk_queue_remove(queue);
+	struct sock *child = req->sk;
+
+	BUG_TRAP(child != NULL);
+
+	sk_acceptq_removed(parent);
+	__reqsk_free(req);
+	return child;
+}
+
+static inline int reqsk_queue_removed(struct request_sock_queue *queue,
+				      struct request_sock *req)
+{
+	struct tcp_listen_opt *lopt = queue->listen_opt;
+
+	if (req->retrans == 0)
+		--lopt->qlen_young;
+
+	return --lopt->qlen;
+}
+
+static inline int reqsk_queue_added(struct request_sock_queue *queue)
+{
+	struct tcp_listen_opt *lopt = queue->listen_opt;
+	const int prev_qlen = lopt->qlen;
+
+	lopt->qlen_young++;
+	lopt->qlen++;
+	return prev_qlen;
+}
+
+static inline int reqsk_queue_len(struct request_sock_queue *queue)
+{
+	return queue->listen_opt != NULL ? queue->listen_opt->qlen : 0;
+}
+
+static inline int reqsk_queue_len_young(struct request_sock_queue *queue)
+{
+	return queue->listen_opt->qlen_young;
+}
+
+static inline int reqsk_queue_is_full(struct request_sock_queue *queue)
+{
+	return queue->listen_opt->qlen >> queue->listen_opt->max_qlen_log;
+}
+
+static inline void reqsk_queue_hash_req(struct request_sock_queue *queue,
+					u32 hash, struct request_sock *req,
+					unsigned timeout)
+{
+	struct tcp_listen_opt *lopt = queue->listen_opt;
+
+	req->expires = jiffies + timeout;
+	req->retrans = 0;
+	req->sk = NULL;
+	req->dl_next = lopt->syn_table[hash];
+
+	write_lock(&queue->syn_wait_lock);
+	lopt->syn_table[hash] = req;
+	write_unlock(&queue->syn_wait_lock);
+}
+
 #endif /* _REQUEST_SOCK_H */
diff --git a/include/net/tcp.h b/include/net/tcp.h
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1686,71 +1686,41 @@ static inline int tcp_full_space(const s
 static inline void tcp_acceptq_queue(struct sock *sk, struct request_sock *req,
 					 struct sock *child)
 {
-	struct tcp_sock *tp = tcp_sk(sk);
-
-	req->sk = child;
-	sk_acceptq_added(sk);
-
-	if (!tp->accept_queue_tail) {
-		tp->accept_queue = req;
-	} else {
-		tp->accept_queue_tail->dl_next = req;
-	}
-	tp->accept_queue_tail = req;
-	req->dl_next = NULL;
+	reqsk_queue_add(&tcp_sk(sk)->accept_queue, req, sk, child);
 }
 
-struct tcp_listen_opt
-{
-	u8			max_qlen_log;	/* log_2 of maximal queued SYNs */
-	int			qlen;
-	int			qlen_young;
-	int			clock_hand;
-	u32			hash_rnd;
-	struct request_sock	*syn_table[TCP_SYNQ_HSIZE];
-};
-
 static inline void
 tcp_synq_removed(struct sock *sk, struct request_sock *req)
 {
-	struct tcp_listen_opt *lopt = tcp_sk(sk)->listen_opt;
-
-	if (--lopt->qlen == 0)
+	if (reqsk_queue_removed(&tcp_sk(sk)->accept_queue, req) == 0)
 		tcp_delete_keepalive_timer(sk);
-	if (req->retrans == 0)
-		lopt->qlen_young--;
 }
 
 static inline void tcp_synq_added(struct sock *sk)
 {
-	struct tcp_listen_opt *lopt = tcp_sk(sk)->listen_opt;
-
-	if (lopt->qlen++ == 0)
+	if (reqsk_queue_added(&tcp_sk(sk)->accept_queue) == 0)
 		tcp_reset_keepalive_timer(sk, TCP_TIMEOUT_INIT);
-	lopt->qlen_young++;
 }
 
 static inline int tcp_synq_len(struct sock *sk)
 {
-	return tcp_sk(sk)->listen_opt->qlen;
+	return reqsk_queue_len(&tcp_sk(sk)->accept_queue);
 }
 
 static inline int tcp_synq_young(struct sock *sk)
 {
-	return tcp_sk(sk)->listen_opt->qlen_young;
+	return reqsk_queue_len_young(&tcp_sk(sk)->accept_queue);
 }
 
 static inline int tcp_synq_is_full(struct sock *sk)
 {
-	return tcp_synq_len(sk) >> tcp_sk(sk)->listen_opt->max_qlen_log;
+	return reqsk_queue_is_full(&tcp_sk(sk)->accept_queue);
 }
 
 static inline void tcp_synq_unlink(struct tcp_sock *tp, struct request_sock *req,
-				       struct request_sock **prev)
+				   struct request_sock **prev)
 {
-	write_lock(&tp->syn_wait_lock);
-	*prev = req->dl_next;
-	write_unlock(&tp->syn_wait_lock);
+	reqsk_queue_unlink(&tp->accept_queue, req, prev);
 }
 
 static inline void tcp_synq_drop(struct sock *sk, struct request_sock *req,
diff --git a/net/core/Makefile b/net/core/Makefile
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -2,7 +2,8 @@
 # Makefile for the Linux networking core.
 #
 
-obj-y := sock.o skbuff.o iovec.o datagram.o stream.o scm.o gen_stats.o gen_estimator.o
+obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \
+	 gen_stats.o gen_estimator.o
 
 obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
 
diff --git a/net/core/request_sock.c b/net/core/request_sock.c
new file mode 100644
--- /dev/null
+++ b/net/core/request_sock.c
@@ -0,0 +1,48 @@
+/*
+ * NET		Generic infrastructure for Network protocols.
+ *
+ * Authors:	Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * 		From code originally in include/net/tcp.h
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include <net/request_sock.h>
+
+int reqsk_queue_alloc(struct request_sock_queue *queue,
+		      const int nr_table_entries)
+{
+	const int lopt_size = sizeof(struct tcp_listen_opt) +
+			      nr_table_entries * sizeof(struct request_sock *);
+	struct tcp_listen_opt *lopt = kmalloc(lopt_size, GFP_KERNEL);
+
+	if (lopt == NULL)
+		return -ENOMEM;
+
+	memset(lopt, 0, lopt_size);
+
+	for (lopt->max_qlen_log = 6;
+	     (1 << lopt->max_qlen_log) < sysctl_max_syn_backlog;
+	     lopt->max_qlen_log++);
+
+	get_random_bytes(&lopt->hash_rnd, sizeof(lopt->hash_rnd));
+	rwlock_init(&queue->syn_wait_lock);
+	queue->rskq_accept_head = queue->rskq_accept_head = NULL;
+
+	write_lock_bh(&queue->syn_wait_lock);
+	queue->listen_opt = lopt;
+	write_unlock_bh(&queue->syn_wait_lock);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(reqsk_queue_alloc);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -316,7 +316,7 @@ EXPORT_SYMBOL(tcp_enter_memory_pressure)
 static __inline__ unsigned int tcp_listen_poll(struct sock *sk,
 					       poll_table *wait)
 {
-	return tcp_sk(sk)->accept_queue ? (POLLIN | POLLRDNORM) : 0;
+	return !reqsk_queue_empty(&tcp_sk(sk)->accept_queue) ? (POLLIN | POLLRDNORM) : 0;
 }
 
 /*
@@ -462,28 +462,15 @@ int tcp_listen_start(struct sock *sk)
 {
 	struct inet_sock *inet = inet_sk(sk);
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_listen_opt *lopt;
+	int rc = reqsk_queue_alloc(&tp->accept_queue, TCP_SYNQ_HSIZE);
+
+	if (rc != 0)
+		return rc;
 
 	sk->sk_max_ack_backlog = 0;
 	sk->sk_ack_backlog = 0;
-	tp->accept_queue = tp->accept_queue_tail = NULL;
-	rwlock_init(&tp->syn_wait_lock);
 	tcp_delack_init(tp);
 
-	lopt = kmalloc(sizeof(struct tcp_listen_opt), GFP_KERNEL);
-	if (!lopt)
-		return -ENOMEM;
-
-	memset(lopt, 0, sizeof(struct tcp_listen_opt));
-	for (lopt->max_qlen_log = 6; ; lopt->max_qlen_log++)
-		if ((1 << lopt->max_qlen_log) >= sysctl_max_syn_backlog)
-			break;
-	get_random_bytes(&lopt->hash_rnd, 4);
-
-	write_lock_bh(&tp->syn_wait_lock);
-	tp->listen_opt = lopt;
-	write_unlock_bh(&tp->syn_wait_lock);
-
 	/* There is race window here: we announce ourselves listening,
 	 * but this transition is still not validated by get_port().
 	 * It is OK, because this socket enters to hash table only
@@ -500,10 +487,7 @@ int tcp_listen_start(struct sock *sk)
 	}
 
 	sk->sk_state = TCP_CLOSE;
-	write_lock_bh(&tp->syn_wait_lock);
-	tp->listen_opt = NULL;
-	write_unlock_bh(&tp->syn_wait_lock);
-	kfree(lopt);
+	reqsk_queue_destroy(&tp->accept_queue);
 	return -EADDRINUSE;
 }
 
@@ -515,18 +499,16 @@ int tcp_listen_start(struct sock *sk)
 static void tcp_listen_stop (struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_listen_opt *lopt = tp->listen_opt;
-	struct request_sock *acc_req = tp->accept_queue;
+	struct tcp_listen_opt *lopt;
+	struct request_sock *acc_req;
 	struct request_sock *req;
 	int i;
 
 	tcp_delete_keepalive_timer(sk);
 
 	/* make all the listen_opt local to us */
-	write_lock_bh(&tp->syn_wait_lock);
-	tp->listen_opt = NULL;
-	write_unlock_bh(&tp->syn_wait_lock);
-	tp->accept_queue = tp->accept_queue_tail = NULL;
+	lopt = reqsk_queue_yank_listen_sk(&tp->accept_queue);
+	acc_req = reqsk_queue_yank_acceptq(&tp->accept_queue);
 
 	if (lopt->qlen) {
 		for (i = 0; i < TCP_SYNQ_HSIZE; i++) {
@@ -1867,11 +1849,11 @@ static int wait_for_connect(struct sock 
 		prepare_to_wait_exclusive(sk->sk_sleep, &wait,
 					  TASK_INTERRUPTIBLE);
 		release_sock(sk);
-		if (!tp->accept_queue)
+		if (reqsk_queue_empty(&tp->accept_queue))
 			timeo = schedule_timeout(timeo);
 		lock_sock(sk);
 		err = 0;
-		if (tp->accept_queue)
+		if (!reqsk_queue_empty(&tp->accept_queue))
 			break;
 		err = -EINVAL;
 		if (sk->sk_state != TCP_LISTEN)
@@ -1894,7 +1876,6 @@ static int wait_for_connect(struct sock 
 struct sock *tcp_accept(struct sock *sk, int flags, int *err)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct request_sock *req;
 	struct sock *newsk;
 	int error;
 
@@ -1905,37 +1886,31 @@ struct sock *tcp_accept(struct sock *sk,
 	 */
 	error = -EINVAL;
 	if (sk->sk_state != TCP_LISTEN)
-		goto out;
+		goto out_err;
 
 	/* Find already established connection */
-	if (!tp->accept_queue) {
+	if (reqsk_queue_empty(&tp->accept_queue)) {
 		long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
 
 		/* If this is a non blocking socket don't sleep */
 		error = -EAGAIN;
 		if (!timeo)
-			goto out;
+			goto out_err;
 
 		error = wait_for_connect(sk, timeo);
 		if (error)
-			goto out;
+			goto out_err;
 	}
 
-	req = tp->accept_queue;
-	if ((tp->accept_queue = req->dl_next) == NULL)
-		tp->accept_queue_tail = NULL;
-
- 	newsk = req->sk;
-	sk_acceptq_removed(sk);
-	__reqsk_free(req);
+	newsk = reqsk_queue_get_child(&tp->accept_queue, sk);
 	BUG_TRAP(newsk->sk_state != TCP_SYN_RECV);
-	release_sock(sk);
-	return newsk;
-
 out:
 	release_sock(sk);
+	return newsk;
+out_err:
+	newsk = NULL;
 	*err = error;
-	return NULL;
+	goto out;
 }
 
 /*
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c
--- a/net/ipv4/tcp_diag.c
+++ b/net/ipv4/tcp_diag.c
@@ -529,9 +529,9 @@ static int tcpdiag_dump_reqs(struct sk_b
 
 	entry.family = sk->sk_family;
 
-	read_lock_bh(&tp->syn_wait_lock);
+	read_lock_bh(&tp->accept_queue.syn_wait_lock);
 
-	lopt = tp->listen_opt;
+	lopt = tp->accept_queue.listen_opt;
 	if (!lopt || !lopt->qlen)
 		goto out;
 
@@ -588,7 +588,7 @@ static int tcpdiag_dump_reqs(struct sk_b
 	}
 
 out:
-	read_unlock_bh(&tp->syn_wait_lock);
+	read_unlock_bh(&tp->accept_queue.syn_wait_lock);
 
 	return err;
 }
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -874,7 +874,7 @@ static struct request_sock *tcp_v4_searc
 					      __u16 rport,
 					      __u32 raddr, __u32 laddr)
 {
-	struct tcp_listen_opt *lopt = tp->listen_opt;
+	struct tcp_listen_opt *lopt = tp->accept_queue.listen_opt;
 	struct request_sock *req, **prev;
 
 	for (prev = &lopt->syn_table[tcp_v4_synq_hash(raddr, rport, lopt->hash_rnd)];
@@ -898,18 +898,10 @@ static struct request_sock *tcp_v4_searc
 static void tcp_v4_synq_add(struct sock *sk, struct request_sock *req)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_listen_opt *lopt = tp->listen_opt;
+	struct tcp_listen_opt *lopt = tp->accept_queue.listen_opt;
 	u32 h = tcp_v4_synq_hash(inet_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd);
 
-	req->expires = jiffies + TCP_TIMEOUT_INIT;
-	req->retrans = 0;
-	req->sk = NULL;
-	req->dl_next = lopt->syn_table[h];
-
-	write_lock(&tp->syn_wait_lock);
-	lopt->syn_table[h] = req;
-	write_unlock(&tp->syn_wait_lock);
-
+	reqsk_queue_hash_req(&tp->accept_queue, h, req, TCP_TIMEOUT_INIT);
 	tcp_synq_added(sk);
 }
 
@@ -2167,17 +2159,17 @@ static void *listening_get_next(struct s
 			if (++st->sbucket >= TCP_SYNQ_HSIZE)
 				break;
 get_req:
-			req = tp->listen_opt->syn_table[st->sbucket];
+			req = tp->accept_queue.listen_opt->syn_table[st->sbucket];
 		}
 		sk	  = sk_next(st->syn_wait_sk);
 		st->state = TCP_SEQ_STATE_LISTENING;
-		read_unlock_bh(&tp->syn_wait_lock);
+		read_unlock_bh(&tp->accept_queue.syn_wait_lock);
 	} else {
 	       	tp = tcp_sk(sk);
-		read_lock_bh(&tp->syn_wait_lock);
-		if (tp->listen_opt && tp->listen_opt->qlen)
+		read_lock_bh(&tp->accept_queue.syn_wait_lock);
+		if (reqsk_queue_len(&tp->accept_queue))
 			goto start_req;
-		read_unlock_bh(&tp->syn_wait_lock);
+		read_unlock_bh(&tp->accept_queue.syn_wait_lock);
 		sk = sk_next(sk);
 	}
 get_sk:
@@ -2187,8 +2179,8 @@ get_sk:
 			goto out;
 		}
 	       	tp = tcp_sk(sk);
-		read_lock_bh(&tp->syn_wait_lock);
-		if (tp->listen_opt && tp->listen_opt->qlen) {
+		read_lock_bh(&tp->accept_queue.syn_wait_lock);
+		if (reqsk_queue_len(&tp->accept_queue)) {
 start_req:
 			st->uid		= sock_i_uid(sk);
 			st->syn_wait_sk = sk;
@@ -2196,7 +2188,7 @@ start_req:
 			st->sbucket	= 0;
 			goto get_req;
 		}
-		read_unlock_bh(&tp->syn_wait_lock);
+		read_unlock_bh(&tp->accept_queue.syn_wait_lock);
 	}
 	if (++st->bucket < TCP_LHTABLE_SIZE) {
 		sk = sk_head(&tcp_listening_hash[st->bucket]);
@@ -2383,7 +2375,7 @@ static void tcp_seq_stop(struct seq_file
 	case TCP_SEQ_STATE_OPENREQ:
 		if (v) {
 			struct tcp_sock *tp = tcp_sk(st->syn_wait_sk);
-			read_unlock_bh(&tp->syn_wait_lock);
+			read_unlock_bh(&tp->accept_queue.syn_wait_lock);
 		}
 	case TCP_SEQ_STATE_LISTENING:
 		if (v != SEQ_START_TOKEN)
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -790,10 +790,8 @@ struct sock *tcp_create_openreq_child(st
 		newtp->probes_out = 0;
 		newtp->rx_opt.num_sacks = 0;
 		newtp->urg_data = 0;
-		newtp->listen_opt = NULL;
-		newtp->accept_queue = newtp->accept_queue_tail = NULL;
-		/* Deinitialize syn_wait_lock to trap illegal accesses. */
-		memset(&newtp->syn_wait_lock, 0, sizeof(newtp->syn_wait_lock));
+		/* Deinitialize accept_queue to trap illegal accesses. */
+		memset(&newtp->accept_queue, 0, sizeof(newtp->accept_queue));
 
 		/* Back to base struct sock members. */
 		newsk->sk_err = 0;
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -464,7 +464,7 @@ out_unlock:
 static void tcp_synack_timer(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_listen_opt *lopt = tp->listen_opt;
+	struct tcp_listen_opt *lopt = tp->accept_queue.listen_opt;
 	int max_retries = tp->syn_retries ? : sysctl_tcp_synack_retries;
 	int thresh = max_retries;
 	unsigned long now = jiffies;
@@ -527,12 +527,8 @@ static void tcp_synack_timer(struct sock
 				}
 
 				/* Drop this request */
-				write_lock(&tp->syn_wait_lock);
-				*reqp = req->dl_next;
-				write_unlock(&tp->syn_wait_lock);
-				lopt->qlen--;
-				if (req->retrans == 0)
-					lopt->qlen_young--;
+				tcp_synq_unlink(tp, req, reqp);
+				reqsk_queue_removed(&tp->accept_queue, req);
 				reqsk_free(req);
 				continue;
 			}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -401,7 +401,7 @@ static struct request_sock *tcp_v6_searc
 					      struct in6_addr *laddr,
 					      int iif)
 {
-	struct tcp_listen_opt *lopt = tp->listen_opt;
+	struct tcp_listen_opt *lopt = tp->accept_queue.listen_opt;
 	struct request_sock *req, **prev;  
 
 	for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport, lopt->hash_rnd)];
@@ -1267,18 +1267,10 @@ static struct sock *tcp_v6_hnd_req(struc
 static void tcp_v6_synq_add(struct sock *sk, struct request_sock *req)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_listen_opt *lopt = tp->listen_opt;
+	struct tcp_listen_opt *lopt = tp->accept_queue.listen_opt;
 	u32 h = tcp_v6_synq_hash(&tcp6_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd);
 
-	req->sk = NULL;
-	req->expires = jiffies + TCP_TIMEOUT_INIT;
-	req->retrans = 0;
-	req->dl_next = lopt->syn_table[h];
-
-	write_lock(&tp->syn_wait_lock);
-	lopt->syn_table[h] = req;
-	write_unlock(&tp->syn_wait_lock);
-
+	reqsk_queue_hash_req(&tp->accept_queue, h, req, TCP_TIMEOUT_INIT);
 	tcp_synq_added(sk);
 }
 

^ permalink raw reply

* Re: [PATCH] Super TSO v3
From: Herbert Xu @ 2005-05-24  0:32 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev
In-Reply-To: <20050523.121943.78708600.davem@davemloft.net>

On Mon, May 23, 2005 at 07:19:43PM +0000, David S. Miller wrote:
> 
> The guts of the logic is in tcp_tso_should_defer().  And
> when dealing with a TSO frame, tcp_write_xmit() calls
> this instead of tcp_nagle_test().  So you can view this
> deferral as a sort of "TSO Nagle".

Should we skip this step if the socket has Nagle turned off?

Also why are we doing this check in tcp_push_one? The only
way we can get there is if the TSO goal has been reached
or there is out-of-band stuff to send.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* [PATCH 6/6] bnx2: Update revision and reldate
From: Michael Chan @ 2005-05-24  0:30 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev
In-Reply-To: <1116892439.4908.1.camel@rh4>

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

Signed-off-by: Michael Chan <mchan@broadcom.com>

[-- Attachment #2: bnx2-16.patch --]
[-- Type: text/x-patch, Size: 478 bytes --]

diff -Nru 15/drivers/net/bnx2.c 16/drivers/net/bnx2.c
--- 15/drivers/net/bnx2.c	2005-05-23 13:31:05.000000000 -0700
+++ 16/drivers/net/bnx2.c	2005-05-23 13:36:40.000000000 -0700
@@ -14,8 +14,8 @@
 
 #define DRV_MODULE_NAME		"bnx2"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"1.2.18"
-#define DRV_MODULE_RELDATE	"May 19, 2005"
+#define DRV_MODULE_VERSION	"1.2.19"
+#define DRV_MODULE_RELDATE	"May 23, 2005"
 
 #define RUN_AT(x) (jiffies + (x))
 

^ permalink raw reply

* [PATCH 5/6] bnx2: Add bnx2 prefix and mark static
From: Michael Chan @ 2005-05-24  0:29 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev
In-Reply-To: <1116892439.4908.1.camel@rh4>

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

Add bnx2_ prefix to some remaining names and mark some remaining names
static.

Spotted by David Miller and Jeff Garzik.

Signed-off-by: Michael Chan <mchan@broadcom.com>

[-- Attachment #2: bnx2-15.patch --]
[-- Type: text/x-patch, Size: 19598 bytes --]

diff -Nru 14/drivers/net/bnx2.c 15/drivers/net/bnx2.c
--- 14/drivers/net/bnx2.c	2005-05-23 13:01:45.000000000 -0700
+++ 15/drivers/net/bnx2.c	2005-05-23 13:31:05.000000000 -0700
@@ -264,7 +264,7 @@
 	synchronize_irq(bp->pdev->irq);
 }
 
-void
+static void
 bnx2_netif_stop(struct bnx2 *bp)
 {
 	bnx2_disable_int_sync(bp);
@@ -275,7 +275,7 @@
 	}
 }
 
-void
+static void
 bnx2_netif_start(struct bnx2 *bp)
 {
 	if (atomic_dec_and_test(&bp->intr_sem)) {
@@ -1807,8 +1807,8 @@
 	struct fw_info fw;
 
 	/* Initialize the RV2P processor. */
-	load_rv2p_fw(bp, rv2p_proc1, sizeof(rv2p_proc1), RV2P_PROC1);
-	load_rv2p_fw(bp, rv2p_proc2, sizeof(rv2p_proc2), RV2P_PROC2);
+	load_rv2p_fw(bp, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1), RV2P_PROC1);
+	load_rv2p_fw(bp, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2), RV2P_PROC2);
 
 	/* Initialize the RX Processor. */
 	cpu_reg.mode = BNX2_RXP_CPU_MODE;
@@ -1824,35 +1824,35 @@
 	cpu_reg.spad_base = BNX2_RXP_SCRATCH;
 	cpu_reg.mips_view_base = 0x8000000;
     
-	fw.ver_major = RXP_b06FwReleaseMajor;
-	fw.ver_minor = RXP_b06FwReleaseMinor;
-	fw.ver_fix = RXP_b06FwReleaseFix;
-	fw.start_addr = RXP_b06FwStartAddr;
+	fw.ver_major = bnx2_RXP_b06FwReleaseMajor;
+	fw.ver_minor = bnx2_RXP_b06FwReleaseMinor;
+	fw.ver_fix = bnx2_RXP_b06FwReleaseFix;
+	fw.start_addr = bnx2_RXP_b06FwStartAddr;
 
-	fw.text_addr = RXP_b06FwTextAddr;
-	fw.text_len = RXP_b06FwTextLen;
+	fw.text_addr = bnx2_RXP_b06FwTextAddr;
+	fw.text_len = bnx2_RXP_b06FwTextLen;
 	fw.text_index = 0;
-	fw.text = RXP_b06FwText;
+	fw.text = bnx2_RXP_b06FwText;
 
-	fw.data_addr = RXP_b06FwDataAddr;
-	fw.data_len = RXP_b06FwDataLen;
+	fw.data_addr = bnx2_RXP_b06FwDataAddr;
+	fw.data_len = bnx2_RXP_b06FwDataLen;
 	fw.data_index = 0;
-	fw.data = RXP_b06FwData;
+	fw.data = bnx2_RXP_b06FwData;
 
-	fw.sbss_addr = RXP_b06FwSbssAddr;
-	fw.sbss_len = RXP_b06FwSbssLen;
+	fw.sbss_addr = bnx2_RXP_b06FwSbssAddr;
+	fw.sbss_len = bnx2_RXP_b06FwSbssLen;
 	fw.sbss_index = 0;
-	fw.sbss = RXP_b06FwSbss;
+	fw.sbss = bnx2_RXP_b06FwSbss;
 
-	fw.bss_addr = RXP_b06FwBssAddr;
-	fw.bss_len = RXP_b06FwBssLen;
+	fw.bss_addr = bnx2_RXP_b06FwBssAddr;
+	fw.bss_len = bnx2_RXP_b06FwBssLen;
 	fw.bss_index = 0;
-	fw.bss = RXP_b06FwBss;
+	fw.bss = bnx2_RXP_b06FwBss;
 
-	fw.rodata_addr = RXP_b06FwRodataAddr;
-	fw.rodata_len = RXP_b06FwRodataLen;
+	fw.rodata_addr = bnx2_RXP_b06FwRodataAddr;
+	fw.rodata_len = bnx2_RXP_b06FwRodataLen;
 	fw.rodata_index = 0;
-	fw.rodata = RXP_b06FwRodata;
+	fw.rodata = bnx2_RXP_b06FwRodata;
 
 	load_cpu_fw(bp, &cpu_reg, &fw);
 
@@ -1870,35 +1870,35 @@
 	cpu_reg.spad_base = BNX2_TXP_SCRATCH;
 	cpu_reg.mips_view_base = 0x8000000;
     
-	fw.ver_major = TXP_b06FwReleaseMajor;
-	fw.ver_minor = TXP_b06FwReleaseMinor;
-	fw.ver_fix = TXP_b06FwReleaseFix;
-	fw.start_addr = TXP_b06FwStartAddr;
+	fw.ver_major = bnx2_TXP_b06FwReleaseMajor;
+	fw.ver_minor = bnx2_TXP_b06FwReleaseMinor;
+	fw.ver_fix = bnx2_TXP_b06FwReleaseFix;
+	fw.start_addr = bnx2_TXP_b06FwStartAddr;
 
-	fw.text_addr = TXP_b06FwTextAddr;
-	fw.text_len = TXP_b06FwTextLen;
+	fw.text_addr = bnx2_TXP_b06FwTextAddr;
+	fw.text_len = bnx2_TXP_b06FwTextLen;
 	fw.text_index = 0;
-	fw.text = TXP_b06FwText;
+	fw.text = bnx2_TXP_b06FwText;
 
-	fw.data_addr = TXP_b06FwDataAddr;
-	fw.data_len = TXP_b06FwDataLen;
+	fw.data_addr = bnx2_TXP_b06FwDataAddr;
+	fw.data_len = bnx2_TXP_b06FwDataLen;
 	fw.data_index = 0;
-	fw.data = TXP_b06FwData;
+	fw.data = bnx2_TXP_b06FwData;
 
-	fw.sbss_addr = TXP_b06FwSbssAddr;
-	fw.sbss_len = TXP_b06FwSbssLen;
+	fw.sbss_addr = bnx2_TXP_b06FwSbssAddr;
+	fw.sbss_len = bnx2_TXP_b06FwSbssLen;
 	fw.sbss_index = 0;
-	fw.sbss = TXP_b06FwSbss;
+	fw.sbss = bnx2_TXP_b06FwSbss;
 
-	fw.bss_addr = TXP_b06FwBssAddr;
-	fw.bss_len = TXP_b06FwBssLen;
+	fw.bss_addr = bnx2_TXP_b06FwBssAddr;
+	fw.bss_len = bnx2_TXP_b06FwBssLen;
 	fw.bss_index = 0;
-	fw.bss = TXP_b06FwBss;
+	fw.bss = bnx2_TXP_b06FwBss;
 
-	fw.rodata_addr = TXP_b06FwRodataAddr;
-	fw.rodata_len = TXP_b06FwRodataLen;
+	fw.rodata_addr = bnx2_TXP_b06FwRodataAddr;
+	fw.rodata_len = bnx2_TXP_b06FwRodataLen;
 	fw.rodata_index = 0;
-	fw.rodata = TXP_b06FwRodata;
+	fw.rodata = bnx2_TXP_b06FwRodata;
 
 	load_cpu_fw(bp, &cpu_reg, &fw);
 
@@ -1916,35 +1916,35 @@
 	cpu_reg.spad_base = BNX2_TPAT_SCRATCH;
 	cpu_reg.mips_view_base = 0x8000000;
     
-	fw.ver_major = TPAT_b06FwReleaseMajor;
-	fw.ver_minor = TPAT_b06FwReleaseMinor;
-	fw.ver_fix = TPAT_b06FwReleaseFix;
-	fw.start_addr = TPAT_b06FwStartAddr;
+	fw.ver_major = bnx2_TPAT_b06FwReleaseMajor;
+	fw.ver_minor = bnx2_TPAT_b06FwReleaseMinor;
+	fw.ver_fix = bnx2_TPAT_b06FwReleaseFix;
+	fw.start_addr = bnx2_TPAT_b06FwStartAddr;
 
-	fw.text_addr = TPAT_b06FwTextAddr;
-	fw.text_len = TPAT_b06FwTextLen;
+	fw.text_addr = bnx2_TPAT_b06FwTextAddr;
+	fw.text_len = bnx2_TPAT_b06FwTextLen;
 	fw.text_index = 0;
-	fw.text = TPAT_b06FwText;
+	fw.text = bnx2_TPAT_b06FwText;
 
-	fw.data_addr = TPAT_b06FwDataAddr;
-	fw.data_len = TPAT_b06FwDataLen;
+	fw.data_addr = bnx2_TPAT_b06FwDataAddr;
+	fw.data_len = bnx2_TPAT_b06FwDataLen;
 	fw.data_index = 0;
-	fw.data = TPAT_b06FwData;
+	fw.data = bnx2_TPAT_b06FwData;
 
-	fw.sbss_addr = TPAT_b06FwSbssAddr;
-	fw.sbss_len = TPAT_b06FwSbssLen;
+	fw.sbss_addr = bnx2_TPAT_b06FwSbssAddr;
+	fw.sbss_len = bnx2_TPAT_b06FwSbssLen;
 	fw.sbss_index = 0;
-	fw.sbss = TPAT_b06FwSbss;
+	fw.sbss = bnx2_TPAT_b06FwSbss;
 
-	fw.bss_addr = TPAT_b06FwBssAddr;
-	fw.bss_len = TPAT_b06FwBssLen;
+	fw.bss_addr = bnx2_TPAT_b06FwBssAddr;
+	fw.bss_len = bnx2_TPAT_b06FwBssLen;
 	fw.bss_index = 0;
-	fw.bss = TPAT_b06FwBss;
+	fw.bss = bnx2_TPAT_b06FwBss;
 
-	fw.rodata_addr = TPAT_b06FwRodataAddr;
-	fw.rodata_len = TPAT_b06FwRodataLen;
+	fw.rodata_addr = bnx2_TPAT_b06FwRodataAddr;
+	fw.rodata_len = bnx2_TPAT_b06FwRodataLen;
 	fw.rodata_index = 0;
-	fw.rodata = TPAT_b06FwRodata;
+	fw.rodata = bnx2_TPAT_b06FwRodata;
 
 	load_cpu_fw(bp, &cpu_reg, &fw);
 
@@ -1962,35 +1962,35 @@
 	cpu_reg.spad_base = BNX2_COM_SCRATCH;
 	cpu_reg.mips_view_base = 0x8000000;
     
-	fw.ver_major = COM_b06FwReleaseMajor;
-	fw.ver_minor = COM_b06FwReleaseMinor;
-	fw.ver_fix = COM_b06FwReleaseFix;
-	fw.start_addr = COM_b06FwStartAddr;
+	fw.ver_major = bnx2_COM_b06FwReleaseMajor;
+	fw.ver_minor = bnx2_COM_b06FwReleaseMinor;
+	fw.ver_fix = bnx2_COM_b06FwReleaseFix;
+	fw.start_addr = bnx2_COM_b06FwStartAddr;
 
-	fw.text_addr = COM_b06FwTextAddr;
-	fw.text_len = COM_b06FwTextLen;
+	fw.text_addr = bnx2_COM_b06FwTextAddr;
+	fw.text_len = bnx2_COM_b06FwTextLen;
 	fw.text_index = 0;
-	fw.text = COM_b06FwText;
+	fw.text = bnx2_COM_b06FwText;
 
-	fw.data_addr = COM_b06FwDataAddr;
-	fw.data_len = COM_b06FwDataLen;
+	fw.data_addr = bnx2_COM_b06FwDataAddr;
+	fw.data_len = bnx2_COM_b06FwDataLen;
 	fw.data_index = 0;
-	fw.data = COM_b06FwData;
+	fw.data = bnx2_COM_b06FwData;
 
-	fw.sbss_addr = COM_b06FwSbssAddr;
-	fw.sbss_len = COM_b06FwSbssLen;
+	fw.sbss_addr = bnx2_COM_b06FwSbssAddr;
+	fw.sbss_len = bnx2_COM_b06FwSbssLen;
 	fw.sbss_index = 0;
-	fw.sbss = COM_b06FwSbss;
+	fw.sbss = bnx2_COM_b06FwSbss;
 
-	fw.bss_addr = COM_b06FwBssAddr;
-	fw.bss_len = COM_b06FwBssLen;
+	fw.bss_addr = bnx2_COM_b06FwBssAddr;
+	fw.bss_len = bnx2_COM_b06FwBssLen;
 	fw.bss_index = 0;
-	fw.bss = COM_b06FwBss;
+	fw.bss = bnx2_COM_b06FwBss;
 
-	fw.rodata_addr = COM_b06FwRodataAddr;
-	fw.rodata_len = COM_b06FwRodataLen;
+	fw.rodata_addr = bnx2_COM_b06FwRodataAddr;
+	fw.rodata_len = bnx2_COM_b06FwRodataLen;
 	fw.rodata_index = 0;
-	fw.rodata = COM_b06FwRodata;
+	fw.rodata = bnx2_COM_b06FwRodata;
 
 	load_cpu_fw(bp, &cpu_reg, &fw);
 
@@ -4695,11 +4695,11 @@
 	return 0;
 }
 
-#define ETH_NUM_STATS 45
+#define BNX2_NUM_STATS 45
 
 struct {
 	char string[ETH_GSTRING_LEN];
-} bnx2_stats_str_arr[ETH_NUM_STATS] = {
+} bnx2_stats_str_arr[BNX2_NUM_STATS] = {
 	{ "rx_bytes" },
 	{ "rx_error_bytes" },
 	{ "tx_bytes" },
@@ -4749,7 +4749,7 @@
 
 #define STATS_OFFSET32(offset_name) (offsetof(struct statistics_block, offset_name) / 4)
 
-unsigned long bnx2_stats_offset_arr[ETH_NUM_STATS] = {
+unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = {
     STATS_OFFSET32(stat_IfHCInOctets_hi),
     STATS_OFFSET32(stat_IfHCInBadOctets_hi),
     STATS_OFFSET32(stat_IfHCOutOctets_hi),
@@ -4800,7 +4800,7 @@
 /* stat_IfHCInBadOctets and stat_Dot3StatsCarrierSenseErrors are
  * skipped because of errata.
  */               
-u8 bnx2_5706_stats_len_arr[ETH_NUM_STATS] = {
+u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = {
 	8,0,8,8,8,8,8,8,8,8,
 	4,0,4,4,4,4,4,4,4,4,
 	4,4,4,4,4,4,4,4,4,4,
@@ -4808,11 +4808,11 @@
 	4,4,4,4,4,
 };
 
-#define ETH_NUM_TESTS 6
+#define BNX2_NUM_TESTS 6
 
 struct {
 	char string[ETH_GSTRING_LEN];
-} bnx2_tests_str_arr[ETH_NUM_TESTS] = {
+} bnx2_tests_str_arr[BNX2_NUM_TESTS] = {
 	{ "register_test (offline)" },
 	{ "memory_test (offline)" },
 	{ "loopback_test (offline)" },
@@ -4824,7 +4824,7 @@
 static int
 bnx2_self_test_count(struct net_device *dev)
 {
-	return ETH_NUM_TESTS;
+	return BNX2_NUM_TESTS;
 }
 
 static void
@@ -4832,7 +4832,7 @@
 {
 	struct bnx2 *bp = dev->priv;
 
-	memset(buf, 0, sizeof(u64) * ETH_NUM_TESTS);
+	memset(buf, 0, sizeof(u64) * BNX2_NUM_TESTS);
 	if (etest->flags & ETH_TEST_FL_OFFLINE) {
 		bnx2_netif_stop(bp);
 		bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_DIAG);
@@ -4899,7 +4899,7 @@
 static int
 bnx2_get_stats_count(struct net_device *dev)
 {
-	return ETH_NUM_STATS;
+	return BNX2_NUM_STATS;
 }
 
 static void
@@ -4912,14 +4912,14 @@
 	u8 *stats_len_arr = 0;
 
 	if (hw_stats == NULL) {
-		memset(buf, 0, sizeof(u64) * ETH_NUM_STATS);
+		memset(buf, 0, sizeof(u64) * BNX2_NUM_STATS);
 		return;
 	}
 
 	if (CHIP_NUM(bp) == CHIP_NUM_5706)
 		stats_len_arr = bnx2_5706_stats_len_arr;
 
-	for (i = 0; i < ETH_NUM_STATS; i++) {
+	for (i = 0; i < BNX2_NUM_STATS; i++) {
 		if (stats_len_arr[i] == 0) {
 			/* skip this counter */
 			buf[i] = 0;
diff -Nru 14/drivers/net/bnx2_fw.h 15/drivers/net/bnx2_fw.h
--- 14/drivers/net/bnx2_fw.h	2005-05-23 13:33:28.000000000 -0700
+++ 15/drivers/net/bnx2_fw.h	2005-05-23 13:31:10.000000000 -0700
@@ -15,21 +15,21 @@
  */
 
 
-int COM_b06FwReleaseMajor = 0x0;
-int COM_b06FwReleaseMinor = 0x0;
-int COM_b06FwReleaseFix = 0x0;
-u32 COM_b06FwStartAddr = 0x080004a0;
-u32 COM_b06FwTextAddr = 0x08000000;
-int COM_b06FwTextLen = 0x4594;
-u32 COM_b06FwDataAddr = 0x080045e0;
-int COM_b06FwDataLen = 0x0;
-u32 COM_b06FwRodataAddr = 0x08004598;
-int COM_b06FwRodataLen = 0x18;
-u32 COM_b06FwBssAddr = 0x08004600;
-int COM_b06FwBssLen = 0x88;
-u32 COM_b06FwSbssAddr = 0x080045e0;
-int COM_b06FwSbssLen = 0x1c;
-u32 COM_b06FwText[(0x4594/4) + 1] = {
+static int bnx2_COM_b06FwReleaseMajor = 0x0;
+static int bnx2_COM_b06FwReleaseMinor = 0x0;
+static int bnx2_COM_b06FwReleaseFix = 0x0;
+static u32 bnx2_COM_b06FwStartAddr = 0x080004a0;
+static u32 bnx2_COM_b06FwTextAddr = 0x08000000;
+static int bnx2_COM_b06FwTextLen = 0x4594;
+static u32 bnx2_COM_b06FwDataAddr = 0x080045e0;
+static int bnx2_COM_b06FwDataLen = 0x0;
+static u32 bnx2_COM_b06FwRodataAddr = 0x08004598;
+static int bnx2_COM_b06FwRodataLen = 0x18;
+static u32 bnx2_COM_b06FwBssAddr = 0x08004600;
+static int bnx2_COM_b06FwBssLen = 0x88;
+static u32 bnx2_COM_b06FwSbssAddr = 0x080045e0;
+static int bnx2_COM_b06FwSbssLen = 0x1c;
+static u32 bnx2_COM_b06FwText[(0x4594/4) + 1] = {
 	0x0a000128, 0x00000000, 0x00000000, 0x0000000d, 0x636f6d20, 0x302e362e,
 	0x39000000, 0x00060902, 0x00000000, 0x00000003, 0x00000014, 0x00000032,
 	0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -774,30 +774,30 @@
 	0x8f420000, 0x30420020, 0x1040fffd, 0x3c020020, 0xaf420030, 0x03e00008,
 	0x00000000, 0x00000000 };
 
-u32 COM_b06FwData[(0x0/4) + 1] = { 0x00000000 };
-u32 COM_b06FwRodata[(0x18/4) + 1] = {
+static u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x00000000 };
+static u32 bnx2_COM_b06FwRodata[(0x18/4) + 1] = {
 	0x08002318, 0x08002348, 0x08002378, 0x080023a8, 0x080023d8, 0x00000000,
 	0x00000000 };
 
-u32 COM_b06FwBss[(0x88/4) + 1] = { 0x00000000 };
-u32 COM_b06FwSbss[(0x1c/4) + 1] = { 0x00000000 };
+static u32 bnx2_COM_b06FwBss[(0x88/4) + 1] = { 0x00000000 };
+static u32 bnx2_COM_b06FwSbss[(0x1c/4) + 1] = { 0x00000000 };
 
-int RXP_b06FwReleaseMajor = 0x0;
-int RXP_b06FwReleaseMinor = 0x0;
-int RXP_b06FwReleaseFix = 0x0;
-u32 RXP_b06FwStartAddr = 0x08000060;
-u32 RXP_b06FwTextAddr = 0x08000000;
-int RXP_b06FwTextLen = 0x20b8;
-u32 RXP_b06FwDataAddr = 0x080020e0;
-int RXP_b06FwDataLen = 0x0;
-u32 RXP_b06FwRodataAddr = 0x00000000;
-int RXP_b06FwRodataLen = 0x0;
-u32 RXP_b06FwBssAddr = 0x08002100;
-int RXP_b06FwBssLen = 0x239c;
-u32 RXP_b06FwSbssAddr = 0x080020e0;
-int RXP_b06FwSbssLen = 0x14;
+static int bnx2_RXP_b06FwReleaseMajor = 0x0;
+static int bnx2_RXP_b06FwReleaseMinor = 0x0;
+static int bnx2_RXP_b06FwReleaseFix = 0x0;
+static u32 bnx2_RXP_b06FwStartAddr = 0x08000060;
+static u32 bnx2_RXP_b06FwTextAddr = 0x08000000;
+static int bnx2_RXP_b06FwTextLen = 0x20b8;
+static u32 bnx2_RXP_b06FwDataAddr = 0x080020e0;
+static int bnx2_RXP_b06FwDataLen = 0x0;
+static u32 bnx2_RXP_b06FwRodataAddr = 0x00000000;
+static int bnx2_RXP_b06FwRodataLen = 0x0;
+static u32 bnx2_RXP_b06FwBssAddr = 0x08002100;
+static int bnx2_RXP_b06FwBssLen = 0x239c;
+static u32 bnx2_RXP_b06FwSbssAddr = 0x080020e0;
+static int bnx2_RXP_b06FwSbssLen = 0x14;
 
-u32 RXP_b06FwText[(0x20b8/4) + 1] = {
+static u32 bnx2_RXP_b06FwText[(0x20b8/4) + 1] = {
 	0x0a000018, 0x00000000, 0x00000000, 0x0000000d, 0x72787020, 0x302e362e,
 	0x39000000, 0x00060903, 0x00000000, 0x0000000d, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -1149,12 +1149,12 @@
 	0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 0x03e00008, 0x00000000,
 	0x00000000 }; 
 
-u32 RXP_b06FwData[(0x0/4) + 1] = { 0x00000000 };
-u32 RXP_b06FwRodata[(0x0/4) + 1] = { 0x00000000 };
-u32 RXP_b06FwBss[(0x239c/4) + 1] = { 0x00000000 };
-u32 RXP_b06FwSbss[(0x14/4) + 1] = { 0x00000000 };
+static u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x00000000 };
+static u32 bnx2_RXP_b06FwRodata[(0x0/4) + 1] = { 0x00000000 };
+static u32 bnx2_RXP_b06FwBss[(0x239c/4) + 1] = { 0x00000000 };
+static u32 bnx2_RXP_b06FwSbss[(0x14/4) + 1] = { 0x00000000 };
 
-u32 rv2p_proc1[] = {
+static u32 bnx2_rv2p_proc1[] = {
 	0x00000008, 0xac000001, 0x0000000c, 0x2f800001, 0x00000010, 0x213f0004,
 	0x00000010, 0x20bf002c, 0x00000010, 0x203f0143, 0x00000018, 0x8000fffd,
 	0x00000010, 0xb1b8b017, 0x0000000b, 0x2fdf0002, 0x00000000, 0x03d80000,
@@ -1279,7 +1279,7 @@
 	0x00000001, 0x860c0e00, 0x00000008, 0x02040004, 0x00000000, 0x02041800,
 	0x00000000, 0x83871800, 0x00000018, 0x00020000 };
 
-u32 rv2p_proc2[] = {
+static u32 bnx2_rv2p_proc2[] = {
 	0x00000000, 0x2a000000, 0x00000010, 0xb1d40000, 0x00000008, 0x02540003,
 	0x00000018, 0x00040000, 0x00000018, 0x8000000a, 0x00000018, 0x8000000a,
 	0x00000018, 0x8000000e, 0x00000018, 0x80000056, 0x00000018, 0x800001b9,
@@ -1536,22 +1536,22 @@
 	0x0000000c, 0x29520000, 0x00000018, 0x80000002, 0x0000000c, 0x29800000,
 	0x00000018, 0x00570000 };
 
-int TPAT_b06FwReleaseMajor = 0x0;
-int TPAT_b06FwReleaseMinor = 0x0;
-int TPAT_b06FwReleaseFix = 0x0;
-u32 TPAT_b06FwStartAddr = 0x08000858;
-u32 TPAT_b06FwTextAddr = 0x08000800;
-int TPAT_b06FwTextLen = 0x1314;
-u32 TPAT_b06FwDataAddr = 0x08001b40;
-int TPAT_b06FwDataLen = 0x0;
-u32 TPAT_b06FwRodataAddr = 0x00000000;
-int TPAT_b06FwRodataLen = 0x0;
-u32 TPAT_b06FwBssAddr = 0x08001b90;
-int TPAT_b06FwBssLen = 0x80;
-u32 TPAT_b06FwSbssAddr = 0x08001b40;
-int TPAT_b06FwSbssLen = 0x48;
+static int bnx2_TPAT_b06FwReleaseMajor = 0x0;
+static int bnx2_TPAT_b06FwReleaseMinor = 0x0;
+static int bnx2_TPAT_b06FwReleaseFix = 0x0;
+static u32 bnx2_TPAT_b06FwStartAddr = 0x08000858;
+static u32 bnx2_TPAT_b06FwTextAddr = 0x08000800;
+static int bnx2_TPAT_b06FwTextLen = 0x1314;
+static u32 bnx2_TPAT_b06FwDataAddr = 0x08001b40;
+static int bnx2_TPAT_b06FwDataLen = 0x0;
+static u32 bnx2_TPAT_b06FwRodataAddr = 0x00000000;
+static int bnx2_TPAT_b06FwRodataLen = 0x0;
+static u32 bnx2_TPAT_b06FwBssAddr = 0x08001b90;
+static int bnx2_TPAT_b06FwBssLen = 0x80;
+static u32 bnx2_TPAT_b06FwSbssAddr = 0x08001b40;
+static int bnx2_TPAT_b06FwSbssLen = 0x48;
 
-u32 TPAT_b06FwText[(0x1314/4) + 1] = {
+static u32 bnx2_TPAT_b06FwText[(0x1314/4) + 1] = {
 	0x0a000216, 0x00000000, 0x00000000, 0x0000000d, 0x74706174, 0x20302e36,
 	0x2e390000, 0x00060901, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -1757,26 +1757,26 @@
 	0x3c056000, 0x24030019, 0xaca223f8, 0xa743014a, 0x8ca44448, 0x3c020800,
 	0xac440854, 0x03e00008, 0x00000000, 0x00000000 };
 
-u32 TPAT_b06FwData[(0x0/4) + 1] = { 0x00000000 };
-u32 TPAT_b06FwRodata[(0x0/4) + 1] = { 0x00000000 };
-u32 TPAT_b06FwBss[(0x80/4) + 1] = { 0x00000000 };
-u32 TPAT_b06FwSbss[(0x48/4) + 1] = { 0x00000000 };
+static u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x00000000 };
+static u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x00000000 };
+static u32 bnx2_TPAT_b06FwBss[(0x80/4) + 1] = { 0x00000000 };
+static u32 bnx2_TPAT_b06FwSbss[(0x48/4) + 1] = { 0x00000000 };
 
-int TXP_b06FwReleaseMajor = 0x0;
-int TXP_b06FwReleaseMinor = 0x0;
-int TXP_b06FwReleaseFix = 0x0;
-u32 TXP_b06FwStartAddr = 0x08002090;
-u32 TXP_b06FwTextAddr = 0x08000000;
-int TXP_b06FwTextLen = 0x3ffc;
-u32 TXP_b06FwDataAddr = 0x08004020;
-int TXP_b06FwDataLen = 0x0;
-u32 TXP_b06FwRodataAddr = 0x00000000;
-int TXP_b06FwRodataLen = 0x0;
-u32 TXP_b06FwBssAddr = 0x08004060;
-int TXP_b06FwBssLen = 0x194;
-u32 TXP_b06FwSbssAddr = 0x08004020;
-int TXP_b06FwSbssLen = 0x34;
-u32 TXP_b06FwText[(0x3ffc/4) + 1] = {
+static int bnx2_TXP_b06FwReleaseMajor = 0x0;
+static int bnx2_TXP_b06FwReleaseMinor = 0x0;
+static int bnx2_TXP_b06FwReleaseFix = 0x0;
+static u32 bnx2_TXP_b06FwStartAddr = 0x08002090;
+static u32 bnx2_TXP_b06FwTextAddr = 0x08000000;
+static int bnx2_TXP_b06FwTextLen = 0x3ffc;
+static u32 bnx2_TXP_b06FwDataAddr = 0x08004020;
+static int bnx2_TXP_b06FwDataLen = 0x0;
+static u32 bnx2_TXP_b06FwRodataAddr = 0x00000000;
+static int bnx2_TXP_b06FwRodataLen = 0x0;
+static u32 bnx2_TXP_b06FwBssAddr = 0x08004060;
+static int bnx2_TXP_b06FwBssLen = 0x194;
+static u32 bnx2_TXP_b06FwSbssAddr = 0x08004020;
+static int bnx2_TXP_b06FwSbssLen = 0x34;
+static u32 bnx2_TXP_b06FwText[(0x3ffc/4) + 1] = {
 	0x0a000824, 0x00000000, 0x00000000, 0x0000000d, 0x74787020, 0x302e362e,
 	0x39000000, 0x00060900, 0x0000000a, 0x000003e8, 0x0000ea60, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -2461,8 +2461,8 @@
 	0x8c820064, 0x254a0001, 0x314a007f, 0x01094021, 0xad6a0060, 0x24420001,
 	0xac820064, 0x03e00008, 0xad05001c, 0x00000000 };
 
-u32 TXP_b06FwData[(0x0/4) + 1] = { 0x00000000 };
-u32 TXP_b06FwRodata[(0x0/4) + 1] = { 0x00000000 };
-u32 TXP_b06FwBss[(0x194/4) + 1] = { 0x00000000 };
-u32 TXP_b06FwSbss[(0x34/4) + 1] = { 0x00000000 };
+static u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x00000000 };
+static u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x00000000 };
+static u32 bnx2_TXP_b06FwBss[(0x194/4) + 1] = { 0x00000000 };
+static u32 bnx2_TXP_b06FwSbss[(0x34/4) + 1] = { 0x00000000 };
 

^ permalink raw reply

* [PATCH 4/6] bnx2: Fix bug in bnx2_close
From: Michael Chan @ 2005-05-24  0:29 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev
In-Reply-To: <1116892439.4908.1.camel@rh4>

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

Fix bug in bnx2_close() by calling flush_scheduled_work() since we are
using a work queue in netdev watchdog. Also added bnx2_netif_stop() call
in bnx2_close().

Spotted by Jeff Garzik.

Signed-off-by: Michael Chan <mchan@broadcom.com>


[-- Attachment #2: bnx2-14.patch --]
[-- Type: text/x-patch, Size: 434 bytes --]

diff -Nru 13/drivers/net/bnx2.c 14/drivers/net/bnx2.c
--- 13/drivers/net/bnx2.c	2005-05-23 10:57:41.000000000 -0700
+++ 14/drivers/net/bnx2.c	2005-05-23 13:01:45.000000000 -0700
@@ -4172,7 +4172,8 @@
 	struct bnx2 *bp = dev->priv;
 	u32 reset_code;
 
-	bnx2_disable_int_sync(bp);
+	flush_scheduled_work();
+	bnx2_netif_stop(bp);
 	del_timer_sync(&bp->timer);
 	if (bp->wol)
 		reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;

^ permalink raw reply

* [PATCH 3/6] bnx2: Fix excessive udelay
From: Michael Chan @ 2005-05-24  0:27 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev
In-Reply-To: <1116892439.4908.1.camel@rh4>

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

Replaced one excessive udelay of 15msec with msleep since the calling
context is always process. Also replaced some schedule_timeout calls
with msleep/msleep_interruptible.

Spotted by Jeff Garzik.

Signed-off-by: Michael Chan <mchan@broadcom.com>

[-- Attachment #2: bnx2-13.patch --]
[-- Type: text/x-patch, Size: 2375 bytes --]

diff -Nru 12/drivers/net/bnx2.c 13/drivers/net/bnx2.c
--- 12/drivers/net/bnx2.c	2005-05-23 10:29:02.000000000 -0700
+++ 13/drivers/net/bnx2.c	2005-05-23 10:57:41.000000000 -0700
@@ -2011,11 +2011,9 @@
 			(pmcsr & ~PCI_PM_CTRL_STATE_MASK) |
 			PCI_PM_CTRL_PME_STATUS);
 
-		if (pmcsr & PCI_PM_CTRL_STATE_MASK) {
+		if (pmcsr & PCI_PM_CTRL_STATE_MASK)
 			/* delay required during transition out of D3hot */
-			current->state = TASK_UNINTERRUPTIBLE;
-			schedule_timeout(HZ / 50);
-		}
+			msleep(20);
 
 		val = REG_RD(bp, BNX2_EMAC_MODE);
 		val |= BNX2_EMAC_MODE_MPKT_RCVD | BNX2_EMAC_MODE_ACPI_RCVD;
@@ -2751,12 +2749,8 @@
 	REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val);
 
 	if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
-	    (CHIP_ID(bp) == CHIP_ID_5706_A1)) {
-
-	        for (i = 0; i < 500; i++) {
-			udelay(30);
-		}
-	}
+	    (CHIP_ID(bp) == CHIP_ID_5706_A1))
+		msleep(15);
 
 	/* Reset takes approximate 30 usec */
 	for (i = 0; i < 10; i++) {
@@ -3785,8 +3779,6 @@
 	REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW);
 	REG_RD(bp, BNX2_HC_COMMAND);
 
-	udelay(80);
-
 	for (i = 0; i < 10; i++) {
 		if ((REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD) & 0xffff) !=
 			status_idx) {
@@ -3794,8 +3786,7 @@
 			break;
 		}
 
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(1);
+		msleep_interruptible(10);
 	}
 	if (i < 10)
 		return 0;
@@ -4478,8 +4469,7 @@
 		bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK);
 		spin_unlock_irq(&bp->phy_lock);
 
-		current->state = TASK_UNINTERRUPTIBLE;
-		schedule_timeout(HZ / 50);
+		msleep(20);
 
 		spin_lock_irq(&bp->phy_lock);
 		if (CHIP_NUM(bp) == CHIP_NUM_5706) {
@@ -4869,12 +4859,9 @@
 		}
 
 		/* wait for link up */
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(3 * HZ);
-		if ((!bp->link_up) && !(bp->phy_flags & PHY_SERDES_FLAG)) {
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(4 * HZ);
-		}
+		msleep_interruptible(3000);
+		if ((!bp->link_up) && !(bp->phy_flags & PHY_SERDES_FLAG))
+			msleep_interruptible(4000);
 	}
 
 	if (bnx2_test_nvram(bp) != 0) {
@@ -4975,8 +4962,7 @@
 				BNX2_EMAC_LED_TRAFFIC_OVERRIDE |
 				BNX2_EMAC_LED_TRAFFIC);
 		}
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(HZ / 2);
+		msleep_interruptible(500);
 		if (signal_pending(current))
 			break;
 	}

^ permalink raw reply

* [PATCH 2/6] bnx2: Fix rx checksum
From: Michael Chan @ 2005-05-24  0:26 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev
In-Reply-To: <1116892439.4908.1.camel@rh4>

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

Fix bug in rx checksum by indicating CHECKSUM_UNNECESSARY only when the
hw calculated checksum is 0xffff.

Spotted by Jeff Garzik.

Signed-off-by: Michael Chan <mchan@broadcom.com>


[-- Attachment #2: bnx2-12.patch --]
[-- Type: text/x-patch, Size: 408 bytes --]

diff -Nru 11/drivers/net/bnx2.c 12/drivers/net/bnx2.c
--- 11/drivers/net/bnx2.c	2005-05-23 10:20:20.000000000 -0700
+++ 12/drivers/net/bnx2.c	2005-05-23 10:29:02.000000000 -0700
@@ -1470,9 +1470,8 @@
 
 			u16 cksum = rx_hdr->l2_fhdr_tcp_udp_xsum;
 
-			if ((cksum == 0xffff) || (cksum == 0)) {
+			if (cksum == 0xffff)
 				skb->ip_summed = CHECKSUM_UNNECESSARY;
-			}
 		}
 
 #ifdef BCM_VLAN

^ permalink raw reply

* [PATCH 1/6] bnx2: Fix excessive stack usage
From: Michael Chan @ 2005-05-24  0:25 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev
In-Reply-To: <1116892439.4908.1.camel@rh4>

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

Fix excessive stack usage in bnx2_alloc_bad_rbuf() by replacing local
variable array with kmalloc array. Also changed function to return error
code, and changed some of the callers to check for the return code.

Spotted by Jeff Garzik.

Signed-off-by: Michael Chan <mchan@broadcom.com>

[-- Attachment #2: bnx2-11.patch --]
[-- Type: text/x-patch, Size: 1818 bytes --]

diff -Nru 10/drivers/net/bnx2.c 11/drivers/net/bnx2.c
--- 10/drivers/net/bnx2.c	2005-05-23 10:20:02.000000000 -0700
+++ 11/drivers/net/bnx2.c	2005-05-23 10:20:20.000000000 -0700
@@ -1138,13 +1138,20 @@
 	}
 }
 
-static void
+static int
 bnx2_alloc_bad_rbuf(struct bnx2 *bp)
 {
-	u16 good_mbuf[512];
+	u16 *good_mbuf;
 	u32 good_mbuf_cnt;
 	u32 val;
 
+	good_mbuf = kmalloc(512 * sizeof(u16), GFP_KERNEL);
+	if (good_mbuf == NULL) {
+		printk(KERN_ERR PFX "Failed to allocate memory in "
+				    "bnx2_alloc_bad_rbuf\n");
+		return -ENOMEM;
+	}
+
 	REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
 		BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE);
 
@@ -1178,6 +1185,7 @@
 
 		REG_WR_IND(bp, BNX2_RBUF_FW_BUF_FREE, val);
 	}
+	return 0;
 }
 
 static void
@@ -2710,7 +2718,7 @@
 bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
 {
 	u32 val;
-	int i;
+	int i, rc = 0;
 
 	/* Wait for the current PCI transaction to complete before
 	 * issuing a reset. */
@@ -2785,10 +2793,10 @@
 		REG_WR(bp, BNX2_MISC_VREG_CONTROL, 0x000000fa);
 
 		/* Remove bad rbuf memory from the free pool. */
-		bnx2_alloc_bad_rbuf(bp);
+		rc = bnx2_alloc_bad_rbuf(bp);
 	}
 
-	return 0;
+	return rc;
 }
 
 static int
@@ -3097,8 +3105,13 @@
 static int
 bnx2_reset_nic(struct bnx2 *bp, u32 reset_code)
 {
-	bnx2_reset_chip(bp, reset_code);
+	int rc;
+
+	rc = bnx2_reset_chip(bp, reset_code);
 	bnx2_free_skbs(bp);
+	if (rc)
+		return rc;
+
 	bnx2_init_chip(bp);
 	bnx2_init_tx_ring(bp);
 	bnx2_init_rx_ring(bp);
@@ -3108,7 +3121,11 @@
 static int
 bnx2_init_nic(struct bnx2 *bp)
 {
-	bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET);
+	int rc;
+
+	if ((rc = bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET)) != 0)
+		return rc;
+
 	bnx2_init_phy(bp);
 	bnx2_set_link(bp);
 	return 0;

^ permalink raw reply

* [PATCH 0/6] bnx2: Misc fixes
From: Michael Chan @ 2005-05-23 23:53 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev

These patches fix the following problems spotted by Jeff Garzik. Thanks
Jeff.

> 8) excessive stack size in bnx2_alloc_bad_rbuf():

> 13) [additional review] why is CHECKSUM_UNNECESSARY used when
> cksum==0xffff or cksum==0 ?

> 15) the following loop is just silly.  use mdelay or (preferably)
> msleep.

> 19) [additional review] need flush_scheduled_work(), if using work
queues?

> 21) need to call bnx2_netif_stop() in bnx2_close()

^ permalink raw reply

* Re: [PATCH] : bug fix in multipath drr code.
From: Herbert Xu @ 2005-05-23 23:22 UTC (permalink / raw)
  To: pravin; +Cc: netdev, David S. Miller
In-Reply-To: <4291CBFF.6080106@calsoftinc.com>

On Mon, May 23, 2005 at 05:56:39PM +0530, pravin wrote:
>  AFAIU, there is a race condition in multipath_drr code,
> these code paths try to access & change last_selection variable
> without any synchronization.

Yes you're right.
 
> Index: linux-2.6.12-rc4/net/ipv4/multipath_drr.c
> ===================================================================
> --- linux-2.6.12-rc4.orig/net/ipv4/multipath_drr.c	2005-05-06 22:20:31.000000000 -0700
> +++ linux-2.6.12-rc4/net/ipv4/multipath_drr.c	2005-05-22 06:41:39.000000000 -0700
> @@ -145,11 +145,13 @@
>  	int cur_min_devidx = -1;
>  
>         	/* if necessary and possible utilize the old alternative */
> -	if ((flp->flags & FLOWI_FLAG_MULTIPATHOLDROUTE) != 0 &&
> -	    last_selection != NULL) {
> -		result = last_selection;
> -		*rp = result;
> -		return;
> +	if ((flp->flags & FLOWI_FLAG_MULTIPATHOLDROUTE) != 0 ) {
> +		struct rtable *last_result = last_selection;
> +		if(last_result != NULL &&
> +		   multipath_comparekeys(&last_result->fl, flp)) {
> +			*rp = last_result;
> +			return;
> +		}
>  	}

You don't need all this code.  All you need to do is do
result = last_selection before the if condition and then
check result in the if condition instead of last_selection.

The multipath_comparekeys isn't necessary either.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: Why /sys/class/net/*/features is read-only?
From: Catalin(ux aka Dino) BOIE @ 2005-05-23 21:53 UTC (permalink / raw)
  To: David S. Miller; +Cc: shemminger, netdev
In-Reply-To: <20050523.145112.78711028.davem@davemloft.net>

On Mon, 23 May 2005, David S. Miller wrote:

> From: "Catalin(ux aka Dino) BOIE" <util@deuroconsult.ro>
> Date: Tue, 24 May 2005 00:33:14 +0300 (EEST)
>
>> On Mon, 23 May 2005, David S. Miller wrote:
>>
>>> Let them use ethtool :-)
>>
>> They can't on a bridge device, right?
>
> Currently no.  But there is no reason the bridge device
> should not have ethtool support added to it, and that's
> where this functionality belongs.

OK. I made this patch only to test how well slave notification worked.
Next days I will implement ethtool for bridge.

Thank you!
---
Catalin(ux aka Dino) BOIE
catab at deuroconsult.ro
http://kernel.umbrella.ro/

^ permalink raw reply

* Re: [PATCH linux-2.6.12-rc4-mm1] ethtool: Add NETIF_F_HW_CSUM support
From: Stephen Hemminger @ 2005-05-23 21:53 UTC (permalink / raw)
  To: David S. Miller; +Cc: jdmason, netdev
In-Reply-To: <20050523.142009.74748115.davem@davemloft.net>

On Mon, 23 May 2005 14:20:09 -0700 (PDT)
"David S. Miller" <davem@davemloft.net> wrote:

> From: Jon Mason <jdmason@us.ibm.com>
> Subject: [PATCH linux-2.6.12-rc4-mm1] ethtool: Add NETIF_F_HW_CSUM support
> Date: Mon, 23 May 2005 16:07:57 -0500
> 
> > Added support to ethtool for NETIF_F_HW_CSUM.
> > 
> > Signed-off-by: Jon Mason <jdmason@us.ibm.com>
> 
> You cannot blindly set these flags, you need to provide
> a method for the driver to override the implementation of
> this method so it can return and error if it cannot provide
> support for this feature.

This patch makes perfect sense because it allows for common code to be
used by device drivers in their ethtool_ops. So this is the logical way to handle
this.

In other words,

drivers/net/sungem.c could do

static struct ethtool_ops gem_ethtool_ops = {

+	.get_tx_csum	  = ethtool_op_get_tx_csum,
+       .set_tx_csum       = ethtool_op_set_tx_hw_csum,
};

^ permalink raw reply

* Re: Why /sys/class/net/*/features is read-only?
From: David S. Miller @ 2005-05-23 21:51 UTC (permalink / raw)
  To: util; +Cc: shemminger, netdev
In-Reply-To: <Pine.LNX.4.62.0505240032480.17855@webhosting.rdsbv.ro>

From: "Catalin(ux aka Dino) BOIE" <util@deuroconsult.ro>
Date: Tue, 24 May 2005 00:33:14 +0300 (EEST)

> On Mon, 23 May 2005, David S. Miller wrote:
> 
> > Let them use ethtool :-)
> 
> They can't on a bridge device, right?

Currently no.  But there is no reason the bridge device
should not have ethtool support added to it, and that's
where this functionality belongs.

^ permalink raw reply

* Re: [PATCH] Super TSO v3
From: David S. Miller @ 2005-05-23 21:50 UTC (permalink / raw)
  To: herbert; +Cc: netdev
In-Reply-To: <E1DaKZK-0006Qv-00@gondolin.me.apana.org.au>

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Tue, 24 May 2005 07:34:38 +1000

> Are there non-Linux systems that have the same receive issue?

Some generate stretch ACKs for other reasons (miscalculation
of MSS due to TCP Timestamps) but I doubt any other OS
implements the Van Jacobson ucopy stuff we do, and also
implement the same ACKing hack on top of that :-)

^ permalink raw reply

* Re: [PATCH linux-2.6.12-rc4-mm1] ethtool: Add NETIF_F_HW_CSUM support
From: David S. Miller @ 2005-05-23 21:48 UTC (permalink / raw)
  To: jdmason; +Cc: netdev
In-Reply-To: <200505231632.55476.jdmason@us.ibm.com>

From: Jon Mason <jdmason@us.ibm.com>
Date: Mon, 23 May 2005 16:32:55 -0500

> If ethtool_set_tx_csum does not point to ethtool_op_set_tx_csum or
> ethtool_op_set_tx_hw_csum (or a local driver function) then it will
> return an error.  Isn't this sufficient (as it is what currently
> happening), or am I not sufficently understanding the problem?

Ok, that looks right.

^ permalink raw reply

* Re: [PATCH] Super TSO v3
From: Herbert Xu @ 2005-05-23 21:34 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev
In-Reply-To: <20050523.121943.78708600.davem@davemloft.net>

David S. Miller <davem@davemloft.net> wrote:
> 
> I discoevered a performance anomaly with Linux receivers,
> cause by enormous stretch ACK generation, which you'll need
> to fix if you want to test this patch against Linux receivers.

Are there non-Linux systems that have the same receive issue?
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ 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