Netdev List
 help / color / mirror / Atom feed
* [DCCP] [RFC] [Patch 0/14]: Ack Vector implementation + fixes
From: Gerrit Renker @ 2007-12-19 14:25 UTC (permalink / raw)
  To: acme; +Cc: dccp, netdev

This set of patches adds functionality to the existing DCCP Ack Vector
implementation, extends it to a full circular buffer, and fixes two
previously undiscovered problems which otherwise result in a corrupted
buffer state. 
It is important that Ack Vectors run reliably since otherwise problems in
other parts (in particular CCID2) can not be fixed.

Quite some testing has been performed so that I am almost convinced it is
bug free. To make 100% sure that it contains no further hidden issues
as before, I would like to post this as RFC, to be eventually submitted
next year.


Patch  #1: Fixes the problem that CCID2 ignores Ack Vectors on some packets.
Patch  #2: Adds a tail pointer to the buffer and makes the size configurable.
Patch  #3: Decouples the use of Elapsed Time from the use of Ack Vectors. 
Patch  #4: Provides inlines for Ack Vector state and run length.
Patch  #5: Removes redundancies from the allocation / de-allocation routines.
Patch  #6: Splits Ack Vector specific code from option-specific code.
Patch  #7: Avoids doing unnecessary work when clearing state: the sender of
           Ack Vectors is only interested in the highest-received Ack Number
	   when clearing state. Hence parsing any Ack Vectors for this purpose
	   (which only contain lower Ack Numbers) is entirely unnecessary.
Patch  #8: Replaces #defines for Ack Vector states with enum.
Patch  #9: Provides two extensions required for robustness: overflow handling
           (indicated by a flag) and tracking the lowest-unacknowledged sequence
	   number (tail_ackno)
Patch #10: Inlines for buffer index manipulation, dynamic buffer length calculation.
Patch #11: Implements algorithm to clear buffer state (non-trivial).
Patch #12: Updates the code which registers incoming packets in the buffer.
Patch #13: Aggregates Ack-Vector specific code into one function, thus making it
           easier/simpler for the main DCCP module to use Ack Vectors.
Patch #14: Cleans up old and now unused bits.


The above patches have been uploaded to 

	git://eden-feed.erg.abdn.ac.uk/dccp_exp		[dccp]

but please note that the server will be switched off from 21/12 ... 01/08.

Detailed information and documentation can be found on 
	http://www.erg.abdn.ac.uk/users/gerrit/dccp/notes/ack_vectors/

^ permalink raw reply

* [PATCH 13/14] [ACKVEC]: Aggregate Ack-Vector related processing into single function
From: Gerrit Renker @ 2007-12-19 14:25 UTC (permalink / raw)
  To: acme; +Cc: dccp, netdev, Gerrit Renker
In-Reply-To: <1198074355-18842-13-git-send-email-gerrit@erg.abdn.ac.uk>

This aggregates Ack Vector processing (handling input and clearing old state)
into one function, for the following reasons and benefits:
 * duplicated code is removed;
 * all Ack Vector-specific processing is now in one place;
 * sanity: from an Ack Vector point of view, it is better to clear the old
   state first before entering new state;
 * Ack Event handling happens mostly within the CCIDs, not the main DCCP module.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/input.c |   38 +++++++++++---------------------------
 1 files changed, 11 insertions(+), 27 deletions(-)

--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -159,13 +159,16 @@ static void dccp_rcv_reset(struct sock *sk, struct sk_buff *skb)
 	dccp_time_wait(sk, DCCP_TIME_WAIT, 0);
 }
 
-static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb)
+static void dccp_handle_ackvec_processing(struct sock *sk, struct sk_buff *skb)
 {
-	struct dccp_sock *dp = dccp_sk(sk);
+	struct dccp_ackvec *av = dccp_sk(sk)->dccps_hc_rx_ackvec;
+	struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
 
-	if (dp->dccps_hc_rx_ackvec != NULL)
-		dccp_ackvec_clear_state(dp->dccps_hc_rx_ackvec,
-					DCCP_SKB_CB(skb)->dccpd_ack_seq);
+	if (av != NULL) {
+		if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
+			dccp_ackvec_clear_state(av, dcb->dccpd_ack_seq);
+		dccp_ackvec_input(av, dcb->dccpd_seq, DCCPAV_RECEIVED);
+	}
 }
 
 static void dccp_deliver_input_to_ccids(struct sock *sk, struct sk_buff *skb)
@@ -364,21 +367,13 @@ discard:
 int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
 			 const struct dccp_hdr *dh, const unsigned len)
 {
-	struct dccp_sock *dp = dccp_sk(sk);
-
 	if (dccp_check_seqno(sk, skb))
 		goto discard;
 
 	if (dccp_parse_options(sk, NULL, skb))
 		goto discard;
 
-	if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
-		dccp_event_ack_recv(sk, skb);
-
-	if (dp->dccps_hc_rx_ackvec != NULL &&
-	    dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
-			    DCCP_SKB_CB(skb)->dccpd_seq, DCCPAV_RECEIVED))
-		goto discard;
+	dccp_handle_ackvec_processing(sk, skb);
 	dccp_deliver_input_to_ccids(sk, skb);
 
 	return __dccp_rcv_established(sk, skb, dh, len);
@@ -507,11 +502,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
 		 */
 		if (dccp_feat_activate_values(sk, &dp->dccps_featneg))
 			goto unable_to_proceed;
-
-		if (dp->dccps_hc_rx_ackvec != NULL &&
-		    dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
-				    DCCP_SKB_CB(skb)->dccpd_seq, DCCPAV_RECEIVED))
-			goto unable_to_proceed;
+		dccp_handle_ackvec_processing(sk, skb);
 
 		dccp_send_ack(sk);
 		return -1;
@@ -632,14 +623,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
 		if (dccp_parse_options(sk, NULL, skb))
 			goto discard;
 
-		if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
-			dccp_event_ack_recv(sk, skb);
-
-		if (dp->dccps_hc_rx_ackvec != NULL &&
-		    dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
-				    DCCP_SKB_CB(skb)->dccpd_seq, DCCPAV_RECEIVED))
-			goto discard;
-
+		dccp_handle_ackvec_processing(sk, skb);
 		dccp_deliver_input_to_ccids(sk, skb);
 	}
 
-- 
1.5.3.GIT


^ permalink raw reply

* [PATCH 14/14] [ACKVEC]: Remove old infrastructure
From: Gerrit Renker @ 2007-12-19 14:25 UTC (permalink / raw)
  To: acme; +Cc: dccp, netdev, Gerrit Renker
In-Reply-To: <1198074355-18842-14-git-send-email-gerrit@erg.abdn.ac.uk>

This removes
 * functions for which updates have been provided in the preceding patches and
 * the @av_vec_len field - it is no longer necessary since the buffer length is
   now always computed dynamically;
 * conditional debugging code (CONFIG_IP_DCCP_ACKVEC).

The reason for removing the latter is that Ack Vectors are an almost
inevitable necessity - RFC 4341 says if you use CCID2, Ack Vectors
must be used. Furthermore, the code would be only interesting for going
bug-hunting. Having dealt with several bugs/problems in the code already,
I am positive that the old debugging code is no longer necessary.

Also updated copyrights.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/Kconfig       |    3 -
 net/dccp/Makefile      |    5 +-
 net/dccp/ackvec.c      |  141 +-----------------------------------------------
 net/dccp/ackvec.h      |   64 +---------------------
 net/dccp/ccids/Kconfig |    1 -
 5 files changed, 7 insertions(+), 207 deletions(-)

--- a/net/dccp/Kconfig
+++ b/net/dccp/Kconfig
@@ -25,9 +25,6 @@ config INET_DCCP_DIAG
 	def_tristate y if (IP_DCCP = y && INET_DIAG = y)
 	def_tristate m
 
-config IP_DCCP_ACKVEC
-	bool
-
 source "net/dccp/ccids/Kconfig"
 
 menu "DCCP Kernel Hacking"
--- a/net/dccp/Makefile
+++ b/net/dccp/Makefile
@@ -1,6 +1,7 @@
 obj-$(CONFIG_IP_DCCP) += dccp.o dccp_ipv4.o
 
-dccp-y := ccid.o feat.o input.o minisocks.o options.o output.o proto.o timer.o
+dccp-y := ccid.o feat.o input.o minisocks.o options.o \
+	  output.o proto.o timer.o ackvec.o
 
 dccp_ipv4-y := ipv4.o
 
@@ -8,8 +9,6 @@ dccp_ipv4-y := ipv4.o
 obj-$(subst y,$(CONFIG_IP_DCCP),$(CONFIG_IPV6)) += dccp_ipv6.o
 dccp_ipv6-y := ipv6.o
 
-dccp-$(CONFIG_IP_DCCP_ACKVEC) += ackvec.o
-
 obj-$(CONFIG_INET_DCCP_DIAG) += dccp_diag.o
 obj-$(CONFIG_NET_DCCPPROBE) += dccp_probe.o
 
--- a/net/dccp/ackvec.c
+++ b/net/dccp/ackvec.c
@@ -1,26 +1,18 @@
 /*
  *  net/dccp/ackvec.c
  *
- *  An implementation of the DCCP protocol
+ *  An implementation of Ack Vectors for the DCCP protocol
+ *  Copyright (c) 2007 University of Aberdeen, Scotland, UK
  *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
  *
  *      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; version 2 of the License;
  */
-
-#include "ackvec.h"
 #include "dccp.h"
-
-#include <linux/dccp.h>
-#include <linux/init.h>
-#include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/skbuff.h>
 #include <linux/slab.h>
 
-#include <net/sock.h>
-
 static struct kmem_cache *dccp_ackvec_slab;
 static struct kmem_cache *dccp_ackvec_record_slab;
 
@@ -31,7 +23,6 @@ struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority)
 	if (av != NULL) {
 		av->av_buf_head	= av->av_buf_tail = DCCPAV_MAX_ACKVEC_LEN - 1;
 		av->av_overflow = 0;
-		av->av_vec_len	 = 0;
 		memset(av->av_buf_nonce, 0, sizeof(av->av_buf_nonce));
 		INIT_LIST_HEAD(&av->av_records);
 	}
@@ -257,134 +248,6 @@ void dccp_ackvec_input(struct dccp_ackvec *av, u64 seqno, u8 state)
 	}
 }
 
-/*
- * If several packets are missing, the HC-Receiver may prefer to enter multiple
- * bytes with run length 0, rather than a single byte with a larger run length;
- * this simplifies table updates if one of the missing packets arrives.
- */
-static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av,
-						 const unsigned int packets,
-						 const unsigned char state)
-{
-	unsigned int gap;
-	long new_head;
-
-	if (av->av_vec_len + packets > DCCPAV_MAX_ACKVEC_LEN)
-		return -ENOBUFS;
-
-	gap	 = packets - 1;
-	new_head = av->av_buf_head - packets;
-
-	if (new_head < 0) {
-		if (gap > 0) {
-			memset(av->av_buf, DCCPAV_NOT_RECEIVED,
-			       gap + new_head + 1);
-			gap = -new_head;
-		}
-		new_head += DCCPAV_MAX_ACKVEC_LEN;
-	}
-
-	av->av_buf_head = new_head;
-
-	if (gap > 0)
-		memset(av->av_buf + av->av_buf_head + 1,
-		       DCCPAV_NOT_RECEIVED, gap);
-
-	av->av_buf[av->av_buf_head] = state;
-	av->av_vec_len += packets;
-	return 0;
-}
-
-/*
- * Implements the RFC 4340, Appendix A
- */
-int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
-		    const u64 ackno, const u8 state)
-{
-	u8 *cur_head = av->av_buf + av->av_buf_head,
-	   *buf_end  = av->av_buf + DCCPAV_MAX_ACKVEC_LEN;
-	/*
-	 * Check at the right places if the buffer is full, if it is, tell the
-	 * caller to start dropping packets till the HC-Sender acks our ACK
-	 * vectors, when we will free up space in av_buf.
-	 *
-	 * We may well decide to do buffer compression, etc, but for now lets
-	 * just drop.
-	 *
-	 * From Appendix A.1.1 (`New Packets'):
-	 *
-	 *	Of course, the circular buffer may overflow, either when the
-	 *	HC-Sender is sending data at a very high rate, when the
-	 *	HC-Receiver's acknowledgements are not reaching the HC-Sender,
-	 *	or when the HC-Sender is forgetting to acknowledge those acks
-	 *	(so the HC-Receiver is unable to clean up old state). In this
-	 *	case, the HC-Receiver should either compress the buffer (by
-	 *	increasing run lengths when possible), transfer its state to
-	 *	a larger buffer, or, as a last resort, drop all received
-	 *	packets, without processing them whatsoever, until its buffer
-	 *	shrinks again.
-	 */
-
-	/* See if this is the first ackno being inserted */
-	if (av->av_vec_len == 0) {
-		*cur_head = state;
-		av->av_vec_len = 1;
-	} else if (after48(ackno, av->av_buf_ackno)) {
-		const u64 delta = dccp_delta_seqno(av->av_buf_ackno, ackno);
-
-		/*
-		 * Look if the state of this packet is the same as the
-		 * previous ackno and if so if we can bump the head len.
-		 */
-		if (delta == 1 && dccp_ackvec_state(cur_head) == state &&
-		    dccp_ackvec_runlen(cur_head) < DCCPAV_MAX_RUNLEN)
-			*cur_head += 1;
-		else if (dccp_ackvec_set_buf_head_state(av, delta, state))
-			return -ENOBUFS;
-	} else {
-		/*
-		 * A.1.2.  Old Packets
-		 *
-		 *	When a packet with Sequence Number S <= buf_ackno
-		 *	arrives, the HC-Receiver will scan the table for
-		 *	the byte corresponding to S. (Indexing structures
-		 *	could reduce the complexity of this scan.)
-		 */
-		u64 delta = dccp_delta_seqno(ackno, av->av_buf_ackno);
-
-		while (1) {
-			const u8 len = dccp_ackvec_runlen(cur_head);
-			/*
-			 * valid packets not yet in av_buf have a reserved
-			 * entry, with a len equal to 0.
-			 */
-			if (*cur_head == DCCPAV_NOT_RECEIVED && delta == 0) {
-				dccp_pr_debug("Found %llu reserved seat!\n",
-					      (unsigned long long)ackno);
-				*cur_head = state;
-				goto out;
-			}
-			/* len == 0 means one packet */
-			if (delta < len + 1)
-				goto out_duplicate;
-
-			delta -= len + 1;
-			if (++cur_head == buf_end)
-				cur_head = av->av_buf;
-		}
-	}
-
-	av->av_buf_ackno = ackno;
-out:
-	return 0;
-
-out_duplicate:
-	/* Duplicate packet */
-	dccp_pr_debug("Received a dup or already considered lost "
-		      "packet: %llu\n", (unsigned long long)ackno);
-	return -EILSEQ;
-}
-
 /**
  * dccp_ackvec_clear_state  -  Perform house-keeping / garbage-collection
  * This routine is called when the peer acknowledges the receipt of Ack Vectors
--- a/net/dccp/ackvec.h
+++ b/net/dccp/ackvec.h
@@ -3,9 +3,9 @@
 /*
  *  net/dccp/ackvec.h
  *
- *  An implementation of the DCCP protocol
+ *  An implementation of Ack Vectors for the DCCP protocol
+ *  Copyright (c) 2007 University of Aberdeen, Scotland, UK
  *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@mandriva.com>
- *
  *	This program is free software; you can redistribute it and/or modify it
  *	under the terms of the GNU General Public License version 2 as
  *	published by the Free Software Foundation.
@@ -59,7 +59,6 @@ static inline u8 dccp_ackvec_state(const u8 *cell)
  *		   %DCCP_SINGLE_OPT_MAXLEN cells in the live portion of @av_buf
  * @av_overflow:   if 1 then buf_head == buf_tail indicates buffer wraparound
  * @av_records:	   list of %dccp_ackvec_record (Ack Vectors sent previously)
- * @av_veclen:	   length of the live portion of @av_buf
  */
 struct dccp_ackvec {
 	u8			av_buf[DCCPAV_MAX_ACKVEC_LEN];
@@ -70,7 +69,6 @@ struct dccp_ackvec {
 	bool			av_buf_nonce[DCCPAV_NUM_ACKVECS];
 	u8			av_overflow:1;
 	struct list_head	av_records;
-	u16			av_vec_len;
 };
 
 /** struct dccp_ackvec_record - Records information about sent Ack Vectors
@@ -96,19 +94,12 @@ struct dccp_ackvec_record {
 	u8		 avr_ack_nonce:1;
 };
 
-struct sock;
-struct sk_buff;
-
-#ifdef CONFIG_IP_DCCP_ACKVEC
-extern int dccp_ackvec_init(void);
+extern int  dccp_ackvec_init(void);
 extern void dccp_ackvec_exit(void);
 
 extern struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority);
 extern void dccp_ackvec_free(struct dccp_ackvec *av);
 
-extern int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
-			   const u64 ackno, const u8 state);
-
 extern void dccp_ackvec_input(struct dccp_ackvec *av, u64 seqno, u8 state);
 extern int  dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seq, u8 sum);
 extern void dccp_ackvec_clear_state(struct dccp_ackvec *av, const u64 ackno);
@@ -118,53 +109,4 @@ static inline bool dccp_ackvec_is_empty(const struct dccp_ackvec *av)
 {
 	return av->av_overflow == 0 && av->av_buf_head == av->av_buf_tail;
 }
-#else /* CONFIG_IP_DCCP_ACKVEC */
-static inline int dccp_ackvec_init(void)
-{
-	return 0;
-}
-
-static inline void dccp_ackvec_exit(void)
-{
-}
-
-static inline struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority)
-{
-	return NULL;
-}
-
-static inline void dccp_ackvec_free(struct dccp_ackvec *av)
-{
-}
-
-static inline void dccp_ackvec_input(struct dccp_ackvec *av, u64 seq, u8 state)
-{
-
-}
-
-static inline int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
-				  const u64 ackno, const u8 state)
-{
-	return -1;
-}
-
-static inline void dccp_ackvec_clear_state(struct dccp_ackvec *av, const u64 ackno)
-{
-}
-
-static inline int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seq, u8 nonce)
-{
-	return -1;
-}
-
-static inline u16 dccp_ackvec_buflen(const struct dccp_ackvec *av)
-{
-	return 0;
-}
-
-static inline bool dccp_ackvec_is_empty(const struct dccp_ackvec *av)
-{
-	return true;
-}
-#endif /* CONFIG_IP_DCCP_ACKVEC */
 #endif /* _ACKVEC_H */
--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -4,7 +4,6 @@ menu "DCCP CCIDs Configuration (EXPERIMENTAL)"
 config IP_DCCP_CCID2
 	tristate "CCID2 (TCP-Like) (EXPERIMENTAL)"
 	def_tristate IP_DCCP
-	select IP_DCCP_ACKVEC
 	---help---
 	  CCID 2, TCP-like Congestion Control, denotes Additive Increase,
 	  Multiplicative Decrease (AIMD) congestion control with behavior
-- 
1.5.3.GIT


^ permalink raw reply

* dn_neigh_table vs pneigh_lookup/pneigh_delete
From: Pavel Emelyanov @ 2007-12-19 14:11 UTC (permalink / raw)
  To: Linux Netdev List, Patrick Caulfield, linux-decnet-user

Hi

The pneigh_lookup/delete silently concerns, that the 
key_len of the table is more that 4 bytes. Look:

         u32 hash_val = *(u32 *)(pkey + key_len - 4);

The hash_val for the proxy neighbor entry is four last bytes
from the pkey.

But the dn_neigh_tables' key_len is sizeof(__le16), that is 2,
so setting (via netlink) the proxy neighbor entry for decnet 
will cause this entry to reside in arbitrary hash chain.

Is this too bad for decnet?

Thanks,
Pavel

^ permalink raw reply

* Re: Inline local_bh_disable when TRACE_IRQFLAGS
From: Ingo Molnar @ 2007-12-19 14:03 UTC (permalink / raw)
  To: Herbert Xu; +Cc: Linux Kernel Mailing List, David S. Miller, netdev
In-Reply-To: <20071219115019.GA9099@gondor.apana.org.au>


* Herbert Xu <herbert@gondor.apana.org.au> wrote:

> On Wed, Dec 19, 2007 at 12:31:52PM +0100, Ingo Molnar wrote:
> >
> > > So I'm wondering if it would be reasonable to make it out-of-line 
> > > when TRACE_IRQFLAGS is off.  This may make a difference because 
> > > the networking stack is a frequent user of local_bh_disable and 
> > > local_bh_enable.
> > 
> > do you mean to make it inline again?
> 
> Yes I meant in-line :)

if that decreases code size then i guess we could do that.

> > (btw., generally i think local_bh_disable() is a poor API because it 
> > is opaque about the data structure dependency that it governs. 
> > Explicit exclusion rules generally work better.)
> 
> I see where you're coming from especially with your preemptible 
> softirq work.  However I'm mostly thinking about the existing callers 
> of local_bh_disable in the networking stack.

yeah, i was just commenting on the general concept of 'naked' 
local_bh_disable(). And just to make it clear: with that i'm not 
implying anything about the quality of the networking code - networking 
is one of the cleanest [if not the cleanest] subsystems in the kernel. 

It's just that it's long term more useful for us if our "global scope" 
APIs have direct, programmatic relationship to the data structures / 
data flow they control. So i'd love to have the same flow/performance, 
just coded a bit more explicitly. [preempt_disable() for example has 
similar issues.]

	Ingo

^ permalink raw reply

* Re: [PATCH/RFC] [v2] TCP: use non-delayed ACK for congestion control RTT
From: Ilpo Järvinen @ 2007-12-19 13:30 UTC (permalink / raw)
  To: Gavin McCullagh; +Cc: Netdev, David Miller
In-Reply-To: <20071219113125.GF31508@nuim.ie>

[-- Attachment #1: Type: TEXT/PLAIN, Size: 2350 bytes --]

On Wed, 19 Dec 2007, Gavin McCullagh wrote:

> On Wed, 19 Dec 2007, Ilpo Järvinen wrote:
>
> > Isn't it also much better this way in a case where ACK losses happened,
> > taking the longest RTT in that case is clearly questionable as it
> > may over-estimate considerably.
> 
> Quite so.
> 
> > However, another thing to consider is the possibility of this value being 
> > used in "timeout-like" fashion in ca modules (I haven't read enough ca 
> > modules code to know if any of them does that), on contrary to 
> > determinating just rtt or packet's delay in which case this change seems 
> > appropriate (most modules do the latter). 
> 
> I'm not aware of any, but I haven't read them all either.  I would have
> thought tp->srtt was the value to use in this instance,

Very likely so...

> > Therefore, if timeout-like module exists one should also add
> > TCP_CONG_RTT_STAMP_LONGEST for that particular module and keep using
> > seq_rtt for it like previously and use ca_seq_rtt only for others.
> 
> Seems reasonable.  I'll add this.

...therefore I said "if". I'm not sure what they all do, haven't read them 
all that carefully... :-) Please check first if ..._LONGEST is necessary 
at all by quickly going through how the ca modules use it, I guess most of 
them won't be that complicated, one can probably figure out the intented 
usage by couple of minutes review. If there aren't any modules who need 
delayed ACK & other path caused delays included, ..._LONGEST would just 
end up being unnecessary cruft :-).

> > This part doesn't exists anymore in development tree. Please base this 
> > patch (and anything in future) you intend to get included to mainline
> > onto net-2.6.25 unless there's a very good reason to not do so or 
> > whatever 2.6.xx is the correct net development tree at that time (if
> > one exists). Thanks.
> 
> Will do.   I gather I should use the latest net- tree in future when
> submitting patches.

Doh, I owe you apology as I was probably too hasty to point you towards 
net-2.6.25. I suppose this could by considered as fix as well and 
therefore could probably be accepted to net-2.6 as well, which is for 
bugfixes only after merge window is closed. But it's Dave how will make 
such decisions, not me :-), and it's he who gets to deal with all 
the resulting conflicts ;-) (I added Cc to him).

-- 
 i.

^ permalink raw reply

* Re: [PATCH net-2.6.25 1/3] Uninline the __inet_hash function
From: Pavel Emelyanov @ 2007-12-19 13:22 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, Linux Netdev List, devel
In-Reply-To: <47690CD1.9060502@cosmosbay.com>

Eric Dumazet wrote:
> Pavel Emelyanov a écrit :
>> This one is used in quite many places in the networking code and
>> seems to big to be inline.
>>
>> After the patch net/ipv4/build-in.o loses 725 bytes:
>> add/remove: 1/0 grow/shrink: 0/5 up/down: 374/-1099 (-725)
>> function                                     old     new   delta
>> __inet_hash                                    -     374    +374
>> tcp_sacktag_write_queue                     2255    2254      -1
>> __inet_lookup_listener                       284     274     -10
>> tcp_v4_syn_recv_sock                         755     495    -260
>> tcp_v4_hash                                  389      40    -349
>> inet_hash_connect                           1165     686    -479
>>
>> Exporting this is for dccp module.
>>
>> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
>>
>> ---
>>
>>  include/net/inet_hashtables.h |   27 ++-------------------------
>>  net/ipv4/inet_hashtables.c    |   27 +++++++++++++++++++++++++++
>>  2 files changed, 29 insertions(+), 25 deletions(-)
>>
>> diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
>> index 37f6cb1..1a43125 100644
>> --- a/include/net/inet_hashtables.h
>> +++ b/include/net/inet_hashtables.h
>> @@ -264,31 +264,8 @@ static inline void inet_listen_unlock(struct inet_hashinfo *hashinfo)
>>  		wake_up(&hashinfo->lhash_wait);
>>  }
>>  
>> -static inline void __inet_hash(struct inet_hashinfo *hashinfo,
>> -			       struct sock *sk, const int listen_possible)
>> -{
>> -	struct hlist_head *list;
>> -	rwlock_t *lock;
>> -
>> -	BUG_TRAP(sk_unhashed(sk));
>> -	if (listen_possible && sk->sk_state == TCP_LISTEN) {
>> -		list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
>> -		lock = &hashinfo->lhash_lock;
>> -		inet_listen_wlock(hashinfo);
>> -	} else {
>> -		struct inet_ehash_bucket *head;
>> -		sk->sk_hash = inet_sk_ehashfn(sk);
>> -		head = inet_ehash_bucket(hashinfo, sk->sk_hash);
>> -		list = &head->chain;
>> -		lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
>> -		write_lock(lock);
>> -	}
>> -	__sk_add_node(sk, list);
>> -	sock_prot_inc_use(sk->sk_prot);
>> -	write_unlock(lock);
>> -	if (listen_possible && sk->sk_state == TCP_LISTEN)
>> -		wake_up(&hashinfo->lhash_wait);
>> -}
>> +extern void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk,
>> +		const int listen_possible);
>>  
>>  static inline void inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk)
>>  {
>> diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
>> index 67704da..46f899b 100644
>> --- a/net/ipv4/inet_hashtables.c
>> +++ b/net/ipv4/inet_hashtables.c
>> @@ -267,6 +267,33 @@ static inline u32 inet_sk_port_offset(const struct sock *sk)
>>  					  inet->dport);
>>  }
>>  
>> +void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk,
>> +		const int listen_possible)
>> +{
>> +	struct hlist_head *list;
>> +	rwlock_t *lock;
>> +
>> +	BUG_TRAP(sk_unhashed(sk));
>> +	if (listen_possible && sk->sk_state == TCP_LISTEN) {
>> +		list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
>> +		lock = &hashinfo->lhash_lock;
>> +		inet_listen_wlock(hashinfo);
>> +	} else {
>> +		struct inet_ehash_bucket *head;
>> +		sk->sk_hash = inet_sk_ehashfn(sk);
>> +		head = inet_ehash_bucket(hashinfo, sk->sk_hash);
>> +		list = &head->chain;
>> +		lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
>> +		write_lock(lock);
>> +	}
>> +	__sk_add_node(sk, list);
>> +	sock_prot_inc_use(sk->sk_prot);
>> +	write_unlock(lock);
>> +	if (listen_possible && sk->sk_state == TCP_LISTEN)
>> +		wake_up(&hashinfo->lhash_wait);
>> +}
>> +EXPORT_SYMBOL_GPL(__inet_hash);
>> +
>>  /*
>>   * Bind a port for a connect operation and hash it.
>>   */
> 
> If you un-inline this (good idea), I am not sure we still need listen_possible 
> argument.
> 
> It was usefull only to help compiler to zap dead code (since it was known at 
> compile time), now it only adds some extra test and argument passing.

Hm... I've tried to address this issue and got worse result - minus
600 bytes (vs minus 725). So, what would be more preferable - get a 
smaller code with one extra 'if' or get a bit larger code without it?

> Thank you

Thanks,
Pavel

^ permalink raw reply

* Re: (usagi-core 34069) Re: [IPSEC]: Do xfrm_state_check_space before encapsulation
From: Kazunori MIAZAWA @ 2007-12-19 13:23 UTC (permalink / raw)
  To: usagi-core; +Cc: herbert, miyazawa, netdev
In-Reply-To: <20071218.221456.49781139.davem@davemloft.net>

David Miller wrote:
> From: Herbert Xu <herbert@gondor.apana.org.au>
> Date: Wed, 19 Dec 2007 14:12:10 +0800
> 
>> [IPSEC]: Do xfrm_state_check_space before encapsulation
>>
>> While merging the IPsec output path I moved the encapsulation output
>> operation to the top of the loop so that it sits outside of the locked
>> section.  Unfortunately in doing so it now sits in front of the space
>> check as well which could be a fatal error.
>>
>> This patch rearranges the calls so that the space check happens as
>> the thing on the output path.
>>
>> This patch also fixes an incorrect goto should the encapsulation output
>> fail.
>>
>> Thanks to Kazunori MIYAZAWA for finding this bug.
>>
>> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
> 
> Applied, thanks Herbert.
> 
> 

Thank you for your quick response :-)

--
Kazunori Miyazawa


^ permalink raw reply

* Re: 2.6.24-rc5-mm1 -- INFO: possible circular locking dependency detected -- pm-suspend/5800 is trying to acquire lock
From: Miles Lane @ 2007-12-19 13:10 UTC (permalink / raw)
  To: Zhu Yi
  Cc: Len Brown, netdev, LKML, ipw3945-devel, Rafael J. Wysocki,
	Pavel Machek, Johannes Berg, Andrew Morton
In-Reply-To: <1198033082.2857.303.camel@debian.sh.intel.com>

On Dec 18, 2007 9:58 PM, Zhu Yi <yi.zhu@intel.com> wrote:
>
> On Tue, 2007-12-18 at 15:57 +0100, Johannes Berg wrote:
> > Thanks. This is a bug in iwlwifi.
> >
> > The problem is actually another case where my workqueue debugging with
> > lockdep is triggering a warning :))
> >
> > Here's the thing:
> >
> > iwl3945_cancel_deferred_work does
> >
> > cancel_delayed_work_sync(&priv->init_alive_start);
> >
> > (which is the "(&(&priv->init_alive_start)->work)" lock)
> >
> > but it is called from within a locked section of
> > mutex_lock(&priv->mutex); (locked from iwl3945_pci_suspend)
> >
> > On the other hand, the task that runs from the init_alive_start
> > workqueue is iwl3945_bg_init_alive_start() which will lock the same
> > mutex.
> >
> > So the deadlock condition is that you can be in
> > cancel_delayed_work_sync() above while the mutex is locked, and be
> > waiting for iwl_3945_bg_init_alive_start() which tries to lock the
> > mutex.
>
> Thanks for the analysis.
>
> Miles, please try the attached patch. I'll send a patch for both 3945
> and 4965 to linux-wireless later.

I tested it and it looks good here.  Thanks!

        Miles

-------------------------------------------------------------------------
SF.Net email is sponsored by:
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services
for just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace

^ permalink raw reply

* Re: After many hours all outbound connections get stuck in SYN_SENT
From: Ilpo Järvinen @ 2007-12-19 12:54 UTC (permalink / raw)
  To: James Nichols; +Cc: Netdev
In-Reply-To: <83a51e120712160834r29112fb0xa1f61c35f180bf8f@mail.gmail.com>

On Sun, 16 Dec 2007, James Nichols wrote:

> I have a Java application that makes a large number of outbound
> webservice calls over HTTP/TCP.  The hosts contacted are a fixed set
> of about 2000 hosts and a web service call is made to each of them
> approximately every 5 mintues by a pool of 200 Java threads.  Over
> time, on average a percentage of these hosts are unreachable for one
> reason or another, usually because they are on wireless cell phone
> NICs, so there is a persistent count of sockets in the SYN_SENT state
> in the range of about 60-80.  This is fine, as these failed connection
> attempts eventually time out.
> 
> However, after approximately 38 hours of operation, all outbound
> connection attempts get stuck in the SYN_SENT state.  It happens
> instantaneously, where I go from the baseline of about 60-80 sockets
> in SYN_SENT to a count of 200 (corresponding to the # of java threads
> that make these calls).
> 
> When I stop and start the Java application, all the new outbound
> connections still get stuck in SYN_SENT state.

Is it so that they don't timeout at all? You can collect some of their 
state from /proc/net/tcp (shows at least timers and attempt counters)....

> During this time, I am
> still able to SSH to the box and run wget to Google, cnn, etc, so the
> problem appears to be specific to the hosts that I'm accessing via the
> webservices.

Are you sure that you just don't get unlucky at some point of time and 
all 200 available threads are just temporarily stuck and your application 
is just very slowly progressing then?

> For a long time, the only thing that would resolve this was rebooting
> the entire machine.  Once I did this, the outbound connections could
> be made succesfully.

To the very same hosts? Or to another set of hosts?

> However, very recently when I had once of these incidents I disabled 
> tcp_sack via:
> 
> echo "0" > /proc/sys/net/ipv4/tcp_sack
> 
> And the problem almost instanteaously resolved itself and outbound
> connection attempts were succesful.

New or the pending ones?

> I hadn't attempted this before because I assumed that if any of my 
> network
> equipment or remote hosts had a problem with SACK, that it would never
> work.

Many bugs just are not like that at all... Usually people who coded things 
had at least some clue :-), so things work "almost correctly"...

>  In my case, it worked fine for about 38 hours before hitting a
> wall where no outbound connections could be made.

How accurate number? Is the lockup somehow related to daytime cycle?

> Is there a kernel buffer or some data structure that tcp_sack uses
> that gets filled up after an extended period of operation?

SACK has pretty little meaning in context of SYNs, there's only the 
sackperm(itted) TCP option which is sent along with the SYN/SYN-ACK.

The SACK scoreboard is currently included to the skbs (has been like 
this for very long time), so no additional data structures should be
there because of SACK...

> How can I debug this problem in the kernel to find out what the root cause is?
> 
> I emailed linux-kernel and they asked for output of netstat -s, I can
> get this the next
> time it occurs- any other usefull data to collect?

/proc/net/tcp couple of times in a row, try something something like
this:

for i in (seq 1 40); do cat /proc/net/tcp; echo "-----"; sleep 10; done


> I'm running kernel 2.6.18 on RedHat, but have had this problem occur
> on earlier kernel versions (all 2.4 and 2.6).

I've done some fixes to SACK processing since 2.6.18 (not sure if RedHat 
has backported them). Though they're not that critical nor anything in 
them should affect in SYN_SENT state.


-- 
 i.

^ permalink raw reply

* Re: [UPDATED PATCH] SGISEEQ: use cached memory access to make driver work on IP28
From: Thomas Bogendoerfer @ 2007-12-19 12:42 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev, linux-mips, ralf
In-Reply-To: <476867F5.3070006@pobox.com>

- Use inline functions for dma_sync_* instead of macros 
- added Kconfig change to make selection for similair SGI boxes easier

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---

 drivers/net/Kconfig   |    2 +-
 drivers/net/sgiseeq.c |   64 ++++++++++++++++++++++++++-----------------------
 2 files changed, 35 insertions(+), 31 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 84df799..f816798 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1807,7 +1807,7 @@ config DE620
 
 config SGISEEQ
 	tristate "SGI Seeq ethernet controller support"
-	depends on SGI_IP22
+	depends on SGI_HAS_SEEQ
 	help
 	  Say Y here if you have an Seeq based Ethernet network card. This is
 	  used in many Silicon Graphics machines.
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index 3145ca1..c69bb8b 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -56,14 +56,6 @@ static char *sgiseeqstr = "SGI Seeq8003";
 				  (dma_addr_t)((unsigned long)(v) -            \
 					       (unsigned long)((sp)->rx_desc)))
 
-#define DMA_SYNC_DESC_CPU(dev, addr) \
-	do { dma_cache_sync((dev)->dev.parent, (void *)addr, \
-	     sizeof(struct sgiseeq_rx_desc), DMA_FROM_DEVICE); } while (0)
-
-#define DMA_SYNC_DESC_DEV(dev, addr) \
-	do { dma_cache_sync((dev)->dev.parent, (void *)addr, \
-	     sizeof(struct sgiseeq_rx_desc), DMA_TO_DEVICE); } while (0)
-
 /* Copy frames shorter than rx_copybreak, otherwise pass on up in
  * a full sized sk_buff.  Value of 100 stolen from tulip.c (!alpha).
  */
@@ -116,6 +108,18 @@ struct sgiseeq_private {
 	spinlock_t tx_lock;
 };
 
+static inline void dma_sync_desc_cpu(struct net_device *dev, void *addr)
+{
+	dma_cache_sync(dev->dev.parent, addr, sizeof(struct sgiseeq_rx_desc),
+		       DMA_FROM_DEVICE);
+}
+
+static inline void dma_sync_desc_dev(struct net_device *dev, void *addr)
+{
+	dma_cache_sync(dev->dev.parent, addr, sizeof(struct sgiseeq_rx_desc),
+		       DMA_TO_DEVICE);
+}
+
 static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs)
 {
 	hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ;
@@ -184,7 +188,7 @@ static int seeq_init_ring(struct net_device *dev)
 	/* Setup tx ring. */
 	for(i = 0; i < SEEQ_TX_BUFFERS; i++) {
 		sp->tx_desc[i].tdma.cntinfo = TCNTINFO_INIT;
-		DMA_SYNC_DESC_DEV(dev, &sp->tx_desc[i]);
+		dma_sync_desc_dev(dev, &sp->tx_desc[i]);
 	}
 
 	/* And now the rx ring. */
@@ -203,10 +207,10 @@ static int seeq_init_ring(struct net_device *dev)
 			sp->rx_desc[i].rdma.pbuf = dma_addr;
 		}
 		sp->rx_desc[i].rdma.cntinfo = RCNTINFO_INIT;
-		DMA_SYNC_DESC_DEV(dev, &sp->rx_desc[i]);
+		dma_sync_desc_dev(dev, &sp->rx_desc[i]);
 	}
 	sp->rx_desc[i - 1].rdma.cntinfo |= HPCDMA_EOR;
-	DMA_SYNC_DESC_DEV(dev, &sp->rx_desc[i - 1]);
+	dma_sync_desc_dev(dev, &sp->rx_desc[i - 1]);
 	return 0;
 }
 
@@ -341,7 +345,7 @@ static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp
 
 	/* Service every received packet. */
 	rd = &sp->rx_desc[sp->rx_new];
-	DMA_SYNC_DESC_CPU(dev, rd);
+	dma_sync_desc_cpu(dev, rd);
 	while (!(rd->rdma.cntinfo & HPCDMA_OWN)) {
 		len = PKT_BUF_SZ - (rd->rdma.cntinfo & HPCDMA_BCNT) - 3;
 		dma_unmap_single(dev->dev.parent, rd->rdma.pbuf,
@@ -397,16 +401,16 @@ memory_squeeze:
 		/* Return the entry to the ring pool. */
 		rd->rdma.cntinfo = RCNTINFO_INIT;
 		sp->rx_new = NEXT_RX(sp->rx_new);
-		DMA_SYNC_DESC_DEV(dev, rd);
+		dma_sync_desc_dev(dev, rd);
 		rd = &sp->rx_desc[sp->rx_new];
-		DMA_SYNC_DESC_CPU(dev, rd);
+		dma_sync_desc_cpu(dev, rd);
 	}
-	DMA_SYNC_DESC_CPU(dev, &sp->rx_desc[orig_end]);
+	dma_sync_desc_cpu(dev, &sp->rx_desc[orig_end]);
 	sp->rx_desc[orig_end].rdma.cntinfo &= ~(HPCDMA_EOR);
-	DMA_SYNC_DESC_DEV(dev, &sp->rx_desc[orig_end]);
-	DMA_SYNC_DESC_CPU(dev, &sp->rx_desc[PREV_RX(sp->rx_new)]);
+	dma_sync_desc_dev(dev, &sp->rx_desc[orig_end]);
+	dma_sync_desc_cpu(dev, &sp->rx_desc[PREV_RX(sp->rx_new)]);
 	sp->rx_desc[PREV_RX(sp->rx_new)].rdma.cntinfo |= HPCDMA_EOR;
-	DMA_SYNC_DESC_DEV(dev, &sp->rx_desc[PREV_RX(sp->rx_new)]);
+	dma_sync_desc_dev(dev, &sp->rx_desc[PREV_RX(sp->rx_new)]);
 	rx_maybe_restart(sp, hregs, sregs);
 }
 
@@ -433,12 +437,12 @@ static inline void kick_tx(struct net_device *dev,
 	 * is not active!
 	 */
 	td = &sp->tx_desc[i];
-	DMA_SYNC_DESC_CPU(dev, td);
+	dma_sync_desc_cpu(dev, td);
 	while ((td->tdma.cntinfo & (HPCDMA_XIU | HPCDMA_ETXD)) ==
 	      (HPCDMA_XIU | HPCDMA_ETXD)) {
 		i = NEXT_TX(i);
 		td = &sp->tx_desc[i];
-		DMA_SYNC_DESC_CPU(dev, td);
+		dma_sync_desc_cpu(dev, td);
 	}
 	if (td->tdma.cntinfo & HPCDMA_XIU) {
 		hregs->tx_ndptr = VIRT_TO_DMA(sp, td);
@@ -470,7 +474,7 @@ static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp
 	for (j = sp->tx_old; j != sp->tx_new; j = NEXT_TX(j)) {
 		td = &sp->tx_desc[j];
 
-		DMA_SYNC_DESC_CPU(dev, td);
+		dma_sync_desc_cpu(dev, td);
 		if (!(td->tdma.cntinfo & (HPCDMA_XIU)))
 			break;
 		if (!(td->tdma.cntinfo & (HPCDMA_ETXD))) {
@@ -488,7 +492,7 @@ static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp
 			dev_kfree_skb_any(td->skb);
 			td->skb = NULL;
 		}
-		DMA_SYNC_DESC_DEV(dev, td);
+		dma_sync_desc_dev(dev, td);
 	}
 }
 
@@ -598,7 +602,7 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev->stats.tx_bytes += len;
 	entry = sp->tx_new;
 	td = &sp->tx_desc[entry];
-	DMA_SYNC_DESC_CPU(dev, td);
+	dma_sync_desc_cpu(dev, td);
 
 	/* Create entry.  There are so many races with adding a new
 	 * descriptor to the chain:
@@ -618,14 +622,14 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
 				       len, DMA_TO_DEVICE);
 	td->tdma.cntinfo = (len & HPCDMA_BCNT) |
 	                   HPCDMA_XIU | HPCDMA_EOXP | HPCDMA_XIE | HPCDMA_EOX;
-	DMA_SYNC_DESC_DEV(dev, td);
+	dma_sync_desc_dev(dev, td);
 	if (sp->tx_old != sp->tx_new) {
 		struct sgiseeq_tx_desc *backend;
 
 		backend = &sp->tx_desc[PREV_TX(sp->tx_new)];
-		DMA_SYNC_DESC_CPU(dev, backend);
+		dma_sync_desc_cpu(dev, backend);
 		backend->tdma.cntinfo &= ~HPCDMA_EOX;
-		DMA_SYNC_DESC_DEV(dev, backend);
+		dma_sync_desc_dev(dev, backend);
 	}
 	sp->tx_new = NEXT_TX(sp->tx_new); /* Advance. */
 
@@ -681,11 +685,11 @@ static inline void setup_tx_ring(struct net_device *dev,
 	while (i < (nbufs - 1)) {
 		buf[i].tdma.pnext = VIRT_TO_DMA(sp, buf + i + 1);
 		buf[i].tdma.pbuf = 0;
-		DMA_SYNC_DESC_DEV(dev, &buf[i]);
+		dma_sync_desc_dev(dev, &buf[i]);
 		i++;
 	}
 	buf[i].tdma.pnext = VIRT_TO_DMA(sp, buf);
-	DMA_SYNC_DESC_DEV(dev, &buf[i]);
+	dma_sync_desc_dev(dev, &buf[i]);
 }
 
 static inline void setup_rx_ring(struct net_device *dev,
@@ -698,12 +702,12 @@ static inline void setup_rx_ring(struct net_device *dev,
 	while (i < (nbufs - 1)) {
 		buf[i].rdma.pnext = VIRT_TO_DMA(sp, buf + i + 1);
 		buf[i].rdma.pbuf = 0;
-		DMA_SYNC_DESC_DEV(dev, &buf[i]);
+		dma_sync_desc_dev(dev, &buf[i]);
 		i++;
 	}
 	buf[i].rdma.pbuf = 0;
 	buf[i].rdma.pnext = VIRT_TO_DMA(sp, buf);
-	DMA_SYNC_DESC_DEV(dev, &buf[i]);
+	dma_sync_desc_dev(dev, &buf[i]);
 }
 
 static int __init sgiseeq_probe(struct platform_device *pdev)

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea.                                                [ RFC1925, 2.3 ]

^ permalink raw reply related

* Re: missing dir in and dir fwd policy on 2.6.23
From: Herbert Xu @ 2007-12-19 12:01 UTC (permalink / raw)
  To: Marco Berizzi; +Cc: herbert, netdev
In-Reply-To: <BAY103-DAV11DB3994E500651501D08B25C0@phx.gbl>

Marco Berizzi <pupilla@hotmail.com> wrote:
>
> Is this bug recently introduced? I'm using this
> config since 2.6.16/openswan 2.4.4 (two years).
> I haven't never noticed: now I must restart openswan
> once a day :-(

No it's been there forever but I haven't worked out exactly
what triggers it yet or I'd have already fixed it :)

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 net-2.6.25 1/3] Uninline the __inet_hash function
From: Eric Dumazet @ 2007-12-19 12:21 UTC (permalink / raw)
  To: Pavel Emelyanov; +Cc: David Miller, Linux Netdev List, devel
In-Reply-To: <4768F77E.5090201@openvz.org>

Pavel Emelyanov a écrit :
> This one is used in quite many places in the networking code and
> seems to big to be inline.
> 
> After the patch net/ipv4/build-in.o loses 725 bytes:
> add/remove: 1/0 grow/shrink: 0/5 up/down: 374/-1099 (-725)
> function                                     old     new   delta
> __inet_hash                                    -     374    +374
> tcp_sacktag_write_queue                     2255    2254      -1
> __inet_lookup_listener                       284     274     -10
> tcp_v4_syn_recv_sock                         755     495    -260
> tcp_v4_hash                                  389      40    -349
> inet_hash_connect                           1165     686    -479
> 
> Exporting this is for dccp module.
> 
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
> 
> ---
> 
>  include/net/inet_hashtables.h |   27 ++-------------------------
>  net/ipv4/inet_hashtables.c    |   27 +++++++++++++++++++++++++++
>  2 files changed, 29 insertions(+), 25 deletions(-)
> 
> diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
> index 37f6cb1..1a43125 100644
> --- a/include/net/inet_hashtables.h
> +++ b/include/net/inet_hashtables.h
> @@ -264,31 +264,8 @@ static inline void inet_listen_unlock(struct inet_hashinfo *hashinfo)
>  		wake_up(&hashinfo->lhash_wait);
>  }
>  
> -static inline void __inet_hash(struct inet_hashinfo *hashinfo,
> -			       struct sock *sk, const int listen_possible)
> -{
> -	struct hlist_head *list;
> -	rwlock_t *lock;
> -
> -	BUG_TRAP(sk_unhashed(sk));
> -	if (listen_possible && sk->sk_state == TCP_LISTEN) {
> -		list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
> -		lock = &hashinfo->lhash_lock;
> -		inet_listen_wlock(hashinfo);
> -	} else {
> -		struct inet_ehash_bucket *head;
> -		sk->sk_hash = inet_sk_ehashfn(sk);
> -		head = inet_ehash_bucket(hashinfo, sk->sk_hash);
> -		list = &head->chain;
> -		lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
> -		write_lock(lock);
> -	}
> -	__sk_add_node(sk, list);
> -	sock_prot_inc_use(sk->sk_prot);
> -	write_unlock(lock);
> -	if (listen_possible && sk->sk_state == TCP_LISTEN)
> -		wake_up(&hashinfo->lhash_wait);
> -}
> +extern void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk,
> +		const int listen_possible);
>  
>  static inline void inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk)
>  {
> diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
> index 67704da..46f899b 100644
> --- a/net/ipv4/inet_hashtables.c
> +++ b/net/ipv4/inet_hashtables.c
> @@ -267,6 +267,33 @@ static inline u32 inet_sk_port_offset(const struct sock *sk)
>  					  inet->dport);
>  }
>  
> +void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk,
> +		const int listen_possible)
> +{
> +	struct hlist_head *list;
> +	rwlock_t *lock;
> +
> +	BUG_TRAP(sk_unhashed(sk));
> +	if (listen_possible && sk->sk_state == TCP_LISTEN) {
> +		list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
> +		lock = &hashinfo->lhash_lock;
> +		inet_listen_wlock(hashinfo);
> +	} else {
> +		struct inet_ehash_bucket *head;
> +		sk->sk_hash = inet_sk_ehashfn(sk);
> +		head = inet_ehash_bucket(hashinfo, sk->sk_hash);
> +		list = &head->chain;
> +		lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
> +		write_lock(lock);
> +	}
> +	__sk_add_node(sk, list);
> +	sock_prot_inc_use(sk->sk_prot);
> +	write_unlock(lock);
> +	if (listen_possible && sk->sk_state == TCP_LISTEN)
> +		wake_up(&hashinfo->lhash_wait);
> +}
> +EXPORT_SYMBOL_GPL(__inet_hash);
> +
>  /*
>   * Bind a port for a connect operation and hash it.
>   */

If you un-inline this (good idea), I am not sure we still need listen_possible 
argument.

It was usefull only to help compiler to zap dead code (since it was known at 
compile time), now it only adds some extra test and argument passing.

Thank you



^ permalink raw reply

* Re: Inline local_bh_disable when TRACE_IRQFLAGS
From: Herbert Xu @ 2007-12-19 11:50 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Linux Kernel Mailing List, David S. Miller, netdev
In-Reply-To: <20071219113152.GD20736@elte.hu>

On Wed, Dec 19, 2007 at 12:31:52PM +0100, Ingo Molnar wrote:
>
> > So I'm wondering if it would be reasonable to make it out-of-line when 
> > TRACE_IRQFLAGS is off.  This may make a difference because the 
> > networking stack is a frequent user of local_bh_disable and 
> > local_bh_enable.
> 
> do you mean to make it inline again?

Yes I meant in-line :)

> (btw., generally i think local_bh_disable() is a poor API because it is 
> opaque about the data structure dependency that it governs. Explicit 
> exclusion rules generally work better.)

I see where you're coming from especially with your preemptible
softirq work.  However I'm mostly thinking about the existing
callers of local_bh_disable in the networking stack.

Thanks,
-- 
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: Inline local_bh_disable when TRACE_IRQFLAGS
From: Ingo Molnar @ 2007-12-19 11:31 UTC (permalink / raw)
  To: Herbert Xu; +Cc: Linux Kernel Mailing List, David S. Miller, netdev
In-Reply-To: <20071219034033.GA5770@gondor.apana.org.au>


* Herbert Xu <herbert@gondor.apana.org.au> wrote:

> Hi Ingo:
> 
> I noticed that local_bh_disable is now always out-of-line.  The change 
> was made when TRACE_IRQFLAGS was added.  However, with TRACE_IRQFLAGS 
> off, local_bh_disable does exactly the same work as before.  In 
> particular, it does pretty much the same as what preempt_disable does 
> and the latter is always inline.
> 
> So I'm wondering if it would be reasonable to make it out-of-line when 
> TRACE_IRQFLAGS is off.  This may make a difference because the 
> networking stack is a frequent user of local_bh_disable and 
> local_bh_enable.

do you mean to make it inline again?

(btw., generally i think local_bh_disable() is a poor API because it is 
opaque about the data structure dependency that it governs. Explicit 
exclusion rules generally work better.)

	Ingo

^ permalink raw reply

* Re: [PATCH/RFC] [v2] TCP: use non-delayed ACK for congestion control RTT
From: Gavin McCullagh @ 2007-12-19 11:31 UTC (permalink / raw)
  To: Ilpo Järvinen; +Cc: Netdev
In-Reply-To: <Pine.LNX.4.64.0712191241450.11908@kivilampi-30.cs.helsinki.fi>

Hi,

On Wed, 19 Dec 2007, Ilpo Järvinen wrote:

> Isn't it also much better this way in a case where ACK losses happened,
> taking the longest RTT in that case is clearly questionable as it
> may over-estimate considerably.

Quite so.

> However, another thing to consider is the possibility of this value being 
> used in "timeout-like" fashion in ca modules (I haven't read enough ca 
> modules code to know if any of them does that), on contrary to 
> determinating just rtt or packet's delay in which case this change seems 
> appropriate (most modules do the latter). 

I'm not aware of any, but I haven't read them all either.  I would have
thought tp->srtt was the value to use in this instance, but perhaps the
individual timestamps including delack delay are useful.

> Therefore, if timeout-like module exists one should also add
> TCP_CONG_RTT_STAMP_LONGEST for that particular module and keep using
> seq_rtt for it like previously and use ca_seq_rtt only for others.

Seems reasonable.  I'll add this.

> This part doesn't exists anymore in development tree. Please base this 
> patch (and anything in future) you intend to get included to mainline
> onto net-2.6.25 unless there's a very good reason to not do so or 
> whatever 2.6.xx is the correct net development tree at that time (if
> one exists). Thanks.

Will do.   I gather I should use the latest net- tree in future when
submitting patches.

Thanks for the helpful comments,

Gavin


^ permalink raw reply

* Re: [PATCH/RFC] [v2] TCP: use non-delayed ACK for congestion control RTT
From: Ilpo Järvinen @ 2007-12-19 11:08 UTC (permalink / raw)
  To: Gavin McCullagh; +Cc: Netdev
In-Reply-To: <20071218204022.GA8936@nuim.ie>

On Tue, 18 Dec 2007, Gavin McCullagh wrote:

> The last attempt didn't take account of the situation where a timestamp
> wasn't available and tcp_clean_rtx_queue() has to feed both the RTO and the
> congestion avoidance.  This updated patch stores both RTTs, making the
> delayed one available for the RTO and the other (ca_seq_rtt) available for
> congestion control.
> 
> 
> Signed-off-by: Gavin McCullagh <gavin.mccullagh@nuim.ie> 
> 
> 
> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
> index 889c893..6fb7989 100644
> --- a/net/ipv4/tcp_input.c
> +++ b/net/ipv4/tcp_input.c
> @@ -2686,13 +2687,15 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p,
>  				if (sacked & TCPCB_SACKED_RETRANS)
>  					tp->retrans_out -= packets_acked;
>  				flag |= FLAG_RETRANS_DATA_ACKED;
> +				ca_seq_rtt = -1;
>  				seq_rtt = -1;
>  				if ((flag & FLAG_DATA_ACKED) ||
>  				    (packets_acked > 1))
>  					flag |= FLAG_NONHEAD_RETRANS_ACKED;
>  			} else {
> +				ca_seq_rtt = now - scb->when;

Isn't it also much better this way in a case where ACK losses happened,
taking the longest RTT in that case is clearly questionable as it
may over-estimate considerably.

However, another thing to consider is the possibility of this value being 
used in "timeout-like" fashion in ca modules (I haven't read enough ca 
modules code to know if any of them does that), on contrary to 
determinating just rtt or packet's delay in which case this change seems 
appropriate (most modules do the latter). Therefore, if timeout-like 
module exists one should also add TCP_CONG_RTT_STAMP_LONGEST for that 
particular module and keep using seq_rtt for it like previously and use 
ca_seq_rtt only for others.

>  				if (seq_rtt < 0) {
> -					seq_rtt = now - scb->when;
> +					seq_rtt = ca_seq_rtt;
>  					if (fully_acked)
>  						last_ackt = skb->tstamp;
>  				}
> @@ -2709,8 +2712,9 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p,
>  			    !before(end_seq, tp->snd_up))
>  				tp->urg_mode = 0;
>  		} else {
> +			ca_seq_rtt = now - scb->when;
>  			if (seq_rtt < 0) {
> -				seq_rtt = now - scb->when;
> +				seq_rtt = ca_seq_rtt;
>  				if (fully_acked)
>  					last_ackt = skb->tstamp;
>  			}

This part doesn't exists anymore in development tree. Please base this 
patch (and anything in future) you intend to get included to mainline
onto net-2.6.25 unless there's a very good reason to not do so or 
whatever 2.6.xx is the correct net development tree at that time (if
one exists). Thanks.


-- 
 i.

^ permalink raw reply

* Re: missing dir in and dir fwd policy on 2.6.23
From: Marco Berizzi @ 2007-12-19 11:01 UTC (permalink / raw)
  To: Herbert Xu; +Cc: netdev
In-Reply-To: <E1J4sxK-0001st-00@gondolin.me.apana.org.au>

Herbert Xu wrote:

> Marco Berizzi <pupilla@hotmail.com> wrote:
> > Hello everybody.
> > I'm experimenting a pretty strange ipsec problem with 2.6.23.x
> > and openswan 2.4.11
> > Here is the output from 'ip -s x p':
>
> It's a bug in openswan but I haven't had the time to track it
> down yet.

Is this bug recently introduced? I'm using this
config since 2.6.16/openswan 2.4.4 (two years).
I haven't never noticed: now I must restart openswan
once a day :-(

> Anyway, the kernel is not involved since the management
> of policies is entirely up to the user-space Key Manager.



^ permalink raw reply

* [PATCH net-2.6.25 3/3] Uninline the inet_twsk_put function
From: Pavel Emelyanov @ 2007-12-19 10:56 UTC (permalink / raw)
  To: David Miller; +Cc: Linux Netdev List, devel

This one is not that big, but is widely used: saves 1200 bytes 
from net/ipv4/built-in.o

add/remove: 1/0 grow/shrink: 1/12 up/down: 97/-1300 (-1203)
function                                     old     new   delta
inet_twsk_put                                  -      87     +87
__inet_lookup_listener                       274     284     +10
tcp_sacktag_write_queue                     2255    2254      -1
tcp_time_wait                                482     411     -71
__inet_check_established                     796     722     -74
tcp_v4_err                                   973     898     -75
__inet_twsk_kill                             230     154     -76
inet_twsk_deschedule                         180     103     -77
tcp_v4_do_rcv                                462     384     -78
inet_hash_connect                            686     607     -79
inet_twdr_do_twkill_work                     236     150     -86
inet_twdr_twcal_tick                         395     307     -88
tcp_v4_rcv                                  1744    1480    -264
tcp_timewait_state_process                   975     644    -331

Export it for ipv6 module.

Signed-off-by: Pavel Emelyanov <xemul@openvz.org>

---
 include/net/inet_timewait_sock.h |   14 +-------------
 net/ipv4/inet_timewait_sock.c    |   15 +++++++++++++++
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index abaff05..67e9250 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -193,19 +193,7 @@ static inline __be32 inet_rcv_saddr(const struct sock *sk)
 		inet_sk(sk)->rcv_saddr : inet_twsk(sk)->tw_rcv_saddr;
 }
 
-static inline void inet_twsk_put(struct inet_timewait_sock *tw)
-{
-	if (atomic_dec_and_test(&tw->tw_refcnt)) {
-		struct module *owner = tw->tw_prot->owner;
-		twsk_destructor((struct sock *)tw);
-#ifdef SOCK_REFCNT_DEBUG
-		printk(KERN_DEBUG "%s timewait_sock %p released\n",
-		       tw->tw_prot->name, tw);
-#endif
-		kmem_cache_free(tw->tw_prot->twsk_prot->twsk_slab, tw);
-		module_put(owner);
-	}
-}
+extern void inet_twsk_put(struct inet_timewait_sock *tw);
 
 extern struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk,
 						  const int state);
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index d43e787..1b7db42 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -48,6 +48,21 @@ static void __inet_twsk_kill(struct inet_timewait_sock *tw,
 	inet_twsk_put(tw);
 }
 
+void inet_twsk_put(struct inet_timewait_sock *tw)
+{
+	if (atomic_dec_and_test(&tw->tw_refcnt)) {
+		struct module *owner = tw->tw_prot->owner;
+		twsk_destructor((struct sock *)tw);
+#ifdef SOCK_REFCNT_DEBUG
+		printk(KERN_DEBUG "%s timewait_sock %p released\n",
+		       tw->tw_prot->name, tw);
+#endif
+		kmem_cache_free(tw->tw_prot->twsk_prot->twsk_slab, tw);
+		module_put(owner);
+	}
+}
+EXPORT_SYMBOL_GPL(inet_twsk_put);
+
 /*
  * Enter the time wait state. This is called with locally disabled BH.
  * Essentially we whip up a timewait bucket, copy the relevant info into it
-- 
1.5.3.4


^ permalink raw reply related

* [PATCH net-2.6.25 2/3] Uninline the __inet_lookup_established function
From: Pavel Emelyanov @ 2007-12-19 10:53 UTC (permalink / raw)
  To: David Miller; +Cc: Linux Netdev List, devel

This is -700 bytes from the net/ipv4/built-in.o

add/remove: 1/0 grow/shrink: 1/3 up/down: 340/-1040 (-700)
function                                     old     new   delta
__inet_lookup_established                      -     339    +339
tcp_sacktag_write_queue                     2254    2255      +1
tcp_v4_err                                  1304     973    -331
tcp_v4_rcv                                  2089    1744    -345
tcp_v4_do_rcv                                826     462    -364

Exporting is for dccp module (used via e.g. inet_lookup).

Signed-off-by: Pavel Emelyanov <xemul@openvz.org>

---
 include/net/inet_hashtables.h |   40 +++-------------------------------------
 net/ipv4/inet_hashtables.c    |   38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 37 deletions(-)

diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 1a43125..a33eab7 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -374,43 +374,9 @@ typedef __u64 __bitwise __addrpair;
  *
  * Local BH must be disabled here.
  */
-static inline struct sock *
-	__inet_lookup_established(struct inet_hashinfo *hashinfo,
-				  const __be32 saddr, const __be16 sport,
-				  const __be32 daddr, const u16 hnum,
-				  const int dif)
-{
-	INET_ADDR_COOKIE(acookie, saddr, daddr)
-	const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
-	struct sock *sk;
-	const struct hlist_node *node;
-	/* Optimize here for direct hit, only listening connections can
-	 * have wildcards anyways.
-	 */
-	unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport);
-	struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
-	rwlock_t *lock = inet_ehash_lockp(hashinfo, hash);
-
-	prefetch(head->chain.first);
-	read_lock(lock);
-	sk_for_each(sk, node, &head->chain) {
-		if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
-			goto hit; /* You sunk my battleship! */
-	}
-
-	/* Must check for a TIME_WAIT'er before going to listener hash. */
-	sk_for_each(sk, node, &head->twchain) {
-		if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
-			goto hit;
-	}
-	sk = NULL;
-out:
-	read_unlock(lock);
-	return sk;
-hit:
-	sock_hold(sk);
-	goto out;
-}
+extern struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo,
+		const __be32 saddr, const __be16 sport,
+		const __be32 daddr, const u16 hnum, const int dif);
 
 static inline struct sock *
 	inet_lookup_established(struct inet_hashinfo *hashinfo,
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 46f899b..db43ddd 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -190,6 +190,44 @@ sherry_cache:
 }
 EXPORT_SYMBOL_GPL(__inet_lookup_listener);
 
+struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo,
+				  const __be32 saddr, const __be16 sport,
+				  const __be32 daddr, const u16 hnum,
+				  const int dif)
+{
+	INET_ADDR_COOKIE(acookie, saddr, daddr)
+	const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
+	struct sock *sk;
+	const struct hlist_node *node;
+	/* Optimize here for direct hit, only listening connections can
+	 * have wildcards anyways.
+	 */
+	unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport);
+	struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
+	rwlock_t *lock = inet_ehash_lockp(hashinfo, hash);
+
+	prefetch(head->chain.first);
+	read_lock(lock);
+	sk_for_each(sk, node, &head->chain) {
+		if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
+			goto hit; /* You sunk my battleship! */
+	}
+
+	/* Must check for a TIME_WAIT'er before going to listener hash. */
+	sk_for_each(sk, node, &head->twchain) {
+		if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
+			goto hit;
+	}
+	sk = NULL;
+out:
+	read_unlock(lock);
+	return sk;
+hit:
+	sock_hold(sk);
+	goto out;
+}
+EXPORT_SYMBOL_GPL(__inet_lookup_established);
+
 /* called with local bh disabled */
 static int __inet_check_established(struct inet_timewait_death_row *death_row,
 				    struct sock *sk, __u16 lport,
-- 
1.5.3.4


^ permalink raw reply related

* [PATCH net-2.6.25 1/3] Uninline the __inet_hash function
From: Pavel Emelyanov @ 2007-12-19 10:50 UTC (permalink / raw)
  To: David Miller; +Cc: Linux Netdev List, devel

This one is used in quite many places in the networking code and
seems to big to be inline.

After the patch net/ipv4/build-in.o loses 725 bytes:
add/remove: 1/0 grow/shrink: 0/5 up/down: 374/-1099 (-725)
function                                     old     new   delta
__inet_hash                                    -     374    +374
tcp_sacktag_write_queue                     2255    2254      -1
__inet_lookup_listener                       284     274     -10
tcp_v4_syn_recv_sock                         755     495    -260
tcp_v4_hash                                  389      40    -349
inet_hash_connect                           1165     686    -479

Exporting this is for dccp module.

Signed-off-by: Pavel Emelyanov <xemul@openvz.org>

---

 include/net/inet_hashtables.h |   27 ++-------------------------
 net/ipv4/inet_hashtables.c    |   27 +++++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 25 deletions(-)

diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 37f6cb1..1a43125 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -264,31 +264,8 @@ static inline void inet_listen_unlock(struct inet_hashinfo *hashinfo)
 		wake_up(&hashinfo->lhash_wait);
 }
 
-static inline void __inet_hash(struct inet_hashinfo *hashinfo,
-			       struct sock *sk, const int listen_possible)
-{
-	struct hlist_head *list;
-	rwlock_t *lock;
-
-	BUG_TRAP(sk_unhashed(sk));
-	if (listen_possible && sk->sk_state == TCP_LISTEN) {
-		list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
-		lock = &hashinfo->lhash_lock;
-		inet_listen_wlock(hashinfo);
-	} else {
-		struct inet_ehash_bucket *head;
-		sk->sk_hash = inet_sk_ehashfn(sk);
-		head = inet_ehash_bucket(hashinfo, sk->sk_hash);
-		list = &head->chain;
-		lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
-		write_lock(lock);
-	}
-	__sk_add_node(sk, list);
-	sock_prot_inc_use(sk->sk_prot);
-	write_unlock(lock);
-	if (listen_possible && sk->sk_state == TCP_LISTEN)
-		wake_up(&hashinfo->lhash_wait);
-}
+extern void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk,
+		const int listen_possible);
 
 static inline void inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk)
 {
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 67704da..46f899b 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -267,6 +267,33 @@ static inline u32 inet_sk_port_offset(const struct sock *sk)
 					  inet->dport);
 }
 
+void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk,
+		const int listen_possible)
+{
+	struct hlist_head *list;
+	rwlock_t *lock;
+
+	BUG_TRAP(sk_unhashed(sk));
+	if (listen_possible && sk->sk_state == TCP_LISTEN) {
+		list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
+		lock = &hashinfo->lhash_lock;
+		inet_listen_wlock(hashinfo);
+	} else {
+		struct inet_ehash_bucket *head;
+		sk->sk_hash = inet_sk_ehashfn(sk);
+		head = inet_ehash_bucket(hashinfo, sk->sk_hash);
+		list = &head->chain;
+		lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
+		write_lock(lock);
+	}
+	__sk_add_node(sk, list);
+	sock_prot_inc_use(sk->sk_prot);
+	write_unlock(lock);
+	if (listen_possible && sk->sk_state == TCP_LISTEN)
+		wake_up(&hashinfo->lhash_wait);
+}
+EXPORT_SYMBOL_GPL(__inet_hash);
+
 /*
  * Bind a port for a connect operation and hash it.
  */
-- 
1.5.3.4


^ permalink raw reply related

* [PATCH] Add me as maintainer of the RDC r6040 driver
From: Florian Fainelli @ 2007-12-19 10:30 UTC (permalink / raw)
  To: netdev; +Cc: Francois Romieu, jeff

This patch adds me as maintainer of the RDC R6040 Fast Ethernet driver.

Signed-off-by: Florian Fainelli <florian.fainelli@telecomint.eu>
-- 
diff --git a/MAINTAINERS b/MAINTAINERS
index 9507b42..6038bfb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3162,6 +3162,12 @@ M:	mporter@kernel.crashing.org
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
+RDC R6040 FAST ETHERNET DRIVER
+P:	Florian Fainelli
+M:	florian.fainelli@telecomint.eu
+L:	netdev@vger.kernel.org
+S:	Maintained
+
 READ-COPY UPDATE (RCU)
 P:	Dipankar Sarma
 M:	dipankar@in.ibm.com

^ permalink raw reply related

* Re: [PATCH/RFC] [v2] TCP: use non-delayed ACK for congestion control RTT
From: Gavin McCullagh @ 2007-12-19 10:28 UTC (permalink / raw)
  To: netdev
In-Reply-To: <20071218204022.GA8936@nuim.ie>

Hi,

On Tue, 18 Dec 2007, Gavin McCullagh wrote:

> The last attempt didn't take account of the situation where a timestamp
> wasn't available and tcp_clean_rtx_queue() has to feed both the RTO and the
> congestion avoidance.  This updated patch stores both RTTs, making the
> delayed one available for the RTO and the other (ca_seq_rtt) available for
> congestion control.

I forgot to include some data to show the difference this can make to the
RTT signal:

	http://www.hamilton.ie/gavinmc/linux/tcp_clean_rtx_queue.html

Gavin


^ permalink raw reply

* Re: [PATCH 2/2] net: neighbor timer power saving
From: Eric Dumazet @ 2007-12-19  7:23 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: parag.warudkar, David Miller, netdev, akpm
In-Reply-To: <20071218181845.2f1b539a@shemminger-laptop>

Stephen Hemminger a écrit :
> The neighbor GC timer runs once a second, but it doesn't need to wake
> up the machine.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> 
> --- a/net/core/neighbour.c	2007-12-18 07:46:07.000000000 -0800
> +++ b/net/core/neighbour.c	2007-12-18 07:47:36.000000000 -0800
> @@ -270,7 +270,7 @@ static struct neighbour *neigh_alloc(str
>  	n->nud_state	  = NUD_NONE;
>  	n->output	  = neigh_blackhole;
>  	n->parms	  = neigh_parms_clone(&tbl->parms);
> -	init_timer(&n->timer);
> +	init_timer_deferrable(&n->timer);
>  	n->timer.function = neigh_timer_handler;
>  	n->timer.data	  = (unsigned long)n;
>  
> @@ -740,7 +740,7 @@ static void neigh_timer_handler(unsigned
>  
>  	state = neigh->nud_state;
>  	now = jiffies;
> -	next = now + HZ;
> +	next = round_jiffies(now + HZ);
>  
>  	if (!(state & NUD_IN_TIMER)) {
>  #ifndef CONFIG_SMP
> @@ -1372,7 +1372,7 @@ void neigh_table_init_no_netlink(struct 
>  	get_random_bytes(&tbl->hash_rnd, sizeof(tbl->hash_rnd));
>  
>  	rwlock_init(&tbl->lock);
> -	init_timer(&tbl->gc_timer);
> +	init_timer_deferrable(&tbl->gc_timer);
>  	tbl->gc_timer.data     = (unsigned long)tbl;
>  	tbl->gc_timer.function = neigh_periodic_timer;
>  	tbl->gc_timer.expires  = now + 1;

I wonder if this deferrable timer thing is the right way to go.

(like read_mostly thing if you want :) )

We are going to convert 99% timers to deferrable.

Maybe the right move should be to have the reverse attribute, to mark a timer 
as non deferrable...

Also, why use round_jiffies() on a deferrable timer ? That sounds unecessary ?


^ permalink raw reply

* Re: missing dir in and dir fwd policy on 2.6.23
From: Herbert Xu @ 2007-12-19  7:03 UTC (permalink / raw)
  To: Marco Berizzi; +Cc: netdev
In-Reply-To: <BAY103-DAV1125DF8000481F6A3CB962B2630@phx.gbl>

Marco Berizzi <pupilla@hotmail.com> wrote:
> Hello everybody.
> I'm experimenting a pretty strange ipsec problem with 2.6.23.x
> and openswan 2.4.11
> Here is the output from 'ip -s x p':

It's a bug in openswan but I haven't had the time to track it
down yet.  Anyway, the kernel is not involved since the management
of policies is entirely up to the user-space Key Manager.

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


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