All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFCv2][PATCH] static builtin CCIDs was  Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation
@ 2008-12-17 21:46 ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 72+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-12-17 21:46 UTC (permalink / raw)
  To: David Miller; +Cc: Gerrit Renker, mirqus, dccp, netdev

Sorry if it gets duplicated, I'm having some mail problems :-\

Em Wed, Dec 17, 2008 at 04:42:28PM -0200, Arnaldo Carvalho de Melo escreveu:
> Em Wed, Dec 17, 2008 at 04:30:41PM -0200, Arnaldo Carvalho de Melo escreveu:
> > Em Wed, Dec 17, 2008 at 04:20:38PM -0200, Arnaldo Carvalho de Melo escreveu:
> > > > IOW we're back to my suggestion on looking at
> > > > tcp_set_congestion_control(). :-)
> > > 
> > > I tried to test this using ttcp over loopback but the tree seems broken
> > > somehow, with or without this patch I'm getting:
> > > 
> > > Could not activate 0 at /home/acme/git/net-next-2.6/net/dccp/feat.c:1176
> > > 
> > > I tried doing a quick chase on this one but failed miserably, Gerrit,
> > > any ideas?
> > 
> > Well, without the patch the problem was that dccp_ccid2 was not being
> > autoloaded, as soon as I manually loaded it, ttcp worked. Now to see
> > why...
> 
> Autoloading mess indeed... what probably is happening is that I start
> the server, that will not try to load the modules it advertises right
> away, but instead wait to do that when the connection completes, but
> then...
> 
> OK, back to my patch to check why it finds ccids[2] as NULL when it
> shouldn't...

Ok, now it survives basic testing, i.e.:

[root@mica ~]# ~acme/ttcp -l256 -cacme -t localhost
ttcp-t: buflen=256, nbuf=2048, align=16384/+0, port=5001  dccp(inet)  ->
localhost
ttcp-t: socket
ttcp-r: accept from mica.ghostprotocols.net
ttcp-t: connect
ttcp-t: 524288 bytes in 0.02 real seconds = 23517.52 KB/sec +++
ttcp-t: 2048 I/O calls, msec/call = 0.01, calls/sec = 94070.09
ttcp-t: 0.0user 0.0sys 0:00real 50% 0i+0d 0maxrss 0+1pf 0+2048csw
ttcp-r: 524288 bytes in 0.02 real seconds = 23164.28 KB/sec +++
ttcp-r: 2049 I/O calls, msec/call = 0.01, calls/sec = 92702.35
ttcp-r: 0.0user 0.0sys 0:00real 0% 0i+0d 0maxrss 0+1pf 2049+0csw
[1]+  Done                    ~acme/ttcp -l256 -cacme -r
[root@mica ~]# 

The problem was that I was not selecting IP_DCCP_ACKVEC, that is needed
by CCID2, with that CCID2 always loads, this option makes no sense and
is thus removed.

So, if nobody sees any problem, please apply.

Build CCID2, because the RFC requires it to be always available, and
CCID3 too as it is the most interesting one for VoIP, etc, together with
the main, layer 3 agnostic, DCCP core code, so that we have a faster
connection path by eliminating the need to always go thru the CCID
registration lock. But keep it there, so that we can experiment with
newer CCIDs without having to rebuild/reboot the whole kernel.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

diff --git a/net/dccp/Kconfig b/net/dccp/Kconfig
index 7aa2a7a..ad6dffd 100644
--- a/net/dccp/Kconfig
+++ b/net/dccp/Kconfig
@@ -1,7 +1,6 @@
 menuconfig IP_DCCP
 	tristate "The DCCP Protocol (EXPERIMENTAL)"
 	depends on INET && EXPERIMENTAL
-	select IP_DCCP_CCID2
 	---help---
 	  Datagram Congestion Control Protocol (RFC 4340)
 
@@ -25,9 +24,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"
diff --git a/net/dccp/Makefile b/net/dccp/Makefile
index f4f8793..ac6ede3 100644
--- a/net/dccp/Makefile
+++ b/net/dccp/Makefile
@@ -1,6 +1,9 @@
 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 ccids/ccid2.o
+
+dccp-$(CONFIG_IP_DCCP_CCID3) += ccids/ccid3.o
 
 dccp_ipv4-y := ipv4.o
 
@@ -8,8 +11,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
 
diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h
index 4ccee03..45f95e5 100644
--- a/net/dccp/ackvec.h
+++ b/net/dccp/ackvec.h
@@ -84,7 +84,6 @@ struct dccp_ackvec_record {
 struct sock;
 struct sk_buff;
 
-#ifdef CONFIG_IP_DCCP_ACKVEC
 extern int dccp_ackvec_init(void);
 extern void dccp_ackvec_exit(void);
 
@@ -106,52 +105,4 @@ static inline int dccp_ackvec_pending(const struct dccp_ackvec *av)
 {
 	return av->av_vec_len;
 }
-#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 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_check_rcv_ackno(struct dccp_ackvec *av,
-					       struct sock *sk, const u64 ackno)
-{
-}
-
-static inline int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
-				    const u64 *ackno, const u8 opt,
-				    const u8 *value, const u8 len)
-{
-	return -1;
-}
-
-static inline int dccp_insert_option_ackvec(const struct sock *sk,
-					    const struct sk_buff *skb)
-{
-	return -1;
-}
-
-static inline int dccp_ackvec_pending(const struct dccp_ackvec *av)
-{
-	return 0;
-}
-#endif /* CONFIG_IP_DCCP_ACKVEC */
 #endif /* _ACKVEC_H */
diff --git a/net/dccp/ccid.c b/net/dccp/ccid.c
index bcc643f..87991ec 100644
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -13,9 +13,21 @@
 
 #include "ccid.h"
 
+extern struct ccid_operations ccid2_ops;
+#ifdef CONFIG_IP_DCCP_CCID3
+extern struct ccid_operations ccid3_ops;
+#endif
+
+static struct ccid_operations *builtin_ccids_ops[] = {
+	&ccid2_ops,		/* CCID2 is supported by default */
+#ifdef CONFIG_IP_DCCP_CCID3
+	&ccid3_ops,
+#endif
+};
+
 static u8 builtin_ccids[] = {
 	DCCPC_CCID2,		/* CCID2 is supported by default */
-#if defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE)
+#ifdef CONFIG_IP_DCCP_CCID3
 	DCCPC_CCID3,
 #endif
 };
@@ -196,11 +208,71 @@ int ccid_unregister(struct ccid_operations *ccid_ops)
 
 EXPORT_SYMBOL_GPL(ccid_unregister);
 
+int ccids_register_builtins(void)
+{
+	int i, err;
+
+	for (i = 0; i < ARRAY_SIZE(builtin_ccids_ops); i++) {
+		err = ccid_register(builtin_ccids_ops[i]);
+		if (err)
+			goto unwind_registrations;
+	}
+		
+	return 0;
+
+unwind_registrations:
+	while(--i >= 0)
+		ccid_unregister(builtin_ccids_ops[i]);
+	return err;
+}
+
+static struct ccid *__ccid_new(struct ccid_operations *ccid_ops, struct sock *sk,
+			       int rx, gfp_t gfp)
+{
+	struct ccid *ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
+						  ccid_ops->ccid_hc_tx_slab, gfp);
+	if (ccid == NULL)
+		return NULL;
+
+	ccid->ccid_ops = ccid_ops;
+	if (rx) {
+		memset(ccid + 1, 0, ccid_ops->ccid_hc_rx_obj_size);
+		if (ccid->ccid_ops->ccid_hc_rx_init != NULL &&
+		    ccid->ccid_ops->ccid_hc_rx_init(ccid, sk) != 0)
+			goto out_free_ccid;
+	} else {
+		memset(ccid + 1, 0, ccid_ops->ccid_hc_tx_obj_size);
+		if (ccid->ccid_ops->ccid_hc_tx_init != NULL &&
+		    ccid->ccid_ops->ccid_hc_tx_init(ccid, sk) != 0)
+			goto out_free_ccid;
+	}
+	return ccid;
+out_free_ccid:
+	kmem_cache_free(rx ? ccid_ops->ccid_hc_rx_slab :
+			     ccid_ops->ccid_hc_tx_slab, ccid);
+	return NULL;
+}
+
+static bool is_builtin_ccid(unsigned char id)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(builtin_ccids); i++)
+		if (id == builtin_ccids[i])
+			return true;
+	return false;
+}
+
 struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
 {
 	struct ccid_operations *ccid_ops;
 	struct ccid *ccid = NULL;
 
+	if (is_builtin_ccid(id)) {
+		ccid_ops = ccids[id];
+		BUG_ON(ccid_ops == NULL);
+		return __ccid_new(ccid_ops, sk, rx, gfp);
+	}
+
 	ccids_read_lock();
 #ifdef CONFIG_MODULES
 	if (ccids[id] == NULL) {
@@ -221,31 +293,14 @@ struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
 
 	ccids_read_unlock();
 
-	ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
-				     ccid_ops->ccid_hc_tx_slab, gfp);
+	ccid = __ccid_new(ccid_ops, sk, rx, gfp);
 	if (ccid == NULL)
 		goto out_module_put;
-	ccid->ccid_ops = ccid_ops;
-	if (rx) {
-		memset(ccid + 1, 0, ccid_ops->ccid_hc_rx_obj_size);
-		if (ccid->ccid_ops->ccid_hc_rx_init != NULL &&
-		    ccid->ccid_ops->ccid_hc_rx_init(ccid, sk) != 0)
-			goto out_free_ccid;
-	} else {
-		memset(ccid + 1, 0, ccid_ops->ccid_hc_tx_obj_size);
-		if (ccid->ccid_ops->ccid_hc_tx_init != NULL &&
-		    ccid->ccid_ops->ccid_hc_tx_init(ccid, sk) != 0)
-			goto out_free_ccid;
-	}
 out:
 	return ccid;
 out_unlock:
 	ccids_read_unlock();
 	goto out;
-out_free_ccid:
-	kmem_cache_free(rx ? ccid_ops->ccid_hc_rx_slab :
-			ccid_ops->ccid_hc_tx_slab, ccid);
-	ccid = NULL;
 out_module_put:
 	module_put(ccid_ops->ccid_owner);
 	goto out;
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h
index 18f6942..192d25d 100644
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -93,6 +93,8 @@ struct ccid_operations {
 extern int ccid_register(struct ccid_operations *ccid_ops);
 extern int ccid_unregister(struct ccid_operations *ccid_ops);
 
+extern int ccids_register_builtins(void);
+
 struct ccid {
 	struct ccid_operations *ccid_ops;
 	char		       ccid_priv[0];
diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig
index 1227594..3698965 100644
--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -1,43 +1,21 @@
 menu "DCCP CCIDs Configuration (EXPERIMENTAL)"
 	depends on 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
-	  modelled directly on TCP, including congestion window, slow start,
-	  timeouts, and so forth [RFC 2581].  CCID 2 achieves maximum
-	  bandwidth over the long term, consistent with the use of end-to-end
-	  congestion control, but halves its congestion window in response to
-	  each congestion event.  This leads to the abrupt rate changes
-	  typical of TCP.  Applications should use CCID 2 if they prefer
-	  maximum bandwidth utilization to steadiness of rate.  This is often
-	  the case for applications that are not playing their data directly
-	  to the user.  For example, a hypothetical application that
-	  transferred files over DCCP, using application-level retransmissions
-	  for lost packets, would prefer CCID 2 to CCID 3.  On-line games may
-	  also prefer CCID 2.  See RFC 4341 for further details.
-
-	  CCID2 is the default CCID used by DCCP.
-
 config IP_DCCP_CCID2_DEBUG
 	  bool "CCID2 debugging messages"
-	  depends on IP_DCCP_CCID2
+	  depends on IP_DCCP
 	  ---help---
 	    Enable CCID2-specific debugging messages.
 
-	    When compiling CCID2 as a module, this debugging output can
+	    When compiling DCCP as a module, this debugging output can
 	    additionally be toggled by setting the ccid2_debug module
 	    parameter to 0 or 1.
 
 	    If in doubt, say N.
 
 config IP_DCCP_CCID3
-	tristate "CCID3 (TCP-Friendly) (EXPERIMENTAL)"
-	def_tristate IP_DCCP
+	bool "CCID3 (TCP-Friendly) (EXPERIMENTAL)"
+	def_bool y if (IP_DCCP = y || IP_DCCP = m)
 	select IP_DCCP_TFRC_LIB
 	---help---
 	  CCID 3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
@@ -59,10 +37,7 @@ config IP_DCCP_CCID3
 	  This text was extracted from RFC 4340 (sec. 10.2),
 	  http://www.ietf.org/rfc/rfc4340.txt
 	  
-	  To compile this CCID as a module, choose M here: the module will be
-	  called dccp_ccid3.
-
-	  If in doubt, say M.
+	  If in doubt, say N.
 
 config IP_DCCP_CCID3_DEBUG
 	  bool "CCID3 debugging messages"
diff --git a/net/dccp/ccids/Makefile b/net/dccp/ccids/Makefile
index 438f20b..cdaefff 100644
--- a/net/dccp/ccids/Makefile
+++ b/net/dccp/ccids/Makefile
@@ -1,9 +1 @@
-obj-$(CONFIG_IP_DCCP_CCID3) += dccp_ccid3.o
-
-dccp_ccid3-y := ccid3.o
-
-obj-$(CONFIG_IP_DCCP_CCID2) += dccp_ccid2.o
-
-dccp_ccid2-y := ccid2.o
-
 obj-y += lib/
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index c9ea19a..f4d2108 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -768,7 +768,7 @@ static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
 	}
 }
 
-static struct ccid_operations ccid2 = {
+struct ccid_operations ccid2_ops = {
 	.ccid_id		= DCCPC_CCID2,
 	.ccid_name		= "TCP-like",
 	.ccid_owner		= THIS_MODULE,
@@ -784,22 +784,5 @@ static struct ccid_operations ccid2 = {
 
 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG
 module_param(ccid2_debug, bool, 0644);
-MODULE_PARM_DESC(ccid2_debug, "Enable debug messages");
+MODULE_PARM_DESC(ccid2_debug, "Enable CCID2 debug messages");
 #endif
-
-static __init int ccid2_module_init(void)
-{
-	return ccid_register(&ccid2);
-}
-module_init(ccid2_module_init);
-
-static __exit void ccid2_module_exit(void)
-{
-	ccid_unregister(&ccid2);
-}
-module_exit(ccid2_module_exit);
-
-MODULE_AUTHOR("Andrea Bittau <a.bittau@cs.ucl.ac.uk>");
-MODULE_DESCRIPTION("DCCP TCP-Like (CCID2) CCID");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("net-dccp-ccid-2");
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 3b8bd7c..62de014 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -940,7 +940,7 @@ static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
 	return 0;
 }
 
-static struct ccid_operations ccid3 = {
+struct ccid_operations ccid3_ops = {
 	.ccid_id		   = DCCPC_CCID3,
 	.ccid_name		   = "TCP-Friendly Rate Control",
 	.ccid_owner		   = THIS_MODULE,
@@ -964,23 +964,5 @@ static struct ccid_operations ccid3 = {
 
 #ifdef CONFIG_IP_DCCP_CCID3_DEBUG
 module_param(ccid3_debug, bool, 0644);
-MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
+MODULE_PARM_DESC(ccid3_debug, "Enable CCID3 debug messages");
 #endif
-
-static __init int ccid3_module_init(void)
-{
-	return ccid_register(&ccid3);
-}
-module_init(ccid3_module_init);
-
-static __exit void ccid3_module_exit(void)
-{
-	ccid_unregister(&ccid3);
-}
-module_exit(ccid3_module_exit);
-
-MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>, "
-	      "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
-MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("net-dccp-ccid-3");
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 0bc4c9a..f2230fc 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -432,10 +432,8 @@ static inline int dccp_ack_pending(const struct sock *sk)
 {
 	const struct dccp_sock *dp = dccp_sk(sk);
 	return dp->dccps_timestamp_echo != 0 ||
-#ifdef CONFIG_IP_DCCP_ACKVEC
 	       (dp->dccps_hc_rx_ackvec != NULL &&
 		dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) ||
-#endif
 	       inet_csk_ack_scheduled(sk);
 }
 
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index d5c2bac..c704b74 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -1117,9 +1117,15 @@ static int __init dccp_init(void)
 	if (rc)
 		goto out_ackvec_exit;
 
+	rc = ccids_register_builtins();
+	if (rc)
+		goto out_sysctl_exit;
+
 	dccp_timestamping_init();
 out:
 	return rc;
+out_sysctl_exit:
+	dccp_sysctl_exit();
 out_ackvec_exit:
 	dccp_ackvec_exit();
 out_free_dccp_mib:

----- End forwarded message -----

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

* [RFCv2][PATCH] static builtin CCIDs was  Re: [PATCH 2/5] dccp:
@ 2008-12-17 21:46 ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 72+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-12-17 21:46 UTC (permalink / raw)
  To: dccp

Sorry if it gets duplicated, I'm having some mail problems :-\

Em Wed, Dec 17, 2008 at 04:42:28PM -0200, Arnaldo Carvalho de Melo escreveu:
> Em Wed, Dec 17, 2008 at 04:30:41PM -0200, Arnaldo Carvalho de Melo escreveu:
> > Em Wed, Dec 17, 2008 at 04:20:38PM -0200, Arnaldo Carvalho de Melo escreveu:
> > > > IOW we're back to my suggestion on looking at
> > > > tcp_set_congestion_control(). :-)
> > > 
> > > I tried to test this using ttcp over loopback but the tree seems broken
> > > somehow, with or without this patch I'm getting:
> > > 
> > > Could not activate 0 at /home/acme/git/net-next-2.6/net/dccp/feat.c:1176
> > > 
> > > I tried doing a quick chase on this one but failed miserably, Gerrit,
> > > any ideas?
> > 
> > Well, without the patch the problem was that dccp_ccid2 was not being
> > autoloaded, as soon as I manually loaded it, ttcp worked. Now to see
> > why...
> 
> Autoloading mess indeed... what probably is happening is that I start
> the server, that will not try to load the modules it advertises right
> away, but instead wait to do that when the connection completes, but
> then...
> 
> OK, back to my patch to check why it finds ccids[2] as NULL when it
> shouldn't...

Ok, now it survives basic testing, i.e.:

[root@mica ~]# ~acme/ttcp -l256 -cacme -t localhost
ttcp-t: buflen%6, nbuf 48, align\x16384/+0, portP01  dccp(inet)  ->
localhost
ttcp-t: socket
ttcp-r: accept from mica.ghostprotocols.net
ttcp-t: connect
ttcp-t: 524288 bytes in 0.02 real seconds = 23517.52 KB/sec +++
ttcp-t: 2048 I/O calls, msec/call = 0.01, calls/sec = 94070.09
ttcp-t: 0.0user 0.0sys 0:00real 50% 0i+0d 0maxrss 0+1pf 0+2048csw
ttcp-r: 524288 bytes in 0.02 real seconds = 23164.28 KB/sec +++
ttcp-r: 2049 I/O calls, msec/call = 0.01, calls/sec = 92702.35
ttcp-r: 0.0user 0.0sys 0:00real 0% 0i+0d 0maxrss 0+1pf 2049+0csw
[1]+  Done                    ~acme/ttcp -l256 -cacme -r
[root@mica ~]# 

The problem was that I was not selecting IP_DCCP_ACKVEC, that is needed
by CCID2, with that CCID2 always loads, this option makes no sense and
is thus removed.

So, if nobody sees any problem, please apply.

Build CCID2, because the RFC requires it to be always available, and
CCID3 too as it is the most interesting one for VoIP, etc, together with
the main, layer 3 agnostic, DCCP core code, so that we have a faster
connection path by eliminating the need to always go thru the CCID
registration lock. But keep it there, so that we can experiment with
newer CCIDs without having to rebuild/reboot the whole kernel.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

diff --git a/net/dccp/Kconfig b/net/dccp/Kconfig
index 7aa2a7a..ad6dffd 100644
--- a/net/dccp/Kconfig
+++ b/net/dccp/Kconfig
@@ -1,7 +1,6 @@
 menuconfig IP_DCCP
 	tristate "The DCCP Protocol (EXPERIMENTAL)"
 	depends on INET && EXPERIMENTAL
-	select IP_DCCP_CCID2
 	---help---
 	  Datagram Congestion Control Protocol (RFC 4340)
 
@@ -25,9 +24,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"
diff --git a/net/dccp/Makefile b/net/dccp/Makefile
index f4f8793..ac6ede3 100644
--- a/net/dccp/Makefile
+++ b/net/dccp/Makefile
@@ -1,6 +1,9 @@
 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 ccids/ccid2.o
+
+dccp-$(CONFIG_IP_DCCP_CCID3) += ccids/ccid3.o
 
 dccp_ipv4-y := ipv4.o
 
@@ -8,8 +11,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
 
diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h
index 4ccee03..45f95e5 100644
--- a/net/dccp/ackvec.h
+++ b/net/dccp/ackvec.h
@@ -84,7 +84,6 @@ struct dccp_ackvec_record {
 struct sock;
 struct sk_buff;
 
-#ifdef CONFIG_IP_DCCP_ACKVEC
 extern int dccp_ackvec_init(void);
 extern void dccp_ackvec_exit(void);
 
@@ -106,52 +105,4 @@ static inline int dccp_ackvec_pending(const struct dccp_ackvec *av)
 {
 	return av->av_vec_len;
 }
-#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 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_check_rcv_ackno(struct dccp_ackvec *av,
-					       struct sock *sk, const u64 ackno)
-{
-}
-
-static inline int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
-				    const u64 *ackno, const u8 opt,
-				    const u8 *value, const u8 len)
-{
-	return -1;
-}
-
-static inline int dccp_insert_option_ackvec(const struct sock *sk,
-					    const struct sk_buff *skb)
-{
-	return -1;
-}
-
-static inline int dccp_ackvec_pending(const struct dccp_ackvec *av)
-{
-	return 0;
-}
-#endif /* CONFIG_IP_DCCP_ACKVEC */
 #endif /* _ACKVEC_H */
diff --git a/net/dccp/ccid.c b/net/dccp/ccid.c
index bcc643f..87991ec 100644
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -13,9 +13,21 @@
 
 #include "ccid.h"
 
+extern struct ccid_operations ccid2_ops;
+#ifdef CONFIG_IP_DCCP_CCID3
+extern struct ccid_operations ccid3_ops;
+#endif
+
+static struct ccid_operations *builtin_ccids_ops[] = {
+	&ccid2_ops,		/* CCID2 is supported by default */
+#ifdef CONFIG_IP_DCCP_CCID3
+	&ccid3_ops,
+#endif
+};
+
 static u8 builtin_ccids[] = {
 	DCCPC_CCID2,		/* CCID2 is supported by default */
-#if defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE)
+#ifdef CONFIG_IP_DCCP_CCID3
 	DCCPC_CCID3,
 #endif
 };
@@ -196,11 +208,71 @@ int ccid_unregister(struct ccid_operations *ccid_ops)
 
 EXPORT_SYMBOL_GPL(ccid_unregister);
 
+int ccids_register_builtins(void)
+{
+	int i, err;
+
+	for (i = 0; i < ARRAY_SIZE(builtin_ccids_ops); i++) {
+		err = ccid_register(builtin_ccids_ops[i]);
+		if (err)
+			goto unwind_registrations;
+	}
+		
+	return 0;
+
+unwind_registrations:
+	while(--i >= 0)
+		ccid_unregister(builtin_ccids_ops[i]);
+	return err;
+}
+
+static struct ccid *__ccid_new(struct ccid_operations *ccid_ops, struct sock *sk,
+			       int rx, gfp_t gfp)
+{
+	struct ccid *ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
+						  ccid_ops->ccid_hc_tx_slab, gfp);
+	if (ccid = NULL)
+		return NULL;
+
+	ccid->ccid_ops = ccid_ops;
+	if (rx) {
+		memset(ccid + 1, 0, ccid_ops->ccid_hc_rx_obj_size);
+		if (ccid->ccid_ops->ccid_hc_rx_init != NULL &&
+		    ccid->ccid_ops->ccid_hc_rx_init(ccid, sk) != 0)
+			goto out_free_ccid;
+	} else {
+		memset(ccid + 1, 0, ccid_ops->ccid_hc_tx_obj_size);
+		if (ccid->ccid_ops->ccid_hc_tx_init != NULL &&
+		    ccid->ccid_ops->ccid_hc_tx_init(ccid, sk) != 0)
+			goto out_free_ccid;
+	}
+	return ccid;
+out_free_ccid:
+	kmem_cache_free(rx ? ccid_ops->ccid_hc_rx_slab :
+			     ccid_ops->ccid_hc_tx_slab, ccid);
+	return NULL;
+}
+
+static bool is_builtin_ccid(unsigned char id)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(builtin_ccids); i++)
+		if (id = builtin_ccids[i])
+			return true;
+	return false;
+}
+
 struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
 {
 	struct ccid_operations *ccid_ops;
 	struct ccid *ccid = NULL;
 
+	if (is_builtin_ccid(id)) {
+		ccid_ops = ccids[id];
+		BUG_ON(ccid_ops = NULL);
+		return __ccid_new(ccid_ops, sk, rx, gfp);
+	}
+
 	ccids_read_lock();
 #ifdef CONFIG_MODULES
 	if (ccids[id] = NULL) {
@@ -221,31 +293,14 @@ struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
 
 	ccids_read_unlock();
 
-	ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
-				     ccid_ops->ccid_hc_tx_slab, gfp);
+	ccid = __ccid_new(ccid_ops, sk, rx, gfp);
 	if (ccid = NULL)
 		goto out_module_put;
-	ccid->ccid_ops = ccid_ops;
-	if (rx) {
-		memset(ccid + 1, 0, ccid_ops->ccid_hc_rx_obj_size);
-		if (ccid->ccid_ops->ccid_hc_rx_init != NULL &&
-		    ccid->ccid_ops->ccid_hc_rx_init(ccid, sk) != 0)
-			goto out_free_ccid;
-	} else {
-		memset(ccid + 1, 0, ccid_ops->ccid_hc_tx_obj_size);
-		if (ccid->ccid_ops->ccid_hc_tx_init != NULL &&
-		    ccid->ccid_ops->ccid_hc_tx_init(ccid, sk) != 0)
-			goto out_free_ccid;
-	}
 out:
 	return ccid;
 out_unlock:
 	ccids_read_unlock();
 	goto out;
-out_free_ccid:
-	kmem_cache_free(rx ? ccid_ops->ccid_hc_rx_slab :
-			ccid_ops->ccid_hc_tx_slab, ccid);
-	ccid = NULL;
 out_module_put:
 	module_put(ccid_ops->ccid_owner);
 	goto out;
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h
index 18f6942..192d25d 100644
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -93,6 +93,8 @@ struct ccid_operations {
 extern int ccid_register(struct ccid_operations *ccid_ops);
 extern int ccid_unregister(struct ccid_operations *ccid_ops);
 
+extern int ccids_register_builtins(void);
+
 struct ccid {
 	struct ccid_operations *ccid_ops;
 	char		       ccid_priv[0];
diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig
index 1227594..3698965 100644
--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -1,43 +1,21 @@
 menu "DCCP CCIDs Configuration (EXPERIMENTAL)"
 	depends on 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
-	  modelled directly on TCP, including congestion window, slow start,
-	  timeouts, and so forth [RFC 2581].  CCID 2 achieves maximum
-	  bandwidth over the long term, consistent with the use of end-to-end
-	  congestion control, but halves its congestion window in response to
-	  each congestion event.  This leads to the abrupt rate changes
-	  typical of TCP.  Applications should use CCID 2 if they prefer
-	  maximum bandwidth utilization to steadiness of rate.  This is often
-	  the case for applications that are not playing their data directly
-	  to the user.  For example, a hypothetical application that
-	  transferred files over DCCP, using application-level retransmissions
-	  for lost packets, would prefer CCID 2 to CCID 3.  On-line games may
-	  also prefer CCID 2.  See RFC 4341 for further details.
-
-	  CCID2 is the default CCID used by DCCP.
-
 config IP_DCCP_CCID2_DEBUG
 	  bool "CCID2 debugging messages"
-	  depends on IP_DCCP_CCID2
+	  depends on IP_DCCP
 	  ---help---
 	    Enable CCID2-specific debugging messages.
 
-	    When compiling CCID2 as a module, this debugging output can
+	    When compiling DCCP as a module, this debugging output can
 	    additionally be toggled by setting the ccid2_debug module
 	    parameter to 0 or 1.
 
 	    If in doubt, say N.
 
 config IP_DCCP_CCID3
-	tristate "CCID3 (TCP-Friendly) (EXPERIMENTAL)"
-	def_tristate IP_DCCP
+	bool "CCID3 (TCP-Friendly) (EXPERIMENTAL)"
+	def_bool y if (IP_DCCP = y || IP_DCCP = m)
 	select IP_DCCP_TFRC_LIB
 	---help---
 	  CCID 3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
@@ -59,10 +37,7 @@ config IP_DCCP_CCID3
 	  This text was extracted from RFC 4340 (sec. 10.2),
 	  http://www.ietf.org/rfc/rfc4340.txt
 	  
-	  To compile this CCID as a module, choose M here: the module will be
-	  called dccp_ccid3.
-
-	  If in doubt, say M.
+	  If in doubt, say N.
 
 config IP_DCCP_CCID3_DEBUG
 	  bool "CCID3 debugging messages"
diff --git a/net/dccp/ccids/Makefile b/net/dccp/ccids/Makefile
index 438f20b..cdaefff 100644
--- a/net/dccp/ccids/Makefile
+++ b/net/dccp/ccids/Makefile
@@ -1,9 +1 @@
-obj-$(CONFIG_IP_DCCP_CCID3) += dccp_ccid3.o
-
-dccp_ccid3-y := ccid3.o
-
-obj-$(CONFIG_IP_DCCP_CCID2) += dccp_ccid2.o
-
-dccp_ccid2-y := ccid2.o
-
 obj-y += lib/
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index c9ea19a..f4d2108 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -768,7 +768,7 @@ static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
 	}
 }
 
-static struct ccid_operations ccid2 = {
+struct ccid_operations ccid2_ops = {
 	.ccid_id		= DCCPC_CCID2,
 	.ccid_name		= "TCP-like",
 	.ccid_owner		= THIS_MODULE,
@@ -784,22 +784,5 @@ static struct ccid_operations ccid2 = {
 
 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG
 module_param(ccid2_debug, bool, 0644);
-MODULE_PARM_DESC(ccid2_debug, "Enable debug messages");
+MODULE_PARM_DESC(ccid2_debug, "Enable CCID2 debug messages");
 #endif
-
-static __init int ccid2_module_init(void)
-{
-	return ccid_register(&ccid2);
-}
-module_init(ccid2_module_init);
-
-static __exit void ccid2_module_exit(void)
-{
-	ccid_unregister(&ccid2);
-}
-module_exit(ccid2_module_exit);
-
-MODULE_AUTHOR("Andrea Bittau <a.bittau@cs.ucl.ac.uk>");
-MODULE_DESCRIPTION("DCCP TCP-Like (CCID2) CCID");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("net-dccp-ccid-2");
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 3b8bd7c..62de014 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -940,7 +940,7 @@ static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
 	return 0;
 }
 
-static struct ccid_operations ccid3 = {
+struct ccid_operations ccid3_ops = {
 	.ccid_id		   = DCCPC_CCID3,
 	.ccid_name		   = "TCP-Friendly Rate Control",
 	.ccid_owner		   = THIS_MODULE,
@@ -964,23 +964,5 @@ static struct ccid_operations ccid3 = {
 
 #ifdef CONFIG_IP_DCCP_CCID3_DEBUG
 module_param(ccid3_debug, bool, 0644);
-MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
+MODULE_PARM_DESC(ccid3_debug, "Enable CCID3 debug messages");
 #endif
-
-static __init int ccid3_module_init(void)
-{
-	return ccid_register(&ccid3);
-}
-module_init(ccid3_module_init);
-
-static __exit void ccid3_module_exit(void)
-{
-	ccid_unregister(&ccid3);
-}
-module_exit(ccid3_module_exit);
-
-MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>, "
-	      "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
-MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("net-dccp-ccid-3");
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 0bc4c9a..f2230fc 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -432,10 +432,8 @@ static inline int dccp_ack_pending(const struct sock *sk)
 {
 	const struct dccp_sock *dp = dccp_sk(sk);
 	return dp->dccps_timestamp_echo != 0 ||
-#ifdef CONFIG_IP_DCCP_ACKVEC
 	       (dp->dccps_hc_rx_ackvec != NULL &&
 		dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) ||
-#endif
 	       inet_csk_ack_scheduled(sk);
 }
 
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index d5c2bac..c704b74 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -1117,9 +1117,15 @@ static int __init dccp_init(void)
 	if (rc)
 		goto out_ackvec_exit;
 
+	rc = ccids_register_builtins();
+	if (rc)
+		goto out_sysctl_exit;
+
 	dccp_timestamping_init();
 out:
 	return rc;
+out_sysctl_exit:
+	dccp_sysctl_exit();
 out_ackvec_exit:
 	dccp_ackvec_exit();
 out_free_dccp_mib:

----- End forwarded message -----

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

* Re: [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation
  2008-12-17 21:46 ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Arnaldo Carvalho de Melo
@ 2008-12-18  5:21   ` David Miller
  -1 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2008-12-18  5:21 UTC (permalink / raw)
  To: acme; +Cc: gerrit, mirqus, dccp, netdev

From: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Date: Wed, 17 Dec 2008 19:46:08 -0200

> So, if nobody sees any problem, please apply.
> 
> Build CCID2, because the RFC requires it to be always available, and
> CCID3 too as it is the most interesting one for VoIP, etc, together with
> the main, layer 3 agnostic, DCCP core code, so that we have a faster
> connection path by eliminating the need to always go thru the CCID
> registration lock. But keep it there, so that we can experiment with
> newer CCIDs without having to rebuild/reboot the whole kernel.
> 
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

Gerrit, are you OK with this?

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

* Re: [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp:
@ 2008-12-18  5:21   ` David Miller
  0 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2008-12-18  5:21 UTC (permalink / raw)
  To: dccp

From: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Date: Wed, 17 Dec 2008 19:46:08 -0200

> So, if nobody sees any problem, please apply.
> 
> Build CCID2, because the RFC requires it to be always available, and
> CCID3 too as it is the most interesting one for VoIP, etc, together with
> the main, layer 3 agnostic, DCCP core code, so that we have a faster
> connection path by eliminating the need to always go thru the CCID
> registration lock. But keep it there, so that we can experiment with
> newer CCIDs without having to rebuild/reboot the whole kernel.
> 
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

Gerrit, are you OK with this?

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

* Re: [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation
  2008-12-17 21:46 ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Arnaldo Carvalho de Melo
@ 2008-12-18  5:33     ` Gerrit Renker
  -1 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-18  5:33 UTC (permalink / raw)
  To: David Miller; +Cc: acme, mirqus, dccp, netdev

| > Build CCID2, because the RFC requires it to be always available, and
| > CCID3 too as it is the most interesting one for VoIP, etc, together with
| > the main, layer 3 agnostic, DCCP core code, so that we have a faster
| > connection path by eliminating the need to always go thru the CCID
| > registration lock. But keep it there, so that we can experiment with
| > newer CCIDs without having to rebuild/reboot the whole kernel.
| > 
| > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
| 
| Gerrit, are you OK with this?
| 
Acked-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>

Yes absolutely and thanks a lot to Arnaldo for the quick reply.

I apologize being late in replying, I actually sat down after work
yesterday and formulated a reply which is in agreement with this code.

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

* Re: [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp:
@ 2008-12-18  5:33     ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-18  5:33 UTC (permalink / raw)
  To: dccp

| > Build CCID2, because the RFC requires it to be always available, and
| > CCID3 too as it is the most interesting one for VoIP, etc, together with
| > the main, layer 3 agnostic, DCCP core code, so that we have a faster
| > connection path by eliminating the need to always go thru the CCID
| > registration lock. But keep it there, so that we can experiment with
| > newer CCIDs without having to rebuild/reboot the whole kernel.
| > 
| > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
| 
| Gerrit, are you OK with this?
| 
Acked-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>

Yes absolutely and thanks a lot to Arnaldo for the quick reply.

I apologize being late in replying, I actually sat down after work
yesterday and formulated a reply which is in agreement with this code.

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

* Re: [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation
  2008-12-17 21:46 ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Arnaldo Carvalho de Melo
@ 2008-12-19  3:15       ` David Miller
  -1 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2008-12-19  3:15 UTC (permalink / raw)
  To: gerrit; +Cc: acme, mirqus, dccp, netdev

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Thu, 18 Dec 2008 06:33:49 +0100

> | > Build CCID2, because the RFC requires it to be always available, and
> | > CCID3 too as it is the most interesting one for VoIP, etc, together with
> | > the main, layer 3 agnostic, DCCP core code, so that we have a faster
> | > connection path by eliminating the need to always go thru the CCID
> | > registration lock. But keep it there, so that we can experiment with
> | > newer CCIDs without having to rebuild/reboot the whole kernel.
> | > 
> | > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> | 
> | Gerrit, are you OK with this?
> | 
> Acked-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>

Applied, thanks everyone.

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

* Re: [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp:
@ 2008-12-19  3:15       ` David Miller
  0 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2008-12-19  3:15 UTC (permalink / raw)
  To: dccp

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Thu, 18 Dec 2008 06:33:49 +0100

> | > Build CCID2, because the RFC requires it to be always available, and
> | > CCID3 too as it is the most interesting one for VoIP, etc, together with
> | > the main, layer 3 agnostic, DCCP core code, so that we have a faster
> | > connection path by eliminating the need to always go thru the CCID
> | > registration lock. But keep it there, so that we can experiment with
> | > newer CCIDs without having to rebuild/reboot the whole kernel.
> | > 
> | > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> | 
> | Gerrit, are you OK with this?
> | 
> Acked-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>

Applied, thanks everyone.

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

* Re: [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation
  2008-12-17 21:46 ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Arnaldo Carvalho de Melo
@ 2008-12-19  5:24         ` Gerrit Renker
  -1 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-19  5:24 UTC (permalink / raw)
  To: David Miller; +Cc: acme, mirqus, dccp, netdev

| > | Gerrit, are you OK with this?
| > | 
| > Acked-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
| 
| Applied, thanks everyone.
| 
I am sorry but I have to revert the Acked-by. As per
yesterday's email I was ok with the basic idea, but
already said that this did not include testing.

Please do not apply this patch yet, it introduces several
new problems and needs more work.

1. Module unloading does no longer work - it seems that
   there is an unmatched module_put somewhere.

2. There is an unresolved cyclic dependency with the
   dccp_tfrc_lib module: as soon as CCID-3 is enabled,
   - dccp.ko needs dccp_tfrc_lib.ko to resolve the
     dependencies of CCID-3
   - dccp_tfrc_lib.ko needs dccp.ko since it imports
     symbols of the main DCCP module.
   That is this also prohibits module unloading.

3. A third point why module unloading does not work is
   that there is no ccid_builtins_unregister() function
   called from dccp_fini() in net/dccp/proto.c.

4. This may be Arnaldo's intention, but I disagree wholly
   with it: why do we still have the module loading stuff
   in net/dccp/ccid.c? We currently have no other CCID 
   modules, and this just keeps the flaws of the old
   interface. When I (have to) fix up CCID-4 to work with
   the new interface then I will simply add a new entry 
   into the ccid_builtin_ops. Also -- is the r/w lock that
   was the cause for making this patch really still
   necessary in ccid.c?

5. (May be the cause for point (4)): we now have 3 arrays
   in ccid.c where a single one would fully do:
    
	struct ccid_operations *ccids[CCID_MAX];
	struct ccid_operations *builtin_ccids_ops[]
	u8 builtin_ccids[]

    Why do we keep the duplication between 'ccids' and
    'builtin_ccids_ops' instead of simply saying

      struct ccid_operations *ccids[CCID_MAX] = {
	  /* CCID-2 is supported by default */
	  [DCCPC_CCID2] = &ccid2_ops,	
      #ifdef CONFIG_IP_DCCP_CCID3
	  [DCCPC_CCID3] = &ccid3_ops,	
      #endif
      };

   In this manner we can do away with all the locking
   and loading overhead for non-builtin modules that
   do not even exist. Furthermore, the new routine
   is_builtin_ccid() is then also redundant.

   The second array redundancy is between builtin_ccids[]
   and builtin_ccids_ops[] - one can get the former via
   builtin_ccids_ops[index]->ccid_id.

   That is, I am asking to 
    * use 1 array instead of 3 that each do similar things
    * not make the complicated distinction between builtin
      and non-builtin (which at the moment is the same as
      non-existing)
    * as a result, several routines automatically fall
      under the table, the code becomes much simpler.
    

6. Suggestion: use '__init' annotation for 
   ccids_register_builtins()? (Since almost all routines in
   ccid.c start with ccid_xxx, would it also be more
   consistent to name the routine 'ccid_register_builtins')

7. When fixing the Kconfig dependency for IP_DCCP_TFRC_LIB 
   we need a bool instead of a tristate, e.g.
   
	config IP_DCCP_TFRC_LIB
		bool
		def_bool y if (IP_DCCP_CCID3 = y)

   And then the module_init/exit routines become unnecessary
   in net/dccp/ccids/lib/tfrc.c. When calling their replacement
   from ccid_builtins_register()/unregister() in net/dccp/ccid.c,
   we would need #ifdefs to avoid fusing the code to ccid3.c, e.g.

	int __init ccid_register_builtins(void)
	{
		int i, err;

	#ifdef CONFIG_IP_DCCP_TFRC_LIB
		err = tfrc_lib_init();
		if (err)
			return err;
	#endif
		for ($i = 0; i < ARRAY_SIZE(builtin_ccids_ops); i++) {
			// ...
		}
		return 0;

	unwind_registrations:
	#ifdef CONFIG_IP_DCCP_TFRC_LIB
		tfrc_lib_exit();
	#endif
		// ...
	}

   Linking the tfrc_lib code into ccid3.o seems not to solve the 
   problem since the init()/exit() routines of tfrc_lib are called
   only once instead of for each new socket, as in ccid3.c.

8. The 'extern struct ccid_operations ccid?_ops;' should be in
   ccid.h instead of ccid.c (found via sparse).

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

* Re: [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp:
@ 2008-12-19  5:24         ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-19  5:24 UTC (permalink / raw)
  To: dccp

| > | Gerrit, are you OK with this?
| > | 
| > Acked-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
| 
| Applied, thanks everyone.
| 
I am sorry but I have to revert the Acked-by. As per
yesterday's email I was ok with the basic idea, but
already said that this did not include testing.

Please do not apply this patch yet, it introduces several
new problems and needs more work.

1. Module unloading does no longer work - it seems that
   there is an unmatched module_put somewhere.

2. There is an unresolved cyclic dependency with the
   dccp_tfrc_lib module: as soon as CCID-3 is enabled,
   - dccp.ko needs dccp_tfrc_lib.ko to resolve the
     dependencies of CCID-3
   - dccp_tfrc_lib.ko needs dccp.ko since it imports
     symbols of the main DCCP module.
   That is this also prohibits module unloading.

3. A third point why module unloading does not work is
   that there is no ccid_builtins_unregister() function
   called from dccp_fini() in net/dccp/proto.c.

4. This may be Arnaldo's intention, but I disagree wholly
   with it: why do we still have the module loading stuff
   in net/dccp/ccid.c? We currently have no other CCID 
   modules, and this just keeps the flaws of the old
   interface. When I (have to) fix up CCID-4 to work with
   the new interface then I will simply add a new entry 
   into the ccid_builtin_ops. Also -- is the r/w lock that
   was the cause for making this patch really still
   necessary in ccid.c?

5. (May be the cause for point (4)): we now have 3 arrays
   in ccid.c where a single one would fully do:
    
	struct ccid_operations *ccids[CCID_MAX];
	struct ccid_operations *builtin_ccids_ops[]
	u8 builtin_ccids[]

    Why do we keep the duplication between 'ccids' and
    'builtin_ccids_ops' instead of simply saying

      struct ccid_operations *ccids[CCID_MAX] = {
	  /* CCID-2 is supported by default */
	  [DCCPC_CCID2] = &ccid2_ops,	
      #ifdef CONFIG_IP_DCCP_CCID3
	  [DCCPC_CCID3] = &ccid3_ops,	
      #endif
      };

   In this manner we can do away with all the locking
   and loading overhead for non-builtin modules that
   do not even exist. Furthermore, the new routine
   is_builtin_ccid() is then also redundant.

   The second array redundancy is between builtin_ccids[]
   and builtin_ccids_ops[] - one can get the former via
   builtin_ccids_ops[index]->ccid_id.

   That is, I am asking to 
    * use 1 array instead of 3 that each do similar things
    * not make the complicated distinction between builtin
      and non-builtin (which at the moment is the same as
      non-existing)
    * as a result, several routines automatically fall
      under the table, the code becomes much simpler.
    

6. Suggestion: use '__init' annotation for 
   ccids_register_builtins()? (Since almost all routines in
   ccid.c start with ccid_xxx, would it also be more
   consistent to name the routine 'ccid_register_builtins')

7. When fixing the Kconfig dependency for IP_DCCP_TFRC_LIB 
   we need a bool instead of a tristate, e.g.
   
	config IP_DCCP_TFRC_LIB
		bool
		def_bool y if (IP_DCCP_CCID3 = y)

   And then the module_init/exit routines become unnecessary
   in net/dccp/ccids/lib/tfrc.c. When calling their replacement
   from ccid_builtins_register()/unregister() in net/dccp/ccid.c,
   we would need #ifdefs to avoid fusing the code to ccid3.c, e.g.

	int __init ccid_register_builtins(void)
	{
		int i, err;

	#ifdef CONFIG_IP_DCCP_TFRC_LIB
		err = tfrc_lib_init();
		if (err)
			return err;
	#endif
		for ($i = 0; i < ARRAY_SIZE(builtin_ccids_ops); i++) {
			// ...
		}
		return 0;

	unwind_registrations:
	#ifdef CONFIG_IP_DCCP_TFRC_LIB
		tfrc_lib_exit();
	#endif
		// ...
	}

   Linking the tfrc_lib code into ccid3.o seems not to solve the 
   problem since the init()/exit() routines of tfrc_lib are called
   only once instead of for each new socket, as in ccid3.c.

8. The 'extern struct ccid_operations ccid?_ops;' should be in
   ccid.h instead of ccid.c (found via sparse).

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

* Re: [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation
  2008-12-17 21:46 ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Arnaldo Carvalho de Melo
@ 2008-12-19  6:28           ` David Miller
  -1 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2008-12-19  6:28 UTC (permalink / raw)
  To: gerrit; +Cc: acme, mirqus, dccp, netdev

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Fri, 19 Dec 2008 06:24:46 +0100

> | > | Gerrit, are you OK with this?
> | > | 
> | > Acked-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
> | 
> | Applied, thanks everyone.
> | 
> I am sorry but I have to revert the Acked-by. As per
> yesterday's email I was ok with the basic idea, but
> already said that this did not include testing.
> 
> Please do not apply this patch yet, it introduces several
> new problems and needs more work.

You are so incredibly lucky I didn't push this out to kernel.org yet,
it's been sitting in my tree all day long.

Don't say ACK unless you mean it.

It's reverted but you should do real reviews before you ACK changes in
the future.


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

* Re: [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp:
@ 2008-12-19  6:28           ` David Miller
  0 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2008-12-19  6:28 UTC (permalink / raw)
  To: dccp

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Fri, 19 Dec 2008 06:24:46 +0100

> | > | Gerrit, are you OK with this?
> | > | 
> | > Acked-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
> | 
> | Applied, thanks everyone.
> | 
> I am sorry but I have to revert the Acked-by. As per
> yesterday's email I was ok with the basic idea, but
> already said that this did not include testing.
> 
> Please do not apply this patch yet, it introduces several
> new problems and needs more work.

You are so incredibly lucky I didn't push this out to kernel.org yet,
it's been sitting in my tree all day long.

Don't say ACK unless you mean it.

It's reverted but you should do real reviews before you ACK changes in
the future.


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

* Re: [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation
  2008-12-17 21:46 ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Arnaldo Carvalho de Melo
@ 2008-12-19  7:56             ` gerrit
  -1 siblings, 0 replies; 72+ messages in thread
From: gerrit @ 2008-12-19  7:56 UTC (permalink / raw)
  To: David Miller; +Cc: gerrit, acme, mirqus, dccp, netdev

> You are so incredibly lucky I didn't push this out to kernel.org yet,
> it's been sitting in my tree all day long.
>
> Don't say ACK unless you mean it.
>
Yes for me that's a lesson learned.

I am waiting for Arnaldo's answer before taking any further steps;
the changes are a bit bigger than expected so that dividing into a
few smaller patches may be useful.

Thanks a lot
Gerrit


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

* Re: [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp:
@ 2008-12-19  7:56             ` gerrit
  0 siblings, 0 replies; 72+ messages in thread
From: gerrit @ 2008-12-19  7:56 UTC (permalink / raw)
  To: dccp

> You are so incredibly lucky I didn't push this out to kernel.org yet,
> it's been sitting in my tree all day long.
>
> Don't say ACK unless you mean it.
>
Yes for me that's a lesson learned.

I am waiting for Arnaldo's answer before taking any further steps;
the changes are a bit bigger than expected so that dividing into a
few smaller patches may be useful.

Thanks a lot
Gerrit


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

* [RFC] [Patch 0/4] dccp: Working prototype of integrating the modules
@ 2008-12-20  8:08             ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-20  8:08 UTC (permalink / raw)
  To: acme; +Cc: dccp, netdev

This set addresses the issues in making CCIDs an available part of DCCP.

I am sending this for discussion, it differs in one point from the previous
patch - this set does not keep the module loading and locking code.

The rationale for this is that
 * at the moment there are only 2 fully standardised CCIDs
 * this situation is not likely to change in the foreseeable
   future (RFC progress is very slow, the update of RFC 3448
   for instance took over 1 year and went through 6 revisions)
 * so it would only be research prototypes as candidates for
   the non-builtin case
 * and for this I think we are better off temporarily modifying
   the build process
 * this includes CCID-4, since its Internet draft has expired
   (http://www.ietf.org/internet-drafts/draft-ietf-dccp-ccid4-03.txt)
 * (but for heretics, we still have the "UDP-like" no-op module)

All patches apply on top of Arnaldo's (your) patch to simplify discussion.
Awaiting feedback, please do not apply immediately.

Patch #1: Removes CCID module references that were still around.
Patch #2: Removes the r/w locks around module loading.
Patch #3: Adds a missing ccid_unregister_builtins() function.
Patch #4: Integrates the TFRC library (which is a dependency of
          CCID-3/4) with DCCP, including necessary initialisation.

I have performed testing with this set yesterday, it worked very
well, including module unloading, use of dccp_probe, different links
(WiFi/Ethernet/loopback).

The set is also available via the test tree (git/patch/tarball):

	git://eden-feed.erg.abdn.ac.uk/dccp_exp	[subtree `dccp']
	http://  (same host)

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

* [RFC] [Patch 0/4] dccp: Working prototype of integrating the
@ 2008-12-20  8:08             ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-20  8:08 UTC (permalink / raw)
  To: dccp

This set addresses the issues in making CCIDs an available part of DCCP.

I am sending this for discussion, it differs in one point from the previous
patch - this set does not keep the module loading and locking code.

The rationale for this is that
 * at the moment there are only 2 fully standardised CCIDs
 * this situation is not likely to change in the foreseeable
   future (RFC progress is very slow, the update of RFC 3448
   for instance took over 1 year and went through 6 revisions)
 * so it would only be research prototypes as candidates for
   the non-builtin case
 * and for this I think we are better off temporarily modifying
   the build process
 * this includes CCID-4, since its Internet draft has expired
   (http://www.ietf.org/internet-drafts/draft-ietf-dccp-ccid4-03.txt)
 * (but for heretics, we still have the "UDP-like" no-op module)

All patches apply on top of Arnaldo's (your) patch to simplify discussion.
Awaiting feedback, please do not apply immediately.

Patch #1: Removes CCID module references that were still around.
Patch #2: Removes the r/w locks around module loading.
Patch #3: Adds a missing ccid_unregister_builtins() function.
Patch #4: Integrates the TFRC library (which is a dependency of
          CCID-3/4) with DCCP, including necessary initialisation.

I have performed testing with this set yesterday, it worked very
well, including module unloading, use of dccp_probe, different links
(WiFi/Ethernet/loopback).

The set is also available via the test tree (git/patch/tarball):

	git://eden-feed.erg.abdn.ac.uk/dccp_exp	[subtree `dccp']
	http://  (same host)

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

* [RFC] [Patch 1/4] dccp: Remove old CCID-module references
@ 2008-12-20  8:08             ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-20  8:08 UTC (permalink / raw)
  To: acme; +Cc: dccp, netdev

dccp: Remove module references

This removes module references of CCID modules, which are no longer
needed as the configured CCIDs are linked into dccp.ko.
 
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/ccid.c        |   12 ------------
 net/dccp/ccid.h        |    2 --
 net/dccp/ccids/ccid2.c |    1 -
 net/dccp/ccids/ccid3.c |    1 -
 4 files changed, 16 deletions(-)

--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -29,7 +29,6 @@ struct tcp_info;
  *  @ccid_id: numerical CCID ID (up to %CCID_MAX, cf. table 5 in RFC 4340, 10.)
  *  @ccid_ccmps: the CCMPS including network/transport headers (0 when disabled)
  *  @ccid_name: alphabetical identifier string for @ccid_id
- *  @ccid_owner: module which implements/owns this CCID
  *  @ccid_hc_{r,t}x_slab: memory pool for the receiver/sender half-connection
  *  @ccid_hc_{r,t}x_obj_size: size of the receiver/sender half-connection socket
  *
@@ -48,7 +47,6 @@ struct ccid_operations {
 	unsigned char		ccid_id;
 	__u32			ccid_ccmps;
 	const char		*ccid_name;
-	struct module		*ccid_owner;
 	struct kmem_cache	*ccid_hc_rx_slab,
 				*ccid_hc_tx_slab;
 	__u32			ccid_hc_rx_obj_size,
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -283,22 +283,14 @@ struct ccid *ccid_new(unsigned char id, 
 	if (ccid_ops == NULL)
 		goto out_unlock;
 
-	if (!try_module_get(ccid_ops->ccid_owner))
-		goto out_unlock;
-
 	ccids_read_unlock();
 
 	ccid = __ccid_new(ccid_ops, sk, rx, gfp);
-	if (ccid == NULL)
-		goto out_module_put;
 out:
 	return ccid;
 out_unlock:
 	ccids_read_unlock();
 	goto out;
-out_module_put:
-	module_put(ccid_ops->ccid_owner);
-	goto out;
 }
 
 EXPORT_SYMBOL_GPL(ccid_new);
@@ -320,10 +312,6 @@ static void ccid_delete(struct ccid *cci
 			ccid_ops->ccid_hc_tx_exit(sk);
 		kmem_cache_free(ccid_ops->ccid_hc_tx_slab,  ccid);
 	}
-	ccids_read_lock();
-	if (ccids[ccid_ops->ccid_id] != NULL)
-		module_put(ccid_ops->ccid_owner);
-	ccids_read_unlock();
 }
 
 void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk)
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -771,7 +771,6 @@ static void ccid2_hc_rx_packet_recv(stru
 struct ccid_operations ccid2_ops = {
 	.ccid_id		= DCCPC_CCID2,
 	.ccid_name		= "TCP-like",
-	.ccid_owner		= THIS_MODULE,
 	.ccid_hc_tx_obj_size	= sizeof(struct ccid2_hc_tx_sock),
 	.ccid_hc_tx_init	= ccid2_hc_tx_init,
 	.ccid_hc_tx_exit	= ccid2_hc_tx_exit,
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -943,7 +943,6 @@ static int ccid3_hc_rx_getsockopt(struct
 struct ccid_operations ccid3_ops = {
 	.ccid_id		   = DCCPC_CCID3,
 	.ccid_name		   = "TCP-Friendly Rate Control",
-	.ccid_owner		   = THIS_MODULE,
 	.ccid_hc_tx_obj_size	   = sizeof(struct ccid3_hc_tx_sock),
 	.ccid_hc_tx_init	   = ccid3_hc_tx_init,
 	.ccid_hc_tx_exit	   = ccid3_hc_tx_exit,

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

* [RFC] [Patch 1/4] dccp: Remove old CCID-module references
@ 2008-12-20  8:08             ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-20  8:08 UTC (permalink / raw)
  To: dccp

dccp: Remove module references

This removes module references of CCID modules, which are no longer
needed as the configured CCIDs are linked into dccp.ko.
 
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/ccid.c        |   12 ------------
 net/dccp/ccid.h        |    2 --
 net/dccp/ccids/ccid2.c |    1 -
 net/dccp/ccids/ccid3.c |    1 -
 4 files changed, 16 deletions(-)

--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -29,7 +29,6 @@ struct tcp_info;
  *  @ccid_id: numerical CCID ID (up to %CCID_MAX, cf. table 5 in RFC 4340, 10.)
  *  @ccid_ccmps: the CCMPS including network/transport headers (0 when disabled)
  *  @ccid_name: alphabetical identifier string for @ccid_id
- *  @ccid_owner: module which implements/owns this CCID
  *  @ccid_hc_{r,t}x_slab: memory pool for the receiver/sender half-connection
  *  @ccid_hc_{r,t}x_obj_size: size of the receiver/sender half-connection socket
  *
@@ -48,7 +47,6 @@ struct ccid_operations {
 	unsigned char		ccid_id;
 	__u32			ccid_ccmps;
 	const char		*ccid_name;
-	struct module		*ccid_owner;
 	struct kmem_cache	*ccid_hc_rx_slab,
 				*ccid_hc_tx_slab;
 	__u32			ccid_hc_rx_obj_size,
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -283,22 +283,14 @@ struct ccid *ccid_new(unsigned char id, 
 	if (ccid_ops = NULL)
 		goto out_unlock;
 
-	if (!try_module_get(ccid_ops->ccid_owner))
-		goto out_unlock;
-
 	ccids_read_unlock();
 
 	ccid = __ccid_new(ccid_ops, sk, rx, gfp);
-	if (ccid = NULL)
-		goto out_module_put;
 out:
 	return ccid;
 out_unlock:
 	ccids_read_unlock();
 	goto out;
-out_module_put:
-	module_put(ccid_ops->ccid_owner);
-	goto out;
 }
 
 EXPORT_SYMBOL_GPL(ccid_new);
@@ -320,10 +312,6 @@ static void ccid_delete(struct ccid *cci
 			ccid_ops->ccid_hc_tx_exit(sk);
 		kmem_cache_free(ccid_ops->ccid_hc_tx_slab,  ccid);
 	}
-	ccids_read_lock();
-	if (ccids[ccid_ops->ccid_id] != NULL)
-		module_put(ccid_ops->ccid_owner);
-	ccids_read_unlock();
 }
 
 void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk)
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -771,7 +771,6 @@ static void ccid2_hc_rx_packet_recv(stru
 struct ccid_operations ccid2_ops = {
 	.ccid_id		= DCCPC_CCID2,
 	.ccid_name		= "TCP-like",
-	.ccid_owner		= THIS_MODULE,
 	.ccid_hc_tx_obj_size	= sizeof(struct ccid2_hc_tx_sock),
 	.ccid_hc_tx_init	= ccid2_hc_tx_init,
 	.ccid_hc_tx_exit	= ccid2_hc_tx_exit,
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -943,7 +943,6 @@ static int ccid3_hc_rx_getsockopt(struct
 struct ccid_operations ccid3_ops = {
 	.ccid_id		   = DCCPC_CCID3,
 	.ccid_name		   = "TCP-Friendly Rate Control",
-	.ccid_owner		   = THIS_MODULE,
 	.ccid_hc_tx_obj_size	   = sizeof(struct ccid3_hc_tx_sock),
 	.ccid_hc_tx_init	   = ccid3_hc_tx_init,
 	.ccid_hc_tx_exit	   = ccid3_hc_tx_exit,

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

* [RFC] [Patch 2/4] dccp: Lockless use of CCID blocks
@ 2008-12-20  8:08             ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-20  8:08 UTC (permalink / raw)
  To: acme; +Cc: dccp, netdev

dccp: Lockless use of CCIDs

This updates the implementation to use only a single array whose size
equals the number of configured CCIDs instead of 255.

Since the CCIDs are fixed array elements, synchronization is no longer
needed.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/ccid.h |   10 ---
 net/dccp/ccid.c |  166 +++++++++++---------------------------------------------
 net/dccp/feat.c |    2 
 3 files changed, 38 insertions(+), 140 deletions(-)

--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -19,14 +19,12 @@
 #include <linux/list.h>
 #include <linux/module.h>
 
-#define CCID_MAX 255
-
 struct tcp_info;
 
 /**
  *  struct ccid_operations  -  Interface to Congestion-Control Infrastructure
  *
- *  @ccid_id: numerical CCID ID (up to %CCID_MAX, cf. table 5 in RFC 4340, 10.)
+ *  @ccid_id: numerical CCID ID (cf. table 5 in RFC 4340, 10.)
  *  @ccid_ccmps: the CCMPS including network/transport headers (0 when disabled)
  *  @ccid_name: alphabetical identifier string for @ccid_id
  *  @ccid_hc_{r,t}x_slab: memory pool for the receiver/sender half-connection
@@ -93,9 +91,6 @@ extern struct ccid_operations ccid2_ops;
 extern struct ccid_operations ccid3_ops;
 #endif
 
-extern int ccid_register(struct ccid_operations *ccid_ops);
-extern int ccid_unregister(struct ccid_operations *ccid_ops);
-
 extern int ccids_register_builtins(void);
 
 struct ccid {
@@ -113,8 +108,7 @@ extern int  ccid_get_builtin_ccids(u8 **
 extern int  ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
 					  char __user *, int __user *);
 
-extern struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx,
-			     gfp_t gfp);
+extern struct ccid *ccid_new(const u8 id, struct sock *sk, bool rx);
 
 static inline int ccid_get_current_rx_ccid(struct dccp_sock *dp)
 {
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -13,8 +13,8 @@
 
 #include "ccid.h"
 
-static struct ccid_operations *builtin_ccids_ops[] = {
-	&ccid2_ops,		/* CCID2 is supported by default */
+static struct ccid_operations *ccids[] = {
+	&ccid2_ops,	/* CCID-2 is supported by default */
 #ifdef CONFIG_IP_DCCP_CCID3
 	&ccid3_ops,
 #endif
@@ -27,49 +27,6 @@ static u8 builtin_ccids[] = {
 #endif
 };
 
-static struct ccid_operations *ccids[CCID_MAX];
-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
-static atomic_t ccids_lockct = ATOMIC_INIT(0);
-static DEFINE_SPINLOCK(ccids_lock);
-
-/*
- * The strategy is: modifications ccids vector are short, do not sleep and
- * veeery rare, but read access should be free of any exclusive locks.
- */
-static void ccids_write_lock(void)
-{
-	spin_lock(&ccids_lock);
-	while (atomic_read(&ccids_lockct) != 0) {
-		spin_unlock(&ccids_lock);
-		yield();
-		spin_lock(&ccids_lock);
-	}
-}
-
-static inline void ccids_write_unlock(void)
-{
-	spin_unlock(&ccids_lock);
-}
-
-static inline void ccids_read_lock(void)
-{
-	atomic_inc(&ccids_lockct);
-	smp_mb__after_atomic_inc();
-	spin_unlock_wait(&ccids_lock);
-}
-
-static inline void ccids_read_unlock(void)
-{
-	atomic_dec(&ccids_lockct);
-}
-
-#else
-#define ccids_write_lock() do { } while(0)
-#define ccids_write_unlock() do { } while(0)
-#define ccids_read_lock() do { } while(0)
-#define ccids_read_unlock() do { } while(0)
-#endif
-
 static struct kmem_cache *ccid_kmem_cache_create(int obj_size, const char *fmt,...)
 {
 	struct kmem_cache *slab;
@@ -141,56 +98,33 @@ int ccid_getsockopt_builtin_ccids(struct
 	return 0;
 }
 
-int ccid_register(struct ccid_operations *ccid_ops)
+static int ccid_register(struct ccid_operations *ccid_ops)
 {
-	int err = -ENOBUFS;
-
 	ccid_ops->ccid_hc_rx_slab =
 			ccid_kmem_cache_create(ccid_ops->ccid_hc_rx_obj_size,
 					       "ccid%u_hc_rx_sock",
 					       ccid_ops->ccid_id);
 	if (ccid_ops->ccid_hc_rx_slab == NULL)
-		goto out;
+		return -ENOBUFS;
 
 	ccid_ops->ccid_hc_tx_slab =
 			ccid_kmem_cache_create(ccid_ops->ccid_hc_tx_obj_size,
 					       "ccid%u_hc_tx_sock",
 					       ccid_ops->ccid_id);
-	if (ccid_ops->ccid_hc_tx_slab == NULL)
-		goto out_free_rx_slab;
 
-	ccids_write_lock();
-	err = -EEXIST;
-	if (ccids[ccid_ops->ccid_id] == NULL) {
-		ccids[ccid_ops->ccid_id] = ccid_ops;
-		err = 0;
+	if (ccid_ops->ccid_hc_tx_slab == NULL) {
+		ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
+		ccid_ops->ccid_hc_rx_slab = NULL;
+		return -ENOBUFS;
 	}
-	ccids_write_unlock();
-	if (err != 0)
-		goto out_free_tx_slab;
 
 	pr_info("CCID: Registered CCID %d (%s)\n",
 		ccid_ops->ccid_id, ccid_ops->ccid_name);
-out:
-	return err;
-out_free_tx_slab:
-	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
-	ccid_ops->ccid_hc_tx_slab = NULL;
-	goto out;
-out_free_rx_slab:
-	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
-	ccid_ops->ccid_hc_rx_slab = NULL;
-	goto out;
+	return 0;
 }
 
-EXPORT_SYMBOL_GPL(ccid_register);
-
-int ccid_unregister(struct ccid_operations *ccid_ops)
+static int ccid_unregister(struct ccid_operations *ccid_ops)
 {
-	ccids_write_lock();
-	ccids[ccid_ops->ccid_id] = NULL;
-	ccids_write_unlock();
-
 	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
 	ccid_ops->ccid_hc_tx_slab = NULL;
 	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
@@ -201,14 +135,12 @@ int ccid_unregister(struct ccid_operatio
 	return 0;
 }
 
-EXPORT_SYMBOL_GPL(ccid_unregister);
-
 int ccids_register_builtins(void)
 {
 	int i, err;
 
-	for (i = 0; i < ARRAY_SIZE(builtin_ccids_ops); i++) {
-		err = ccid_register(builtin_ccids_ops[i]);
+	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
+		err = ccid_register(ccids[i]);
 		if (err)
 			goto unwind_registrations;
 	}
@@ -217,15 +149,31 @@ int ccids_register_builtins(void)
 
 unwind_registrations:
 	while(--i >= 0)
-		ccid_unregister(builtin_ccids_ops[i]);
+		ccid_unregister(ccids[i]);
 	return err;
 }
 
-static struct ccid *__ccid_new(struct ccid_operations *ccid_ops, struct sock *sk,
-			       int rx, gfp_t gfp)
+
+static struct ccid_operations *ccid_find_by_id(const u8 id)
 {
-	struct ccid *ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
-						  ccid_ops->ccid_hc_tx_slab, gfp);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ccids); i++)
+		if (ccids[i]->ccid_id == id)
+			return ccids[i];
+	return NULL;
+}
+
+struct ccid *ccid_new(const u8 id, struct sock *sk, bool rx)
+{
+	struct ccid_operations *ccid_ops = ccid_find_by_id(id);
+	struct ccid *ccid;
+
+	if (ccid_ops == NULL)
+		return NULL;
+
+	ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
+				     ccid_ops->ccid_hc_tx_slab, gfp_any());
 	if (ccid == NULL)
 		return NULL;
 
@@ -241,58 +189,14 @@ static struct ccid *__ccid_new(struct cc
 		    ccid->ccid_ops->ccid_hc_tx_init(ccid, sk) != 0)
 			goto out_free_ccid;
 	}
+
 	return ccid;
+
 out_free_ccid:
 	kmem_cache_free(rx ? ccid_ops->ccid_hc_rx_slab :
 			     ccid_ops->ccid_hc_tx_slab, ccid);
 	return NULL;
 }
-
-static bool is_builtin_ccid(unsigned char id)
-{
-	int i;
-	for (i = 0; i < ARRAY_SIZE(builtin_ccids); i++)
-		if (id == builtin_ccids[i])
-			return true;
-	return false;
-}
-
-struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
-{
-	struct ccid_operations *ccid_ops;
-	struct ccid *ccid = NULL;
-
-	if (is_builtin_ccid(id)) {
-		ccid_ops = ccids[id];
-		BUG_ON(ccid_ops == NULL);
-		return __ccid_new(ccid_ops, sk, rx, gfp);
-	}
-
-	ccids_read_lock();
-#ifdef CONFIG_MODULES
-	if (ccids[id] == NULL) {
-		/* We only try to load if in process context */
-		ccids_read_unlock();
-		if (gfp & GFP_ATOMIC)
-			goto out;
-		request_module("net-dccp-ccid-%d", id);
-		ccids_read_lock();
-	}
-#endif
-	ccid_ops = ccids[id];
-	if (ccid_ops == NULL)
-		goto out_unlock;
-
-	ccids_read_unlock();
-
-	ccid = __ccid_new(ccid_ops, sk, rx, gfp);
-out:
-	return ccid;
-out_unlock:
-	ccids_read_unlock();
-	goto out;
-}
-
 EXPORT_SYMBOL_GPL(ccid_new);
 
 static void ccid_delete(struct ccid *ccid, struct sock *sk, int rx)
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -34,7 +34,7 @@
 static int dccp_hdlr_ccid(struct sock *sk, u64 ccid, bool rx)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
-	struct ccid *new_ccid = ccid_new(ccid, sk, rx, gfp_any());
+	struct ccid *new_ccid = ccid_new(ccid, sk, rx);
 
 	if (new_ccid == NULL)
 		return -ENOMEM;

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

* [RFC] [Patch 2/4] dccp: Lockless use of CCID blocks
@ 2008-12-20  8:08             ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-20  8:08 UTC (permalink / raw)
  To: dccp

dccp: Lockless use of CCIDs

This updates the implementation to use only a single array whose size
equals the number of configured CCIDs instead of 255.

Since the CCIDs are fixed array elements, synchronization is no longer
needed.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/ccid.h |   10 ---
 net/dccp/ccid.c |  166 +++++++++++---------------------------------------------
 net/dccp/feat.c |    2 
 3 files changed, 38 insertions(+), 140 deletions(-)

--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -19,14 +19,12 @@
 #include <linux/list.h>
 #include <linux/module.h>
 
-#define CCID_MAX 255
-
 struct tcp_info;
 
 /**
  *  struct ccid_operations  -  Interface to Congestion-Control Infrastructure
  *
- *  @ccid_id: numerical CCID ID (up to %CCID_MAX, cf. table 5 in RFC 4340, 10.)
+ *  @ccid_id: numerical CCID ID (cf. table 5 in RFC 4340, 10.)
  *  @ccid_ccmps: the CCMPS including network/transport headers (0 when disabled)
  *  @ccid_name: alphabetical identifier string for @ccid_id
  *  @ccid_hc_{r,t}x_slab: memory pool for the receiver/sender half-connection
@@ -93,9 +91,6 @@ extern struct ccid_operations ccid2_ops;
 extern struct ccid_operations ccid3_ops;
 #endif
 
-extern int ccid_register(struct ccid_operations *ccid_ops);
-extern int ccid_unregister(struct ccid_operations *ccid_ops);
-
 extern int ccids_register_builtins(void);
 
 struct ccid {
@@ -113,8 +108,7 @@ extern int  ccid_get_builtin_ccids(u8 **
 extern int  ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
 					  char __user *, int __user *);
 
-extern struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx,
-			     gfp_t gfp);
+extern struct ccid *ccid_new(const u8 id, struct sock *sk, bool rx);
 
 static inline int ccid_get_current_rx_ccid(struct dccp_sock *dp)
 {
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -13,8 +13,8 @@
 
 #include "ccid.h"
 
-static struct ccid_operations *builtin_ccids_ops[] = {
-	&ccid2_ops,		/* CCID2 is supported by default */
+static struct ccid_operations *ccids[] = {
+	&ccid2_ops,	/* CCID-2 is supported by default */
 #ifdef CONFIG_IP_DCCP_CCID3
 	&ccid3_ops,
 #endif
@@ -27,49 +27,6 @@ static u8 builtin_ccids[] = {
 #endif
 };
 
-static struct ccid_operations *ccids[CCID_MAX];
-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
-static atomic_t ccids_lockct = ATOMIC_INIT(0);
-static DEFINE_SPINLOCK(ccids_lock);
-
-/*
- * The strategy is: modifications ccids vector are short, do not sleep and
- * veeery rare, but read access should be free of any exclusive locks.
- */
-static void ccids_write_lock(void)
-{
-	spin_lock(&ccids_lock);
-	while (atomic_read(&ccids_lockct) != 0) {
-		spin_unlock(&ccids_lock);
-		yield();
-		spin_lock(&ccids_lock);
-	}
-}
-
-static inline void ccids_write_unlock(void)
-{
-	spin_unlock(&ccids_lock);
-}
-
-static inline void ccids_read_lock(void)
-{
-	atomic_inc(&ccids_lockct);
-	smp_mb__after_atomic_inc();
-	spin_unlock_wait(&ccids_lock);
-}
-
-static inline void ccids_read_unlock(void)
-{
-	atomic_dec(&ccids_lockct);
-}
-
-#else
-#define ccids_write_lock() do { } while(0)
-#define ccids_write_unlock() do { } while(0)
-#define ccids_read_lock() do { } while(0)
-#define ccids_read_unlock() do { } while(0)
-#endif
-
 static struct kmem_cache *ccid_kmem_cache_create(int obj_size, const char *fmt,...)
 {
 	struct kmem_cache *slab;
@@ -141,56 +98,33 @@ int ccid_getsockopt_builtin_ccids(struct
 	return 0;
 }
 
-int ccid_register(struct ccid_operations *ccid_ops)
+static int ccid_register(struct ccid_operations *ccid_ops)
 {
-	int err = -ENOBUFS;
-
 	ccid_ops->ccid_hc_rx_slab  			ccid_kmem_cache_create(ccid_ops->ccid_hc_rx_obj_size,
 					       "ccid%u_hc_rx_sock",
 					       ccid_ops->ccid_id);
 	if (ccid_ops->ccid_hc_rx_slab = NULL)
-		goto out;
+		return -ENOBUFS;
 
 	ccid_ops->ccid_hc_tx_slab  			ccid_kmem_cache_create(ccid_ops->ccid_hc_tx_obj_size,
 					       "ccid%u_hc_tx_sock",
 					       ccid_ops->ccid_id);
-	if (ccid_ops->ccid_hc_tx_slab = NULL)
-		goto out_free_rx_slab;
 
-	ccids_write_lock();
-	err = -EEXIST;
-	if (ccids[ccid_ops->ccid_id] = NULL) {
-		ccids[ccid_ops->ccid_id] = ccid_ops;
-		err = 0;
+	if (ccid_ops->ccid_hc_tx_slab = NULL) {
+		ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
+		ccid_ops->ccid_hc_rx_slab = NULL;
+		return -ENOBUFS;
 	}
-	ccids_write_unlock();
-	if (err != 0)
-		goto out_free_tx_slab;
 
 	pr_info("CCID: Registered CCID %d (%s)\n",
 		ccid_ops->ccid_id, ccid_ops->ccid_name);
-out:
-	return err;
-out_free_tx_slab:
-	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
-	ccid_ops->ccid_hc_tx_slab = NULL;
-	goto out;
-out_free_rx_slab:
-	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
-	ccid_ops->ccid_hc_rx_slab = NULL;
-	goto out;
+	return 0;
 }
 
-EXPORT_SYMBOL_GPL(ccid_register);
-
-int ccid_unregister(struct ccid_operations *ccid_ops)
+static int ccid_unregister(struct ccid_operations *ccid_ops)
 {
-	ccids_write_lock();
-	ccids[ccid_ops->ccid_id] = NULL;
-	ccids_write_unlock();
-
 	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
 	ccid_ops->ccid_hc_tx_slab = NULL;
 	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
@@ -201,14 +135,12 @@ int ccid_unregister(struct ccid_operatio
 	return 0;
 }
 
-EXPORT_SYMBOL_GPL(ccid_unregister);
-
 int ccids_register_builtins(void)
 {
 	int i, err;
 
-	for (i = 0; i < ARRAY_SIZE(builtin_ccids_ops); i++) {
-		err = ccid_register(builtin_ccids_ops[i]);
+	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
+		err = ccid_register(ccids[i]);
 		if (err)
 			goto unwind_registrations;
 	}
@@ -217,15 +149,31 @@ int ccids_register_builtins(void)
 
 unwind_registrations:
 	while(--i >= 0)
-		ccid_unregister(builtin_ccids_ops[i]);
+		ccid_unregister(ccids[i]);
 	return err;
 }
 
-static struct ccid *__ccid_new(struct ccid_operations *ccid_ops, struct sock *sk,
-			       int rx, gfp_t gfp)
+
+static struct ccid_operations *ccid_find_by_id(const u8 id)
 {
-	struct ccid *ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
-						  ccid_ops->ccid_hc_tx_slab, gfp);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ccids); i++)
+		if (ccids[i]->ccid_id = id)
+			return ccids[i];
+	return NULL;
+}
+
+struct ccid *ccid_new(const u8 id, struct sock *sk, bool rx)
+{
+	struct ccid_operations *ccid_ops = ccid_find_by_id(id);
+	struct ccid *ccid;
+
+	if (ccid_ops = NULL)
+		return NULL;
+
+	ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
+				     ccid_ops->ccid_hc_tx_slab, gfp_any());
 	if (ccid = NULL)
 		return NULL;
 
@@ -241,58 +189,14 @@ static struct ccid *__ccid_new(struct cc
 		    ccid->ccid_ops->ccid_hc_tx_init(ccid, sk) != 0)
 			goto out_free_ccid;
 	}
+
 	return ccid;
+
 out_free_ccid:
 	kmem_cache_free(rx ? ccid_ops->ccid_hc_rx_slab :
 			     ccid_ops->ccid_hc_tx_slab, ccid);
 	return NULL;
 }
-
-static bool is_builtin_ccid(unsigned char id)
-{
-	int i;
-	for (i = 0; i < ARRAY_SIZE(builtin_ccids); i++)
-		if (id = builtin_ccids[i])
-			return true;
-	return false;
-}
-
-struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
-{
-	struct ccid_operations *ccid_ops;
-	struct ccid *ccid = NULL;
-
-	if (is_builtin_ccid(id)) {
-		ccid_ops = ccids[id];
-		BUG_ON(ccid_ops = NULL);
-		return __ccid_new(ccid_ops, sk, rx, gfp);
-	}
-
-	ccids_read_lock();
-#ifdef CONFIG_MODULES
-	if (ccids[id] = NULL) {
-		/* We only try to load if in process context */
-		ccids_read_unlock();
-		if (gfp & GFP_ATOMIC)
-			goto out;
-		request_module("net-dccp-ccid-%d", id);
-		ccids_read_lock();
-	}
-#endif
-	ccid_ops = ccids[id];
-	if (ccid_ops = NULL)
-		goto out_unlock;
-
-	ccids_read_unlock();
-
-	ccid = __ccid_new(ccid_ops, sk, rx, gfp);
-out:
-	return ccid;
-out_unlock:
-	ccids_read_unlock();
-	goto out;
-}
-
 EXPORT_SYMBOL_GPL(ccid_new);
 
 static void ccid_delete(struct ccid *ccid, struct sock *sk, int rx)
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -34,7 +34,7 @@
 static int dccp_hdlr_ccid(struct sock *sk, u64 ccid, bool rx)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
-	struct ccid *new_ccid = ccid_new(ccid, sk, rx, gfp_any());
+	struct ccid *new_ccid = ccid_new(ccid, sk, rx);
 
 	if (new_ccid = NULL)
 		return -ENOMEM;

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

* [RFC] [Patch 3/4] dccp: Add unregister function
@ 2008-12-20  8:08             ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-20  8:08 UTC (permalink / raw)
  To: acme; +Cc: dccp, netdev

dccp: Add unregister function

This adds an unregister function to facilitate unloading the DCCP module.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/ccid.h  |    3 ++-
 net/dccp/ccid.c  |   48 +++++++++++++++++++++++++++---------------------
 net/dccp/proto.c |    3 ++-
 3 files changed, 31 insertions(+), 23 deletions(-)

--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -91,7 +91,8 @@ extern struct ccid_operations ccid2_ops;
 extern struct ccid_operations ccid3_ops;
 #endif
 
-extern int ccids_register_builtins(void);
+extern int  ccid_register_builtins(void);
+extern void ccid_unregister_builtins(void);
 
 struct ccid {
 	struct ccid_operations *ccid_ops;
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -123,7 +123,7 @@ static int ccid_register(struct ccid_ope
 	return 0;
 }
 
-static int ccid_unregister(struct ccid_operations *ccid_ops)
+static void ccid_unregister(struct ccid_operations *ccid_ops)
 {
 	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
 	ccid_ops->ccid_hc_tx_slab = NULL;
@@ -132,28 +132,8 @@ static int ccid_unregister(struct ccid_o
 
 	pr_info("CCID: Unregistered CCID %d (%s)\n",
 		ccid_ops->ccid_id, ccid_ops->ccid_name);
-	return 0;
-}
-
-int ccids_register_builtins(void)
-{
-	int i, err;
-
-	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
-		err = ccid_register(ccids[i]);
-		if (err)
-			goto unwind_registrations;
-	}
-
-	return 0;
-
-unwind_registrations:
-	while(--i >= 0)
-		ccid_unregister(ccids[i]);
-	return err;
 }
 
-
 static struct ccid_operations *ccid_find_by_id(const u8 id)
 {
 	int i;
@@ -231,3 +211,29 @@ void ccid_hc_tx_delete(struct ccid *ccid
 }
 
 EXPORT_SYMBOL_GPL(ccid_hc_tx_delete);
+
+int __init ccid_register_builtins(void)
+{
+	int i, err;
+
+	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
+		err = ccid_register(ccids[i]);
+		if (err)
+			goto unwind_registrations;
+	}
+
+	return 0;
+
+unwind_registrations:
+	while(--i >= 0)
+		ccid_unregister(ccids[i]);
+	return err;
+}
+
+void ccid_unregister_builtins(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ccids); i++)
+		ccid_unregister(ccids[i]);
+}
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -1119,7 +1119,7 @@ static int __init dccp_init(void)
 	if (rc)
 		goto out_ackvec_exit;
 
-	rc = ccids_register_builtins();
+	rc = ccid_register_builtins();
 	if (rc)
 		goto out_sysctl_exit;
 
@@ -1148,6 +1148,7 @@ out_free_bind_bucket_cachep:
 
 static void __exit dccp_fini(void)
 {
+	ccid_unregister_builtins();
 	dccp_mib_exit();
 	free_pages((unsigned long)dccp_hashinfo.bhash,
 		   get_order(dccp_hashinfo.bhash_size *

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

* [RFC] [Patch 3/4] dccp: Add unregister function
@ 2008-12-20  8:08             ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-20  8:08 UTC (permalink / raw)
  To: dccp

dccp: Add unregister function

This adds an unregister function to facilitate unloading the DCCP module.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/ccid.h  |    3 ++-
 net/dccp/ccid.c  |   48 +++++++++++++++++++++++++++---------------------
 net/dccp/proto.c |    3 ++-
 3 files changed, 31 insertions(+), 23 deletions(-)

--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -91,7 +91,8 @@ extern struct ccid_operations ccid2_ops;
 extern struct ccid_operations ccid3_ops;
 #endif
 
-extern int ccids_register_builtins(void);
+extern int  ccid_register_builtins(void);
+extern void ccid_unregister_builtins(void);
 
 struct ccid {
 	struct ccid_operations *ccid_ops;
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -123,7 +123,7 @@ static int ccid_register(struct ccid_ope
 	return 0;
 }
 
-static int ccid_unregister(struct ccid_operations *ccid_ops)
+static void ccid_unregister(struct ccid_operations *ccid_ops)
 {
 	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
 	ccid_ops->ccid_hc_tx_slab = NULL;
@@ -132,28 +132,8 @@ static int ccid_unregister(struct ccid_o
 
 	pr_info("CCID: Unregistered CCID %d (%s)\n",
 		ccid_ops->ccid_id, ccid_ops->ccid_name);
-	return 0;
-}
-
-int ccids_register_builtins(void)
-{
-	int i, err;
-
-	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
-		err = ccid_register(ccids[i]);
-		if (err)
-			goto unwind_registrations;
-	}
-
-	return 0;
-
-unwind_registrations:
-	while(--i >= 0)
-		ccid_unregister(ccids[i]);
-	return err;
 }
 
-
 static struct ccid_operations *ccid_find_by_id(const u8 id)
 {
 	int i;
@@ -231,3 +211,29 @@ void ccid_hc_tx_delete(struct ccid *ccid
 }
 
 EXPORT_SYMBOL_GPL(ccid_hc_tx_delete);
+
+int __init ccid_register_builtins(void)
+{
+	int i, err;
+
+	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
+		err = ccid_register(ccids[i]);
+		if (err)
+			goto unwind_registrations;
+	}
+
+	return 0;
+
+unwind_registrations:
+	while(--i >= 0)
+		ccid_unregister(ccids[i]);
+	return err;
+}
+
+void ccid_unregister_builtins(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ccids); i++)
+		ccid_unregister(ccids[i]);
+}
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -1119,7 +1119,7 @@ static int __init dccp_init(void)
 	if (rc)
 		goto out_ackvec_exit;
 
-	rc = ccids_register_builtins();
+	rc = ccid_register_builtins();
 	if (rc)
 		goto out_sysctl_exit;
 
@@ -1148,6 +1148,7 @@ out_free_bind_bucket_cachep:
 
 static void __exit dccp_fini(void)
 {
+	ccid_unregister_builtins();
 	dccp_mib_exit();
 	free_pages((unsigned long)dccp_hashinfo.bhash,
 		   get_order(dccp_hashinfo.bhash_size *

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

* [RFC] [Patch 4/4] dccp: Integrate the TFRC library (dependency)
@ 2008-12-20  8:08             ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-20  8:08 UTC (permalink / raw)
  To: acme; +Cc: dccp, netdev

dccp: Integrate the TFRC library objects into DCCP

The TFRC library is a dependency of the CCID-3 (and CCID-4)
modules. The patch updates the Kconfig menu and Makefiles.

Note -- This solution is simple, I am sure that it can be
done better and thus welcome suggestions to improve the
conditional build statement below.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/Makefile           |    7 +++++--
 net/dccp/ccid.c             |    5 +++++
 net/dccp/ccid.h             |    9 +++++++++
 net/dccp/ccids/Kconfig      |    5 ++---
 net/dccp/ccids/Makefile     |    1 -
 net/dccp/ccids/lib/Makefile |    3 ---
 net/dccp/ccids/lib/tfrc.c   |   15 +++------------
 7 files changed, 24 insertions(+), 21 deletions(-)

--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -16,7 +16,6 @@ config IP_DCCP_CCID2_DEBUG
 config IP_DCCP_CCID3
 	bool "CCID3 (TCP-Friendly) (EXPERIMENTAL)"
 	def_bool y if (IP_DCCP = y || IP_DCCP = m)
-	select IP_DCCP_TFRC_LIB
 	---help---
 	  CCID 3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
 	  rate-controlled congestion control mechanism.  TFRC is designed to
@@ -83,8 +82,8 @@ config IP_DCCP_CCID3_RTO
 	    therefore not be performed on WANs.
 
 config IP_DCCP_TFRC_LIB
-	tristate
-	default n
+	bool
+	def_bool y if (IP_DCCP_CCID3 = y)
 
 config IP_DCCP_TFRC_DEBUG
 	bool
--- a/net/dccp/Makefile
+++ b/net/dccp/Makefile
@@ -5,6 +5,11 @@ dccp-y := ccid.o feat.o input.o minisock
 
 dccp-$(CONFIG_IP_DCCP_CCID3) += ccids/ccid3.o
 
+dccp-$(CONFIG_IP_DCCP_TFRC_LIB) += ccids/lib/tfrc.o		\
+				   ccids/lib/tfrc_equation.o	\
+				   ccids/lib/packet_history.o	\
+				   ccids/lib/loss_interval.o
+
 dccp_ipv4-y := ipv4.o
 
 # build dccp_ipv6 as module whenever either IPv6 or DCCP is a module
@@ -18,5 +23,3 @@ dccp-$(CONFIG_SYSCTL) += sysctl.o
 
 dccp_diag-y := diag.o
 dccp_probe-y := probe.o
-
-obj-y += ccids/
--- a/net/dccp/ccids/lib/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_IP_DCCP_TFRC_LIB) += dccp_tfrc_lib.o
-
-dccp_tfrc_lib-y := tfrc.o tfrc_equation.o packet_history.o loss_interval.o
--- a/net/dccp/ccids/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-y += lib/
--- a/net/dccp/ccids/lib/tfrc.c
+++ b/net/dccp/ccids/lib/tfrc.c
@@ -11,10 +11,10 @@
 #ifdef CONFIG_IP_DCCP_TFRC_DEBUG
 int tfrc_debug;
 module_param(tfrc_debug, bool, 0644);
-MODULE_PARM_DESC(tfrc_debug, "Enable debug messages");
+MODULE_PARM_DESC(tfrc_debug, "Enable TFRC debug messages");
 #endif
 
-static int __init tfrc_module_init(void)
+int __init tfrc_lib_init(void)
 {
 	int rc = tfrc_li_init();
 
@@ -38,18 +38,9 @@ out:
 	return rc;
 }
 
-static void __exit tfrc_module_exit(void)
+void __exit tfrc_lib_exit(void)
 {
 	tfrc_rx_packet_history_exit();
 	tfrc_tx_packet_history_exit();
 	tfrc_li_exit();
 }
-
-module_init(tfrc_module_init);
-module_exit(tfrc_module_exit);
-
-MODULE_AUTHOR("Gerrit Renker <gerrit@erg.abdn.ac.uk>, "
-	      "Ian McDonald <ian.mcdonald@jandi.co.nz>, "
-	      "Arnaldo Carvalho de Melo <acme@redhat.com>");
-MODULE_DESCRIPTION("DCCP TFRC library");
-MODULE_LICENSE("GPL");
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -216,6 +216,9 @@ int __init ccid_register_builtins(void)
 {
 	int i, err;
 
+	err = tfrc_lib_init();
+	if (err)
+		return err;
 	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
 		err = ccid_register(ccids[i]);
 		if (err)
@@ -225,6 +228,7 @@ int __init ccid_register_builtins(void)
 	return 0;
 
 unwind_registrations:
+	tfrc_lib_exit();
 	while(--i >= 0)
 		ccid_unregister(ccids[i]);
 	return err;
@@ -236,4 +240,5 @@ void ccid_unregister_builtins(void)
 
 	for (i = 0; i < ARRAY_SIZE(ccids); i++)
 		ccid_unregister(ccids[i]);
+	tfrc_lib_exit();
 }
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -91,6 +91,15 @@ extern struct ccid_operations ccid2_ops;
 extern struct ccid_operations ccid3_ops;
 #endif
 
+/* The TFRC library is a dependency of CCID-3 */
+#ifdef CONFIG_IP_DCCP_TFRC_LIB
+extern	int  tfrc_lib_init(void);
+extern	void tfrc_lib_exit(void);
+#else
+#define	tfrc_lib_init() (0)
+#define	tfrc_lib_exit()
+#endif
+
 extern int  ccid_register_builtins(void);
 extern void ccid_unregister_builtins(void);
 

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

* [RFC] [Patch 4/4] dccp: Integrate the TFRC library (dependency)
@ 2008-12-20  8:08             ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-20  8:08 UTC (permalink / raw)
  To: dccp

dccp: Integrate the TFRC library objects into DCCP

The TFRC library is a dependency of the CCID-3 (and CCID-4)
modules. The patch updates the Kconfig menu and Makefiles.

Note -- This solution is simple, I am sure that it can be
done better and thus welcome suggestions to improve the
conditional build statement below.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/Makefile           |    7 +++++--
 net/dccp/ccid.c             |    5 +++++
 net/dccp/ccid.h             |    9 +++++++++
 net/dccp/ccids/Kconfig      |    5 ++---
 net/dccp/ccids/Makefile     |    1 -
 net/dccp/ccids/lib/Makefile |    3 ---
 net/dccp/ccids/lib/tfrc.c   |   15 +++------------
 7 files changed, 24 insertions(+), 21 deletions(-)

--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -16,7 +16,6 @@ config IP_DCCP_CCID2_DEBUG
 config IP_DCCP_CCID3
 	bool "CCID3 (TCP-Friendly) (EXPERIMENTAL)"
 	def_bool y if (IP_DCCP = y || IP_DCCP = m)
-	select IP_DCCP_TFRC_LIB
 	---help---
 	  CCID 3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
 	  rate-controlled congestion control mechanism.  TFRC is designed to
@@ -83,8 +82,8 @@ config IP_DCCP_CCID3_RTO
 	    therefore not be performed on WANs.
 
 config IP_DCCP_TFRC_LIB
-	tristate
-	default n
+	bool
+	def_bool y if (IP_DCCP_CCID3 = y)
 
 config IP_DCCP_TFRC_DEBUG
 	bool
--- a/net/dccp/Makefile
+++ b/net/dccp/Makefile
@@ -5,6 +5,11 @@ dccp-y := ccid.o feat.o input.o minisock
 
 dccp-$(CONFIG_IP_DCCP_CCID3) += ccids/ccid3.o
 
+dccp-$(CONFIG_IP_DCCP_TFRC_LIB) += ccids/lib/tfrc.o		\
+				   ccids/lib/tfrc_equation.o	\
+				   ccids/lib/packet_history.o	\
+				   ccids/lib/loss_interval.o
+
 dccp_ipv4-y := ipv4.o
 
 # build dccp_ipv6 as module whenever either IPv6 or DCCP is a module
@@ -18,5 +23,3 @@ dccp-$(CONFIG_SYSCTL) += sysctl.o
 
 dccp_diag-y := diag.o
 dccp_probe-y := probe.o
-
-obj-y += ccids/
--- a/net/dccp/ccids/lib/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_IP_DCCP_TFRC_LIB) += dccp_tfrc_lib.o
-
-dccp_tfrc_lib-y := tfrc.o tfrc_equation.o packet_history.o loss_interval.o
--- a/net/dccp/ccids/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-y += lib/
--- a/net/dccp/ccids/lib/tfrc.c
+++ b/net/dccp/ccids/lib/tfrc.c
@@ -11,10 +11,10 @@
 #ifdef CONFIG_IP_DCCP_TFRC_DEBUG
 int tfrc_debug;
 module_param(tfrc_debug, bool, 0644);
-MODULE_PARM_DESC(tfrc_debug, "Enable debug messages");
+MODULE_PARM_DESC(tfrc_debug, "Enable TFRC debug messages");
 #endif
 
-static int __init tfrc_module_init(void)
+int __init tfrc_lib_init(void)
 {
 	int rc = tfrc_li_init();
 
@@ -38,18 +38,9 @@ out:
 	return rc;
 }
 
-static void __exit tfrc_module_exit(void)
+void __exit tfrc_lib_exit(void)
 {
 	tfrc_rx_packet_history_exit();
 	tfrc_tx_packet_history_exit();
 	tfrc_li_exit();
 }
-
-module_init(tfrc_module_init);
-module_exit(tfrc_module_exit);
-
-MODULE_AUTHOR("Gerrit Renker <gerrit@erg.abdn.ac.uk>, "
-	      "Ian McDonald <ian.mcdonald@jandi.co.nz>, "
-	      "Arnaldo Carvalho de Melo <acme@redhat.com>");
-MODULE_DESCRIPTION("DCCP TFRC library");
-MODULE_LICENSE("GPL");
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -216,6 +216,9 @@ int __init ccid_register_builtins(void)
 {
 	int i, err;
 
+	err = tfrc_lib_init();
+	if (err)
+		return err;
 	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
 		err = ccid_register(ccids[i]);
 		if (err)
@@ -225,6 +228,7 @@ int __init ccid_register_builtins(void)
 	return 0;
 
 unwind_registrations:
+	tfrc_lib_exit();
 	while(--i >= 0)
 		ccid_unregister(ccids[i]);
 	return err;
@@ -236,4 +240,5 @@ void ccid_unregister_builtins(void)
 
 	for (i = 0; i < ARRAY_SIZE(ccids); i++)
 		ccid_unregister(ccids[i]);
+	tfrc_lib_exit();
 }
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -91,6 +91,15 @@ extern struct ccid_operations ccid2_ops;
 extern struct ccid_operations ccid3_ops;
 #endif
 
+/* The TFRC library is a dependency of CCID-3 */
+#ifdef CONFIG_IP_DCCP_TFRC_LIB
+extern	int  tfrc_lib_init(void);
+extern	void tfrc_lib_exit(void);
+#else
+#define	tfrc_lib_init() (0)
+#define	tfrc_lib_exit()
+#endif
+
 extern int  ccid_register_builtins(void);
 extern void ccid_unregister_builtins(void);
 

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

* Re: [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation
  2008-12-17 21:46 ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Arnaldo Carvalho de Melo
@ 2008-12-20 23:51               ` Arnaldo Carvalho de Melo
  -1 siblings, 0 replies; 72+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-12-20 23:51 UTC (permalink / raw)
  To: gerrit; +Cc: David Miller, mirqus, dccp, netdev

Em Fri, Dec 19, 2008 at 07:56:25AM -0000, gerrit@erg.abdn.ac.uk escreveu:
> > You are so incredibly lucky I didn't push this out to kernel.org yet,
> > it's been sitting in my tree all day long.
> >
> > Don't say ACK unless you mean it.
> >
> Yes for me that's a lesson learned.
> 
> I am waiting for Arnaldo's answer before taking any further steps;
> the changes are a bit bigger than expected so that dividing into a
> few smaller patches may be useful.
> 
> Thanks a lot
> Gerrit
> 

I was away, travelling, will look at the points you raised tomorrow.

- Arnaldo

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

* Re: [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp:
@ 2008-12-20 23:51               ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 72+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-12-20 23:51 UTC (permalink / raw)
  To: dccp

Em Fri, Dec 19, 2008 at 07:56:25AM -0000, gerrit@erg.abdn.ac.uk escreveu:
> > You are so incredibly lucky I didn't push this out to kernel.org yet,
> > it's been sitting in my tree all day long.
> >
> > Don't say ACK unless you mean it.
> >
> Yes for me that's a lesson learned.
> 
> I am waiting for Arnaldo's answer before taking any further steps;
> the changes are a bit bigger than expected so that dividing into a
> few smaller patches may be useful.
> 
> Thanks a lot
> Gerrit
> 

I was away, travelling, will look at the points you raised tomorrow.

- Arnaldo

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

* Re: [RFC] [Patch 2/4] dccp: Lockless use of CCID blocks
  2008-12-20  8:08             ` Gerrit Renker
@ 2008-12-21  0:32               ` Arnaldo Carvalho de Melo
  -1 siblings, 0 replies; 72+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-12-21  0:32 UTC (permalink / raw)
  To: Gerrit Renker; +Cc: dccp, netdev

Em Sat, Dec 20, 2008 at 09:08:13AM +0100, Gerrit Renker escreveu:
> dccp: Lockless use of CCIDs
> 
> This updates the implementation to use only a single array whose size
> equals the number of configured CCIDs instead of 255.
> 
> Since the CCIDs are fixed array elements, synchronization is no longer
> needed.
> 
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
> ---
>  net/dccp/ccid.h |   10 ---
>  net/dccp/ccid.c |  166 +++++++++++---------------------------------------------
>  net/dccp/feat.c |    2 
>  3 files changed, 38 insertions(+), 140 deletions(-)
> 
> --- a/net/dccp/ccid.h
> +++ b/net/dccp/ccid.h
> @@ -19,14 +19,12 @@
>  #include <linux/list.h>
>  #include <linux/module.h>
>  
> -#define CCID_MAX 255
> -
>  struct tcp_info;
>  
>  /**
>   *  struct ccid_operations  -  Interface to Congestion-Control Infrastructure
>   *
> - *  @ccid_id: numerical CCID ID (up to %CCID_MAX, cf. table 5 in RFC 4340, 10.)
> + *  @ccid_id: numerical CCID ID (cf. table 5 in RFC 4340, 10.)
>   *  @ccid_ccmps: the CCMPS including network/transport headers (0 when disabled)
>   *  @ccid_name: alphabetical identifier string for @ccid_id
>   *  @ccid_hc_{r,t}x_slab: memory pool for the receiver/sender half-connection
> @@ -93,9 +91,6 @@ extern struct ccid_operations ccid2_ops;
>  extern struct ccid_operations ccid3_ops;
>  #endif
>  
> -extern int ccid_register(struct ccid_operations *ccid_ops);
> -extern int ccid_unregister(struct ccid_operations *ccid_ops);
> -
>  extern int ccids_register_builtins(void);
>  
>  struct ccid {
> @@ -113,8 +108,7 @@ extern int  ccid_get_builtin_ccids(u8 **
>  extern int  ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
>  					  char __user *, int __user *);
>  
> -extern struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx,
> -			     gfp_t gfp);
> +extern struct ccid *ccid_new(const u8 id, struct sock *sk, bool rx);
>  
>  static inline int ccid_get_current_rx_ccid(struct dccp_sock *dp)
>  {
> --- a/net/dccp/ccid.c
> +++ b/net/dccp/ccid.c
> @@ -13,8 +13,8 @@
>  
>  #include "ccid.h"
>  
> -static struct ccid_operations *builtin_ccids_ops[] = {
> -	&ccid2_ops,		/* CCID2 is supported by default */
> +static struct ccid_operations *ccids[] = {
> +	&ccid2_ops,	/* CCID-2 is supported by default */
>  #ifdef CONFIG_IP_DCCP_CCID3
>  	&ccid3_ops,
>  #endif
> @@ -27,49 +27,6 @@ static u8 builtin_ccids[] = {
>  #endif
>  };
>  
> -static struct ccid_operations *ccids[CCID_MAX];
> -#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
> -static atomic_t ccids_lockct = ATOMIC_INIT(0);
> -static DEFINE_SPINLOCK(ccids_lock);
> -
> -/*
> - * The strategy is: modifications ccids vector are short, do not sleep and
> - * veeery rare, but read access should be free of any exclusive locks.
> - */
> -static void ccids_write_lock(void)
> -{
> -	spin_lock(&ccids_lock);
> -	while (atomic_read(&ccids_lockct) != 0) {
> -		spin_unlock(&ccids_lock);
> -		yield();
> -		spin_lock(&ccids_lock);
> -	}
> -}
> -
> -static inline void ccids_write_unlock(void)
> -{
> -	spin_unlock(&ccids_lock);
> -}
> -
> -static inline void ccids_read_lock(void)
> -{
> -	atomic_inc(&ccids_lockct);
> -	smp_mb__after_atomic_inc();
> -	spin_unlock_wait(&ccids_lock);
> -}
> -
> -static inline void ccids_read_unlock(void)
> -{
> -	atomic_dec(&ccids_lockct);
> -}
> -
> -#else
> -#define ccids_write_lock() do { } while(0)
> -#define ccids_write_unlock() do { } while(0)
> -#define ccids_read_lock() do { } while(0)
> -#define ccids_read_unlock() do { } while(0)
> -#endif
> -
>  static struct kmem_cache *ccid_kmem_cache_create(int obj_size, const char *fmt,...)
>  {
>  	struct kmem_cache *slab;
> @@ -141,56 +98,33 @@ int ccid_getsockopt_builtin_ccids(struct
>  	return 0;
>  }
>  
> -int ccid_register(struct ccid_operations *ccid_ops)
> +static int ccid_register(struct ccid_operations *ccid_ops)
>  {
> -	int err = -ENOBUFS;
> -
>  	ccid_ops->ccid_hc_rx_slab =
>  			ccid_kmem_cache_create(ccid_ops->ccid_hc_rx_obj_size,
>  					       "ccid%u_hc_rx_sock",
>  					       ccid_ops->ccid_id);
>  	if (ccid_ops->ccid_hc_rx_slab == NULL)
> -		goto out;
> +		return -ENOBUFS;

You could have maintained the gotos, that way the patch would be
smaller...

>  
>  	ccid_ops->ccid_hc_tx_slab =
>  			ccid_kmem_cache_create(ccid_ops->ccid_hc_tx_obj_size,
>  					       "ccid%u_hc_tx_sock",
>  					       ccid_ops->ccid_id);
> -	if (ccid_ops->ccid_hc_tx_slab == NULL)
> -		goto out_free_rx_slab;
>  
> -	ccids_write_lock();

I.e. we would see that in the end what you did here was just to remove
the locking.

> -	err = -EEXIST;
> -	if (ccids[ccid_ops->ccid_id] == NULL) {
> -		ccids[ccid_ops->ccid_id] = ccid_ops;
> -		err = 0;
> +	if (ccid_ops->ccid_hc_tx_slab == NULL) {
> +		ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
> +		ccid_ops->ccid_hc_rx_slab = NULL;
> +		return -ENOBUFS;
>  	}
> -	ccids_write_unlock();
> -	if (err != 0)
> -		goto out_free_tx_slab;
>  
>  	pr_info("CCID: Registered CCID %d (%s)\n",
>  		ccid_ops->ccid_id, ccid_ops->ccid_name);
> -out:
> -	return err;
> -out_free_tx_slab:
> -	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
> -	ccid_ops->ccid_hc_tx_slab = NULL;
> -	goto out;
> -out_free_rx_slab:
> -	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
> -	ccid_ops->ccid_hc_rx_slab = NULL;
> -	goto out;
> +	return 0;
>  }
>  
> -EXPORT_SYMBOL_GPL(ccid_register);
> -
> -int ccid_unregister(struct ccid_operations *ccid_ops)
> +static int ccid_unregister(struct ccid_operations *ccid_ops)
>  {
> -	ccids_write_lock();
> -	ccids[ccid_ops->ccid_id] = NULL;
> -	ccids_write_unlock();
> -
>  	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
>  	ccid_ops->ccid_hc_tx_slab = NULL;
>  	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);

And "register/unregister" now don't make much sense since there is no
registration being done, just allocating/deallocating resources

> @@ -201,14 +135,12 @@ int ccid_unregister(struct ccid_operatio
>  	return 0;
>  }
>  
> -EXPORT_SYMBOL_GPL(ccid_unregister);
> -
>  int ccids_register_builtins(void)
>  {
>  	int i, err;
>  
> -	for (i = 0; i < ARRAY_SIZE(builtin_ccids_ops); i++) {
> -		err = ccid_register(builtin_ccids_ops[i]);
> +	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
> +		err = ccid_register(ccids[i]);
>  		if (err)
>  			goto unwind_registrations;
>  	}
> @@ -217,15 +149,31 @@ int ccids_register_builtins(void)
>  
>  unwind_registrations:
>  	while(--i >= 0)
> -		ccid_unregister(builtin_ccids_ops[i]);
> +		ccid_unregister(ccids[i]);
>  	return err;
>  }
>  
> -static struct ccid *__ccid_new(struct ccid_operations *ccid_ops, struct sock *sk,
> -			       int rx, gfp_t gfp)
> +
> +static struct ccid_operations *ccid_find_by_id(const u8 id)
>  {
> -	struct ccid *ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
> -						  ccid_ops->ccid_hc_tx_slab, gfp);
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(ccids); i++)
> +		if (ccids[i]->ccid_id == id)
> +			return ccids[i];
> +	return NULL;

Why the we searching? Can't we just do:

{
	if (id > ARRAY_SIZE(ccids) - 2)
		return NULL;
	return ccids[id - 2];
}

?

> +}
> +
> +struct ccid *ccid_new(const u8 id, struct sock *sk, bool rx)
> +{
> +	struct ccid_operations *ccid_ops = ccid_find_by_id(id);
> +	struct ccid *ccid;
> +
> +	if (ccid_ops == NULL)
> +		return NULL;
> +
> +	ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
> +				     ccid_ops->ccid_hc_tx_slab, gfp_any());
>  	if (ccid == NULL)
>  		return NULL;
>  
> @@ -241,58 +189,14 @@ static struct ccid *__ccid_new(struct cc
>  		    ccid->ccid_ops->ccid_hc_tx_init(ccid, sk) != 0)
>  			goto out_free_ccid;
>  	}
> +
>  	return ccid;
> +
>  out_free_ccid:
>  	kmem_cache_free(rx ? ccid_ops->ccid_hc_rx_slab :
>  			     ccid_ops->ccid_hc_tx_slab, ccid);
>  	return NULL;
>  }
> -
> -static bool is_builtin_ccid(unsigned char id)
> -{
> -	int i;
> -	for (i = 0; i < ARRAY_SIZE(builtin_ccids); i++)
> -		if (id == builtin_ccids[i])
> -			return true;
> -	return false;
> -}
> -
> -struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
> -{
> -	struct ccid_operations *ccid_ops;
> -	struct ccid *ccid = NULL;
> -
> -	if (is_builtin_ccid(id)) {
> -		ccid_ops = ccids[id];
> -		BUG_ON(ccid_ops == NULL);
> -		return __ccid_new(ccid_ops, sk, rx, gfp);
> -	}
> -
> -	ccids_read_lock();
> -#ifdef CONFIG_MODULES
> -	if (ccids[id] == NULL) {
> -		/* We only try to load if in process context */
> -		ccids_read_unlock();
> -		if (gfp & GFP_ATOMIC)
> -			goto out;
> -		request_module("net-dccp-ccid-%d", id);
> -		ccids_read_lock();
> -	}
> -#endif
> -	ccid_ops = ccids[id];
> -	if (ccid_ops == NULL)
> -		goto out_unlock;
> -
> -	ccids_read_unlock();
> -
> -	ccid = __ccid_new(ccid_ops, sk, rx, gfp);
> -out:
> -	return ccid;
> -out_unlock:
> -	ccids_read_unlock();
> -	goto out;
> -}
> -
>  EXPORT_SYMBOL_GPL(ccid_new);
>  
>  static void ccid_delete(struct ccid *ccid, struct sock *sk, int rx)
> --- a/net/dccp/feat.c
> +++ b/net/dccp/feat.c
> @@ -34,7 +34,7 @@
>  static int dccp_hdlr_ccid(struct sock *sk, u64 ccid, bool rx)
>  {
>  	struct dccp_sock *dp = dccp_sk(sk);
> -	struct ccid *new_ccid = ccid_new(ccid, sk, rx, gfp_any());
> +	struct ccid *new_ccid = ccid_new(ccid, sk, rx);
>  
>  	if (new_ccid == NULL)
>  		return -ENOMEM;

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

* Re: [RFC] [Patch 2/4] dccp: Lockless use of CCID blocks
@ 2008-12-21  0:32               ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 72+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-12-21  0:32 UTC (permalink / raw)
  To: dccp

Em Sat, Dec 20, 2008 at 09:08:13AM +0100, Gerrit Renker escreveu:
> dccp: Lockless use of CCIDs
> 
> This updates the implementation to use only a single array whose size
> equals the number of configured CCIDs instead of 255.
> 
> Since the CCIDs are fixed array elements, synchronization is no longer
> needed.
> 
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
> ---
>  net/dccp/ccid.h |   10 ---
>  net/dccp/ccid.c |  166 +++++++++++---------------------------------------------
>  net/dccp/feat.c |    2 
>  3 files changed, 38 insertions(+), 140 deletions(-)
> 
> --- a/net/dccp/ccid.h
> +++ b/net/dccp/ccid.h
> @@ -19,14 +19,12 @@
>  #include <linux/list.h>
>  #include <linux/module.h>
>  
> -#define CCID_MAX 255
> -
>  struct tcp_info;
>  
>  /**
>   *  struct ccid_operations  -  Interface to Congestion-Control Infrastructure
>   *
> - *  @ccid_id: numerical CCID ID (up to %CCID_MAX, cf. table 5 in RFC 4340, 10.)
> + *  @ccid_id: numerical CCID ID (cf. table 5 in RFC 4340, 10.)
>   *  @ccid_ccmps: the CCMPS including network/transport headers (0 when disabled)
>   *  @ccid_name: alphabetical identifier string for @ccid_id
>   *  @ccid_hc_{r,t}x_slab: memory pool for the receiver/sender half-connection
> @@ -93,9 +91,6 @@ extern struct ccid_operations ccid2_ops;
>  extern struct ccid_operations ccid3_ops;
>  #endif
>  
> -extern int ccid_register(struct ccid_operations *ccid_ops);
> -extern int ccid_unregister(struct ccid_operations *ccid_ops);
> -
>  extern int ccids_register_builtins(void);
>  
>  struct ccid {
> @@ -113,8 +108,7 @@ extern int  ccid_get_builtin_ccids(u8 **
>  extern int  ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
>  					  char __user *, int __user *);
>  
> -extern struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx,
> -			     gfp_t gfp);
> +extern struct ccid *ccid_new(const u8 id, struct sock *sk, bool rx);
>  
>  static inline int ccid_get_current_rx_ccid(struct dccp_sock *dp)
>  {
> --- a/net/dccp/ccid.c
> +++ b/net/dccp/ccid.c
> @@ -13,8 +13,8 @@
>  
>  #include "ccid.h"
>  
> -static struct ccid_operations *builtin_ccids_ops[] = {
> -	&ccid2_ops,		/* CCID2 is supported by default */
> +static struct ccid_operations *ccids[] = {
> +	&ccid2_ops,	/* CCID-2 is supported by default */
>  #ifdef CONFIG_IP_DCCP_CCID3
>  	&ccid3_ops,
>  #endif
> @@ -27,49 +27,6 @@ static u8 builtin_ccids[] = {
>  #endif
>  };
>  
> -static struct ccid_operations *ccids[CCID_MAX];
> -#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
> -static atomic_t ccids_lockct = ATOMIC_INIT(0);
> -static DEFINE_SPINLOCK(ccids_lock);
> -
> -/*
> - * The strategy is: modifications ccids vector are short, do not sleep and
> - * veeery rare, but read access should be free of any exclusive locks.
> - */
> -static void ccids_write_lock(void)
> -{
> -	spin_lock(&ccids_lock);
> -	while (atomic_read(&ccids_lockct) != 0) {
> -		spin_unlock(&ccids_lock);
> -		yield();
> -		spin_lock(&ccids_lock);
> -	}
> -}
> -
> -static inline void ccids_write_unlock(void)
> -{
> -	spin_unlock(&ccids_lock);
> -}
> -
> -static inline void ccids_read_lock(void)
> -{
> -	atomic_inc(&ccids_lockct);
> -	smp_mb__after_atomic_inc();
> -	spin_unlock_wait(&ccids_lock);
> -}
> -
> -static inline void ccids_read_unlock(void)
> -{
> -	atomic_dec(&ccids_lockct);
> -}
> -
> -#else
> -#define ccids_write_lock() do { } while(0)
> -#define ccids_write_unlock() do { } while(0)
> -#define ccids_read_lock() do { } while(0)
> -#define ccids_read_unlock() do { } while(0)
> -#endif
> -
>  static struct kmem_cache *ccid_kmem_cache_create(int obj_size, const char *fmt,...)
>  {
>  	struct kmem_cache *slab;
> @@ -141,56 +98,33 @@ int ccid_getsockopt_builtin_ccids(struct
>  	return 0;
>  }
>  
> -int ccid_register(struct ccid_operations *ccid_ops)
> +static int ccid_register(struct ccid_operations *ccid_ops)
>  {
> -	int err = -ENOBUFS;
> -
>  	ccid_ops->ccid_hc_rx_slab >  			ccid_kmem_cache_create(ccid_ops->ccid_hc_rx_obj_size,
>  					       "ccid%u_hc_rx_sock",
>  					       ccid_ops->ccid_id);
>  	if (ccid_ops->ccid_hc_rx_slab = NULL)
> -		goto out;
> +		return -ENOBUFS;

You could have maintained the gotos, that way the patch would be
smaller...

>  
>  	ccid_ops->ccid_hc_tx_slab >  			ccid_kmem_cache_create(ccid_ops->ccid_hc_tx_obj_size,
>  					       "ccid%u_hc_tx_sock",
>  					       ccid_ops->ccid_id);
> -	if (ccid_ops->ccid_hc_tx_slab = NULL)
> -		goto out_free_rx_slab;
>  
> -	ccids_write_lock();

I.e. we would see that in the end what you did here was just to remove
the locking.

> -	err = -EEXIST;
> -	if (ccids[ccid_ops->ccid_id] = NULL) {
> -		ccids[ccid_ops->ccid_id] = ccid_ops;
> -		err = 0;
> +	if (ccid_ops->ccid_hc_tx_slab = NULL) {
> +		ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
> +		ccid_ops->ccid_hc_rx_slab = NULL;
> +		return -ENOBUFS;
>  	}
> -	ccids_write_unlock();
> -	if (err != 0)
> -		goto out_free_tx_slab;
>  
>  	pr_info("CCID: Registered CCID %d (%s)\n",
>  		ccid_ops->ccid_id, ccid_ops->ccid_name);
> -out:
> -	return err;
> -out_free_tx_slab:
> -	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
> -	ccid_ops->ccid_hc_tx_slab = NULL;
> -	goto out;
> -out_free_rx_slab:
> -	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
> -	ccid_ops->ccid_hc_rx_slab = NULL;
> -	goto out;
> +	return 0;
>  }
>  
> -EXPORT_SYMBOL_GPL(ccid_register);
> -
> -int ccid_unregister(struct ccid_operations *ccid_ops)
> +static int ccid_unregister(struct ccid_operations *ccid_ops)
>  {
> -	ccids_write_lock();
> -	ccids[ccid_ops->ccid_id] = NULL;
> -	ccids_write_unlock();
> -
>  	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
>  	ccid_ops->ccid_hc_tx_slab = NULL;
>  	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);

And "register/unregister" now don't make much sense since there is no
registration being done, just allocating/deallocating resources

> @@ -201,14 +135,12 @@ int ccid_unregister(struct ccid_operatio
>  	return 0;
>  }
>  
> -EXPORT_SYMBOL_GPL(ccid_unregister);
> -
>  int ccids_register_builtins(void)
>  {
>  	int i, err;
>  
> -	for (i = 0; i < ARRAY_SIZE(builtin_ccids_ops); i++) {
> -		err = ccid_register(builtin_ccids_ops[i]);
> +	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
> +		err = ccid_register(ccids[i]);
>  		if (err)
>  			goto unwind_registrations;
>  	}
> @@ -217,15 +149,31 @@ int ccids_register_builtins(void)
>  
>  unwind_registrations:
>  	while(--i >= 0)
> -		ccid_unregister(builtin_ccids_ops[i]);
> +		ccid_unregister(ccids[i]);
>  	return err;
>  }
>  
> -static struct ccid *__ccid_new(struct ccid_operations *ccid_ops, struct sock *sk,
> -			       int rx, gfp_t gfp)
> +
> +static struct ccid_operations *ccid_find_by_id(const u8 id)
>  {
> -	struct ccid *ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
> -						  ccid_ops->ccid_hc_tx_slab, gfp);
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(ccids); i++)
> +		if (ccids[i]->ccid_id = id)
> +			return ccids[i];
> +	return NULL;

Why the we searching? Can't we just do:

{
	if (id > ARRAY_SIZE(ccids) - 2)
		return NULL;
	return ccids[id - 2];
}

?

> +}
> +
> +struct ccid *ccid_new(const u8 id, struct sock *sk, bool rx)
> +{
> +	struct ccid_operations *ccid_ops = ccid_find_by_id(id);
> +	struct ccid *ccid;
> +
> +	if (ccid_ops = NULL)
> +		return NULL;
> +
> +	ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
> +				     ccid_ops->ccid_hc_tx_slab, gfp_any());
>  	if (ccid = NULL)
>  		return NULL;
>  
> @@ -241,58 +189,14 @@ static struct ccid *__ccid_new(struct cc
>  		    ccid->ccid_ops->ccid_hc_tx_init(ccid, sk) != 0)
>  			goto out_free_ccid;
>  	}
> +
>  	return ccid;
> +
>  out_free_ccid:
>  	kmem_cache_free(rx ? ccid_ops->ccid_hc_rx_slab :
>  			     ccid_ops->ccid_hc_tx_slab, ccid);
>  	return NULL;
>  }
> -
> -static bool is_builtin_ccid(unsigned char id)
> -{
> -	int i;
> -	for (i = 0; i < ARRAY_SIZE(builtin_ccids); i++)
> -		if (id = builtin_ccids[i])
> -			return true;
> -	return false;
> -}
> -
> -struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
> -{
> -	struct ccid_operations *ccid_ops;
> -	struct ccid *ccid = NULL;
> -
> -	if (is_builtin_ccid(id)) {
> -		ccid_ops = ccids[id];
> -		BUG_ON(ccid_ops = NULL);
> -		return __ccid_new(ccid_ops, sk, rx, gfp);
> -	}
> -
> -	ccids_read_lock();
> -#ifdef CONFIG_MODULES
> -	if (ccids[id] = NULL) {
> -		/* We only try to load if in process context */
> -		ccids_read_unlock();
> -		if (gfp & GFP_ATOMIC)
> -			goto out;
> -		request_module("net-dccp-ccid-%d", id);
> -		ccids_read_lock();
> -	}
> -#endif
> -	ccid_ops = ccids[id];
> -	if (ccid_ops = NULL)
> -		goto out_unlock;
> -
> -	ccids_read_unlock();
> -
> -	ccid = __ccid_new(ccid_ops, sk, rx, gfp);
> -out:
> -	return ccid;
> -out_unlock:
> -	ccids_read_unlock();
> -	goto out;
> -}
> -
>  EXPORT_SYMBOL_GPL(ccid_new);
>  
>  static void ccid_delete(struct ccid *ccid, struct sock *sk, int rx)
> --- a/net/dccp/feat.c
> +++ b/net/dccp/feat.c
> @@ -34,7 +34,7 @@
>  static int dccp_hdlr_ccid(struct sock *sk, u64 ccid, bool rx)
>  {
>  	struct dccp_sock *dp = dccp_sk(sk);
> -	struct ccid *new_ccid = ccid_new(ccid, sk, rx, gfp_any());
> +	struct ccid *new_ccid = ccid_new(ccid, sk, rx);
>  
>  	if (new_ccid = NULL)
>  		return -ENOMEM;

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

* Re: [RFC] [Patch 3/4] dccp: Add unregister function
  2008-12-20  8:08             ` Gerrit Renker
@ 2008-12-21  0:35               ` Arnaldo Carvalho de Melo
  -1 siblings, 0 replies; 72+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-12-21  0:35 UTC (permalink / raw)
  To: Gerrit Renker; +Cc: dccp, netdev

Em Sat, Dec 20, 2008 at 09:08:21AM +0100, Gerrit Renker escreveu:
> dccp: Add unregister function
> 
> This adds an unregister function to facilitate unloading the DCCP module.
> 
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
> ---
>  net/dccp/ccid.h  |    3 ++-
>  net/dccp/ccid.c  |   48 +++++++++++++++++++++++++++---------------------
>  net/dccp/proto.c |    3 ++-
>  3 files changed, 31 insertions(+), 23 deletions(-)
> 
> --- a/net/dccp/ccid.h
> +++ b/net/dccp/ccid.h
> @@ -91,7 +91,8 @@ extern struct ccid_operations ccid2_ops;
>  extern struct ccid_operations ccid3_ops;
>  #endif
>  
> -extern int ccids_register_builtins(void);
> +extern int  ccid_register_builtins(void);
> +extern void ccid_unregister_builtins(void);
>  
>  struct ccid {
>  	struct ccid_operations *ccid_ops;
> --- a/net/dccp/ccid.c
> +++ b/net/dccp/ccid.c
> @@ -123,7 +123,7 @@ static int ccid_register(struct ccid_ope
>  	return 0;
>  }
>  
> -static int ccid_unregister(struct ccid_operations *ccid_ops)
> +static void ccid_unregister(struct ccid_operations *ccid_ops)
>  {
>  	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
>  	ccid_ops->ccid_hc_tx_slab = NULL;
> @@ -132,28 +132,8 @@ static int ccid_unregister(struct ccid_o
>  
>  	pr_info("CCID: Unregistered CCID %d (%s)\n",
>  		ccid_ops->ccid_id, ccid_ops->ccid_name);
> -	return 0;
> -}
> -
> -int ccids_register_builtins(void)
> -{
> -	int i, err;
> -
> -	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
> -		err = ccid_register(ccids[i]);
> -		if (err)
> -			goto unwind_registrations;
> -	}
> -
> -	return 0;
> -
> -unwind_registrations:
> -	while(--i >= 0)
> -		ccid_unregister(ccids[i]);
> -	return err;
>  }

Why remove this?
  
> -
>  static struct ccid_operations *ccid_find_by_id(const u8 id)
>  {
>  	int i;
> @@ -231,3 +211,29 @@ void ccid_hc_tx_delete(struct ccid *ccid
>  }
>  
>  EXPORT_SYMBOL_GPL(ccid_hc_tx_delete);
> +
> +int __init ccid_register_builtins(void)
> +{
> +	int i, err;
> +
> +	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
> +		err = ccid_register(ccids[i]);
> +		if (err)
> +			goto unwind_registrations;
> +	}
> +
> +	return 0;
> +
> +unwind_registrations:
> +	while(--i >= 0)
> +		ccid_unregister(ccids[i]);
> +	return err;
> +}

Ah, just moved it around.

> +void ccid_unregister_builtins(void)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(ccids); i++)
> +		ccid_unregister(ccids[i]);
> +}
> --- a/net/dccp/proto.c
> +++ b/net/dccp/proto.c
> @@ -1119,7 +1119,7 @@ static int __init dccp_init(void)
>  	if (rc)
>  		goto out_ackvec_exit;
>  
> -	rc = ccids_register_builtins();
> +	rc = ccid_register_builtins();
>  	if (rc)
>  		goto out_sysctl_exit;
>  
> @@ -1148,6 +1148,7 @@ out_free_bind_bucket_cachep:
>  
>  static void __exit dccp_fini(void)
>  {
> +	ccid_unregister_builtins();
>  	dccp_mib_exit();
>  	free_pages((unsigned long)dccp_hashinfo.bhash,
>  		   get_order(dccp_hashinfo.bhash_size *

OK:

Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>

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

* Re: [RFC] [Patch 3/4] dccp: Add unregister function
@ 2008-12-21  0:35               ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 72+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-12-21  0:35 UTC (permalink / raw)
  To: dccp

Em Sat, Dec 20, 2008 at 09:08:21AM +0100, Gerrit Renker escreveu:
> dccp: Add unregister function
> 
> This adds an unregister function to facilitate unloading the DCCP module.
> 
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
> ---
>  net/dccp/ccid.h  |    3 ++-
>  net/dccp/ccid.c  |   48 +++++++++++++++++++++++++++---------------------
>  net/dccp/proto.c |    3 ++-
>  3 files changed, 31 insertions(+), 23 deletions(-)
> 
> --- a/net/dccp/ccid.h
> +++ b/net/dccp/ccid.h
> @@ -91,7 +91,8 @@ extern struct ccid_operations ccid2_ops;
>  extern struct ccid_operations ccid3_ops;
>  #endif
>  
> -extern int ccids_register_builtins(void);
> +extern int  ccid_register_builtins(void);
> +extern void ccid_unregister_builtins(void);
>  
>  struct ccid {
>  	struct ccid_operations *ccid_ops;
> --- a/net/dccp/ccid.c
> +++ b/net/dccp/ccid.c
> @@ -123,7 +123,7 @@ static int ccid_register(struct ccid_ope
>  	return 0;
>  }
>  
> -static int ccid_unregister(struct ccid_operations *ccid_ops)
> +static void ccid_unregister(struct ccid_operations *ccid_ops)
>  {
>  	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
>  	ccid_ops->ccid_hc_tx_slab = NULL;
> @@ -132,28 +132,8 @@ static int ccid_unregister(struct ccid_o
>  
>  	pr_info("CCID: Unregistered CCID %d (%s)\n",
>  		ccid_ops->ccid_id, ccid_ops->ccid_name);
> -	return 0;
> -}
> -
> -int ccids_register_builtins(void)
> -{
> -	int i, err;
> -
> -	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
> -		err = ccid_register(ccids[i]);
> -		if (err)
> -			goto unwind_registrations;
> -	}
> -
> -	return 0;
> -
> -unwind_registrations:
> -	while(--i >= 0)
> -		ccid_unregister(ccids[i]);
> -	return err;
>  }

Why remove this?
  
> -
>  static struct ccid_operations *ccid_find_by_id(const u8 id)
>  {
>  	int i;
> @@ -231,3 +211,29 @@ void ccid_hc_tx_delete(struct ccid *ccid
>  }
>  
>  EXPORT_SYMBOL_GPL(ccid_hc_tx_delete);
> +
> +int __init ccid_register_builtins(void)
> +{
> +	int i, err;
> +
> +	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
> +		err = ccid_register(ccids[i]);
> +		if (err)
> +			goto unwind_registrations;
> +	}
> +
> +	return 0;
> +
> +unwind_registrations:
> +	while(--i >= 0)
> +		ccid_unregister(ccids[i]);
> +	return err;
> +}

Ah, just moved it around.

> +void ccid_unregister_builtins(void)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(ccids); i++)
> +		ccid_unregister(ccids[i]);
> +}
> --- a/net/dccp/proto.c
> +++ b/net/dccp/proto.c
> @@ -1119,7 +1119,7 @@ static int __init dccp_init(void)
>  	if (rc)
>  		goto out_ackvec_exit;
>  
> -	rc = ccids_register_builtins();
> +	rc = ccid_register_builtins();
>  	if (rc)
>  		goto out_sysctl_exit;
>  
> @@ -1148,6 +1148,7 @@ out_free_bind_bucket_cachep:
>  
>  static void __exit dccp_fini(void)
>  {
> +	ccid_unregister_builtins();
>  	dccp_mib_exit();
>  	free_pages((unsigned long)dccp_hashinfo.bhash,
>  		   get_order(dccp_hashinfo.bhash_size *

OK:

Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>

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

* Re: [RFC] [Patch 4/4] dccp: Integrate the TFRC library (dependency)
  2008-12-20  8:08             ` Gerrit Renker
@ 2008-12-21  0:55               ` Arnaldo Carvalho de Melo
  -1 siblings, 0 replies; 72+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-12-21  0:55 UTC (permalink / raw)
  To: Gerrit Renker; +Cc: dccp, netdev

Em Sat, Dec 20, 2008 at 09:08:26AM +0100, Gerrit Renker escreveu:
> dccp: Integrate the TFRC library objects into DCCP
> 
> The TFRC library is a dependency of the CCID-3 (and CCID-4)
> modules. The patch updates the Kconfig menu and Makefiles.
> 
> Note -- This solution is simple, I am sure that it can be
> done better and thus welcome suggestions to improve the
> conditional build statement below.

See below how I was reworking the Makefile and Kconfig files before
fetchmail got to your patch series.

I.e. IP_DCCP_TFRC_LIB is also deleted, and in
net/dccp/ccids/libs/Makefile we do simply:

dccp-$(CONFIG_IP_DCCP_CCID3) += tfrc.o tfrc_equation.o packet_history.o loss_interval.o

- Arnaldo

P.S. It just feels wrong that TCP, that was not designed with multiple
congestion modules in mind have in Linux a plugabble congestion control
infrastructure, one idea that was something that BSD also adopted after
Linux became a more easy platform to try new congestion algorithms.

Now DCCP, that was specifically designed with such infrastructure in
mind will not have such facility :-\

Yes, the locking there used code from other parts of the kernel
(sock_create) and bitrotted while the sock_create code took advantage of
better locking facilities later introduced (RCU), so we could just make
DCCP use that new facilities and not simply remove altogether the
dynamic loading capability.

I mentioned where the old code came from and pointed the cset where it
was transformed into RCU, didn't made the conversion trying to keep the
initial patch as small as possible.
 
diff --git a/net/dccp/Kconfig b/net/dccp/Kconfig
index 7aa2a7a..ad6dffd 100644
--- a/net/dccp/Kconfig
+++ b/net/dccp/Kconfig
@@ -1,7 +1,6 @@
 menuconfig IP_DCCP
 	tristate "The DCCP Protocol (EXPERIMENTAL)"
 	depends on INET && EXPERIMENTAL
-	select IP_DCCP_CCID2
 	---help---
 	  Datagram Congestion Control Protocol (RFC 4340)
 
@@ -25,9 +24,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"
diff --git a/net/dccp/Makefile b/net/dccp/Makefile
index f4f8793..e923a4d 100644
--- 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
 
diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig
index 1227594..96bfa1f 100644
--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -1,44 +1,21 @@
 menu "DCCP CCIDs Configuration (EXPERIMENTAL)"
 	depends on 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
-	  modelled directly on TCP, including congestion window, slow start,
-	  timeouts, and so forth [RFC 2581].  CCID 2 achieves maximum
-	  bandwidth over the long term, consistent with the use of end-to-end
-	  congestion control, but halves its congestion window in response to
-	  each congestion event.  This leads to the abrupt rate changes
-	  typical of TCP.  Applications should use CCID 2 if they prefer
-	  maximum bandwidth utilization to steadiness of rate.  This is often
-	  the case for applications that are not playing their data directly
-	  to the user.  For example, a hypothetical application that
-	  transferred files over DCCP, using application-level retransmissions
-	  for lost packets, would prefer CCID 2 to CCID 3.  On-line games may
-	  also prefer CCID 2.  See RFC 4341 for further details.
-
-	  CCID2 is the default CCID used by DCCP.
-
 config IP_DCCP_CCID2_DEBUG
 	  bool "CCID2 debugging messages"
-	  depends on IP_DCCP_CCID2
+	  depends on IP_DCCP
 	  ---help---
 	    Enable CCID2-specific debugging messages.
 
-	    When compiling CCID2 as a module, this debugging output can
+	    When compiling DCCP as a module, this debugging output can
 	    additionally be toggled by setting the ccid2_debug module
 	    parameter to 0 or 1.
 
 	    If in doubt, say N.
 
 config IP_DCCP_CCID3
-	tristate "CCID3 (TCP-Friendly) (EXPERIMENTAL)"
-	def_tristate IP_DCCP
-	select IP_DCCP_TFRC_LIB
+	bool "CCID3 (TCP-Friendly) (EXPERIMENTAL)"
+	def_bool y if (IP_DCCP = y || IP_DCCP = m)
 	---help---
 	  CCID 3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
 	  rate-controlled congestion control mechanism.  TFRC is designed to
@@ -59,10 +36,7 @@ config IP_DCCP_CCID3
 	  This text was extracted from RFC 4340 (sec. 10.2),
 	  http://www.ietf.org/rfc/rfc4340.txt
 	  
-	  To compile this CCID as a module, choose M here: the module will be
-	  called dccp_ccid3.
-
-	  If in doubt, say M.
+	  If in doubt, say N.
 
 config IP_DCCP_CCID3_DEBUG
 	  bool "CCID3 debugging messages"
@@ -107,13 +81,8 @@ config IP_DCCP_CCID3_RTO
 	    is serious network congestion: experimenting with larger values should
 	    therefore not be performed on WANs.
 
-config IP_DCCP_TFRC_LIB
-	tristate
-	default n
-
 config IP_DCCP_TFRC_DEBUG
 	bool
-	depends on IP_DCCP_TFRC_LIB
 	default y if IP_DCCP_CCID3_DEBUG
 
 endmenu
diff --git a/net/dccp/ccids/Makefile b/net/dccp/ccids/Makefile
index 438f20b..4d4b1da 100644
--- a/net/dccp/ccids/Makefile
+++ b/net/dccp/ccids/Makefile
@@ -1,9 +1,4 @@
-obj-$(CONFIG_IP_DCCP_CCID3) += dccp_ccid3.o
-
-dccp_ccid3-y := ccid3.o
-
-obj-$(CONFIG_IP_DCCP_CCID2) += dccp_ccid2.o
-
-dccp_ccid2-y := ccid2.o
-
 obj-y += lib/
+
+dccp-y += ccid2.o
+dccp-$(CONFIG_IP_DCCP_CCID3) += ccid3.o
diff --git a/net/dccp/ccids/lib/Makefile b/net/dccp/ccids/lib/Makefile
index 68c93e3..95ad0d9 100644
--- a/net/dccp/ccids/lib/Makefile
+++ b/net/dccp/ccids/lib/Makefile
@@ -1,3 +1 @@
-obj-$(CONFIG_IP_DCCP_TFRC_LIB) += dccp_tfrc_lib.o
-
-dccp_tfrc_lib-y := tfrc.o tfrc_equation.o packet_history.o loss_interval.o
+dccp-$(CONFIG_IP_DCCP_CCID3) += tfrc.o tfrc_equation.o packet_history.o loss_interval.o

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

* Re: [RFC] [Patch 4/4] dccp: Integrate the TFRC library (dependency)
@ 2008-12-21  0:55               ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 72+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-12-21  0:55 UTC (permalink / raw)
  To: dccp

Em Sat, Dec 20, 2008 at 09:08:26AM +0100, Gerrit Renker escreveu:
> dccp: Integrate the TFRC library objects into DCCP
> 
> The TFRC library is a dependency of the CCID-3 (and CCID-4)
> modules. The patch updates the Kconfig menu and Makefiles.
> 
> Note -- This solution is simple, I am sure that it can be
> done better and thus welcome suggestions to improve the
> conditional build statement below.

See below how I was reworking the Makefile and Kconfig files before
fetchmail got to your patch series.

I.e. IP_DCCP_TFRC_LIB is also deleted, and in
net/dccp/ccids/libs/Makefile we do simply:

dccp-$(CONFIG_IP_DCCP_CCID3) += tfrc.o tfrc_equation.o packet_history.o loss_interval.o

- Arnaldo

P.S. It just feels wrong that TCP, that was not designed with multiple
congestion modules in mind have in Linux a plugabble congestion control
infrastructure, one idea that was something that BSD also adopted after
Linux became a more easy platform to try new congestion algorithms.

Now DCCP, that was specifically designed with such infrastructure in
mind will not have such facility :-\

Yes, the locking there used code from other parts of the kernel
(sock_create) and bitrotted while the sock_create code took advantage of
better locking facilities later introduced (RCU), so we could just make
DCCP use that new facilities and not simply remove altogether the
dynamic loading capability.

I mentioned where the old code came from and pointed the cset where it
was transformed into RCU, didn't made the conversion trying to keep the
initial patch as small as possible.
 
diff --git a/net/dccp/Kconfig b/net/dccp/Kconfig
index 7aa2a7a..ad6dffd 100644
--- a/net/dccp/Kconfig
+++ b/net/dccp/Kconfig
@@ -1,7 +1,6 @@
 menuconfig IP_DCCP
 	tristate "The DCCP Protocol (EXPERIMENTAL)"
 	depends on INET && EXPERIMENTAL
-	select IP_DCCP_CCID2
 	---help---
 	  Datagram Congestion Control Protocol (RFC 4340)
 
@@ -25,9 +24,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"
diff --git a/net/dccp/Makefile b/net/dccp/Makefile
index f4f8793..e923a4d 100644
--- 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
 
diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig
index 1227594..96bfa1f 100644
--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -1,44 +1,21 @@
 menu "DCCP CCIDs Configuration (EXPERIMENTAL)"
 	depends on 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
-	  modelled directly on TCP, including congestion window, slow start,
-	  timeouts, and so forth [RFC 2581].  CCID 2 achieves maximum
-	  bandwidth over the long term, consistent with the use of end-to-end
-	  congestion control, but halves its congestion window in response to
-	  each congestion event.  This leads to the abrupt rate changes
-	  typical of TCP.  Applications should use CCID 2 if they prefer
-	  maximum bandwidth utilization to steadiness of rate.  This is often
-	  the case for applications that are not playing their data directly
-	  to the user.  For example, a hypothetical application that
-	  transferred files over DCCP, using application-level retransmissions
-	  for lost packets, would prefer CCID 2 to CCID 3.  On-line games may
-	  also prefer CCID 2.  See RFC 4341 for further details.
-
-	  CCID2 is the default CCID used by DCCP.
-
 config IP_DCCP_CCID2_DEBUG
 	  bool "CCID2 debugging messages"
-	  depends on IP_DCCP_CCID2
+	  depends on IP_DCCP
 	  ---help---
 	    Enable CCID2-specific debugging messages.
 
-	    When compiling CCID2 as a module, this debugging output can
+	    When compiling DCCP as a module, this debugging output can
 	    additionally be toggled by setting the ccid2_debug module
 	    parameter to 0 or 1.
 
 	    If in doubt, say N.
 
 config IP_DCCP_CCID3
-	tristate "CCID3 (TCP-Friendly) (EXPERIMENTAL)"
-	def_tristate IP_DCCP
-	select IP_DCCP_TFRC_LIB
+	bool "CCID3 (TCP-Friendly) (EXPERIMENTAL)"
+	def_bool y if (IP_DCCP = y || IP_DCCP = m)
 	---help---
 	  CCID 3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
 	  rate-controlled congestion control mechanism.  TFRC is designed to
@@ -59,10 +36,7 @@ config IP_DCCP_CCID3
 	  This text was extracted from RFC 4340 (sec. 10.2),
 	  http://www.ietf.org/rfc/rfc4340.txt
 	  
-	  To compile this CCID as a module, choose M here: the module will be
-	  called dccp_ccid3.
-
-	  If in doubt, say M.
+	  If in doubt, say N.
 
 config IP_DCCP_CCID3_DEBUG
 	  bool "CCID3 debugging messages"
@@ -107,13 +81,8 @@ config IP_DCCP_CCID3_RTO
 	    is serious network congestion: experimenting with larger values should
 	    therefore not be performed on WANs.
 
-config IP_DCCP_TFRC_LIB
-	tristate
-	default n
-
 config IP_DCCP_TFRC_DEBUG
 	bool
-	depends on IP_DCCP_TFRC_LIB
 	default y if IP_DCCP_CCID3_DEBUG
 
 endmenu
diff --git a/net/dccp/ccids/Makefile b/net/dccp/ccids/Makefile
index 438f20b..4d4b1da 100644
--- a/net/dccp/ccids/Makefile
+++ b/net/dccp/ccids/Makefile
@@ -1,9 +1,4 @@
-obj-$(CONFIG_IP_DCCP_CCID3) += dccp_ccid3.o
-
-dccp_ccid3-y := ccid3.o
-
-obj-$(CONFIG_IP_DCCP_CCID2) += dccp_ccid2.o
-
-dccp_ccid2-y := ccid2.o
-
 obj-y += lib/
+
+dccp-y += ccid2.o
+dccp-$(CONFIG_IP_DCCP_CCID3) += ccid3.o
diff --git a/net/dccp/ccids/lib/Makefile b/net/dccp/ccids/lib/Makefile
index 68c93e3..95ad0d9 100644
--- a/net/dccp/ccids/lib/Makefile
+++ b/net/dccp/ccids/lib/Makefile
@@ -1,3 +1 @@
-obj-$(CONFIG_IP_DCCP_TFRC_LIB) += dccp_tfrc_lib.o
-
-dccp_tfrc_lib-y := tfrc.o tfrc_equation.o packet_history.o loss_interval.o
+dccp-$(CONFIG_IP_DCCP_CCID3) += tfrc.o tfrc_equation.o packet_history.o loss_interval.o

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

* Re: [RFC] [Patch 4/4] dccp: Integrate the TFRC library (dependency)
  2008-12-20  8:08             ` Gerrit Renker
@ 2008-12-23 10:54                 ` Gerrit Renker
  -1 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-23 10:54 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, dccp, netdev

Hi Arnaldo,

thanks a lot for the replies. The patches that I have sent were also
bona fide 'RFC', i.e. they also need more work. I am in the process
of revising the patches again, but will probably not finish before
the holidays.

The plan is to address the comments, combine that with your patch
and then resubmit the tidied-up results.

| I.e. IP_DCCP_TFRC_LIB is also deleted, and in
| net/dccp/ccids/libs/Makefile we do simply:
|
| dccp-$(CONFIG_IP_DCCP_CCID3) += tfrc.o tfrc_equation.o packet_history.o loss_interval.o
|
At first I didn't like the removal of 'IP_DCCP_TFRC_LIB', but I also don't like
TFRC. If there is consensus to forget the expired CCID-4 then we can remove it,
otherwise we probably need to keep IP_DCCP_TFRC_LIB for the sake of CCID-4.

I tried above suggestion in different variations: the problem is that kbuild considers
objects for dccp-y/dccp-objs only from within the Makefile in net/dccp, i.e. the above
does not compile (lost a lot of time about it).

Hence I will revert to the previous solution which is similar to the above and worked
fine.

| P.S. It just feels wrong that TCP, that was not designed with multiple
| congestion modules in mind have in Linux a plugabble congestion control
| infrastructure, one idea that was something that BSD also adopted after
| Linux became a more easy platform to try new congestion algorithms.
| 
| Now DCCP, that was specifically designed with such infrastructure in
| mind will not have such facility :-\
| 
Yes, at the moment it is sad to see the loading and locking code go, in
particular since a lot of thought had been put into its design. Frankly,
I think that this code is too good/much/rich for the present situation.

The situation is that at the moment we only have a handful of CCIDs which
still need a lot more work (after the work that went in already) before they
could be considered a serious alternative to UDP/TCP/SCTP.

And I think that David Miller is right here - for those two CCIDs we don't
need elaborate locking/loading.

At the moment there are also no Internet Drafts specifying CCIDs. As soon
as there is one, the new CCID either becomes a potential new builtin CCID
or reaches the current state of CCID-4 ('expired').

But the 'builtin' solution also has a natural limit: each new CCID module
will increase the size of dccp.ko. A connection can only use 1 CCID (since
mixing different CCIDs for RX/TX is not practicable/supported), so loading
the code of 9 CCIDs where only one is used means a "size" overhead.

When and if this situation is reached it again would make sense to use
loadable modules, where the loading/locking scheme is then needed again.

Once this feature-negotiation patch set is over, we are one step ahead of TCP,
which was not designed for negotiating capabilities (e.g. the "negotiation"
of timestamp usage in RFC1323).


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

* Re: [RFC] [Patch 4/4] dccp: Integrate the TFRC library (dependency)
@ 2008-12-23 10:54                 ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-23 10:54 UTC (permalink / raw)
  To: dccp

Hi Arnaldo,

thanks a lot for the replies. The patches that I have sent were also
bona fide 'RFC', i.e. they also need more work. I am in the process
of revising the patches again, but will probably not finish before
the holidays.

The plan is to address the comments, combine that with your patch
and then resubmit the tidied-up results.

| I.e. IP_DCCP_TFRC_LIB is also deleted, and in
| net/dccp/ccids/libs/Makefile we do simply:
|
| dccp-$(CONFIG_IP_DCCP_CCID3) += tfrc.o tfrc_equation.o packet_history.o loss_interval.o
|
At first I didn't like the removal of 'IP_DCCP_TFRC_LIB', but I also don't like
TFRC. If there is consensus to forget the expired CCID-4 then we can remove it,
otherwise we probably need to keep IP_DCCP_TFRC_LIB for the sake of CCID-4.

I tried above suggestion in different variations: the problem is that kbuild considers
objects for dccp-y/dccp-objs only from within the Makefile in net/dccp, i.e. the above
does not compile (lost a lot of time about it).

Hence I will revert to the previous solution which is similar to the above and worked
fine.

| P.S. It just feels wrong that TCP, that was not designed with multiple
| congestion modules in mind have in Linux a plugabble congestion control
| infrastructure, one idea that was something that BSD also adopted after
| Linux became a more easy platform to try new congestion algorithms.
| 
| Now DCCP, that was specifically designed with such infrastructure in
| mind will not have such facility :-\
| 
Yes, at the moment it is sad to see the loading and locking code go, in
particular since a lot of thought had been put into its design. Frankly,
I think that this code is too good/much/rich for the present situation.

The situation is that at the moment we only have a handful of CCIDs which
still need a lot more work (after the work that went in already) before they
could be considered a serious alternative to UDP/TCP/SCTP.

And I think that David Miller is right here - for those two CCIDs we don't
need elaborate locking/loading.

At the moment there are also no Internet Drafts specifying CCIDs. As soon
as there is one, the new CCID either becomes a potential new builtin CCID
or reaches the current state of CCID-4 ('expired').

But the 'builtin' solution also has a natural limit: each new CCID module
will increase the size of dccp.ko. A connection can only use 1 CCID (since
mixing different CCIDs for RX/TX is not practicable/supported), so loading
the code of 9 CCIDs where only one is used means a "size" overhead.

When and if this situation is reached it again would make sense to use
loadable modules, where the loading/locking scheme is then needed again.

Once this feature-negotiation patch set is over, we are one step ahead of TCP,
which was not designed for negotiating capabilities (e.g. the "negotiation"
of timestamp usage in RFC1323).


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

* Re: [RFC] [Patch 2/4] dccp: Lockless use of CCID blocks
  2008-12-20  8:08             ` Gerrit Renker
@ 2008-12-23 17:08                 ` Gerrit Renker
  -1 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-23 17:08 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, dccp, netdev

| > -int ccid_unregister(struct ccid_operations *ccid_ops)
| > +static int ccid_unregister(struct ccid_operations *ccid_ops)
| >  {
<snip>
| 
| And "register/unregister" now don't make much sense since there is no
| registration being done, just allocating/deallocating resources
| 
Yes agree - this needs revision. We can also drop the EXPORT_SYMBOLS
from the now-static routines.

| > +
| > +static struct ccid_operations *ccid_find_by_id(const u8 id)
| >  {
| > -	struct ccid *ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
| > -						  ccid_ops->ccid_hc_tx_slab, gfp);
| > +	int i;
| > +
| > +	for (i = 0; i < ARRAY_SIZE(ccids); i++)
| > +		if (ccids[i]->ccid_id == id)
| > +			return ccids[i];
| > +	return NULL;
| 
| Why the we searching? Can't we just do:
| 
| {
| 	if (id > ARRAY_SIZE(ccids) - 2)
| 		return NULL;
| 	return ccids[id - 2];
| }
| 
Agree 100%, I don't like the routine myself and have been thinking about
how to rewrite it. Current idea is to go back to the original and use

static struct ccid_operations *ccids[CCIDS_MAX] = {
	[DCCPC_CCID2] = &ccid2_ops,
#ifdef CONFIG_IP_DCCP_CCID3
	[DCCPC_CCID3] = &ccid3_ops,
#endif
};

And then use 
	
	if (id < 0 || id >= CCIDS_MAX)
		return NULL;
	return ccids[id];		

which may be NULL if there is no entry in the array. Better?	

Gerrit

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

* Re: [RFC] [Patch 2/4] dccp: Lockless use of CCID blocks
@ 2008-12-23 17:08                 ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-23 17:08 UTC (permalink / raw)
  To: dccp

| > -int ccid_unregister(struct ccid_operations *ccid_ops)
| > +static int ccid_unregister(struct ccid_operations *ccid_ops)
| >  {
<snip>
| 
| And "register/unregister" now don't make much sense since there is no
| registration being done, just allocating/deallocating resources
| 
Yes agree - this needs revision. We can also drop the EXPORT_SYMBOLS
from the now-static routines.

| > +
| > +static struct ccid_operations *ccid_find_by_id(const u8 id)
| >  {
| > -	struct ccid *ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
| > -						  ccid_ops->ccid_hc_tx_slab, gfp);
| > +	int i;
| > +
| > +	for (i = 0; i < ARRAY_SIZE(ccids); i++)
| > +		if (ccids[i]->ccid_id = id)
| > +			return ccids[i];
| > +	return NULL;
| 
| Why the we searching? Can't we just do:
| 
| {
| 	if (id > ARRAY_SIZE(ccids) - 2)
| 		return NULL;
| 	return ccids[id - 2];
| }
| 
Agree 100%, I don't like the routine myself and have been thinking about
how to rewrite it. Current idea is to go back to the original and use

static struct ccid_operations *ccids[CCIDS_MAX] = {
	[DCCPC_CCID2] = &ccid2_ops,
#ifdef CONFIG_IP_DCCP_CCID3
	[DCCPC_CCID3] = &ccid3_ops,
#endif
};

And then use 
	
	if (id < 0 || id >= CCIDS_MAX)
		return NULL;
	return ccids[id];		

which may be NULL if there is no entry in the array. Better?	

Gerrit

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

* Re: [RFC] [Patch 2/4] dccp: Lockless use of CCID blocks
  2008-12-20  8:08             ` Gerrit Renker
@ 2008-12-23 17:17                 ` Gerrit Renker
  -1 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-23 17:17 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, dccp, netdev

| > -int ccid_unregister(struct ccid_operations *ccid_ops)
| > +static int ccid_unregister(struct ccid_operations *ccid_ops)
| >  {
<snip>
| 
| And "register/unregister" now don't make much sense since there is no
| registration being done, just allocating/deallocating resources
| 
Yes agree - this needs revision. We can also drop the EXPORT_SYMBOLS
from the now-static routines.

| > +
| > +static struct ccid_operations *ccid_find_by_id(const u8 id)
| >  {
| > -	struct ccid *ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
| > -						  ccid_ops->ccid_hc_tx_slab, gfp);
| > +	int i;
| > +
| > +	for (i = 0; i < ARRAY_SIZE(ccids); i++)
| > +		if (ccids[i]->ccid_id == id)
| > +			return ccids[i];
| > +	return NULL;
| 
| Why the we searching? Can't we just do:
| 
| {
| 	if (id > ARRAY_SIZE(ccids) - 2)
| 		return NULL;
| 	return ccids[id - 2];
| }
| 
Agree 100%, I don't like the routine myself and have been thinking about
how to rewrite it. Current idea is to go back to the original and use

static struct ccid_operations *ccids[CCIDS_MAX] = {
	[DCCPC_CCID2] = &ccid2_ops,
#ifdef CONFIG_IP_DCCP_CCID3
	[DCCPC_CCID3] = &ccid3_ops,
#endif
};

And then use 
	
	if (id < 0 || id >= CCIDS_MAX)
		return NULL;
	return ccids[id];		

which may be NULL if there is no entry in the array. Better?	

Gerrit

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

* Re: [RFC] [Patch 2/4] dccp: Lockless use of CCID blocks
@ 2008-12-23 17:17                 ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2008-12-23 17:17 UTC (permalink / raw)
  To: dccp

| > -int ccid_unregister(struct ccid_operations *ccid_ops)
| > +static int ccid_unregister(struct ccid_operations *ccid_ops)
| >  {
<snip>
| 
| And "register/unregister" now don't make much sense since there is no
| registration being done, just allocating/deallocating resources
| 
Yes agree - this needs revision. We can also drop the EXPORT_SYMBOLS
from the now-static routines.

| > +
| > +static struct ccid_operations *ccid_find_by_id(const u8 id)
| >  {
| > -	struct ccid *ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
| > -						  ccid_ops->ccid_hc_tx_slab, gfp);
| > +	int i;
| > +
| > +	for (i = 0; i < ARRAY_SIZE(ccids); i++)
| > +		if (ccids[i]->ccid_id = id)
| > +			return ccids[i];
| > +	return NULL;
| 
| Why the we searching? Can't we just do:
| 
| {
| 	if (id > ARRAY_SIZE(ccids) - 2)
| 		return NULL;
| 	return ccids[id - 2];
| }
| 
Agree 100%, I don't like the routine myself and have been thinking about
how to rewrite it. Current idea is to go back to the original and use

static struct ccid_operations *ccids[CCIDS_MAX] = {
	[DCCPC_CCID2] = &ccid2_ops,
#ifdef CONFIG_IP_DCCP_CCID3
	[DCCPC_CCID3] = &ccid3_ops,
#endif
};

And then use 
	
	if (id < 0 || id >= CCIDS_MAX)
		return NULL;
	return ccids[id];		

which may be NULL if there is no entry in the array. Better?	

Gerrit

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

* Re: [RFC] [Patch 2/4] dccp: Lockless use of CCID blocks
  2008-12-20  8:08             ` Gerrit Renker
@ 2009-01-01 10:49                   ` Gerrit Renker
  -1 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-01 10:49 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, dccp, netdev

| | > +	for (i = 0; i < ARRAY_SIZE(ccids); i++)
| | > +		if (ccids[i]->ccid_id == id)
| | > +			return ccids[i];
| | > +	return NULL;
| | 
| | Why the we searching? Can't we just do:
| | 
| | {
| | 	if (id > ARRAY_SIZE(ccids) - 2)
| | 		return NULL;
| | 	return ccids[id - 2];
| | }
| | 
| Agree 100%, I don't like the routine myself and have been thinking about
| how to rewrite it. Current idea is to go back to the original and use
| 
| static struct ccid_operations *ccids[CCIDS_MAX] = {
| 	[DCCPC_CCID2] = &ccid2_ops,
| #ifdef CONFIG_IP_DCCP_CCID3
| 	[DCCPC_CCID3] = &ccid3_ops,
| #endif
| };
| 
Unfortunately I found later that this solution introduces a lot of waste: 
during initialisation, the code must step over 255 - 2 = 253 NULL entries
and the same happens when ejecting the CCID.

I went through several revisions and summarize the findings below.

The following functions need to query for built-in CCIDs:

bool ccid_support_check(u8 const *ccid_array, u8 array_len);
   This is used by the feature-negotiation code to determine whether
   all elements in 'ccid_array' are supported; for checking the CCID
   setsockopt values and to check whether the CCID suggested by the
   peer is locally available.

int ccid_get_builtin_ccids(u8 **ccid_array, u8 *array_len);
   This is used during initialisation of the feature-negotiation code,
   to create a list of the CCID values that can be advertised.

int ccid_getsockopt_builtin_ccids(struct sock *sk, int len, ...);
   Used to provide the DCCP_SOCKOPT_AVAILABLE_CCIDS getsockopt option
   which passes a list of available CCIDs to userspace.
   
struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, ...);
   This function is called by the CCID handler in feat.c to set the RX/TX	
   CCID after it has been negotiated with the peer.


The first 3 functions can be implemented by simply walking through the
array, the last one requires to map a CCID value (Table 5 in RFC 4340,
10) into an array index. In the above, CCID ID = array index but only
2 out of 256 possible IDs (0..255) are non-empty (less than 0.8%).

Furthermore, the CCIDs need not be in consecutive order. For example
CCID-248 .. CCID-254 are experimental (RFC 4340, 19.5), so we could
have an array like

 struct ccid_operations *ccids[] = {
	 &ccid2_ops, &ccid3_ops, &ccid247_ops, &ccid254_ops
 };

This gives the mapping 0 +-> 2, 1 +-> 3, 2 +-> 247, 3 +-> 254. The
ccid_new() function needs the inverse mapping, e.g. for CCID-247 it
needs to find the third array entry.

So we have the choice of
 * O(1) access for ccid_new() when using an array with 256 entries,
   but have to pay the price of more complex registration /
   unregistration routines. In addition, the 'get_builtin_xxx'
   routines need to make two passes instead of one, to determine
   the number of non-NULL entries.
 * O(n) linear search to map a CCID number into the corresponding
   array index, but simpler implementation of several routines.

Since n is much smaller than 255, I think the latter is better here.

[patch is on the way, need to finish testing]

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

* Re: [RFC] [Patch 2/4] dccp: Lockless use of CCID blocks
@ 2009-01-01 10:49                   ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-01 10:49 UTC (permalink / raw)
  To: dccp

| | > +	for (i = 0; i < ARRAY_SIZE(ccids); i++)
| | > +		if (ccids[i]->ccid_id = id)
| | > +			return ccids[i];
| | > +	return NULL;
| | 
| | Why the we searching? Can't we just do:
| | 
| | {
| | 	if (id > ARRAY_SIZE(ccids) - 2)
| | 		return NULL;
| | 	return ccids[id - 2];
| | }
| | 
| Agree 100%, I don't like the routine myself and have been thinking about
| how to rewrite it. Current idea is to go back to the original and use
| 
| static struct ccid_operations *ccids[CCIDS_MAX] = {
| 	[DCCPC_CCID2] = &ccid2_ops,
| #ifdef CONFIG_IP_DCCP_CCID3
| 	[DCCPC_CCID3] = &ccid3_ops,
| #endif
| };
| 
Unfortunately I found later that this solution introduces a lot of waste: 
during initialisation, the code must step over 255 - 2 = 253 NULL entries
and the same happens when ejecting the CCID.

I went through several revisions and summarize the findings below.

The following functions need to query for built-in CCIDs:

bool ccid_support_check(u8 const *ccid_array, u8 array_len);
   This is used by the feature-negotiation code to determine whether
   all elements in 'ccid_array' are supported; for checking the CCID
   setsockopt values and to check whether the CCID suggested by the
   peer is locally available.

int ccid_get_builtin_ccids(u8 **ccid_array, u8 *array_len);
   This is used during initialisation of the feature-negotiation code,
   to create a list of the CCID values that can be advertised.

int ccid_getsockopt_builtin_ccids(struct sock *sk, int len, ...);
   Used to provide the DCCP_SOCKOPT_AVAILABLE_CCIDS getsockopt option
   which passes a list of available CCIDs to userspace.
   
struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, ...);
   This function is called by the CCID handler in feat.c to set the RX/TX	
   CCID after it has been negotiated with the peer.


The first 3 functions can be implemented by simply walking through the
array, the last one requires to map a CCID value (Table 5 in RFC 4340,
10) into an array index. In the above, CCID ID = array index but only
2 out of 256 possible IDs (0..255) are non-empty (less than 0.8%).

Furthermore, the CCIDs need not be in consecutive order. For example
CCID-248 .. CCID-254 are experimental (RFC 4340, 19.5), so we could
have an array like

 struct ccid_operations *ccids[] = {
	 &ccid2_ops, &ccid3_ops, &ccid247_ops, &ccid254_ops
 };

This gives the mapping 0 +-> 2, 1 +-> 3, 2 +-> 247, 3 +-> 254. The
ccid_new() function needs the inverse mapping, e.g. for CCID-247 it
needs to find the third array entry.

So we have the choice of
 * O(1) access for ccid_new() when using an array with 256 entries,
   but have to pay the price of more complex registration /
   unregistration routines. In addition, the 'get_builtin_xxx'
   routines need to make two passes instead of one, to determine
   the number of non-NULL entries.
 * O(n) linear search to map a CCID number into the corresponding
   array index, but simpler implementation of several routines.

Since n is much smaller than 255, I think the latter is better here.

[patch is on the way, need to finish testing]

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

* [Patch 0/3] dccp: Lockless use of CCID blocks
@ 2009-01-03  7:30                     ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-03  7:30 UTC (permalink / raw)
  To: davem; +Cc: dccp, netdev

Hi Dave,

please find attached an updated and tested revision of the earlier 
patch set to enable lockless use of CCID plugins within DCCP.

It combines the initial patch by Arnaldo with further work, following
discussions on this mailing list.

All patches have been compile individually (sparse enabled) and have
been verified to work.

Wishing a good new year
Gerrit


Changes relative to earlier revision:
-------------------------------------
 * incorporated Arnaldo's feedback regarding the deletion of jump labels
 * and the renaming of the register/unregister functions (for want of a
   better word, 'activate' has been used here);
 * added un-registration function to allow module unloading;
 * removed now obsolute module references from the CCIDs (ccid_owner);
 * updated Kconfig menu to reflect all the new changes.


List of patches:
----------------
Patch #1: Integrates CCID plugins with dccp.ko main module.
Patch #2: Cleans up the old interface.
Patch #3: Integrates the TFRC library, a dependency of CCID-3.


The set is also available for online viewing, at
http://eden-feed.erg.abdn.ac.uk/cgi-bin/gitweb.cgi?p=dccp_exp.git;a=commitdiff;h=07b69e62ebcb01c4ec9e372e70aabbdd21d9c4fc

CCID-4 has also been updated and likewise been tested - negotiation,
as well as a longer test involving audio streaming.
http://eden-feed.erg.abdn.ac.uk/cgi-bin/gitweb.cgi?p=dccp_exp.git;a=shortlog;h=ccid4


Patch stats:
------------
 net/dccp/Kconfig                    |    4 
 net/dccp/Makefile                   |   15 +
 net/dccp/ackvec.h                   |   53 ------
 net/dccp/ccid.c                     |  300 ++++++++++++++----------------------
 net/dccp/ccid.h                     |   14 -
 net/dccp/ccids/Kconfig              |   73 ++------
 net/dccp/ccids/Makefile             |    9 -
 net/dccp/ccids/ccid2.c              |   22 --
 net/dccp/ccids/ccid3.c              |   23 --
 net/dccp/ccids/lib/Makefile         |    3 
 net/dccp/ccids/lib/loss_interval.c  |    3 
 net/dccp/ccids/lib/packet_history.c |    9 -
 net/dccp/ccids/lib/tfrc.c           |   19 --
 net/dccp/ccids/lib/tfrc.h           |   11 +
 net/dccp/ccids/lib/tfrc_equation.c  |    4 
 net/dccp/dccp.h                     |    2 
 net/dccp/feat.c                     |    6 
 net/dccp/input.c                    |    2 
 net/dccp/proto.c                    |    7 
 19 files changed, 186 insertions(+), 393 deletions(-)

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

* [Patch 0/3] dccp: Lockless use of CCID blocks
@ 2009-01-03  7:30                     ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-03  7:30 UTC (permalink / raw)
  To: dccp

Hi Dave,

please find attached an updated and tested revision of the earlier 
patch set to enable lockless use of CCID plugins within DCCP.

It combines the initial patch by Arnaldo with further work, following
discussions on this mailing list.

All patches have been compile individually (sparse enabled) and have
been verified to work.

Wishing a good new year
Gerrit


Changes relative to earlier revision:
-------------------------------------
 * incorporated Arnaldo's feedback regarding the deletion of jump labels
 * and the renaming of the register/unregister functions (for want of a
   better word, 'activate' has been used here);
 * added un-registration function to allow module unloading;
 * removed now obsolute module references from the CCIDs (ccid_owner);
 * updated Kconfig menu to reflect all the new changes.


List of patches:
----------------
Patch #1: Integrates CCID plugins with dccp.ko main module.
Patch #2: Cleans up the old interface.
Patch #3: Integrates the TFRC library, a dependency of CCID-3.


The set is also available for online viewing, at
http://eden-feed.erg.abdn.ac.uk/cgi-bin/gitweb.cgi?p‹cp_exp.git;a=commitdiff;h\ab69e62ebcb01c4ec9e372e70aabbdd21d9c4fc

CCID-4 has also been updated and likewise been tested - negotiation,
as well as a longer test involving audio streaming.
http://eden-feed.erg.abdn.ac.uk/cgi-bin/gitweb.cgi?p‹cp_exp.git;a=shortlog;hÃid4


Patch stats:
------------
 net/dccp/Kconfig                    |    4 
 net/dccp/Makefile                   |   15 +
 net/dccp/ackvec.h                   |   53 ------
 net/dccp/ccid.c                     |  300 ++++++++++++++----------------------
 net/dccp/ccid.h                     |   14 -
 net/dccp/ccids/Kconfig              |   73 ++------
 net/dccp/ccids/Makefile             |    9 -
 net/dccp/ccids/ccid2.c              |   22 --
 net/dccp/ccids/ccid3.c              |   23 --
 net/dccp/ccids/lib/Makefile         |    3 
 net/dccp/ccids/lib/loss_interval.c  |    3 
 net/dccp/ccids/lib/packet_history.c |    9 -
 net/dccp/ccids/lib/tfrc.c           |   19 --
 net/dccp/ccids/lib/tfrc.h           |   11 +
 net/dccp/ccids/lib/tfrc_equation.c  |    4 
 net/dccp/dccp.h                     |    2 
 net/dccp/feat.c                     |    6 
 net/dccp/input.c                    |    2 
 net/dccp/proto.c                    |    7 
 19 files changed, 186 insertions(+), 393 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe dccp" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 1/3] dccp: Lockless integration of CCID congestion-control plugins
@ 2009-01-03  7:30                       ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-03  7:30 UTC (permalink / raw)
  To: davem; +Cc: dccp, netdev, Gerrit Renker

Based on Arnaldo's earlier patch, this patch integrates the standardised
CCID congestion control plugins (CCID-2 and CCID-3) of DCCP with dccp.ko:

 * enables a faster connection path by eliminating the need to always go 
   through the CCID registration lock;

 * updates the implementation to use only a single array whose size equals
   the number of configured CCIDs instead of the maximum (256);

 * since the CCIDs are now fixed array elements, synchronization is no
   longer needed, simplifying use and implementation.

CCID-2 is suggested as minimum for a basic DCCP implementation (RFC 4340, 10);
CCID-3 is a standards-track CCID supported by RFC 4342 and RFC 5348.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/Kconfig        |    4 -
 net/dccp/Makefile       |    9 ++
 net/dccp/ackvec.h       |    4 -
 net/dccp/ccid.c         |  156 ++++++++++++++++++++++++++++++------------------
 net/dccp/ccid.h         |   11 ++-
 net/dccp/ccids/Kconfig  |   70 ++++++---------------
 net/dccp/ccids/Makefile |    8 --
 net/dccp/ccids/ccid2.c  |   22 ------
 net/dccp/ccids/ccid3.c  |   23 -------
 net/dccp/dccp.h         |    2 
 net/dccp/proto.c        |    7 ++
 11 files changed, 148 insertions(+), 168 deletions(-)

--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -1,80 +1,52 @@
 menu "DCCP CCIDs Configuration (EXPERIMENTAL)"
 	depends on 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
-	  modelled directly on TCP, including congestion window, slow start,
-	  timeouts, and so forth [RFC 2581].  CCID 2 achieves maximum
-	  bandwidth over the long term, consistent with the use of end-to-end
-	  congestion control, but halves its congestion window in response to
-	  each congestion event.  This leads to the abrupt rate changes
-	  typical of TCP.  Applications should use CCID 2 if they prefer
-	  maximum bandwidth utilization to steadiness of rate.  This is often
-	  the case for applications that are not playing their data directly
-	  to the user.  For example, a hypothetical application that
-	  transferred files over DCCP, using application-level retransmissions
-	  for lost packets, would prefer CCID 2 to CCID 3.  On-line games may
-	  also prefer CCID 2.  See RFC 4341 for further details.
-
-	  CCID2 is the default CCID used by DCCP.
-
 config IP_DCCP_CCID2_DEBUG
-	  bool "CCID2 debugging messages"
-	  depends on IP_DCCP_CCID2
-	  ---help---
-	    Enable CCID2-specific debugging messages.
+	bool "CCID-2 debugging messages"
+	---help---
+	  Enable CCID-2 specific debugging messages.
 
-	    When compiling CCID2 as a module, this debugging output can
-	    additionally be toggled by setting the ccid2_debug module
-	    parameter to 0 or 1.
+	  The debugging output can additionally be toggled by setting the
+	  ccid2_debug parameter to 0 or 1.
 
-	    If in doubt, say N.
+	  If in doubt, say N.
 
 config IP_DCCP_CCID3
-	tristate "CCID3 (TCP-Friendly) (EXPERIMENTAL)"
-	def_tristate IP_DCCP
+	bool "CCID-3 (TCP-Friendly) (EXPERIMENTAL)"
+	def_bool y if (IP_DCCP = y || IP_DCCP = m)
 	select IP_DCCP_TFRC_LIB
 	---help---
-	  CCID 3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
+	  CCID-3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
 	  rate-controlled congestion control mechanism.  TFRC is designed to
 	  be reasonably fair when competing for bandwidth with TCP-like flows,
 	  where a flow is "reasonably fair" if its sending rate is generally
 	  within a factor of two of the sending rate of a TCP flow under the
 	  same conditions.  However, TFRC has a much lower variation of
-	  throughput over time compared with TCP, which makes CCID 3 more
-	  suitable than CCID 2 for applications such streaming media where a
+	  throughput over time compared with TCP, which makes CCID-3 more
+	  suitable than CCID-2 for applications such streaming media where a
 	  relatively smooth sending rate is of importance.
 
-	  CCID 3 is further described in RFC 4342,
+	  CCID-3 is further described in RFC 4342,
 	  http://www.ietf.org/rfc/rfc4342.txt
 
 	  The TFRC congestion control algorithms were initially described in
-	  RFC 3448.
+	  RFC 5448.
 
 	  This text was extracted from RFC 4340 (sec. 10.2),
 	  http://www.ietf.org/rfc/rfc4340.txt
-	  
-	  To compile this CCID as a module, choose M here: the module will be
-	  called dccp_ccid3.
 
-	  If in doubt, say M.
+	  If in doubt, say N.
 
 config IP_DCCP_CCID3_DEBUG
-	  bool "CCID3 debugging messages"
-	  depends on IP_DCCP_CCID3
-	  ---help---
-	    Enable CCID3-specific debugging messages.
+	bool "CCID-3 debugging messages"
+	depends on IP_DCCP_CCID3
+	---help---
+	  Enable CCID-3 specific debugging messages.
 
-	    When compiling CCID3 as a module, this debugging output can
-	    additionally be toggled by setting the ccid3_debug module
-	    parameter to 0 or 1.
+	  The debugging output can additionally be toggled by setting the
+	  ccid3_debug parameter to 0 or 1.
 
-	    If in doubt, say N.
+	  If in doubt, say N.
 
 config IP_DCCP_CCID3_RTO
 	  int "Use higher bound for nofeedback timer"
--- a/net/dccp/Kconfig
+++ b/net/dccp/Kconfig
@@ -1,7 +1,6 @@
 menuconfig IP_DCCP
 	tristate "The DCCP Protocol (EXPERIMENTAL)"
 	depends on INET && EXPERIMENTAL
-	select IP_DCCP_CCID2
 	---help---
 	  Datagram Congestion Control Protocol (RFC 4340)
 
@@ -25,9 +24,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
@@ -2,14 +2,19 @@ obj-$(CONFIG_IP_DCCP) += dccp.o dccp_ipv
 
 dccp-y := ccid.o feat.o input.o minisocks.o options.o output.o proto.o timer.o
 
+#
+# CCID algorithms to be used by dccp.ko
+#
+# CCID-2 is default (RFC 4340, p. 77) and has Ack Vectors as dependency
+dccp-y += ccids/ccid2.o ackvec.o
+dccp-$(CONFIG_IP_DCCP_CCID3)	+= ccids/ccid3.o
+
 dccp_ipv4-y := ipv4.o
 
 # build dccp_ipv6 as module whenever either IPv6 or DCCP is a module
 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/ccids/Makefile
+++ b/net/dccp/ccids/Makefile
@@ -1,9 +1 @@
-obj-$(CONFIG_IP_DCCP_CCID3) += dccp_ccid3.o
-
-dccp_ccid3-y := ccid3.o
-
-obj-$(CONFIG_IP_DCCP_CCID2) += dccp_ccid2.o
-
-dccp_ccid2-y := ccid2.o
-
 obj-y += lib/
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -29,7 +29,6 @@ struct tcp_info;
  *  @ccid_id: numerical CCID ID (up to %CCID_MAX, cf. table 5 in RFC 4340, 10.)
  *  @ccid_ccmps: the CCMPS including network/transport headers (0 when disabled)
  *  @ccid_name: alphabetical identifier string for @ccid_id
- *  @ccid_owner: module which implements/owns this CCID
  *  @ccid_hc_{r,t}x_slab: memory pool for the receiver/sender half-connection
  *  @ccid_hc_{r,t}x_obj_size: size of the receiver/sender half-connection socket
  *
@@ -48,7 +47,6 @@ struct ccid_operations {
 	unsigned char		ccid_id;
 	__u32			ccid_ccmps;
 	const char		*ccid_name;
-	struct module		*ccid_owner;
 	struct kmem_cache	*ccid_hc_rx_slab,
 				*ccid_hc_tx_slab;
 	__u32			ccid_hc_rx_obj_size,
@@ -90,8 +88,13 @@ struct ccid_operations {
 						 int __user *optlen);
 };
 
-extern int ccid_register(struct ccid_operations *ccid_ops);
-extern int ccid_unregister(struct ccid_operations *ccid_ops);
+extern struct ccid_operations ccid2_ops;
+#ifdef CONFIG_IP_DCCP_CCID3
+extern struct ccid_operations ccid3_ops;
+#endif
+
+extern int  ccid_initialize_builtins(void);
+extern void ccid_cleanup_builtins(void);
 
 struct ccid {
 	struct ccid_operations *ccid_ops;
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -13,6 +13,70 @@
 
 #include "ccid.h"
 
+static struct ccid_operations *ccids[] = {
+	&ccid2_ops,
+#ifdef CONFIG_IP_DCCP_CCID3
+	&ccid3_ops,
+#endif
+};
+
+static struct ccid_operations *ccid_by_number(const u8 id)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ccids); i++)
+		if (ccids[i]->ccid_id == id)
+			return ccids[i];
+	return NULL;
+}
+
+/* check that up to @array_len members in @ccid_array are supported */
+bool ccid_support_check(u8 const *ccid_array, u8 array_len)
+{
+	while (array_len > 0)
+		if (ccid_by_number(ccid_array[--array_len]) == NULL)
+			return false;
+	return true;
+}
+
+/**
+ * ccid_get_builtin_ccids  -  Populate a list of built-in CCIDs
+ * @ccid_array: pointer to copy into
+ * @array_len: value to return length into
+ * This function allocates memory - caller must see that it is freed after use.
+ */
+int ccid_get_builtin_ccids(u8 **ccid_array, u8 *array_len)
+{
+	*ccid_array = kmalloc(ARRAY_SIZE(ccids), gfp_any());
+	if (*ccid_array == NULL)
+		return -ENOBUFS;
+
+	for (*array_len = 0; *array_len < ARRAY_SIZE(ccids); *array_len += 1)
+		(*ccid_array)[*array_len] = ccids[*array_len]->ccid_id;
+	return 0;
+}
+
+int ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
+				  char __user *optval, int __user *optlen)
+{
+	u8 *ccid_array, array_len;
+	int err = 0;
+
+	if (len < ARRAY_SIZE(ccids))
+		return -EINVAL;
+
+	if (ccid_get_builtin_ccids(&ccid_array, &array_len))
+		return -ENOBUFS;
+
+	if (put_user(array_len, optlen) ||
+	    copy_to_user(optval, ccid_array, array_len))
+		err = -EFAULT;
+
+	kfree(ccid_array);
+	return err;
+}
+
+#ifdef ___OLD_INTERFACE_TO_BE_REMOVED___
 static u8 builtin_ccids[] = {
 	DCCPC_CCID2,		/* CCID2 is supported by default */
 #if defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE)
@@ -62,6 +126,7 @@ static inline void ccids_read_unlock(voi
 #define ccids_read_lock() do { } while(0)
 #define ccids_read_unlock() do { } while(0)
 #endif
+#endif /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
 
 static struct kmem_cache *ccid_kmem_cache_create(int obj_size, const char *fmt,...)
 {
@@ -93,6 +158,7 @@ static void ccid_kmem_cache_destroy(stru
 	}
 }
 
+#ifdef ___OLD_INTERFACE_TO_BE_REMOVED___
 /* check that up to @array_len members in @ccid_array are supported */
 bool ccid_support_check(u8 const *ccid_array, u8 array_len)
 {
@@ -133,8 +199,9 @@ int ccid_getsockopt_builtin_ccids(struct
 		return -EFAULT;
 	return 0;
 }
+#endif /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
 
-int ccid_register(struct ccid_operations *ccid_ops)
+static int ccid_activate(struct ccid_operations *ccid_ops)
 {
 	int err = -ENOBUFS;
 
@@ -152,79 +219,40 @@ int ccid_register(struct ccid_operations
 	if (ccid_ops->ccid_hc_tx_slab == NULL)
 		goto out_free_rx_slab;
 
-	ccids_write_lock();
-	err = -EEXIST;
-	if (ccids[ccid_ops->ccid_id] == NULL) {
-		ccids[ccid_ops->ccid_id] = ccid_ops;
-		err = 0;
-	}
-	ccids_write_unlock();
-	if (err != 0)
-		goto out_free_tx_slab;
-
-	pr_info("CCID: Registered CCID %d (%s)\n",
+	pr_info("CCID: Activated CCID %d (%s)\n",
 		ccid_ops->ccid_id, ccid_ops->ccid_name);
+	err = 0;
 out:
 	return err;
-out_free_tx_slab:
-	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
-	ccid_ops->ccid_hc_tx_slab = NULL;
-	goto out;
 out_free_rx_slab:
 	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
 	ccid_ops->ccid_hc_rx_slab = NULL;
 	goto out;
 }
 
-EXPORT_SYMBOL_GPL(ccid_register);
-
-int ccid_unregister(struct ccid_operations *ccid_ops)
+static void ccid_deactivate(struct ccid_operations *ccid_ops)
 {
-	ccids_write_lock();
-	ccids[ccid_ops->ccid_id] = NULL;
-	ccids_write_unlock();
-
 	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
 	ccid_ops->ccid_hc_tx_slab = NULL;
 	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
 	ccid_ops->ccid_hc_rx_slab = NULL;
 
-	pr_info("CCID: Unregistered CCID %d (%s)\n",
+	pr_info("CCID: Deactivated CCID %d (%s)\n",
 		ccid_ops->ccid_id, ccid_ops->ccid_name);
-	return 0;
 }
 
-EXPORT_SYMBOL_GPL(ccid_unregister);
-
 struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
 {
-	struct ccid_operations *ccid_ops;
+	struct ccid_operations *ccid_ops = ccid_by_number(id);
 	struct ccid *ccid = NULL;
 
-	ccids_read_lock();
-#ifdef CONFIG_MODULES
-	if (ccids[id] == NULL) {
-		/* We only try to load if in process context */
-		ccids_read_unlock();
-		if (gfp & GFP_ATOMIC)
-			goto out;
-		request_module("net-dccp-ccid-%d", id);
-		ccids_read_lock();
-	}
-#endif
-	ccid_ops = ccids[id];
 	if (ccid_ops == NULL)
-		goto out_unlock;
-
-	if (!try_module_get(ccid_ops->ccid_owner))
-		goto out_unlock;
-
-	ccids_read_unlock();
+		goto out;
 
 	ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
 				     ccid_ops->ccid_hc_tx_slab, gfp);
 	if (ccid == NULL)
-		goto out_module_put;
+		goto out;
 	ccid->ccid_ops = ccid_ops;
 	if (rx) {
 		memset(ccid + 1, 0, ccid_ops->ccid_hc_rx_obj_size);
@@ -239,15 +267,10 @@ struct ccid *ccid_new(unsigned char id, 
 	}
 out:
 	return ccid;
-out_unlock:
-	ccids_read_unlock();
-	goto out;
 out_free_ccid:
 	kmem_cache_free(rx ? ccid_ops->ccid_hc_rx_slab :
 			ccid_ops->ccid_hc_tx_slab, ccid);
 	ccid = NULL;
-out_module_put:
-	module_put(ccid_ops->ccid_owner);
 	goto out;
 }
 
@@ -270,10 +293,6 @@ static void ccid_delete(struct ccid *cci
 			ccid_ops->ccid_hc_tx_exit(sk);
 		kmem_cache_free(ccid_ops->ccid_hc_tx_slab,  ccid);
 	}
-	ccids_read_lock();
-	if (ccids[ccid_ops->ccid_id] != NULL)
-		module_put(ccid_ops->ccid_owner);
-	ccids_read_unlock();
 }
 
 void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk)
@@ -289,3 +308,28 @@ void ccid_hc_tx_delete(struct ccid *ccid
 }
 
 EXPORT_SYMBOL_GPL(ccid_hc_tx_delete);
+
+int __init ccid_initialize_builtins(void)
+{
+	int i, err;
+
+	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
+		err = ccid_activate(ccids[i]);
+		if (err)
+			goto unwind_registrations;
+	}
+	return 0;
+
+unwind_registrations:
+	while(--i >= 0)
+		ccid_deactivate(ccids[i]);
+	return err;
+}
+
+void ccid_cleanup_builtins(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ccids); i++)
+		ccid_deactivate(ccids[i]);
+}
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -1118,9 +1118,15 @@ static int __init dccp_init(void)
 	if (rc)
 		goto out_ackvec_exit;
 
+	rc = ccid_initialize_builtins();
+	if (rc)
+		goto out_sysctl_exit;
+
 	dccp_timestamping_init();
 out:
 	return rc;
+out_sysctl_exit:
+	dccp_sysctl_exit();
 out_ackvec_exit:
 	dccp_ackvec_exit();
 out_free_dccp_mib:
@@ -1143,6 +1149,7 @@ out_free_percpu:
 
 static void __exit dccp_fini(void)
 {
+	ccid_cleanup_builtins();
 	dccp_mib_exit();
 	free_pages((unsigned long)dccp_hashinfo.bhash,
 		   get_order(dccp_hashinfo.bhash_size *
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -940,10 +940,9 @@ static int ccid3_hc_rx_getsockopt(struct
 	return 0;
 }
 
-static struct ccid_operations ccid3 = {
+struct ccid_operations ccid3_ops = {
 	.ccid_id		   = DCCPC_CCID3,
 	.ccid_name		   = "TCP-Friendly Rate Control",
-	.ccid_owner		   = THIS_MODULE,
 	.ccid_hc_tx_obj_size	   = sizeof(struct ccid3_hc_tx_sock),
 	.ccid_hc_tx_init	   = ccid3_hc_tx_init,
 	.ccid_hc_tx_exit	   = ccid3_hc_tx_exit,
@@ -964,23 +963,5 @@ static struct ccid_operations ccid3 = {
 
 #ifdef CONFIG_IP_DCCP_CCID3_DEBUG
 module_param(ccid3_debug, bool, 0644);
-MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
+MODULE_PARM_DESC(ccid3_debug, "Enable CCID-3 debug messages");
 #endif
-
-static __init int ccid3_module_init(void)
-{
-	return ccid_register(&ccid3);
-}
-module_init(ccid3_module_init);
-
-static __exit void ccid3_module_exit(void)
-{
-	ccid_unregister(&ccid3);
-}
-module_exit(ccid3_module_exit);
-
-MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>, "
-	      "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
-MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("net-dccp-ccid-3");
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -768,10 +768,9 @@ static void ccid2_hc_rx_packet_recv(stru
 	}
 }
 
-static struct ccid_operations ccid2 = {
+struct ccid_operations ccid2_ops = {
 	.ccid_id		= DCCPC_CCID2,
 	.ccid_name		= "TCP-like",
-	.ccid_owner		= THIS_MODULE,
 	.ccid_hc_tx_obj_size	= sizeof(struct ccid2_hc_tx_sock),
 	.ccid_hc_tx_init	= ccid2_hc_tx_init,
 	.ccid_hc_tx_exit	= ccid2_hc_tx_exit,
@@ -784,22 +783,5 @@ static struct ccid_operations ccid2 = {
 
 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG
 module_param(ccid2_debug, bool, 0644);
-MODULE_PARM_DESC(ccid2_debug, "Enable debug messages");
+MODULE_PARM_DESC(ccid2_debug, "Enable CCID-2 debug messages");
 #endif
-
-static __init int ccid2_module_init(void)
-{
-	return ccid_register(&ccid2);
-}
-module_init(ccid2_module_init);
-
-static __exit void ccid2_module_exit(void)
-{
-	ccid_unregister(&ccid2);
-}
-module_exit(ccid2_module_exit);
-
-MODULE_AUTHOR("Andrea Bittau <a.bittau@cs.ucl.ac.uk>");
-MODULE_DESCRIPTION("DCCP TCP-Like (CCID2) CCID");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("net-dccp-ccid-2");
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -432,10 +432,8 @@ static inline int dccp_ack_pending(const
 {
 	const struct dccp_sock *dp = dccp_sk(sk);
 	return dp->dccps_timestamp_echo != 0 ||
-#ifdef CONFIG_IP_DCCP_ACKVEC
 	       (dp->dccps_hc_rx_ackvec != NULL &&
 		dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) ||
-#endif
 	       inet_csk_ack_scheduled(sk);
 }
 
--- a/net/dccp/ackvec.h
+++ b/net/dccp/ackvec.h
@@ -84,7 +84,7 @@ struct dccp_ackvec_record {
 struct sock;
 struct sk_buff;
 
-#ifdef CONFIG_IP_DCCP_ACKVEC
+#ifndef ___OLD_INTERFACE_TO_BE_REMOVED___
 extern int dccp_ackvec_init(void);
 extern void dccp_ackvec_exit(void);
 
@@ -106,7 +106,7 @@ static inline int dccp_ackvec_pending(co
 {
 	return av->av_vec_len;
 }
-#else /* CONFIG_IP_DCCP_ACKVEC */
+#else /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
 static inline int dccp_ackvec_init(void)
 {
 	return 0;

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

* [PATCH 1/3] dccp: Lockless integration of CCID congestion-control plugins
@ 2009-01-03  7:30                       ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-03  7:30 UTC (permalink / raw)
  To: dccp

Based on Arnaldo's earlier patch, this patch integrates the standardised
CCID congestion control plugins (CCID-2 and CCID-3) of DCCP with dccp.ko:

 * enables a faster connection path by eliminating the need to always go 
   through the CCID registration lock;

 * updates the implementation to use only a single array whose size equals
   the number of configured CCIDs instead of the maximum (256);

 * since the CCIDs are now fixed array elements, synchronization is no
   longer needed, simplifying use and implementation.

CCID-2 is suggested as minimum for a basic DCCP implementation (RFC 4340, 10);
CCID-3 is a standards-track CCID supported by RFC 4342 and RFC 5348.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/Kconfig        |    4 -
 net/dccp/Makefile       |    9 ++
 net/dccp/ackvec.h       |    4 -
 net/dccp/ccid.c         |  156 ++++++++++++++++++++++++++++++------------------
 net/dccp/ccid.h         |   11 ++-
 net/dccp/ccids/Kconfig  |   70 ++++++---------------
 net/dccp/ccids/Makefile |    8 --
 net/dccp/ccids/ccid2.c  |   22 ------
 net/dccp/ccids/ccid3.c  |   23 -------
 net/dccp/dccp.h         |    2 
 net/dccp/proto.c        |    7 ++
 11 files changed, 148 insertions(+), 168 deletions(-)

--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -1,80 +1,52 @@
 menu "DCCP CCIDs Configuration (EXPERIMENTAL)"
 	depends on 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
-	  modelled directly on TCP, including congestion window, slow start,
-	  timeouts, and so forth [RFC 2581].  CCID 2 achieves maximum
-	  bandwidth over the long term, consistent with the use of end-to-end
-	  congestion control, but halves its congestion window in response to
-	  each congestion event.  This leads to the abrupt rate changes
-	  typical of TCP.  Applications should use CCID 2 if they prefer
-	  maximum bandwidth utilization to steadiness of rate.  This is often
-	  the case for applications that are not playing their data directly
-	  to the user.  For example, a hypothetical application that
-	  transferred files over DCCP, using application-level retransmissions
-	  for lost packets, would prefer CCID 2 to CCID 3.  On-line games may
-	  also prefer CCID 2.  See RFC 4341 for further details.
-
-	  CCID2 is the default CCID used by DCCP.
-
 config IP_DCCP_CCID2_DEBUG
-	  bool "CCID2 debugging messages"
-	  depends on IP_DCCP_CCID2
-	  ---help---
-	    Enable CCID2-specific debugging messages.
+	bool "CCID-2 debugging messages"
+	---help---
+	  Enable CCID-2 specific debugging messages.
 
-	    When compiling CCID2 as a module, this debugging output can
-	    additionally be toggled by setting the ccid2_debug module
-	    parameter to 0 or 1.
+	  The debugging output can additionally be toggled by setting the
+	  ccid2_debug parameter to 0 or 1.
 
-	    If in doubt, say N.
+	  If in doubt, say N.
 
 config IP_DCCP_CCID3
-	tristate "CCID3 (TCP-Friendly) (EXPERIMENTAL)"
-	def_tristate IP_DCCP
+	bool "CCID-3 (TCP-Friendly) (EXPERIMENTAL)"
+	def_bool y if (IP_DCCP = y || IP_DCCP = m)
 	select IP_DCCP_TFRC_LIB
 	---help---
-	  CCID 3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
+	  CCID-3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
 	  rate-controlled congestion control mechanism.  TFRC is designed to
 	  be reasonably fair when competing for bandwidth with TCP-like flows,
 	  where a flow is "reasonably fair" if its sending rate is generally
 	  within a factor of two of the sending rate of a TCP flow under the
 	  same conditions.  However, TFRC has a much lower variation of
-	  throughput over time compared with TCP, which makes CCID 3 more
-	  suitable than CCID 2 for applications such streaming media where a
+	  throughput over time compared with TCP, which makes CCID-3 more
+	  suitable than CCID-2 for applications such streaming media where a
 	  relatively smooth sending rate is of importance.
 
-	  CCID 3 is further described in RFC 4342,
+	  CCID-3 is further described in RFC 4342,
 	  http://www.ietf.org/rfc/rfc4342.txt
 
 	  The TFRC congestion control algorithms were initially described in
-	  RFC 3448.
+	  RFC 5448.
 
 	  This text was extracted from RFC 4340 (sec. 10.2),
 	  http://www.ietf.org/rfc/rfc4340.txt
-	  
-	  To compile this CCID as a module, choose M here: the module will be
-	  called dccp_ccid3.
 
-	  If in doubt, say M.
+	  If in doubt, say N.
 
 config IP_DCCP_CCID3_DEBUG
-	  bool "CCID3 debugging messages"
-	  depends on IP_DCCP_CCID3
-	  ---help---
-	    Enable CCID3-specific debugging messages.
+	bool "CCID-3 debugging messages"
+	depends on IP_DCCP_CCID3
+	---help---
+	  Enable CCID-3 specific debugging messages.
 
-	    When compiling CCID3 as a module, this debugging output can
-	    additionally be toggled by setting the ccid3_debug module
-	    parameter to 0 or 1.
+	  The debugging output can additionally be toggled by setting the
+	  ccid3_debug parameter to 0 or 1.
 
-	    If in doubt, say N.
+	  If in doubt, say N.
 
 config IP_DCCP_CCID3_RTO
 	  int "Use higher bound for nofeedback timer"
--- a/net/dccp/Kconfig
+++ b/net/dccp/Kconfig
@@ -1,7 +1,6 @@
 menuconfig IP_DCCP
 	tristate "The DCCP Protocol (EXPERIMENTAL)"
 	depends on INET && EXPERIMENTAL
-	select IP_DCCP_CCID2
 	---help---
 	  Datagram Congestion Control Protocol (RFC 4340)
 
@@ -25,9 +24,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
@@ -2,14 +2,19 @@ obj-$(CONFIG_IP_DCCP) += dccp.o dccp_ipv
 
 dccp-y := ccid.o feat.o input.o minisocks.o options.o output.o proto.o timer.o
 
+#
+# CCID algorithms to be used by dccp.ko
+#
+# CCID-2 is default (RFC 4340, p. 77) and has Ack Vectors as dependency
+dccp-y += ccids/ccid2.o ackvec.o
+dccp-$(CONFIG_IP_DCCP_CCID3)	+= ccids/ccid3.o
+
 dccp_ipv4-y := ipv4.o
 
 # build dccp_ipv6 as module whenever either IPv6 or DCCP is a module
 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/ccids/Makefile
+++ b/net/dccp/ccids/Makefile
@@ -1,9 +1 @@
-obj-$(CONFIG_IP_DCCP_CCID3) += dccp_ccid3.o
-
-dccp_ccid3-y := ccid3.o
-
-obj-$(CONFIG_IP_DCCP_CCID2) += dccp_ccid2.o
-
-dccp_ccid2-y := ccid2.o
-
 obj-y += lib/
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -29,7 +29,6 @@ struct tcp_info;
  *  @ccid_id: numerical CCID ID (up to %CCID_MAX, cf. table 5 in RFC 4340, 10.)
  *  @ccid_ccmps: the CCMPS including network/transport headers (0 when disabled)
  *  @ccid_name: alphabetical identifier string for @ccid_id
- *  @ccid_owner: module which implements/owns this CCID
  *  @ccid_hc_{r,t}x_slab: memory pool for the receiver/sender half-connection
  *  @ccid_hc_{r,t}x_obj_size: size of the receiver/sender half-connection socket
  *
@@ -48,7 +47,6 @@ struct ccid_operations {
 	unsigned char		ccid_id;
 	__u32			ccid_ccmps;
 	const char		*ccid_name;
-	struct module		*ccid_owner;
 	struct kmem_cache	*ccid_hc_rx_slab,
 				*ccid_hc_tx_slab;
 	__u32			ccid_hc_rx_obj_size,
@@ -90,8 +88,13 @@ struct ccid_operations {
 						 int __user *optlen);
 };
 
-extern int ccid_register(struct ccid_operations *ccid_ops);
-extern int ccid_unregister(struct ccid_operations *ccid_ops);
+extern struct ccid_operations ccid2_ops;
+#ifdef CONFIG_IP_DCCP_CCID3
+extern struct ccid_operations ccid3_ops;
+#endif
+
+extern int  ccid_initialize_builtins(void);
+extern void ccid_cleanup_builtins(void);
 
 struct ccid {
 	struct ccid_operations *ccid_ops;
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -13,6 +13,70 @@
 
 #include "ccid.h"
 
+static struct ccid_operations *ccids[] = {
+	&ccid2_ops,
+#ifdef CONFIG_IP_DCCP_CCID3
+	&ccid3_ops,
+#endif
+};
+
+static struct ccid_operations *ccid_by_number(const u8 id)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ccids); i++)
+		if (ccids[i]->ccid_id = id)
+			return ccids[i];
+	return NULL;
+}
+
+/* check that up to @array_len members in @ccid_array are supported */
+bool ccid_support_check(u8 const *ccid_array, u8 array_len)
+{
+	while (array_len > 0)
+		if (ccid_by_number(ccid_array[--array_len]) = NULL)
+			return false;
+	return true;
+}
+
+/**
+ * ccid_get_builtin_ccids  -  Populate a list of built-in CCIDs
+ * @ccid_array: pointer to copy into
+ * @array_len: value to return length into
+ * This function allocates memory - caller must see that it is freed after use.
+ */
+int ccid_get_builtin_ccids(u8 **ccid_array, u8 *array_len)
+{
+	*ccid_array = kmalloc(ARRAY_SIZE(ccids), gfp_any());
+	if (*ccid_array = NULL)
+		return -ENOBUFS;
+
+	for (*array_len = 0; *array_len < ARRAY_SIZE(ccids); *array_len += 1)
+		(*ccid_array)[*array_len] = ccids[*array_len]->ccid_id;
+	return 0;
+}
+
+int ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
+				  char __user *optval, int __user *optlen)
+{
+	u8 *ccid_array, array_len;
+	int err = 0;
+
+	if (len < ARRAY_SIZE(ccids))
+		return -EINVAL;
+
+	if (ccid_get_builtin_ccids(&ccid_array, &array_len))
+		return -ENOBUFS;
+
+	if (put_user(array_len, optlen) ||
+	    copy_to_user(optval, ccid_array, array_len))
+		err = -EFAULT;
+
+	kfree(ccid_array);
+	return err;
+}
+
+#ifdef ___OLD_INTERFACE_TO_BE_REMOVED___
 static u8 builtin_ccids[] = {
 	DCCPC_CCID2,		/* CCID2 is supported by default */
 #if defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE)
@@ -62,6 +126,7 @@ static inline void ccids_read_unlock(voi
 #define ccids_read_lock() do { } while(0)
 #define ccids_read_unlock() do { } while(0)
 #endif
+#endif /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
 
 static struct kmem_cache *ccid_kmem_cache_create(int obj_size, const char *fmt,...)
 {
@@ -93,6 +158,7 @@ static void ccid_kmem_cache_destroy(stru
 	}
 }
 
+#ifdef ___OLD_INTERFACE_TO_BE_REMOVED___
 /* check that up to @array_len members in @ccid_array are supported */
 bool ccid_support_check(u8 const *ccid_array, u8 array_len)
 {
@@ -133,8 +199,9 @@ int ccid_getsockopt_builtin_ccids(struct
 		return -EFAULT;
 	return 0;
 }
+#endif /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
 
-int ccid_register(struct ccid_operations *ccid_ops)
+static int ccid_activate(struct ccid_operations *ccid_ops)
 {
 	int err = -ENOBUFS;
 
@@ -152,79 +219,40 @@ int ccid_register(struct ccid_operations
 	if (ccid_ops->ccid_hc_tx_slab = NULL)
 		goto out_free_rx_slab;
 
-	ccids_write_lock();
-	err = -EEXIST;
-	if (ccids[ccid_ops->ccid_id] = NULL) {
-		ccids[ccid_ops->ccid_id] = ccid_ops;
-		err = 0;
-	}
-	ccids_write_unlock();
-	if (err != 0)
-		goto out_free_tx_slab;
-
-	pr_info("CCID: Registered CCID %d (%s)\n",
+	pr_info("CCID: Activated CCID %d (%s)\n",
 		ccid_ops->ccid_id, ccid_ops->ccid_name);
+	err = 0;
 out:
 	return err;
-out_free_tx_slab:
-	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
-	ccid_ops->ccid_hc_tx_slab = NULL;
-	goto out;
 out_free_rx_slab:
 	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
 	ccid_ops->ccid_hc_rx_slab = NULL;
 	goto out;
 }
 
-EXPORT_SYMBOL_GPL(ccid_register);
-
-int ccid_unregister(struct ccid_operations *ccid_ops)
+static void ccid_deactivate(struct ccid_operations *ccid_ops)
 {
-	ccids_write_lock();
-	ccids[ccid_ops->ccid_id] = NULL;
-	ccids_write_unlock();
-
 	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
 	ccid_ops->ccid_hc_tx_slab = NULL;
 	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
 	ccid_ops->ccid_hc_rx_slab = NULL;
 
-	pr_info("CCID: Unregistered CCID %d (%s)\n",
+	pr_info("CCID: Deactivated CCID %d (%s)\n",
 		ccid_ops->ccid_id, ccid_ops->ccid_name);
-	return 0;
 }
 
-EXPORT_SYMBOL_GPL(ccid_unregister);
-
 struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
 {
-	struct ccid_operations *ccid_ops;
+	struct ccid_operations *ccid_ops = ccid_by_number(id);
 	struct ccid *ccid = NULL;
 
-	ccids_read_lock();
-#ifdef CONFIG_MODULES
-	if (ccids[id] = NULL) {
-		/* We only try to load if in process context */
-		ccids_read_unlock();
-		if (gfp & GFP_ATOMIC)
-			goto out;
-		request_module("net-dccp-ccid-%d", id);
-		ccids_read_lock();
-	}
-#endif
-	ccid_ops = ccids[id];
 	if (ccid_ops = NULL)
-		goto out_unlock;
-
-	if (!try_module_get(ccid_ops->ccid_owner))
-		goto out_unlock;
-
-	ccids_read_unlock();
+		goto out;
 
 	ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
 				     ccid_ops->ccid_hc_tx_slab, gfp);
 	if (ccid = NULL)
-		goto out_module_put;
+		goto out;
 	ccid->ccid_ops = ccid_ops;
 	if (rx) {
 		memset(ccid + 1, 0, ccid_ops->ccid_hc_rx_obj_size);
@@ -239,15 +267,10 @@ struct ccid *ccid_new(unsigned char id, 
 	}
 out:
 	return ccid;
-out_unlock:
-	ccids_read_unlock();
-	goto out;
 out_free_ccid:
 	kmem_cache_free(rx ? ccid_ops->ccid_hc_rx_slab :
 			ccid_ops->ccid_hc_tx_slab, ccid);
 	ccid = NULL;
-out_module_put:
-	module_put(ccid_ops->ccid_owner);
 	goto out;
 }
 
@@ -270,10 +293,6 @@ static void ccid_delete(struct ccid *cci
 			ccid_ops->ccid_hc_tx_exit(sk);
 		kmem_cache_free(ccid_ops->ccid_hc_tx_slab,  ccid);
 	}
-	ccids_read_lock();
-	if (ccids[ccid_ops->ccid_id] != NULL)
-		module_put(ccid_ops->ccid_owner);
-	ccids_read_unlock();
 }
 
 void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk)
@@ -289,3 +308,28 @@ void ccid_hc_tx_delete(struct ccid *ccid
 }
 
 EXPORT_SYMBOL_GPL(ccid_hc_tx_delete);
+
+int __init ccid_initialize_builtins(void)
+{
+	int i, err;
+
+	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
+		err = ccid_activate(ccids[i]);
+		if (err)
+			goto unwind_registrations;
+	}
+	return 0;
+
+unwind_registrations:
+	while(--i >= 0)
+		ccid_deactivate(ccids[i]);
+	return err;
+}
+
+void ccid_cleanup_builtins(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ccids); i++)
+		ccid_deactivate(ccids[i]);
+}
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -1118,9 +1118,15 @@ static int __init dccp_init(void)
 	if (rc)
 		goto out_ackvec_exit;
 
+	rc = ccid_initialize_builtins();
+	if (rc)
+		goto out_sysctl_exit;
+
 	dccp_timestamping_init();
 out:
 	return rc;
+out_sysctl_exit:
+	dccp_sysctl_exit();
 out_ackvec_exit:
 	dccp_ackvec_exit();
 out_free_dccp_mib:
@@ -1143,6 +1149,7 @@ out_free_percpu:
 
 static void __exit dccp_fini(void)
 {
+	ccid_cleanup_builtins();
 	dccp_mib_exit();
 	free_pages((unsigned long)dccp_hashinfo.bhash,
 		   get_order(dccp_hashinfo.bhash_size *
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -940,10 +940,9 @@ static int ccid3_hc_rx_getsockopt(struct
 	return 0;
 }
 
-static struct ccid_operations ccid3 = {
+struct ccid_operations ccid3_ops = {
 	.ccid_id		   = DCCPC_CCID3,
 	.ccid_name		   = "TCP-Friendly Rate Control",
-	.ccid_owner		   = THIS_MODULE,
 	.ccid_hc_tx_obj_size	   = sizeof(struct ccid3_hc_tx_sock),
 	.ccid_hc_tx_init	   = ccid3_hc_tx_init,
 	.ccid_hc_tx_exit	   = ccid3_hc_tx_exit,
@@ -964,23 +963,5 @@ static struct ccid_operations ccid3 = {
 
 #ifdef CONFIG_IP_DCCP_CCID3_DEBUG
 module_param(ccid3_debug, bool, 0644);
-MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
+MODULE_PARM_DESC(ccid3_debug, "Enable CCID-3 debug messages");
 #endif
-
-static __init int ccid3_module_init(void)
-{
-	return ccid_register(&ccid3);
-}
-module_init(ccid3_module_init);
-
-static __exit void ccid3_module_exit(void)
-{
-	ccid_unregister(&ccid3);
-}
-module_exit(ccid3_module_exit);
-
-MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>, "
-	      "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
-MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("net-dccp-ccid-3");
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -768,10 +768,9 @@ static void ccid2_hc_rx_packet_recv(stru
 	}
 }
 
-static struct ccid_operations ccid2 = {
+struct ccid_operations ccid2_ops = {
 	.ccid_id		= DCCPC_CCID2,
 	.ccid_name		= "TCP-like",
-	.ccid_owner		= THIS_MODULE,
 	.ccid_hc_tx_obj_size	= sizeof(struct ccid2_hc_tx_sock),
 	.ccid_hc_tx_init	= ccid2_hc_tx_init,
 	.ccid_hc_tx_exit	= ccid2_hc_tx_exit,
@@ -784,22 +783,5 @@ static struct ccid_operations ccid2 = {
 
 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG
 module_param(ccid2_debug, bool, 0644);
-MODULE_PARM_DESC(ccid2_debug, "Enable debug messages");
+MODULE_PARM_DESC(ccid2_debug, "Enable CCID-2 debug messages");
 #endif
-
-static __init int ccid2_module_init(void)
-{
-	return ccid_register(&ccid2);
-}
-module_init(ccid2_module_init);
-
-static __exit void ccid2_module_exit(void)
-{
-	ccid_unregister(&ccid2);
-}
-module_exit(ccid2_module_exit);
-
-MODULE_AUTHOR("Andrea Bittau <a.bittau@cs.ucl.ac.uk>");
-MODULE_DESCRIPTION("DCCP TCP-Like (CCID2) CCID");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("net-dccp-ccid-2");
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -432,10 +432,8 @@ static inline int dccp_ack_pending(const
 {
 	const struct dccp_sock *dp = dccp_sk(sk);
 	return dp->dccps_timestamp_echo != 0 ||
-#ifdef CONFIG_IP_DCCP_ACKVEC
 	       (dp->dccps_hc_rx_ackvec != NULL &&
 		dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) ||
-#endif
 	       inet_csk_ack_scheduled(sk);
 }
 
--- a/net/dccp/ackvec.h
+++ b/net/dccp/ackvec.h
@@ -84,7 +84,7 @@ struct dccp_ackvec_record {
 struct sock;
 struct sk_buff;
 
-#ifdef CONFIG_IP_DCCP_ACKVEC
+#ifndef ___OLD_INTERFACE_TO_BE_REMOVED___
 extern int dccp_ackvec_init(void);
 extern void dccp_ackvec_exit(void);
 
@@ -106,7 +106,7 @@ static inline int dccp_ackvec_pending(co
 {
 	return av->av_vec_len;
 }
-#else /* CONFIG_IP_DCCP_ACKVEC */
+#else /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
 static inline int dccp_ackvec_init(void)
 {
 	return 0;

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

* [PATCH 2/3] dccp: Clean up ccid.c after integration of CCID plugins
@ 2009-01-03  7:30                         ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-03  7:30 UTC (permalink / raw)
  To: davem; +Cc: dccp, netdev, Gerrit Renker

This patch cleans up after integrating the CCID modules and, in addition,

 * moves the if/else cases from ccid_delete() into ccid_hc_{tx,rx}_delete();
 * removes the 'gfp' argument to ccid_new() - since it is always gfp_any().

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/ackvec.h |   49 -------------------
 net/dccp/ccid.c   |  136 ++++--------------------------------------------------
 net/dccp/ccid.h   |    3 -
 net/dccp/feat.c   |    2 
 4 files changed, 14 insertions(+), 176 deletions(-)

--- a/net/dccp/ackvec.h
+++ b/net/dccp/ackvec.h
@@ -84,7 +84,6 @@ struct dccp_ackvec_record {
 struct sock;
 struct sk_buff;
 
-#ifndef ___OLD_INTERFACE_TO_BE_REMOVED___
 extern int dccp_ackvec_init(void);
 extern void dccp_ackvec_exit(void);
 
@@ -106,52 +105,4 @@ static inline int dccp_ackvec_pending(co
 {
 	return av->av_vec_len;
 }
-#else /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
-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 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_check_rcv_ackno(struct dccp_ackvec *av,
-					       struct sock *sk, const u64 ackno)
-{
-}
-
-static inline int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
-				    const u64 *ackno, const u8 opt,
-				    const u8 *value, const u8 len)
-{
-	return -1;
-}
-
-static inline int dccp_insert_option_ackvec(const struct sock *sk,
-					    const struct sk_buff *skb)
-{
-	return -1;
-}
-
-static inline int dccp_ackvec_pending(const struct dccp_ackvec *av)
-{
-	return 0;
-}
-#endif /* CONFIG_IP_DCCP_ACKVEC */
 #endif /* _ACKVEC_H */
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -76,58 +76,6 @@ int ccid_getsockopt_builtin_ccids(struct
 	return err;
 }
 
-#ifdef ___OLD_INTERFACE_TO_BE_REMOVED___
-static u8 builtin_ccids[] = {
-	DCCPC_CCID2,		/* CCID2 is supported by default */
-#if defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE)
-	DCCPC_CCID3,
-#endif
-};
-
-static struct ccid_operations *ccids[CCID_MAX];
-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
-static atomic_t ccids_lockct = ATOMIC_INIT(0);
-static DEFINE_SPINLOCK(ccids_lock);
-
-/*
- * The strategy is: modifications ccids vector are short, do not sleep and
- * veeery rare, but read access should be free of any exclusive locks.
- */
-static void ccids_write_lock(void)
-{
-	spin_lock(&ccids_lock);
-	while (atomic_read(&ccids_lockct) != 0) {
-		spin_unlock(&ccids_lock);
-		yield();
-		spin_lock(&ccids_lock);
-	}
-}
-
-static inline void ccids_write_unlock(void)
-{
-	spin_unlock(&ccids_lock);
-}
-
-static inline void ccids_read_lock(void)
-{
-	atomic_inc(&ccids_lockct);
-	smp_mb__after_atomic_inc();
-	spin_unlock_wait(&ccids_lock);
-}
-
-static inline void ccids_read_unlock(void)
-{
-	atomic_dec(&ccids_lockct);
-}
-
-#else
-#define ccids_write_lock() do { } while(0)
-#define ccids_write_unlock() do { } while(0)
-#define ccids_read_lock() do { } while(0)
-#define ccids_read_unlock() do { } while(0)
-#endif
-#endif /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
-
 static struct kmem_cache *ccid_kmem_cache_create(int obj_size, const char *fmt,...)
 {
 	struct kmem_cache *slab;
@@ -158,49 +106,6 @@ static void ccid_kmem_cache_destroy(stru
 	}
 }
 
-#ifdef ___OLD_INTERFACE_TO_BE_REMOVED___
-/* check that up to @array_len members in @ccid_array are supported */
-bool ccid_support_check(u8 const *ccid_array, u8 array_len)
-{
-	u8 i, j, found;
-
-	for (i = 0, found = 0; i < array_len; i++, found = 0) {
-		for (j = 0; !found && j < ARRAY_SIZE(builtin_ccids); j++)
-			found = (ccid_array[i] == builtin_ccids[j]);
-		if (!found)
-			return false;
-	}
-	return true;
-}
-
-/**
- * ccid_get_builtin_ccids  -  Provide copy of `builtin' CCID array
- * @ccid_array: pointer to copy into
- * @array_len: value to return length into
- * This function allocates memory - caller must see that it is freed after use.
- */
-int ccid_get_builtin_ccids(u8 **ccid_array, u8 *array_len)
-{
-	*ccid_array = kmemdup(builtin_ccids, sizeof(builtin_ccids), gfp_any());
-	if (*ccid_array == NULL)
-		return -ENOBUFS;
-	*array_len = ARRAY_SIZE(builtin_ccids);
-	return 0;
-}
-
-int ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
-				    char __user *optval, int __user *optlen)
-{
-	if (len < sizeof(builtin_ccids))
-		return -EINVAL;
-
-	if (put_user(sizeof(builtin_ccids), optlen) ||
-	    copy_to_user(optval, builtin_ccids, sizeof(builtin_ccids)))
-		return -EFAULT;
-	return 0;
-}
-#endif /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
-
 static int ccid_activate(struct ccid_operations *ccid_ops)
 {
 	int err = -ENOBUFS;
@@ -241,7 +146,7 @@ static void ccid_deactivate(struct ccid_
 		ccid_ops->ccid_id, ccid_ops->ccid_name);
 }
 
-struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
+struct ccid *ccid_new(const u8 id, struct sock *sk, bool rx)
 {
 	struct ccid_operations *ccid_ops = ccid_by_number(id);
 	struct ccid *ccid = NULL;
@@ -250,7 +155,7 @@ struct ccid *ccid_new(unsigned char id, 
 		goto out;
 
 	ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
-				     ccid_ops->ccid_hc_tx_slab, gfp);
+				     ccid_ops->ccid_hc_tx_slab, gfp_any());
 	if (ccid == NULL)
 		goto out;
 	ccid->ccid_ops = ccid_ops;
@@ -274,41 +179,24 @@ out_free_ccid:
 	goto out;
 }
 
-EXPORT_SYMBOL_GPL(ccid_new);
-
-static void ccid_delete(struct ccid *ccid, struct sock *sk, int rx)
-{
-	struct ccid_operations *ccid_ops;
-
-	if (ccid == NULL)
-		return;
-
-	ccid_ops = ccid->ccid_ops;
-	if (rx) {
-		if (ccid_ops->ccid_hc_rx_exit != NULL)
-			ccid_ops->ccid_hc_rx_exit(sk);
-		kmem_cache_free(ccid_ops->ccid_hc_rx_slab,  ccid);
-	} else {
-		if (ccid_ops->ccid_hc_tx_exit != NULL)
-			ccid_ops->ccid_hc_tx_exit(sk);
-		kmem_cache_free(ccid_ops->ccid_hc_tx_slab,  ccid);
-	}
-}
-
 void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk)
 {
-	ccid_delete(ccid, sk, 1);
+	if (ccid != NULL) {
+		if (ccid->ccid_ops->ccid_hc_rx_exit != NULL)
+			ccid->ccid_ops->ccid_hc_rx_exit(sk);
+		kmem_cache_free(ccid->ccid_ops->ccid_hc_rx_slab, ccid);
+	}
 }
 
-EXPORT_SYMBOL_GPL(ccid_hc_rx_delete);
-
 void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk)
 {
-	ccid_delete(ccid, sk, 0);
+	if (ccid != NULL) {
+		if (ccid->ccid_ops->ccid_hc_tx_exit != NULL)
+			ccid->ccid_ops->ccid_hc_tx_exit(sk);
+		kmem_cache_free(ccid->ccid_ops->ccid_hc_tx_slab, ccid);
+	}
 }
 
-EXPORT_SYMBOL_GPL(ccid_hc_tx_delete);
-
 int __init ccid_initialize_builtins(void)
 {
 	int i, err;
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -111,8 +111,7 @@ extern int  ccid_get_builtin_ccids(u8 **
 extern int  ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
 					  char __user *, int __user *);
 
-extern struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx,
-			     gfp_t gfp);
+extern struct ccid *ccid_new(const u8 id, struct sock *sk, bool rx);
 
 static inline int ccid_get_current_rx_ccid(struct dccp_sock *dp)
 {
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -34,7 +34,7 @@
 static int dccp_hdlr_ccid(struct sock *sk, u64 ccid, bool rx)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
-	struct ccid *new_ccid = ccid_new(ccid, sk, rx, gfp_any());
+	struct ccid *new_ccid = ccid_new(ccid, sk, rx);
 
 	if (new_ccid == NULL)
 		return -ENOMEM;

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

* [PATCH 2/3] dccp: Clean up ccid.c after integration of CCID plugins
@ 2009-01-03  7:30                         ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-03  7:30 UTC (permalink / raw)
  To: dccp

This patch cleans up after integrating the CCID modules and, in addition,

 * moves the if/else cases from ccid_delete() into ccid_hc_{tx,rx}_delete();
 * removes the 'gfp' argument to ccid_new() - since it is always gfp_any().

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/ackvec.h |   49 -------------------
 net/dccp/ccid.c   |  136 ++++--------------------------------------------------
 net/dccp/ccid.h   |    3 -
 net/dccp/feat.c   |    2 
 4 files changed, 14 insertions(+), 176 deletions(-)

--- a/net/dccp/ackvec.h
+++ b/net/dccp/ackvec.h
@@ -84,7 +84,6 @@ struct dccp_ackvec_record {
 struct sock;
 struct sk_buff;
 
-#ifndef ___OLD_INTERFACE_TO_BE_REMOVED___
 extern int dccp_ackvec_init(void);
 extern void dccp_ackvec_exit(void);
 
@@ -106,52 +105,4 @@ static inline int dccp_ackvec_pending(co
 {
 	return av->av_vec_len;
 }
-#else /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
-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 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_check_rcv_ackno(struct dccp_ackvec *av,
-					       struct sock *sk, const u64 ackno)
-{
-}
-
-static inline int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
-				    const u64 *ackno, const u8 opt,
-				    const u8 *value, const u8 len)
-{
-	return -1;
-}
-
-static inline int dccp_insert_option_ackvec(const struct sock *sk,
-					    const struct sk_buff *skb)
-{
-	return -1;
-}
-
-static inline int dccp_ackvec_pending(const struct dccp_ackvec *av)
-{
-	return 0;
-}
-#endif /* CONFIG_IP_DCCP_ACKVEC */
 #endif /* _ACKVEC_H */
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -76,58 +76,6 @@ int ccid_getsockopt_builtin_ccids(struct
 	return err;
 }
 
-#ifdef ___OLD_INTERFACE_TO_BE_REMOVED___
-static u8 builtin_ccids[] = {
-	DCCPC_CCID2,		/* CCID2 is supported by default */
-#if defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE)
-	DCCPC_CCID3,
-#endif
-};
-
-static struct ccid_operations *ccids[CCID_MAX];
-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
-static atomic_t ccids_lockct = ATOMIC_INIT(0);
-static DEFINE_SPINLOCK(ccids_lock);
-
-/*
- * The strategy is: modifications ccids vector are short, do not sleep and
- * veeery rare, but read access should be free of any exclusive locks.
- */
-static void ccids_write_lock(void)
-{
-	spin_lock(&ccids_lock);
-	while (atomic_read(&ccids_lockct) != 0) {
-		spin_unlock(&ccids_lock);
-		yield();
-		spin_lock(&ccids_lock);
-	}
-}
-
-static inline void ccids_write_unlock(void)
-{
-	spin_unlock(&ccids_lock);
-}
-
-static inline void ccids_read_lock(void)
-{
-	atomic_inc(&ccids_lockct);
-	smp_mb__after_atomic_inc();
-	spin_unlock_wait(&ccids_lock);
-}
-
-static inline void ccids_read_unlock(void)
-{
-	atomic_dec(&ccids_lockct);
-}
-
-#else
-#define ccids_write_lock() do { } while(0)
-#define ccids_write_unlock() do { } while(0)
-#define ccids_read_lock() do { } while(0)
-#define ccids_read_unlock() do { } while(0)
-#endif
-#endif /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
-
 static struct kmem_cache *ccid_kmem_cache_create(int obj_size, const char *fmt,...)
 {
 	struct kmem_cache *slab;
@@ -158,49 +106,6 @@ static void ccid_kmem_cache_destroy(stru
 	}
 }
 
-#ifdef ___OLD_INTERFACE_TO_BE_REMOVED___
-/* check that up to @array_len members in @ccid_array are supported */
-bool ccid_support_check(u8 const *ccid_array, u8 array_len)
-{
-	u8 i, j, found;
-
-	for (i = 0, found = 0; i < array_len; i++, found = 0) {
-		for (j = 0; !found && j < ARRAY_SIZE(builtin_ccids); j++)
-			found = (ccid_array[i] = builtin_ccids[j]);
-		if (!found)
-			return false;
-	}
-	return true;
-}
-
-/**
- * ccid_get_builtin_ccids  -  Provide copy of `builtin' CCID array
- * @ccid_array: pointer to copy into
- * @array_len: value to return length into
- * This function allocates memory - caller must see that it is freed after use.
- */
-int ccid_get_builtin_ccids(u8 **ccid_array, u8 *array_len)
-{
-	*ccid_array = kmemdup(builtin_ccids, sizeof(builtin_ccids), gfp_any());
-	if (*ccid_array = NULL)
-		return -ENOBUFS;
-	*array_len = ARRAY_SIZE(builtin_ccids);
-	return 0;
-}
-
-int ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
-				    char __user *optval, int __user *optlen)
-{
-	if (len < sizeof(builtin_ccids))
-		return -EINVAL;
-
-	if (put_user(sizeof(builtin_ccids), optlen) ||
-	    copy_to_user(optval, builtin_ccids, sizeof(builtin_ccids)))
-		return -EFAULT;
-	return 0;
-}
-#endif /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
-
 static int ccid_activate(struct ccid_operations *ccid_ops)
 {
 	int err = -ENOBUFS;
@@ -241,7 +146,7 @@ static void ccid_deactivate(struct ccid_
 		ccid_ops->ccid_id, ccid_ops->ccid_name);
 }
 
-struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
+struct ccid *ccid_new(const u8 id, struct sock *sk, bool rx)
 {
 	struct ccid_operations *ccid_ops = ccid_by_number(id);
 	struct ccid *ccid = NULL;
@@ -250,7 +155,7 @@ struct ccid *ccid_new(unsigned char id, 
 		goto out;
 
 	ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
-				     ccid_ops->ccid_hc_tx_slab, gfp);
+				     ccid_ops->ccid_hc_tx_slab, gfp_any());
 	if (ccid = NULL)
 		goto out;
 	ccid->ccid_ops = ccid_ops;
@@ -274,41 +179,24 @@ out_free_ccid:
 	goto out;
 }
 
-EXPORT_SYMBOL_GPL(ccid_new);
-
-static void ccid_delete(struct ccid *ccid, struct sock *sk, int rx)
-{
-	struct ccid_operations *ccid_ops;
-
-	if (ccid = NULL)
-		return;
-
-	ccid_ops = ccid->ccid_ops;
-	if (rx) {
-		if (ccid_ops->ccid_hc_rx_exit != NULL)
-			ccid_ops->ccid_hc_rx_exit(sk);
-		kmem_cache_free(ccid_ops->ccid_hc_rx_slab,  ccid);
-	} else {
-		if (ccid_ops->ccid_hc_tx_exit != NULL)
-			ccid_ops->ccid_hc_tx_exit(sk);
-		kmem_cache_free(ccid_ops->ccid_hc_tx_slab,  ccid);
-	}
-}
-
 void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk)
 {
-	ccid_delete(ccid, sk, 1);
+	if (ccid != NULL) {
+		if (ccid->ccid_ops->ccid_hc_rx_exit != NULL)
+			ccid->ccid_ops->ccid_hc_rx_exit(sk);
+		kmem_cache_free(ccid->ccid_ops->ccid_hc_rx_slab, ccid);
+	}
 }
 
-EXPORT_SYMBOL_GPL(ccid_hc_rx_delete);
-
 void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk)
 {
-	ccid_delete(ccid, sk, 0);
+	if (ccid != NULL) {
+		if (ccid->ccid_ops->ccid_hc_tx_exit != NULL)
+			ccid->ccid_ops->ccid_hc_tx_exit(sk);
+		kmem_cache_free(ccid->ccid_ops->ccid_hc_tx_slab, ccid);
+	}
 }
 
-EXPORT_SYMBOL_GPL(ccid_hc_tx_delete);
-
 int __init ccid_initialize_builtins(void)
 {
 	int i, err;
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -111,8 +111,7 @@ extern int  ccid_get_builtin_ccids(u8 **
 extern int  ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
 					  char __user *, int __user *);
 
-extern struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx,
-			     gfp_t gfp);
+extern struct ccid *ccid_new(const u8 id, struct sock *sk, bool rx);
 
 static inline int ccid_get_current_rx_ccid(struct dccp_sock *dp)
 {
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -34,7 +34,7 @@
 static int dccp_hdlr_ccid(struct sock *sk, u64 ccid, bool rx)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
-	struct ccid *new_ccid = ccid_new(ccid, sk, rx, gfp_any());
+	struct ccid *new_ccid = ccid_new(ccid, sk, rx);
 
 	if (new_ccid = NULL)
 		return -ENOMEM;

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

* [PATCH 3/3] dccp: Integrate the TFRC library with DCCP
@ 2009-01-03  7:30                           ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-03  7:30 UTC (permalink / raw)
  To: davem; +Cc: dccp, netdev, Gerrit Renker

This patch integrates the TFRC library, which is a dependency of CCID-3 (and
CCID-4), with the new use of CCIDs in the DCCP module.		

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/Makefile                   |    6 ++++--
 net/dccp/ccid.c                     |    8 +++++++-
 net/dccp/ccids/Kconfig              |    9 ++-------
 net/dccp/ccids/Makefile             |    1 -
 net/dccp/ccids/lib/Makefile         |    3 ---
 net/dccp/ccids/lib/loss_interval.c  |    3 ---
 net/dccp/ccids/lib/packet_history.c |    9 ---------
 net/dccp/ccids/lib/tfrc.c           |   19 ++++---------------
 net/dccp/ccids/lib/tfrc.h           |   11 ++++++++++-
 net/dccp/ccids/lib/tfrc_equation.c  |    4 ----
 net/dccp/feat.c                     |    4 ----
 net/dccp/input.c                    |    2 --
 12 files changed, 27 insertions(+), 52 deletions(-)

--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -14,7 +14,6 @@ config IP_DCCP_CCID2_DEBUG
 config IP_DCCP_CCID3
 	bool "CCID-3 (TCP-Friendly) (EXPERIMENTAL)"
 	def_bool y if (IP_DCCP = y || IP_DCCP = m)
-	select IP_DCCP_TFRC_LIB
 	---help---
 	  CCID 3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
 	  rate-controlled congestion control mechanism.  TFRC is designed to
@@ -80,12 +79,8 @@ config IP_DCCP_CCID3_RTO
 	    therefore not be performed on WANs.
 
 config IP_DCCP_TFRC_LIB
-	tristate
-	default n
+	def_bool y if IP_DCCP_CCID3
 
 config IP_DCCP_TFRC_DEBUG
-	bool
-	depends on IP_DCCP_TFRC_LIB
-	default y if IP_DCCP_CCID3_DEBUG
-
+	def_bool y if IP_DCCP_CCID3_DEBUG
 endmenu
--- a/net/dccp/Makefile
+++ b/net/dccp/Makefile
@@ -8,6 +8,10 @@ dccp-y := ccid.o feat.o input.o minisock
 # CCID-2 is default (RFC 4340, p. 77) and has Ack Vectors as dependency
 dccp-y += ccids/ccid2.o ackvec.o
 dccp-$(CONFIG_IP_DCCP_CCID3)	+= ccids/ccid3.o
+dccp-$(CONFIG_IP_DCCP_TFRC_LIB) += ccids/lib/tfrc.o		\
+				   ccids/lib/tfrc_equation.o	\
+				   ccids/lib/packet_history.o	\
+				   ccids/lib/loss_interval.o
 
 dccp_ipv4-y := ipv4.o
 
@@ -22,5 +26,3 @@ dccp-$(CONFIG_SYSCTL) += sysctl.o
 
 dccp_diag-y := diag.o
 dccp_probe-y := probe.o
-
-obj-y += ccids/
--- a/net/dccp/ccids/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-y += lib/
--- a/net/dccp/ccids/lib/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_IP_DCCP_TFRC_LIB) += dccp_tfrc_lib.o
-
-dccp_tfrc_lib-y := tfrc.o tfrc_equation.o packet_history.o loss_interval.o
--- a/net/dccp/ccids/lib/tfrc.h
+++ b/net/dccp/ccids/lib/tfrc.h
@@ -17,7 +17,8 @@
 #include <linux/types.h>
 #include <linux/math64.h>
 #include "../../dccp.h"
-/* internal includes that this module exports: */
+
+/* internal includes that this library exports: */
 #include "loss_interval.h"
 #include "packet_history.h"
 
@@ -66,4 +67,12 @@ extern void tfrc_rx_packet_history_exit(
 
 extern int  tfrc_li_init(void);
 extern void tfrc_li_exit(void);
+
+#ifdef CONFIG_IP_DCCP_TFRC_LIB
+extern int  tfrc_lib_init(void);
+extern void tfrc_lib_exit(void);
+#else
+#define tfrc_lib_init() (0)
+#define tfrc_lib_exit()
+#endif
 #endif /* _TFRC_H_ */
--- a/net/dccp/ccids/lib/tfrc.c
+++ b/net/dccp/ccids/lib/tfrc.c
@@ -1,20 +1,18 @@
 /*
- * TFRC: main module holding the pieces of the TFRC library together
+ * TFRC library initialisation
  *
  * Copyright (c) 2007 The University of Aberdeen, Scotland, UK
  * Copyright (c) 2007 Arnaldo Carvalho de Melo <acme@redhat.com>
  */
-#include <linux/module.h>
-#include <linux/moduleparam.h>
 #include "tfrc.h"
 
 #ifdef CONFIG_IP_DCCP_TFRC_DEBUG
 int tfrc_debug;
 module_param(tfrc_debug, bool, 0644);
-MODULE_PARM_DESC(tfrc_debug, "Enable debug messages");
+MODULE_PARM_DESC(tfrc_debug, "Enable TFRC debug messages");
 #endif
 
-static int __init tfrc_module_init(void)
+int __init tfrc_lib_init(void)
 {
 	int rc = tfrc_li_init();
 
@@ -38,18 +36,9 @@ out:
 	return rc;
 }
 
-static void __exit tfrc_module_exit(void)
+void __exit tfrc_lib_exit(void)
 {
 	tfrc_rx_packet_history_exit();
 	tfrc_tx_packet_history_exit();
 	tfrc_li_exit();
 }
-
-module_init(tfrc_module_init);
-module_exit(tfrc_module_exit);
-
-MODULE_AUTHOR("Gerrit Renker <gerrit@erg.abdn.ac.uk>, "
-	      "Ian McDonald <ian.mcdonald@jandi.co.nz>, "
-	      "Arnaldo Carvalho de Melo <acme@redhat.com>");
-MODULE_DESCRIPTION("DCCP TFRC library");
-MODULE_LICENSE("GPL");
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -12,6 +12,7 @@
  */
 
 #include "ccid.h"
+#include "ccids/lib/tfrc.h"
 
 static struct ccid_operations *ccids[] = {
 	&ccid2_ops,
@@ -199,7 +200,10 @@ void ccid_hc_tx_delete(struct ccid *ccid
 
 int __init ccid_initialize_builtins(void)
 {
-	int i, err;
+	int i, err = tfrc_lib_init();
+
+	if (err)
+		return err;
 
 	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
 		err = ccid_activate(ccids[i]);
@@ -211,6 +215,7 @@ int __init ccid_initialize_builtins(void
 unwind_registrations:
 	while(--i >= 0)
 		ccid_deactivate(ccids[i]);
+	tfrc_lib_exit();
 	return err;
 }
 
@@ -220,4 +225,5 @@ void ccid_cleanup_builtins(void)
 
 	for (i = 0; i < ARRAY_SIZE(ccids); i++)
 		ccid_deactivate(ccids[i]);
+	tfrc_lib_exit();
 }
--- a/net/dccp/ccids/lib/loss_interval.c
+++ b/net/dccp/ccids/lib/loss_interval.c
@@ -60,7 +60,6 @@ void tfrc_lh_cleanup(struct tfrc_loss_hi
 			lh->ring[LIH_INDEX(lh->counter)] = NULL;
 		}
 }
-EXPORT_SYMBOL_GPL(tfrc_lh_cleanup);
 
 static void tfrc_lh_calc_i_mean(struct tfrc_loss_hist *lh)
 {
@@ -121,7 +120,6 @@ u8 tfrc_lh_update_i_mean(struct tfrc_los
 
 	return (lh->i_mean < old_i_mean);
 }
-EXPORT_SYMBOL_GPL(tfrc_lh_update_i_mean);
 
 /* Determine if `new_loss' does begin a new loss interval [RFC 4342, 10.2] */
 static inline u8 tfrc_lh_is_new_loss(struct tfrc_loss_interval *cur,
@@ -169,7 +167,6 @@ int tfrc_lh_interval_add(struct tfrc_los
 	}
 	return 1;
 }
-EXPORT_SYMBOL_GPL(tfrc_lh_interval_add);
 
 int __init tfrc_li_init(void)
 {
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -94,7 +94,6 @@ int tfrc_tx_hist_add(struct tfrc_tx_hist
 	*headp	     = entry;
 	return 0;
 }
-EXPORT_SYMBOL_GPL(tfrc_tx_hist_add);
 
 void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp)
 {
@@ -109,7 +108,6 @@ void tfrc_tx_hist_purge(struct tfrc_tx_h
 
 	*headp = NULL;
 }
-EXPORT_SYMBOL_GPL(tfrc_tx_hist_purge);
 
 u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head, const u64 seqno,
 		     const ktime_t now)
@@ -127,7 +125,6 @@ u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist
 
 	return rtt;
 }
-EXPORT_SYMBOL_GPL(tfrc_tx_hist_rtt);
 
 
 /*
@@ -172,7 +169,6 @@ void tfrc_rx_hist_add_packet(struct tfrc
 
 	tfrc_rx_hist_entry_from_skb(entry, skb, ndp);
 }
-EXPORT_SYMBOL_GPL(tfrc_rx_hist_add_packet);
 
 /* has the packet contained in skb been seen before? */
 int tfrc_rx_hist_duplicate(struct tfrc_rx_hist *h, struct sk_buff *skb)
@@ -189,7 +185,6 @@ int tfrc_rx_hist_duplicate(struct tfrc_r
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(tfrc_rx_hist_duplicate);
 
 static void tfrc_rx_hist_swap(struct tfrc_rx_hist *h, const u8 a, const u8 b)
 {
@@ -390,7 +385,6 @@ int tfrc_rx_handle_loss(struct tfrc_rx_h
 	}
 	return is_new_loss;
 }
-EXPORT_SYMBOL_GPL(tfrc_rx_handle_loss);
 
 int tfrc_rx_hist_alloc(struct tfrc_rx_hist *h)
 {
@@ -412,7 +406,6 @@ out_free:
 	}
 	return -ENOBUFS;
 }
-EXPORT_SYMBOL_GPL(tfrc_rx_hist_alloc);
 
 void tfrc_rx_hist_purge(struct tfrc_rx_hist *h)
 {
@@ -424,7 +417,6 @@ void tfrc_rx_hist_purge(struct tfrc_rx_h
 			h->ring[i] = NULL;
 		}
 }
-EXPORT_SYMBOL_GPL(tfrc_rx_hist_purge);
 
 /**
  * tfrc_rx_hist_rtt_last_s - reference entry to compute RTT samples against
@@ -495,4 +487,3 @@ keep_ref_for_next_time:
 
 	return sample;
 }
-EXPORT_SYMBOL_GPL(tfrc_rx_hist_sample_rtt);
--- a/net/dccp/ccids/lib/tfrc_equation.c
+++ b/net/dccp/ccids/lib/tfrc_equation.c
@@ -659,8 +659,6 @@ u32 tfrc_calc_x(u16 s, u32 R, u32 p)
 	return scaled_div32(result, f);
 }
 
-EXPORT_SYMBOL_GPL(tfrc_calc_x);
-
 /**
  *  tfrc_calc_x_reverse_lookup  -  try to find p given f(p)
  *
@@ -693,5 +691,3 @@ u32 tfrc_calc_x_reverse_lookup(u32 fvalu
 	index = tfrc_binsearch(fvalue, 0);
 	return (index + 1) * 1000000 / TFRC_CALC_X_ARRSIZE;
 }
-
-EXPORT_SYMBOL_GPL(tfrc_calc_x_reverse_lookup);
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -1214,8 +1214,6 @@ const char *dccp_feat_typename(const u8 
 	return NULL;
 }
 
-EXPORT_SYMBOL_GPL(dccp_feat_typename);
-
 const char *dccp_feat_name(const u8 feat)
 {
 	static const char *feature_names[] = {
@@ -1240,6 +1238,4 @@ const char *dccp_feat_name(const u8 feat
 
 	return feature_names[feat];
 }
-
-EXPORT_SYMBOL_GPL(dccp_feat_name);
 #endif /* CONFIG_IP_DCCP_DEBUG */
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -741,5 +741,3 @@ u32 dccp_sample_rtt(struct sock *sk, lon
 
 	return delta;
 }
-
-EXPORT_SYMBOL_GPL(dccp_sample_rtt);

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

* [PATCH 3/3] dccp: Integrate the TFRC library with DCCP
@ 2009-01-03  7:30                           ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-03  7:30 UTC (permalink / raw)
  To: dccp

This patch integrates the TFRC library, which is a dependency of CCID-3 (and
CCID-4), with the new use of CCIDs in the DCCP module.		

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/Makefile                   |    6 ++++--
 net/dccp/ccid.c                     |    8 +++++++-
 net/dccp/ccids/Kconfig              |    9 ++-------
 net/dccp/ccids/Makefile             |    1 -
 net/dccp/ccids/lib/Makefile         |    3 ---
 net/dccp/ccids/lib/loss_interval.c  |    3 ---
 net/dccp/ccids/lib/packet_history.c |    9 ---------
 net/dccp/ccids/lib/tfrc.c           |   19 ++++---------------
 net/dccp/ccids/lib/tfrc.h           |   11 ++++++++++-
 net/dccp/ccids/lib/tfrc_equation.c  |    4 ----
 net/dccp/feat.c                     |    4 ----
 net/dccp/input.c                    |    2 --
 12 files changed, 27 insertions(+), 52 deletions(-)

--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -14,7 +14,6 @@ config IP_DCCP_CCID2_DEBUG
 config IP_DCCP_CCID3
 	bool "CCID-3 (TCP-Friendly) (EXPERIMENTAL)"
 	def_bool y if (IP_DCCP = y || IP_DCCP = m)
-	select IP_DCCP_TFRC_LIB
 	---help---
 	  CCID 3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
 	  rate-controlled congestion control mechanism.  TFRC is designed to
@@ -80,12 +79,8 @@ config IP_DCCP_CCID3_RTO
 	    therefore not be performed on WANs.
 
 config IP_DCCP_TFRC_LIB
-	tristate
-	default n
+	def_bool y if IP_DCCP_CCID3
 
 config IP_DCCP_TFRC_DEBUG
-	bool
-	depends on IP_DCCP_TFRC_LIB
-	default y if IP_DCCP_CCID3_DEBUG
-
+	def_bool y if IP_DCCP_CCID3_DEBUG
 endmenu
--- a/net/dccp/Makefile
+++ b/net/dccp/Makefile
@@ -8,6 +8,10 @@ dccp-y := ccid.o feat.o input.o minisock
 # CCID-2 is default (RFC 4340, p. 77) and has Ack Vectors as dependency
 dccp-y += ccids/ccid2.o ackvec.o
 dccp-$(CONFIG_IP_DCCP_CCID3)	+= ccids/ccid3.o
+dccp-$(CONFIG_IP_DCCP_TFRC_LIB) += ccids/lib/tfrc.o		\
+				   ccids/lib/tfrc_equation.o	\
+				   ccids/lib/packet_history.o	\
+				   ccids/lib/loss_interval.o
 
 dccp_ipv4-y := ipv4.o
 
@@ -22,5 +26,3 @@ dccp-$(CONFIG_SYSCTL) += sysctl.o
 
 dccp_diag-y := diag.o
 dccp_probe-y := probe.o
-
-obj-y += ccids/
--- a/net/dccp/ccids/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-y += lib/
--- a/net/dccp/ccids/lib/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_IP_DCCP_TFRC_LIB) += dccp_tfrc_lib.o
-
-dccp_tfrc_lib-y := tfrc.o tfrc_equation.o packet_history.o loss_interval.o
--- a/net/dccp/ccids/lib/tfrc.h
+++ b/net/dccp/ccids/lib/tfrc.h
@@ -17,7 +17,8 @@
 #include <linux/types.h>
 #include <linux/math64.h>
 #include "../../dccp.h"
-/* internal includes that this module exports: */
+
+/* internal includes that this library exports: */
 #include "loss_interval.h"
 #include "packet_history.h"
 
@@ -66,4 +67,12 @@ extern void tfrc_rx_packet_history_exit(
 
 extern int  tfrc_li_init(void);
 extern void tfrc_li_exit(void);
+
+#ifdef CONFIG_IP_DCCP_TFRC_LIB
+extern int  tfrc_lib_init(void);
+extern void tfrc_lib_exit(void);
+#else
+#define tfrc_lib_init() (0)
+#define tfrc_lib_exit()
+#endif
 #endif /* _TFRC_H_ */
--- a/net/dccp/ccids/lib/tfrc.c
+++ b/net/dccp/ccids/lib/tfrc.c
@@ -1,20 +1,18 @@
 /*
- * TFRC: main module holding the pieces of the TFRC library together
+ * TFRC library initialisation
  *
  * Copyright (c) 2007 The University of Aberdeen, Scotland, UK
  * Copyright (c) 2007 Arnaldo Carvalho de Melo <acme@redhat.com>
  */
-#include <linux/module.h>
-#include <linux/moduleparam.h>
 #include "tfrc.h"
 
 #ifdef CONFIG_IP_DCCP_TFRC_DEBUG
 int tfrc_debug;
 module_param(tfrc_debug, bool, 0644);
-MODULE_PARM_DESC(tfrc_debug, "Enable debug messages");
+MODULE_PARM_DESC(tfrc_debug, "Enable TFRC debug messages");
 #endif
 
-static int __init tfrc_module_init(void)
+int __init tfrc_lib_init(void)
 {
 	int rc = tfrc_li_init();
 
@@ -38,18 +36,9 @@ out:
 	return rc;
 }
 
-static void __exit tfrc_module_exit(void)
+void __exit tfrc_lib_exit(void)
 {
 	tfrc_rx_packet_history_exit();
 	tfrc_tx_packet_history_exit();
 	tfrc_li_exit();
 }
-
-module_init(tfrc_module_init);
-module_exit(tfrc_module_exit);
-
-MODULE_AUTHOR("Gerrit Renker <gerrit@erg.abdn.ac.uk>, "
-	      "Ian McDonald <ian.mcdonald@jandi.co.nz>, "
-	      "Arnaldo Carvalho de Melo <acme@redhat.com>");
-MODULE_DESCRIPTION("DCCP TFRC library");
-MODULE_LICENSE("GPL");
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -12,6 +12,7 @@
  */
 
 #include "ccid.h"
+#include "ccids/lib/tfrc.h"
 
 static struct ccid_operations *ccids[] = {
 	&ccid2_ops,
@@ -199,7 +200,10 @@ void ccid_hc_tx_delete(struct ccid *ccid
 
 int __init ccid_initialize_builtins(void)
 {
-	int i, err;
+	int i, err = tfrc_lib_init();
+
+	if (err)
+		return err;
 
 	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
 		err = ccid_activate(ccids[i]);
@@ -211,6 +215,7 @@ int __init ccid_initialize_builtins(void
 unwind_registrations:
 	while(--i >= 0)
 		ccid_deactivate(ccids[i]);
+	tfrc_lib_exit();
 	return err;
 }
 
@@ -220,4 +225,5 @@ void ccid_cleanup_builtins(void)
 
 	for (i = 0; i < ARRAY_SIZE(ccids); i++)
 		ccid_deactivate(ccids[i]);
+	tfrc_lib_exit();
 }
--- a/net/dccp/ccids/lib/loss_interval.c
+++ b/net/dccp/ccids/lib/loss_interval.c
@@ -60,7 +60,6 @@ void tfrc_lh_cleanup(struct tfrc_loss_hi
 			lh->ring[LIH_INDEX(lh->counter)] = NULL;
 		}
 }
-EXPORT_SYMBOL_GPL(tfrc_lh_cleanup);
 
 static void tfrc_lh_calc_i_mean(struct tfrc_loss_hist *lh)
 {
@@ -121,7 +120,6 @@ u8 tfrc_lh_update_i_mean(struct tfrc_los
 
 	return (lh->i_mean < old_i_mean);
 }
-EXPORT_SYMBOL_GPL(tfrc_lh_update_i_mean);
 
 /* Determine if `new_loss' does begin a new loss interval [RFC 4342, 10.2] */
 static inline u8 tfrc_lh_is_new_loss(struct tfrc_loss_interval *cur,
@@ -169,7 +167,6 @@ int tfrc_lh_interval_add(struct tfrc_los
 	}
 	return 1;
 }
-EXPORT_SYMBOL_GPL(tfrc_lh_interval_add);
 
 int __init tfrc_li_init(void)
 {
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -94,7 +94,6 @@ int tfrc_tx_hist_add(struct tfrc_tx_hist
 	*headp	     = entry;
 	return 0;
 }
-EXPORT_SYMBOL_GPL(tfrc_tx_hist_add);
 
 void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp)
 {
@@ -109,7 +108,6 @@ void tfrc_tx_hist_purge(struct tfrc_tx_h
 
 	*headp = NULL;
 }
-EXPORT_SYMBOL_GPL(tfrc_tx_hist_purge);
 
 u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head, const u64 seqno,
 		     const ktime_t now)
@@ -127,7 +125,6 @@ u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist
 
 	return rtt;
 }
-EXPORT_SYMBOL_GPL(tfrc_tx_hist_rtt);
 
 
 /*
@@ -172,7 +169,6 @@ void tfrc_rx_hist_add_packet(struct tfrc
 
 	tfrc_rx_hist_entry_from_skb(entry, skb, ndp);
 }
-EXPORT_SYMBOL_GPL(tfrc_rx_hist_add_packet);
 
 /* has the packet contained in skb been seen before? */
 int tfrc_rx_hist_duplicate(struct tfrc_rx_hist *h, struct sk_buff *skb)
@@ -189,7 +185,6 @@ int tfrc_rx_hist_duplicate(struct tfrc_r
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(tfrc_rx_hist_duplicate);
 
 static void tfrc_rx_hist_swap(struct tfrc_rx_hist *h, const u8 a, const u8 b)
 {
@@ -390,7 +385,6 @@ int tfrc_rx_handle_loss(struct tfrc_rx_h
 	}
 	return is_new_loss;
 }
-EXPORT_SYMBOL_GPL(tfrc_rx_handle_loss);
 
 int tfrc_rx_hist_alloc(struct tfrc_rx_hist *h)
 {
@@ -412,7 +406,6 @@ out_free:
 	}
 	return -ENOBUFS;
 }
-EXPORT_SYMBOL_GPL(tfrc_rx_hist_alloc);
 
 void tfrc_rx_hist_purge(struct tfrc_rx_hist *h)
 {
@@ -424,7 +417,6 @@ void tfrc_rx_hist_purge(struct tfrc_rx_h
 			h->ring[i] = NULL;
 		}
 }
-EXPORT_SYMBOL_GPL(tfrc_rx_hist_purge);
 
 /**
  * tfrc_rx_hist_rtt_last_s - reference entry to compute RTT samples against
@@ -495,4 +487,3 @@ keep_ref_for_next_time:
 
 	return sample;
 }
-EXPORT_SYMBOL_GPL(tfrc_rx_hist_sample_rtt);
--- a/net/dccp/ccids/lib/tfrc_equation.c
+++ b/net/dccp/ccids/lib/tfrc_equation.c
@@ -659,8 +659,6 @@ u32 tfrc_calc_x(u16 s, u32 R, u32 p)
 	return scaled_div32(result, f);
 }
 
-EXPORT_SYMBOL_GPL(tfrc_calc_x);
-
 /**
  *  tfrc_calc_x_reverse_lookup  -  try to find p given f(p)
  *
@@ -693,5 +691,3 @@ u32 tfrc_calc_x_reverse_lookup(u32 fvalu
 	index = tfrc_binsearch(fvalue, 0);
 	return (index + 1) * 1000000 / TFRC_CALC_X_ARRSIZE;
 }
-
-EXPORT_SYMBOL_GPL(tfrc_calc_x_reverse_lookup);
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -1214,8 +1214,6 @@ const char *dccp_feat_typename(const u8 
 	return NULL;
 }
 
-EXPORT_SYMBOL_GPL(dccp_feat_typename);
-
 const char *dccp_feat_name(const u8 feat)
 {
 	static const char *feature_names[] = {
@@ -1240,6 +1238,4 @@ const char *dccp_feat_name(const u8 feat
 
 	return feature_names[feat];
 }
-
-EXPORT_SYMBOL_GPL(dccp_feat_name);
 #endif /* CONFIG_IP_DCCP_DEBUG */
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -741,5 +741,3 @@ u32 dccp_sample_rtt(struct sock *sk, lon
 
 	return delta;
 }
-
-EXPORT_SYMBOL_GPL(dccp_sample_rtt);

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

* Re: [PATCH 1/3] dccp: Lockless integration of CCID congestion-control plugins
  2009-01-03  7:30                       ` Gerrit Renker
@ 2009-01-05  5:45                         ` David Miller
  -1 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2009-01-05  5:45 UTC (permalink / raw)
  To: gerrit; +Cc: dccp, netdev

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Sat,  3 Jan 2009 08:30:47 +0100

> Based on Arnaldo's earlier patch, this patch integrates the standardised
> CCID congestion control plugins (CCID-2 and CCID-3) of DCCP with dccp.ko:
> 
>  * enables a faster connection path by eliminating the need to always go 
>    through the CCID registration lock;
> 
>  * updates the implementation to use only a single array whose size equals
>    the number of configured CCIDs instead of the maximum (256);
> 
>  * since the CCIDs are now fixed array elements, synchronization is no
>    longer needed, simplifying use and implementation.
> 
> CCID-2 is suggested as minimum for a basic DCCP implementation (RFC 4340, 10);
> CCID-3 is a standards-track CCID supported by RFC 4342 and RFC 5348.
> 
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>

Applied.

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

* Re: [PATCH 1/3] dccp: Lockless integration of CCID
@ 2009-01-05  5:45                         ` David Miller
  0 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2009-01-05  5:45 UTC (permalink / raw)
  To: dccp

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Sat,  3 Jan 2009 08:30:47 +0100

> Based on Arnaldo's earlier patch, this patch integrates the standardised
> CCID congestion control plugins (CCID-2 and CCID-3) of DCCP with dccp.ko:
> 
>  * enables a faster connection path by eliminating the need to always go 
>    through the CCID registration lock;
> 
>  * updates the implementation to use only a single array whose size equals
>    the number of configured CCIDs instead of the maximum (256);
> 
>  * since the CCIDs are now fixed array elements, synchronization is no
>    longer needed, simplifying use and implementation.
> 
> CCID-2 is suggested as minimum for a basic DCCP implementation (RFC 4340, 10);
> CCID-3 is a standards-track CCID supported by RFC 4342 and RFC 5348.
> 
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>

Applied.

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

* Re: [PATCH 2/3] dccp: Clean up ccid.c after integration of CCID plugins
  2009-01-03  7:30                         ` Gerrit Renker
@ 2009-01-05  5:46                           ` David Miller
  -1 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2009-01-05  5:46 UTC (permalink / raw)
  To: gerrit; +Cc: dccp, netdev

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Sat,  3 Jan 2009 08:30:48 +0100

> This patch cleans up after integrating the CCID modules and, in addition,
> 
>  * moves the if/else cases from ccid_delete() into ccid_hc_{tx,rx}_delete();
>  * removes the 'gfp' argument to ccid_new() - since it is always gfp_any().
> 
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>

Applied.

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

* Re: [PATCH 2/3] dccp: Clean up ccid.c after integration of CCID
@ 2009-01-05  5:46                           ` David Miller
  0 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2009-01-05  5:46 UTC (permalink / raw)
  To: dccp

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Sat,  3 Jan 2009 08:30:48 +0100

> This patch cleans up after integrating the CCID modules and, in addition,
> 
>  * moves the if/else cases from ccid_delete() into ccid_hc_{tx,rx}_delete();
>  * removes the 'gfp' argument to ccid_new() - since it is always gfp_any().
> 
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>

Applied.

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

* Re: [PATCH 3/3] dccp: Integrate the TFRC library with DCCP
  2009-01-03  7:30                           ` Gerrit Renker
@ 2009-01-05  5:46                             ` David Miller
  -1 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2009-01-05  5:46 UTC (permalink / raw)
  To: gerrit; +Cc: dccp, netdev

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Sat,  3 Jan 2009 08:30:49 +0100

> This patch integrates the TFRC library, which is a dependency of CCID-3 (and
> CCID-4), with the new use of CCIDs in the DCCP module.		
> 
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>

Applied.

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

* Re: [PATCH 3/3] dccp: Integrate the TFRC library with DCCP
@ 2009-01-05  5:46                             ` David Miller
  0 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2009-01-05  5:46 UTC (permalink / raw)
  To: dccp

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Sat,  3 Jan 2009 08:30:49 +0100

> This patch integrates the TFRC library, which is a dependency of CCID-3 (and
> CCID-4), with the new use of CCIDs in the DCCP module.		
> 
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>

Applied.

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

* [PATCH 0/4] dccp: Completing feature negotiation
@ 2009-01-17  9:36                               ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-17  9:36 UTC (permalink / raw)
  To: davem; +Cc: dccp, netdev

Hi Dave,

following the re-design of the CCID-plugin loading into dccp.ko and further
testing, please find attached the patch set to complete the implementation
of static feature negotiation in DCCP.

Patches have been tested to compile standalone, with sparse enabled.

Gerrit


Commit summary:
---------------
This set completes the self-contained implementation of static feature
negotiation for DCCP endpoints (RFC 4340 - 4342, RFC 5348).

The whole set is structured into 3 main blocks - (1) basis, (2) core, (3)
integration and cleanup.

This set is the final in block (3) and implements the initialization of
feature-negotiation state. 

There is further work going on in the test tree  to also dynamically update
(non-negotiable) feature values such as Ack Ratio. Before this can be done,
however, the CCIDs themselves need some more work.

List of patches in this set:
----------------------------
Patch #1: Initialisation framework for the supported features.
Patch #2: Adds full support for local/remote Sequence Window.
Patch #3: Initialisation and type-checking of involved sysctls.
Patch #4: A set of (useful) debugging/printing helper functions.

The set is also available for viewing online, beginning at
commit bde1e830e87f3a3e51a72fa5b35405c313b64b74 of
http://eden-feed.erg.abdn.ac.uk/cgi-bin/gitweb.cgi?p=dccp_exp.git

Patch stats:
------------
 Documentation/networking/dccp.txt |    3 
 include/linux/dccp.h              |   51 --------
 net/dccp/dccp.h                   |   21 +--
 net/dccp/feat.c                   |  240 ++++++++++++++++++++++++++++----------
 net/dccp/feat.h                   |   23 +--
 net/dccp/minisocks.c              |   11 -
 net/dccp/options.c                |    8 -
 net/dccp/proto.c                  |    2 
 net/dccp/sysctl.c                 |   43 ++++--
 9 files changed, 237 insertions(+), 165 deletions(-)

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

* [PATCH 0/4] dccp: Completing feature negotiation
@ 2009-01-17  9:36                               ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-17  9:36 UTC (permalink / raw)
  To: dccp

Hi Dave,

following the re-design of the CCID-plugin loading into dccp.ko and further
testing, please find attached the patch set to complete the implementation
of static feature negotiation in DCCP.

Patches have been tested to compile standalone, with sparse enabled.

Gerrit


Commit summary:
---------------
This set completes the self-contained implementation of static feature
negotiation for DCCP endpoints (RFC 4340 - 4342, RFC 5348).

The whole set is structured into 3 main blocks - (1) basis, (2) core, (3)
integration and cleanup.

This set is the final in block (3) and implements the initialization of
feature-negotiation state. 

There is further work going on in the test tree  to also dynamically update
(non-negotiable) feature values such as Ack Ratio. Before this can be done,
however, the CCIDs themselves need some more work.

List of patches in this set:
----------------------------
Patch #1: Initialisation framework for the supported features.
Patch #2: Adds full support for local/remote Sequence Window.
Patch #3: Initialisation and type-checking of involved sysctls.
Patch #4: A set of (useful) debugging/printing helper functions.

The set is also available for viewing online, beginning at
commit bde1e830e87f3a3e51a72fa5b35405c313b64b74 of
http://eden-feed.erg.abdn.ac.uk/cgi-bin/gitweb.cgi?p‹cp_exp.git

Patch stats:
------------
 Documentation/networking/dccp.txt |    3 
 include/linux/dccp.h              |   51 --------
 net/dccp/dccp.h                   |   21 +--
 net/dccp/feat.c                   |  240 ++++++++++++++++++++++++++++----------
 net/dccp/feat.h                   |   23 +--
 net/dccp/minisocks.c              |   11 -
 net/dccp/options.c                |    8 -
 net/dccp/proto.c                  |    2 
 net/dccp/sysctl.c                 |   43 ++++--
 9 files changed, 237 insertions(+), 165 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe dccp" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 1/4] dccp: Initialisation framework for feature negotiation
@ 2009-01-17  9:36                                 ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-17  9:36 UTC (permalink / raw)
  To: davem; +Cc: dccp, netdev, Gerrit Renker

This initialises feature negotiation from two tables, which are in turn are
initialised from sysctls.

As a novel feature, specifics of the implementation (e.g. that short seqnos
and ECN are not yet available) are advertised for robustness.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
---
 include/linux/dccp.h |   19 --------------
 net/dccp/feat.c      |   67 +++++++++++++++++++++++++++++++++++++++++++--------
 net/dccp/feat.h      |    2 -
 3 files changed, 58 insertions(+), 30 deletions(-)

--- a/net/dccp/feat.h
+++ b/net/dccp/feat.h
@@ -113,13 +113,13 @@ static inline void dccp_feat_debug(const
 #define dccp_feat_debug(type, feat, val)
 #endif /* CONFIG_IP_DCCP_DEBUG */
 
+extern int  dccp_feat_init(struct sock *sk);
 extern int  dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
 				  u8 const *list, u8 len);
 extern int  dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val);
 extern int  dccp_feat_parse_options(struct sock *, struct dccp_request_sock *,
 				    u8 mand, u8 opt, u8 feat, u8 *val, u8 len);
 extern int  dccp_feat_clone_list(struct list_head const *, struct list_head *);
-extern int  dccp_feat_init(struct sock *sk);
 
 /*
  * Encoding variable-length options and their maximum length.
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -369,28 +369,9 @@ static inline unsigned int dccp_hdr_len(
   * Will be used to pass the state from dccp_request_sock to dccp_sock.
   *
   * @dccpms_sequence_window - Sequence Window Feature (section 7.5.2)
-  * @dccpms_pending - List of features being negotiated
-  * @dccpms_conf -
   */
 struct dccp_minisock {
 	__u64			dccpms_sequence_window;
-	struct list_head	dccpms_pending;
-	struct list_head	dccpms_conf;
-};
-
-struct dccp_opt_conf {
-	__u8			*dccpoc_val;
-	__u8			dccpoc_len;
-};
-
-struct dccp_opt_pend {
-	struct list_head	dccpop_node;
-	__u8			dccpop_type;
-	__u8			dccpop_feat;
-	__u8		        *dccpop_val;
-	__u8			dccpop_len;
-	int			dccpop_conf;
-	struct dccp_opt_conf    *dccpop_sc;
 };
 
 extern void dccp_minisock_init(struct dccp_minisock *dmsk);
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -1115,23 +1115,70 @@ int dccp_feat_parse_options(struct sock 
 	return 0;	/* ignore FN options in all other states */
 }
 
+/**
+ * dccp_feat_init  -  Seed feature negotiation with host-specific defaults
+ * This initialises global defaults, depending on the value of the sysctls.
+ * These can later be overridden by registering changes via setsockopt calls.
+ * The last link in the chain is finalise_settings, to make sure that between
+ * here and the start of actual feature negotiation no inconsistencies enter.
+ *
+ * All features not appearing below use either defaults or are otherwise
+ * later adjusted through dccp_feat_finalise_settings().
+ */
 int dccp_feat_init(struct sock *sk)
 {
-	struct dccp_sock *dp = dccp_sk(sk);
-	struct dccp_minisock *dmsk = dccp_msk(sk);
+	struct list_head *fn = &dccp_sk(sk)->dccps_featneg;
+	u8 on = 1, off = 0;
 	int rc;
+	struct {
+		u8 *val;
+		u8 len;
+	} tx, rx;
+
+	/* Non-negotiable (NN) features */
+	rc = __feat_register_nn(fn, DCCPF_SEQUENCE_WINDOW, 0,
+				    sysctl_dccp_feat_sequence_window);
+	if (rc)
+		return rc;
+
+	/* Server-priority (SP) features */
+
+	/* Advertise that short seqnos are not supported (7.6.1) */
+	rc = __feat_register_sp(fn, DCCPF_SHORT_SEQNOS, true, true, &off, 1);
+	if (rc)
+		return rc;
+
+	/* RFC 4340 12.1: "If a DCCP is not ECN capable, ..." */
+	rc = __feat_register_sp(fn, DCCPF_ECN_INCAPABLE, true, true, &on, 1);
+	if (rc)
+		return rc;
 
-	INIT_LIST_HEAD(&dmsk->dccpms_pending);	/* XXX no longer used */
-	INIT_LIST_HEAD(&dmsk->dccpms_conf);	/* XXX no longer used */
-
-	/* Ack ratio */
-	rc = __feat_register_nn(&dp->dccps_featneg, DCCPF_ACK_RATIO, 0,
-				dp->dccps_l_ack_ratio);
+	/*
+	 * We advertise the available list of CCIDs and reorder according to
+	 * preferences, to avoid failure resulting from negotiating different
+	 * singleton values (which always leads to failure).
+	 * These settings can still (later) be overridden via sockopts.
+	 */
+	if (ccid_get_builtin_ccids(&tx.val, &tx.len) ||
+	    ccid_get_builtin_ccids(&rx.val, &rx.len))
+		return -ENOBUFS;
+
+	if (!dccp_feat_prefer(sysctl_dccp_feat_tx_ccid, tx.val, tx.len) ||
+	    !dccp_feat_prefer(sysctl_dccp_feat_rx_ccid, rx.val, rx.len))
+		goto free_ccid_lists;
+
+	rc = __feat_register_sp(fn, DCCPF_CCID, true, false, tx.val, tx.len);
+	if (rc)
+		goto free_ccid_lists;
+
+	rc = __feat_register_sp(fn, DCCPF_CCID, false, false, rx.val, rx.len);
+
+free_ccid_lists:
+	kfree(tx.val);
+	kfree(rx.val);
 	return rc;
 }
 
-EXPORT_SYMBOL_GPL(dccp_feat_init);
-
 int dccp_feat_activate_values(struct sock *sk, struct list_head *fn_list)
 {
 	struct dccp_sock *dp = dccp_sk(sk);

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

* [PATCH 1/4] dccp: Initialisation framework for feature negotiation
@ 2009-01-17  9:36                                 ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-17  9:36 UTC (permalink / raw)
  To: dccp

This initialises feature negotiation from two tables, which are in turn are
initialised from sysctls.

As a novel feature, specifics of the implementation (e.g. that short seqnos
and ECN are not yet available) are advertised for robustness.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
---
 include/linux/dccp.h |   19 --------------
 net/dccp/feat.c      |   67 +++++++++++++++++++++++++++++++++++++++++++--------
 net/dccp/feat.h      |    2 -
 3 files changed, 58 insertions(+), 30 deletions(-)

--- a/net/dccp/feat.h
+++ b/net/dccp/feat.h
@@ -113,13 +113,13 @@ static inline void dccp_feat_debug(const
 #define dccp_feat_debug(type, feat, val)
 #endif /* CONFIG_IP_DCCP_DEBUG */
 
+extern int  dccp_feat_init(struct sock *sk);
 extern int  dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
 				  u8 const *list, u8 len);
 extern int  dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val);
 extern int  dccp_feat_parse_options(struct sock *, struct dccp_request_sock *,
 				    u8 mand, u8 opt, u8 feat, u8 *val, u8 len);
 extern int  dccp_feat_clone_list(struct list_head const *, struct list_head *);
-extern int  dccp_feat_init(struct sock *sk);
 
 /*
  * Encoding variable-length options and their maximum length.
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -369,28 +369,9 @@ static inline unsigned int dccp_hdr_len(
   * Will be used to pass the state from dccp_request_sock to dccp_sock.
   *
   * @dccpms_sequence_window - Sequence Window Feature (section 7.5.2)
-  * @dccpms_pending - List of features being negotiated
-  * @dccpms_conf -
   */
 struct dccp_minisock {
 	__u64			dccpms_sequence_window;
-	struct list_head	dccpms_pending;
-	struct list_head	dccpms_conf;
-};
-
-struct dccp_opt_conf {
-	__u8			*dccpoc_val;
-	__u8			dccpoc_len;
-};
-
-struct dccp_opt_pend {
-	struct list_head	dccpop_node;
-	__u8			dccpop_type;
-	__u8			dccpop_feat;
-	__u8		        *dccpop_val;
-	__u8			dccpop_len;
-	int			dccpop_conf;
-	struct dccp_opt_conf    *dccpop_sc;
 };
 
 extern void dccp_minisock_init(struct dccp_minisock *dmsk);
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -1115,23 +1115,70 @@ int dccp_feat_parse_options(struct sock 
 	return 0;	/* ignore FN options in all other states */
 }
 
+/**
+ * dccp_feat_init  -  Seed feature negotiation with host-specific defaults
+ * This initialises global defaults, depending on the value of the sysctls.
+ * These can later be overridden by registering changes via setsockopt calls.
+ * The last link in the chain is finalise_settings, to make sure that between
+ * here and the start of actual feature negotiation no inconsistencies enter.
+ *
+ * All features not appearing below use either defaults or are otherwise
+ * later adjusted through dccp_feat_finalise_settings().
+ */
 int dccp_feat_init(struct sock *sk)
 {
-	struct dccp_sock *dp = dccp_sk(sk);
-	struct dccp_minisock *dmsk = dccp_msk(sk);
+	struct list_head *fn = &dccp_sk(sk)->dccps_featneg;
+	u8 on = 1, off = 0;
 	int rc;
+	struct {
+		u8 *val;
+		u8 len;
+	} tx, rx;
+
+	/* Non-negotiable (NN) features */
+	rc = __feat_register_nn(fn, DCCPF_SEQUENCE_WINDOW, 0,
+				    sysctl_dccp_feat_sequence_window);
+	if (rc)
+		return rc;
+
+	/* Server-priority (SP) features */
+
+	/* Advertise that short seqnos are not supported (7.6.1) */
+	rc = __feat_register_sp(fn, DCCPF_SHORT_SEQNOS, true, true, &off, 1);
+	if (rc)
+		return rc;
+
+	/* RFC 4340 12.1: "If a DCCP is not ECN capable, ..." */
+	rc = __feat_register_sp(fn, DCCPF_ECN_INCAPABLE, true, true, &on, 1);
+	if (rc)
+		return rc;
 
-	INIT_LIST_HEAD(&dmsk->dccpms_pending);	/* XXX no longer used */
-	INIT_LIST_HEAD(&dmsk->dccpms_conf);	/* XXX no longer used */
-
-	/* Ack ratio */
-	rc = __feat_register_nn(&dp->dccps_featneg, DCCPF_ACK_RATIO, 0,
-				dp->dccps_l_ack_ratio);
+	/*
+	 * We advertise the available list of CCIDs and reorder according to
+	 * preferences, to avoid failure resulting from negotiating different
+	 * singleton values (which always leads to failure).
+	 * These settings can still (later) be overridden via sockopts.
+	 */
+	if (ccid_get_builtin_ccids(&tx.val, &tx.len) ||
+	    ccid_get_builtin_ccids(&rx.val, &rx.len))
+		return -ENOBUFS;
+
+	if (!dccp_feat_prefer(sysctl_dccp_feat_tx_ccid, tx.val, tx.len) ||
+	    !dccp_feat_prefer(sysctl_dccp_feat_rx_ccid, rx.val, rx.len))
+		goto free_ccid_lists;
+
+	rc = __feat_register_sp(fn, DCCPF_CCID, true, false, tx.val, tx.len);
+	if (rc)
+		goto free_ccid_lists;
+
+	rc = __feat_register_sp(fn, DCCPF_CCID, false, false, rx.val, rx.len);
+
+free_ccid_lists:
+	kfree(tx.val);
+	kfree(rx.val);
 	return rc;
 }
 
-EXPORT_SYMBOL_GPL(dccp_feat_init);
-
 int dccp_feat_activate_values(struct sock *sk, struct list_head *fn_list)
 {
 	struct dccp_sock *dp = dccp_sk(sk);

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

* [PATCH 2/4] dccp: Implement both feature-local and feature-remote Sequence Window feature
@ 2009-01-17  9:36                                   ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-17  9:36 UTC (permalink / raw)
  To: davem; +Cc: dccp, netdev, Gerrit Renker

This adds full support for local/remote Sequence Window feature, from which the 
  * sequence-number-validity (W) and 
  * acknowledgment-number-validity (W') windows 
derive as specified in RFC 4340, 7.5.3. 

Specifically, the following is contained in this patch:
  * integrated new socket fields into dccp_sk;
  * updated the update_gsr/gss routines with regard to these fields;
  * updated handler code: the Sequence Window feature is located at the TX side,
    so the local feature is meant if the handler-rx flag is false;
  * the initialisation of `rcv_wnd' in reqsk is removed, since
    - rcv_wnd is not used by the code anywhere;
    - sequence number checks are not done in the LISTEN state (cf. 7.5.3);
    - dccp_check_req checks the Ack number validity more rigorously;
  * the `struct dccp_minisock' became empty and is now removed.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
---
 Documentation/networking/dccp.txt |    3 ++-
 include/linux/dccp.h              |   24 ++++--------------------
 net/dccp/dccp.h                   |   16 +++++++---------
 net/dccp/feat.c                   |   13 +++++++++++--
 net/dccp/minisocks.c              |   11 -----------
 net/dccp/proto.c                  |    2 --
 6 files changed, 24 insertions(+), 45 deletions(-)

--- a/Documentation/networking/dccp.txt
+++ b/Documentation/networking/dccp.txt
@@ -141,7 +141,8 @@ rx_ccid = 2
 	Default CCID for the receiver-sender half-connection; see tx_ccid.
 
 seq_window = 100
-	The initial sequence window (sec. 7.5.2).
+	The initial sequence window (sec. 7.5.2) of the sender. This influences
+	the local ackno validity and the remote seqno validity windows (7.5.1).
 
 tx_qlen = 5
 	The size of the transmit buffer in packets. A value of 0 corresponds
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -364,19 +364,6 @@ static inline unsigned int dccp_hdr_len(
 #define DCCPF_INITIAL_SEND_NDP_COUNT		1
 
 /**
-  * struct dccp_minisock - Minimal DCCP connection representation
-  *
-  * Will be used to pass the state from dccp_request_sock to dccp_sock.
-  *
-  * @dccpms_sequence_window - Sequence Window Feature (section 7.5.2)
-  */
-struct dccp_minisock {
-	__u64			dccpms_sequence_window;
-};
-
-extern void dccp_minisock_init(struct dccp_minisock *dmsk);
-
-/**
  * struct dccp_request_sock  -  represent DCCP-specific connection request
  * @dreq_inet_rsk: structure inherited from
  * @dreq_iss: initial sequence number sent on the Response (RFC 4340, 7.1)
@@ -464,13 +451,14 @@ struct dccp_ackvec;
  * @dccps_timestamp_time - time of receiving latest @dccps_timestamp_echo
  * @dccps_l_ack_ratio - feature-local Ack Ratio
  * @dccps_r_ack_ratio - feature-remote Ack Ratio
+ * @dccps_l_seq_win - local Sequence Window (influences ack number validity)
+ * @dccps_r_seq_win - remote Sequence Window (influences seq number validity)
  * @dccps_pcslen - sender   partial checksum coverage (via sockopt)
  * @dccps_pcrlen - receiver partial checksum coverage (via sockopt)
  * @dccps_send_ndp_count - local Send NDP Count feature (7.7.2)
  * @dccps_ndp_count - number of Non Data Packets since last data packet
  * @dccps_mss_cache - current value of MSS (path MTU minus header sizes)
  * @dccps_rate_last - timestamp for rate-limiting DCCP-Sync (RFC 4340, 7.5.4)
- * @dccps_minisock - associated minisock (accessed via dccp_msk)
  * @dccps_featneg - tracks feature-negotiation state (mostly during handshake)
  * @dccps_hc_rx_ackvec - rx half connection ack vector
  * @dccps_hc_rx_ccid - CCID used for the receiver (or receiving half-connection)
@@ -504,12 +492,13 @@ struct dccp_sock {
 	__u32				dccps_timestamp_time;
 	__u16				dccps_l_ack_ratio;
 	__u16				dccps_r_ack_ratio;
+	__u64				dccps_l_seq_win:48;
+	__u64				dccps_r_seq_win:48;
 	__u8				dccps_pcslen:4;
 	__u8				dccps_pcrlen:4;
 	__u8				dccps_send_ndp_count:1;
 	__u64				dccps_ndp_count:48;
 	unsigned long			dccps_rate_last;
-	struct dccp_minisock		dccps_minisock;
 	struct list_head		dccps_featneg;
 	struct dccp_ackvec		*dccps_hc_rx_ackvec;
 	struct ccid			*dccps_hc_rx_ccid;
@@ -527,11 +516,6 @@ static inline struct dccp_sock *dccp_sk(
 	return (struct dccp_sock *)sk;
 }
 
-static inline struct dccp_minisock *dccp_msk(const struct sock *sk)
-{
-	return (struct dccp_minisock *)&dccp_sk(sk)->dccps_minisock;
-}
-
 static inline const char *dccp_role(const struct sock *sk)
 {
 	switch (dccp_sk(sk)->dccps_role) {
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -409,23 +409,21 @@ static inline void dccp_hdr_set_ack(stru
 static inline void dccp_update_gsr(struct sock *sk, u64 seq)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
-	const struct dccp_minisock *dmsk = dccp_msk(sk);
 
 	dp->dccps_gsr = seq;
-	dccp_set_seqno(&dp->dccps_swl,
-		       dp->dccps_gsr + 1 - (dmsk->dccpms_sequence_window / 4));
-	dccp_set_seqno(&dp->dccps_swh,
-		       dp->dccps_gsr + (3 * dmsk->dccpms_sequence_window) / 4);
+	/* Sequence validity window depends on remote Sequence Window (7.5.1) */
+	dp->dccps_swl = SUB48(ADD48(dp->dccps_gsr, 1), dp->dccps_r_seq_win / 4);
+	dp->dccps_swh = ADD48(dp->dccps_gsr, (3 * dp->dccps_r_seq_win) / 4);
 }
 
 static inline void dccp_update_gss(struct sock *sk, u64 seq)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
 
-	dp->dccps_awh = dp->dccps_gss = seq;
-	dccp_set_seqno(&dp->dccps_awl,
-		       (dp->dccps_gss -
-			dccp_msk(sk)->dccpms_sequence_window + 1));
+	dp->dccps_gss = seq;
+	/* Ack validity window depends on local Sequence Window value (7.5.1) */
+	dp->dccps_awl = SUB48(ADD48(dp->dccps_gss, 1), dp->dccps_l_seq_win);
+	dp->dccps_awh = dp->dccps_gss;
 }
 
 static inline int dccp_ack_pending(const struct sock *sk)
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -51,8 +51,17 @@ static int dccp_hdlr_ccid(struct sock *s
 
 static int dccp_hdlr_seq_win(struct sock *sk, u64 seq_win, bool rx)
 {
-	if (!rx)
-		dccp_msk(sk)->dccpms_sequence_window = seq_win;
+	struct dccp_sock *dp = dccp_sk(sk);
+
+	if (rx) {
+		dp->dccps_r_seq_win = seq_win;
+		/* propagate changes to update SWL/SWH */
+		dccp_update_gsr(sk, dp->dccps_gsr);
+	} else {
+		dp->dccps_l_seq_win = seq_win;
+		/* propagate changes to update AWL */
+		dccp_update_gss(sk, dp->dccps_gss);
+	}
 	return 0;
 }
 
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -42,11 +42,6 @@ struct inet_timewait_death_row dccp_deat
 
 EXPORT_SYMBOL_GPL(dccp_death_row);
 
-void dccp_minisock_init(struct dccp_minisock *dmsk)
-{
-	dmsk->dccpms_sequence_window = sysctl_dccp_feat_sequence_window;
-}
-
 void dccp_time_wait(struct sock *sk, int state, int timeo)
 {
 	struct inet_timewait_sock *tw = NULL;
@@ -110,7 +105,6 @@ struct sock *dccp_create_openreq_child(s
 		struct dccp_request_sock *dreq = dccp_rsk(req);
 		struct inet_connection_sock *newicsk = inet_csk(newsk);
 		struct dccp_sock *newdp = dccp_sk(newsk);
-		struct dccp_minisock *newdmsk = dccp_msk(newsk);
 
 		newdp->dccps_role	    = DCCP_ROLE_SERVER;
 		newdp->dccps_hc_rx_ackvec   = NULL;
@@ -128,10 +122,6 @@ struct sock *dccp_create_openreq_child(s
 		 *    Initialize S.GAR := S.ISS
 		 *    Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies
 		 */
-
-		/* See dccp_v4_conn_request */
-		newdmsk->dccpms_sequence_window = req->rcv_wnd;
-
 		newdp->dccps_gar = newdp->dccps_iss = dreq->dreq_iss;
 		dccp_update_gss(newsk, dreq->dreq_iss);
 
@@ -290,7 +280,6 @@ int dccp_reqsk_init(struct request_sock 
 	inet_rsk(req)->rmt_port	  = dccp_hdr(skb)->dccph_sport;
 	inet_rsk(req)->loc_port	  = dccp_hdr(skb)->dccph_dport;
 	inet_rsk(req)->acked	  = 0;
-	req->rcv_wnd		  = sysctl_dccp_feat_sequence_window;
 	dreq->dreq_timestamp_echo = 0;
 
 	/* inherit feature negotiation options from listening socket */
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -174,8 +174,6 @@ int dccp_init_sock(struct sock *sk, cons
 	struct dccp_sock *dp = dccp_sk(sk);
 	struct inet_connection_sock *icsk = inet_csk(sk);
 
-	dccp_minisock_init(&dp->dccps_minisock);
-
 	icsk->icsk_rto		= DCCP_TIMEOUT_INIT;
 	icsk->icsk_syn_retries	= sysctl_dccp_request_retries;
 	sk->sk_state		= DCCP_CLOSED;

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

* [PATCH 2/4] dccp: Implement both feature-local and feature-remote Sequence Window feature
@ 2009-01-17  9:36                                   ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-17  9:36 UTC (permalink / raw)
  To: dccp

This adds full support for local/remote Sequence Window feature, from which the 
  * sequence-number-validity (W) and 
  * acknowledgment-number-validity (W') windows 
derive as specified in RFC 4340, 7.5.3. 

Specifically, the following is contained in this patch:
  * integrated new socket fields into dccp_sk;
  * updated the update_gsr/gss routines with regard to these fields;
  * updated handler code: the Sequence Window feature is located at the TX side,
    so the local feature is meant if the handler-rx flag is false;
  * the initialisation of `rcv_wnd' in reqsk is removed, since
    - rcv_wnd is not used by the code anywhere;
    - sequence number checks are not done in the LISTEN state (cf. 7.5.3);
    - dccp_check_req checks the Ack number validity more rigorously;
  * the `struct dccp_minisock' became empty and is now removed.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
---
 Documentation/networking/dccp.txt |    3 ++-
 include/linux/dccp.h              |   24 ++++--------------------
 net/dccp/dccp.h                   |   16 +++++++---------
 net/dccp/feat.c                   |   13 +++++++++++--
 net/dccp/minisocks.c              |   11 -----------
 net/dccp/proto.c                  |    2 --
 6 files changed, 24 insertions(+), 45 deletions(-)

--- a/Documentation/networking/dccp.txt
+++ b/Documentation/networking/dccp.txt
@@ -141,7 +141,8 @@ rx_ccid = 2
 	Default CCID for the receiver-sender half-connection; see tx_ccid.
 
 seq_window = 100
-	The initial sequence window (sec. 7.5.2).
+	The initial sequence window (sec. 7.5.2) of the sender. This influences
+	the local ackno validity and the remote seqno validity windows (7.5.1).
 
 tx_qlen = 5
 	The size of the transmit buffer in packets. A value of 0 corresponds
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -364,19 +364,6 @@ static inline unsigned int dccp_hdr_len(
 #define DCCPF_INITIAL_SEND_NDP_COUNT		1
 
 /**
-  * struct dccp_minisock - Minimal DCCP connection representation
-  *
-  * Will be used to pass the state from dccp_request_sock to dccp_sock.
-  *
-  * @dccpms_sequence_window - Sequence Window Feature (section 7.5.2)
-  */
-struct dccp_minisock {
-	__u64			dccpms_sequence_window;
-};
-
-extern void dccp_minisock_init(struct dccp_minisock *dmsk);
-
-/**
  * struct dccp_request_sock  -  represent DCCP-specific connection request
  * @dreq_inet_rsk: structure inherited from
  * @dreq_iss: initial sequence number sent on the Response (RFC 4340, 7.1)
@@ -464,13 +451,14 @@ struct dccp_ackvec;
  * @dccps_timestamp_time - time of receiving latest @dccps_timestamp_echo
  * @dccps_l_ack_ratio - feature-local Ack Ratio
  * @dccps_r_ack_ratio - feature-remote Ack Ratio
+ * @dccps_l_seq_win - local Sequence Window (influences ack number validity)
+ * @dccps_r_seq_win - remote Sequence Window (influences seq number validity)
  * @dccps_pcslen - sender   partial checksum coverage (via sockopt)
  * @dccps_pcrlen - receiver partial checksum coverage (via sockopt)
  * @dccps_send_ndp_count - local Send NDP Count feature (7.7.2)
  * @dccps_ndp_count - number of Non Data Packets since last data packet
  * @dccps_mss_cache - current value of MSS (path MTU minus header sizes)
  * @dccps_rate_last - timestamp for rate-limiting DCCP-Sync (RFC 4340, 7.5.4)
- * @dccps_minisock - associated minisock (accessed via dccp_msk)
  * @dccps_featneg - tracks feature-negotiation state (mostly during handshake)
  * @dccps_hc_rx_ackvec - rx half connection ack vector
  * @dccps_hc_rx_ccid - CCID used for the receiver (or receiving half-connection)
@@ -504,12 +492,13 @@ struct dccp_sock {
 	__u32				dccps_timestamp_time;
 	__u16				dccps_l_ack_ratio;
 	__u16				dccps_r_ack_ratio;
+	__u64				dccps_l_seq_win:48;
+	__u64				dccps_r_seq_win:48;
 	__u8				dccps_pcslen:4;
 	__u8				dccps_pcrlen:4;
 	__u8				dccps_send_ndp_count:1;
 	__u64				dccps_ndp_count:48;
 	unsigned long			dccps_rate_last;
-	struct dccp_minisock		dccps_minisock;
 	struct list_head		dccps_featneg;
 	struct dccp_ackvec		*dccps_hc_rx_ackvec;
 	struct ccid			*dccps_hc_rx_ccid;
@@ -527,11 +516,6 @@ static inline struct dccp_sock *dccp_sk(
 	return (struct dccp_sock *)sk;
 }
 
-static inline struct dccp_minisock *dccp_msk(const struct sock *sk)
-{
-	return (struct dccp_minisock *)&dccp_sk(sk)->dccps_minisock;
-}
-
 static inline const char *dccp_role(const struct sock *sk)
 {
 	switch (dccp_sk(sk)->dccps_role) {
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -409,23 +409,21 @@ static inline void dccp_hdr_set_ack(stru
 static inline void dccp_update_gsr(struct sock *sk, u64 seq)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
-	const struct dccp_minisock *dmsk = dccp_msk(sk);
 
 	dp->dccps_gsr = seq;
-	dccp_set_seqno(&dp->dccps_swl,
-		       dp->dccps_gsr + 1 - (dmsk->dccpms_sequence_window / 4));
-	dccp_set_seqno(&dp->dccps_swh,
-		       dp->dccps_gsr + (3 * dmsk->dccpms_sequence_window) / 4);
+	/* Sequence validity window depends on remote Sequence Window (7.5.1) */
+	dp->dccps_swl = SUB48(ADD48(dp->dccps_gsr, 1), dp->dccps_r_seq_win / 4);
+	dp->dccps_swh = ADD48(dp->dccps_gsr, (3 * dp->dccps_r_seq_win) / 4);
 }
 
 static inline void dccp_update_gss(struct sock *sk, u64 seq)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
 
-	dp->dccps_awh = dp->dccps_gss = seq;
-	dccp_set_seqno(&dp->dccps_awl,
-		       (dp->dccps_gss -
-			dccp_msk(sk)->dccpms_sequence_window + 1));
+	dp->dccps_gss = seq;
+	/* Ack validity window depends on local Sequence Window value (7.5.1) */
+	dp->dccps_awl = SUB48(ADD48(dp->dccps_gss, 1), dp->dccps_l_seq_win);
+	dp->dccps_awh = dp->dccps_gss;
 }
 
 static inline int dccp_ack_pending(const struct sock *sk)
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -51,8 +51,17 @@ static int dccp_hdlr_ccid(struct sock *s
 
 static int dccp_hdlr_seq_win(struct sock *sk, u64 seq_win, bool rx)
 {
-	if (!rx)
-		dccp_msk(sk)->dccpms_sequence_window = seq_win;
+	struct dccp_sock *dp = dccp_sk(sk);
+
+	if (rx) {
+		dp->dccps_r_seq_win = seq_win;
+		/* propagate changes to update SWL/SWH */
+		dccp_update_gsr(sk, dp->dccps_gsr);
+	} else {
+		dp->dccps_l_seq_win = seq_win;
+		/* propagate changes to update AWL */
+		dccp_update_gss(sk, dp->dccps_gss);
+	}
 	return 0;
 }
 
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -42,11 +42,6 @@ struct inet_timewait_death_row dccp_deat
 
 EXPORT_SYMBOL_GPL(dccp_death_row);
 
-void dccp_minisock_init(struct dccp_minisock *dmsk)
-{
-	dmsk->dccpms_sequence_window = sysctl_dccp_feat_sequence_window;
-}
-
 void dccp_time_wait(struct sock *sk, int state, int timeo)
 {
 	struct inet_timewait_sock *tw = NULL;
@@ -110,7 +105,6 @@ struct sock *dccp_create_openreq_child(s
 		struct dccp_request_sock *dreq = dccp_rsk(req);
 		struct inet_connection_sock *newicsk = inet_csk(newsk);
 		struct dccp_sock *newdp = dccp_sk(newsk);
-		struct dccp_minisock *newdmsk = dccp_msk(newsk);
 
 		newdp->dccps_role	    = DCCP_ROLE_SERVER;
 		newdp->dccps_hc_rx_ackvec   = NULL;
@@ -128,10 +122,6 @@ struct sock *dccp_create_openreq_child(s
 		 *    Initialize S.GAR := S.ISS
 		 *    Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies
 		 */
-
-		/* See dccp_v4_conn_request */
-		newdmsk->dccpms_sequence_window = req->rcv_wnd;
-
 		newdp->dccps_gar = newdp->dccps_iss = dreq->dreq_iss;
 		dccp_update_gss(newsk, dreq->dreq_iss);
 
@@ -290,7 +280,6 @@ int dccp_reqsk_init(struct request_sock 
 	inet_rsk(req)->rmt_port	  = dccp_hdr(skb)->dccph_sport;
 	inet_rsk(req)->loc_port	  = dccp_hdr(skb)->dccph_dport;
 	inet_rsk(req)->acked	  = 0;
-	req->rcv_wnd		  = sysctl_dccp_feat_sequence_window;
 	dreq->dreq_timestamp_echo = 0;
 
 	/* inherit feature negotiation options from listening socket */
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -174,8 +174,6 @@ int dccp_init_sock(struct sock *sk, cons
 	struct dccp_sock *dp = dccp_sk(sk);
 	struct inet_connection_sock *icsk = inet_csk(sk);
 
-	dccp_minisock_init(&dp->dccps_minisock);
-
 	icsk->icsk_rto		= DCCP_TIMEOUT_INIT;
 	icsk->icsk_syn_retries	= sysctl_dccp_request_retries;
 	sk->sk_state		= DCCP_CLOSED;

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

* [PATCH 3/4] dccp: Initialisation and type-checking of feature sysctls
@ 2009-01-17  9:36                                     ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-17  9:36 UTC (permalink / raw)
  To: davem; +Cc: dccp, netdev, Gerrit Renker

This patch takes care of initialising and type-checking sysctls related to
feature negotiation. Type checking is important since some of the sysctls
now directly impact the feature-negotiation process.

The sysctls are initialised with the known default values for each feature.
For the type-checking the value constraints from RFC 4340 are used:

 * Sequence Window uses the specified Wmin=32, the maximum is ulong (4 bytes),
   tested and confirmed that it works up to 4294967295 - for Gbps speed;
 * Ack Ratio is between 0 .. 0xffff (2-byte unsigned integer);
 * CCIDs are between 0 .. 255;
 * request_retries, retries1, retries2 also between 0..255 for good measure;
 * tx_qlen is checked to be non-negative;
 * sync_ratelimit remains as before.

Notes: 
------
 1. Die s@sysctl_dccp_feat@sysctl_dccp@g since the sysctls are now in feat.c.
 2. As pointed out by Arnaldo, the pattern of type-checking repeats itself in
    other places, sometimes with exactly the same kind of definitions (e.g. 
    "static int zero;"). It may be a good idea (kernel janitors?) to consolidate
    type checking. For the sake of keeping the changeset small and in order not
    to affect other subsystems, I have not strived to generalise here.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
---
 include/linux/dccp.h |    8 --------
 net/dccp/dccp.h      |    3 ---
 net/dccp/feat.c      |   11 ++++++++---
 net/dccp/feat.h      |    8 ++++++++
 net/dccp/options.c   |    4 ----
 net/dccp/sysctl.c    |   43 ++++++++++++++++++++++++++++++-------------
 6 files changed, 46 insertions(+), 31 deletions(-)

--- a/net/dccp/feat.h
+++ b/net/dccp/feat.h
@@ -100,6 +100,13 @@ struct ccid_dependency {
 	u8	val;
 };
 
+/*
+ * Sysctls to seed defaults for feature negotiation
+ */
+extern unsigned long sysctl_dccp_sequence_window;
+extern int	     sysctl_dccp_rx_ccid;
+extern int	     sysctl_dccp_tx_ccid;
+
 #ifdef CONFIG_IP_DCCP_DEBUG
 extern const char *dccp_feat_typename(const u8 type);
 extern const char *dccp_feat_name(const u8 feat);
@@ -114,6 +121,7 @@ static inline void dccp_feat_debug(const
 #endif /* CONFIG_IP_DCCP_DEBUG */
 
 extern int  dccp_feat_init(struct sock *sk);
+extern void dccp_feat_initialise_sysctls(void);
 extern int  dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
 				  u8 const *list, u8 len);
 extern int  dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val);
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -25,6 +25,11 @@
 #include "ccid.h"
 #include "feat.h"
 
+/* feature-specific sysctls - initialised to the defaults from RFC 4340, 6.4 */
+unsigned long	sysctl_dccp_sequence_window __read_mostly = 100;
+int		sysctl_dccp_rx_ccid	    __read_mostly = 2,
+		sysctl_dccp_tx_ccid	    __read_mostly = 2;
+
 /*
  * Feature activation handlers.
  *
@@ -1146,7 +1151,7 @@ int dccp_feat_init(struct sock *sk)
 
 	/* Non-negotiable (NN) features */
 	rc = __feat_register_nn(fn, DCCPF_SEQUENCE_WINDOW, 0,
-				    sysctl_dccp_feat_sequence_window);
+				    sysctl_dccp_sequence_window);
 	if (rc)
 		return rc;
 
@@ -1172,8 +1177,8 @@ int dccp_feat_init(struct sock *sk)
 	    ccid_get_builtin_ccids(&rx.val, &rx.len))
 		return -ENOBUFS;
 
-	if (!dccp_feat_prefer(sysctl_dccp_feat_tx_ccid, tx.val, tx.len) ||
-	    !dccp_feat_prefer(sysctl_dccp_feat_rx_ccid, rx.val, rx.len))
+	if (!dccp_feat_prefer(sysctl_dccp_tx_ccid, tx.val, tx.len) ||
+	    !dccp_feat_prefer(sysctl_dccp_rx_ccid, rx.val, rx.len))
 		goto free_ccid_lists;
 
 	rc = __feat_register_sp(fn, DCCPF_CCID, true, false, tx.val, tx.len);
--- a/net/dccp/sysctl.c
+++ b/net/dccp/sysctl.c
@@ -18,55 +18,72 @@
 #error This file should not be compiled without CONFIG_SYSCTL defined
 #endif
 
+/* Boundary values */
+static int		zero     = 0,
+			u8_max   = 0xFF;
+static unsigned long	seqw_min = 32;
+
 static struct ctl_table dccp_default_table[] = {
 	{
 		.procname	= "seq_window",
-		.data		= &sysctl_dccp_feat_sequence_window,
-		.maxlen		= sizeof(sysctl_dccp_feat_sequence_window),
+		.data		= &sysctl_dccp_sequence_window,
+		.maxlen		= sizeof(sysctl_dccp_sequence_window),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_doulongvec_minmax,
+		.extra1		= &seqw_min,		/* RFC 4340, 7.5.2 */
 	},
 	{
 		.procname	= "rx_ccid",
-		.data		= &sysctl_dccp_feat_rx_ccid,
-		.maxlen		= sizeof(sysctl_dccp_feat_rx_ccid),
+		.data		= &sysctl_dccp_rx_ccid,
+		.maxlen		= sizeof(sysctl_dccp_rx_ccid),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &u8_max,		/* RFC 4340, 10. */
 	},
 	{
 		.procname	= "tx_ccid",
-		.data		= &sysctl_dccp_feat_tx_ccid,
-		.maxlen		= sizeof(sysctl_dccp_feat_tx_ccid),
+		.data		= &sysctl_dccp_tx_ccid,
+		.maxlen		= sizeof(sysctl_dccp_tx_ccid),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &u8_max,		/* RFC 4340, 10. */
 	},
 	{
 		.procname	= "request_retries",
 		.data		= &sysctl_dccp_request_retries,
 		.maxlen		= sizeof(sysctl_dccp_request_retries),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &u8_max,
 	},
 	{
 		.procname	= "retries1",
 		.data		= &sysctl_dccp_retries1,
 		.maxlen		= sizeof(sysctl_dccp_retries1),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &u8_max,
 	},
 	{
 		.procname	= "retries2",
 		.data		= &sysctl_dccp_retries2,
 		.maxlen		= sizeof(sysctl_dccp_retries2),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &u8_max,
 	},
 	{
 		.procname	= "tx_qlen",
 		.data		= &sysctl_dccp_tx_qlen,
 		.maxlen		= sizeof(sysctl_dccp_tx_qlen),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
 	},
 	{
 		.procname	= "sync_ratelimit",
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -355,14 +355,6 @@ static inline unsigned int dccp_hdr_len(
 	return __dccp_hdr_len(dccp_hdr(skb));
 }
 
-
-/* initial values for each feature */
-#define DCCPF_INITIAL_SEQUENCE_WINDOW		100
-#define DCCPF_INITIAL_ACK_RATIO			2
-#define DCCPF_INITIAL_CCID			DCCPC_CCID2
-/* FIXME: for now we're default to 1 but it should really be 0 */
-#define DCCPF_INITIAL_SEND_NDP_COUNT		1
-
 /**
  * struct dccp_request_sock  -  represent DCCP-specific connection request
  * @dreq_inet_rsk: structure inherited from
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -95,9 +95,6 @@ extern void dccp_time_wait(struct sock *
 extern int  sysctl_dccp_request_retries;
 extern int  sysctl_dccp_retries1;
 extern int  sysctl_dccp_retries2;
-extern int  sysctl_dccp_feat_sequence_window;
-extern int  sysctl_dccp_feat_rx_ccid;
-extern int  sysctl_dccp_feat_tx_ccid;
 extern int  sysctl_dccp_tx_qlen;
 extern int  sysctl_dccp_sync_ratelimit;
 
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -23,10 +23,6 @@
 #include "dccp.h"
 #include "feat.h"
 
-int sysctl_dccp_feat_sequence_window = DCCPF_INITIAL_SEQUENCE_WINDOW;
-int sysctl_dccp_feat_rx_ccid	      = DCCPF_INITIAL_CCID;
-int sysctl_dccp_feat_tx_ccid	      = DCCPF_INITIAL_CCID;
-
 u64 dccp_decode_value_var(const u8 *bf, const u8 len)
 {
 	u64 value = 0;

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

* [PATCH 3/4] dccp: Initialisation and type-checking of feature sysctls
@ 2009-01-17  9:36                                     ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-17  9:36 UTC (permalink / raw)
  To: dccp

This patch takes care of initialising and type-checking sysctls related to
feature negotiation. Type checking is important since some of the sysctls
now directly impact the feature-negotiation process.

The sysctls are initialised with the known default values for each feature.
For the type-checking the value constraints from RFC 4340 are used:

 * Sequence Window uses the specified Wmin2, the maximum is ulong (4 bytes),
   tested and confirmed that it works up to 4294967295 - for Gbps speed;
 * Ack Ratio is between 0 .. 0xffff (2-byte unsigned integer);
 * CCIDs are between 0 .. 255;
 * request_retries, retries1, retries2 also between 0..255 for good measure;
 * tx_qlen is checked to be non-negative;
 * sync_ratelimit remains as before.

Notes: 
------
 1. Die s@sysctl_dccp_feat@sysctl_dccp@g since the sysctls are now in feat.c.
 2. As pointed out by Arnaldo, the pattern of type-checking repeats itself in
    other places, sometimes with exactly the same kind of definitions (e.g. 
    "static int zero;"). It may be a good idea (kernel janitors?) to consolidate
    type checking. For the sake of keeping the changeset small and in order not
    to affect other subsystems, I have not strived to generalise here.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
---
 include/linux/dccp.h |    8 --------
 net/dccp/dccp.h      |    3 ---
 net/dccp/feat.c      |   11 ++++++++---
 net/dccp/feat.h      |    8 ++++++++
 net/dccp/options.c   |    4 ----
 net/dccp/sysctl.c    |   43 ++++++++++++++++++++++++++++++-------------
 6 files changed, 46 insertions(+), 31 deletions(-)

--- a/net/dccp/feat.h
+++ b/net/dccp/feat.h
@@ -100,6 +100,13 @@ struct ccid_dependency {
 	u8	val;
 };
 
+/*
+ * Sysctls to seed defaults for feature negotiation
+ */
+extern unsigned long sysctl_dccp_sequence_window;
+extern int	     sysctl_dccp_rx_ccid;
+extern int	     sysctl_dccp_tx_ccid;
+
 #ifdef CONFIG_IP_DCCP_DEBUG
 extern const char *dccp_feat_typename(const u8 type);
 extern const char *dccp_feat_name(const u8 feat);
@@ -114,6 +121,7 @@ static inline void dccp_feat_debug(const
 #endif /* CONFIG_IP_DCCP_DEBUG */
 
 extern int  dccp_feat_init(struct sock *sk);
+extern void dccp_feat_initialise_sysctls(void);
 extern int  dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
 				  u8 const *list, u8 len);
 extern int  dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val);
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -25,6 +25,11 @@
 #include "ccid.h"
 #include "feat.h"
 
+/* feature-specific sysctls - initialised to the defaults from RFC 4340, 6.4 */
+unsigned long	sysctl_dccp_sequence_window __read_mostly = 100;
+int		sysctl_dccp_rx_ccid	    __read_mostly = 2,
+		sysctl_dccp_tx_ccid	    __read_mostly = 2;
+
 /*
  * Feature activation handlers.
  *
@@ -1146,7 +1151,7 @@ int dccp_feat_init(struct sock *sk)
 
 	/* Non-negotiable (NN) features */
 	rc = __feat_register_nn(fn, DCCPF_SEQUENCE_WINDOW, 0,
-				    sysctl_dccp_feat_sequence_window);
+				    sysctl_dccp_sequence_window);
 	if (rc)
 		return rc;
 
@@ -1172,8 +1177,8 @@ int dccp_feat_init(struct sock *sk)
 	    ccid_get_builtin_ccids(&rx.val, &rx.len))
 		return -ENOBUFS;
 
-	if (!dccp_feat_prefer(sysctl_dccp_feat_tx_ccid, tx.val, tx.len) ||
-	    !dccp_feat_prefer(sysctl_dccp_feat_rx_ccid, rx.val, rx.len))
+	if (!dccp_feat_prefer(sysctl_dccp_tx_ccid, tx.val, tx.len) ||
+	    !dccp_feat_prefer(sysctl_dccp_rx_ccid, rx.val, rx.len))
 		goto free_ccid_lists;
 
 	rc = __feat_register_sp(fn, DCCPF_CCID, true, false, tx.val, tx.len);
--- a/net/dccp/sysctl.c
+++ b/net/dccp/sysctl.c
@@ -18,55 +18,72 @@
 #error This file should not be compiled without CONFIG_SYSCTL defined
 #endif
 
+/* Boundary values */
+static int		zero     = 0,
+			u8_max   = 0xFF;
+static unsigned long	seqw_min = 32;
+
 static struct ctl_table dccp_default_table[] = {
 	{
 		.procname	= "seq_window",
-		.data		= &sysctl_dccp_feat_sequence_window,
-		.maxlen		= sizeof(sysctl_dccp_feat_sequence_window),
+		.data		= &sysctl_dccp_sequence_window,
+		.maxlen		= sizeof(sysctl_dccp_sequence_window),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_doulongvec_minmax,
+		.extra1		= &seqw_min,		/* RFC 4340, 7.5.2 */
 	},
 	{
 		.procname	= "rx_ccid",
-		.data		= &sysctl_dccp_feat_rx_ccid,
-		.maxlen		= sizeof(sysctl_dccp_feat_rx_ccid),
+		.data		= &sysctl_dccp_rx_ccid,
+		.maxlen		= sizeof(sysctl_dccp_rx_ccid),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &u8_max,		/* RFC 4340, 10. */
 	},
 	{
 		.procname	= "tx_ccid",
-		.data		= &sysctl_dccp_feat_tx_ccid,
-		.maxlen		= sizeof(sysctl_dccp_feat_tx_ccid),
+		.data		= &sysctl_dccp_tx_ccid,
+		.maxlen		= sizeof(sysctl_dccp_tx_ccid),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &u8_max,		/* RFC 4340, 10. */
 	},
 	{
 		.procname	= "request_retries",
 		.data		= &sysctl_dccp_request_retries,
 		.maxlen		= sizeof(sysctl_dccp_request_retries),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &u8_max,
 	},
 	{
 		.procname	= "retries1",
 		.data		= &sysctl_dccp_retries1,
 		.maxlen		= sizeof(sysctl_dccp_retries1),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &u8_max,
 	},
 	{
 		.procname	= "retries2",
 		.data		= &sysctl_dccp_retries2,
 		.maxlen		= sizeof(sysctl_dccp_retries2),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &u8_max,
 	},
 	{
 		.procname	= "tx_qlen",
 		.data		= &sysctl_dccp_tx_qlen,
 		.maxlen		= sizeof(sysctl_dccp_tx_qlen),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
 	},
 	{
 		.procname	= "sync_ratelimit",
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -355,14 +355,6 @@ static inline unsigned int dccp_hdr_len(
 	return __dccp_hdr_len(dccp_hdr(skb));
 }
 
-
-/* initial values for each feature */
-#define DCCPF_INITIAL_SEQUENCE_WINDOW		100
-#define DCCPF_INITIAL_ACK_RATIO			2
-#define DCCPF_INITIAL_CCID			DCCPC_CCID2
-/* FIXME: for now we're default to 1 but it should really be 0 */
-#define DCCPF_INITIAL_SEND_NDP_COUNT		1
-
 /**
  * struct dccp_request_sock  -  represent DCCP-specific connection request
  * @dreq_inet_rsk: structure inherited from
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -95,9 +95,6 @@ extern void dccp_time_wait(struct sock *
 extern int  sysctl_dccp_request_retries;
 extern int  sysctl_dccp_retries1;
 extern int  sysctl_dccp_retries2;
-extern int  sysctl_dccp_feat_sequence_window;
-extern int  sysctl_dccp_feat_rx_ccid;
-extern int  sysctl_dccp_feat_tx_ccid;
 extern int  sysctl_dccp_tx_qlen;
 extern int  sysctl_dccp_sync_ratelimit;
 
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -23,10 +23,6 @@
 #include "dccp.h"
 #include "feat.h"
 
-int sysctl_dccp_feat_sequence_window = DCCPF_INITIAL_SEQUENCE_WINDOW;
-int sysctl_dccp_feat_rx_ccid	      = DCCPF_INITIAL_CCID;
-int sysctl_dccp_feat_tx_ccid	      = DCCPF_INITIAL_CCID;
-
 u64 dccp_decode_value_var(const u8 *bf, const u8 len)
 {
 	u64 value = 0;

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

* [PATCH 4/4] dccp: Debugging functions for feature negotiation
@ 2009-01-17  9:36                                       ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-17  9:36 UTC (permalink / raw)
  To: davem; +Cc: dccp, netdev, Gerrit Renker

Since all feature-negotiation processing now takes place in feat.c, functions
for producing verbose debugging output are concentrated there.

New functions to print out values, entry records, and options are provided,
and also a macro is defined to not always have the function name in the
output line.

Thanks a lot to Wei Yongjun and Giuseppe Galeota for help and discussion with an
earlier revision of this patch.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
---
 net/dccp/dccp.h    |    2 
 net/dccp/feat.c    |  149 ++++++++++++++++++++++++++++++++++++++---------------
 net/dccp/feat.h    |   13 ----
 net/dccp/options.c |    4 -
 4 files changed, 109 insertions(+), 59 deletions(-)

--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -42,9 +42,11 @@
 extern int dccp_debug;
 #define dccp_pr_debug(format, a...)	  DCCP_PR_DEBUG(dccp_debug, format, ##a)
 #define dccp_pr_debug_cat(format, a...)   DCCP_PRINTK(dccp_debug, format, ##a)
+#define dccp_debug(fmt, a...)		  dccp_pr_debug_cat(KERN_DEBUG fmt, ##a)
 #else
 #define dccp_pr_debug(format, a...)
 #define dccp_pr_debug_cat(format, a...)
+#define dccp_debug(format, a...)
 #endif
 
 extern struct inet_hashinfo dccp_hashinfo;
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -208,6 +208,100 @@ static int dccp_feat_default_value(u8 fe
 	return idx < 0 ? 0 : dccp_feat_table[idx].default_value;
 }
 
+/*
+ *	Debugging and verbose-printing section
+ */
+static const char *dccp_feat_fname(const u8 feat)
+{
+	static const char *feature_names[] = {
+		[DCCPF_RESERVED]	= "Reserved",
+		[DCCPF_CCID]		= "CCID",
+		[DCCPF_SHORT_SEQNOS]	= "Allow Short Seqnos",
+		[DCCPF_SEQUENCE_WINDOW]	= "Sequence Window",
+		[DCCPF_ECN_INCAPABLE]	= "ECN Incapable",
+		[DCCPF_ACK_RATIO]	= "Ack Ratio",
+		[DCCPF_SEND_ACK_VECTOR]	= "Send ACK Vector",
+		[DCCPF_SEND_NDP_COUNT]	= "Send NDP Count",
+		[DCCPF_MIN_CSUM_COVER]	= "Min. Csum Coverage",
+		[DCCPF_DATA_CHECKSUM]	= "Send Data Checksum",
+	};
+	if (feat > DCCPF_DATA_CHECKSUM && feat < DCCPF_MIN_CCID_SPECIFIC)
+		return feature_names[DCCPF_RESERVED];
+
+	if (feat ==  DCCPF_SEND_LEV_RATE)
+		return "Send Loss Event Rate";
+	if (feat >= DCCPF_MIN_CCID_SPECIFIC)
+		return "CCID-specific";
+
+	return feature_names[feat];
+}
+
+static const char *dccp_feat_sname[] = { "DEFAULT", "INITIALISING", "CHANGING",
+					 "UNSTABLE", "STABLE" };
+
+#ifdef CONFIG_IP_DCCP_DEBUG
+static const char *dccp_feat_oname(const u8 opt)
+{
+	switch (opt) {
+	case DCCPO_CHANGE_L:  return "Change_L";
+	case DCCPO_CONFIRM_L: return "Confirm_L";
+	case DCCPO_CHANGE_R:  return "Change_R";
+	case DCCPO_CONFIRM_R: return "Confirm_R";
+	}
+	return NULL;
+}
+
+static void dccp_feat_printval(u8 feat_num, dccp_feat_val const *val)
+{
+	u8 i, type = dccp_feat_type(feat_num);
+
+	if (val == NULL || (type == FEAT_SP && val->sp.vec == NULL))
+		dccp_pr_debug_cat("(NULL)");
+	else if (type == FEAT_SP)
+		for (i = 0; i < val->sp.len; i++)
+			dccp_pr_debug_cat("%s%u", i ? " " : "", val->sp.vec[i]);
+	else if (type == FEAT_NN)
+		dccp_pr_debug_cat("%llu", (unsigned long long)val->nn);
+	else
+		dccp_pr_debug_cat("unknown type %u", type);
+}
+
+static void dccp_feat_printvals(u8 feat_num, u8 *list, u8 len)
+{
+	u8 type = dccp_feat_type(feat_num);
+	dccp_feat_val fval = { .sp.vec = list, .sp.len = len };
+
+	if (type == FEAT_NN)
+		fval.nn = dccp_decode_value_var(list, len);
+	dccp_feat_printval(feat_num, &fval);
+}
+
+static void dccp_feat_print_entry(struct dccp_feat_entry const *entry)
+{
+	dccp_debug("   * %s %s = ", entry->is_local ? "local" : "remote",
+				    dccp_feat_fname(entry->feat_num));
+	dccp_feat_printval(entry->feat_num, &entry->val);
+	dccp_pr_debug_cat(", state=%s %s\n", dccp_feat_sname[entry->state],
+			  entry->needs_confirm ? "(Confirm pending)" : "");
+}
+
+#define dccp_feat_print_opt(opt, feat, val, len, mandatory)	do {	      \
+	dccp_pr_debug("%s(%s, ", dccp_feat_oname(opt), dccp_feat_fname(feat));\
+	dccp_feat_printvals(feat, val, len);				      \
+	dccp_pr_debug_cat(") %s\n", mandatory ? "!" : "");	} while (0)
+
+#define dccp_feat_print_fnlist(fn_list)  {		\
+	const struct dccp_feat_entry *___entry;		\
+							\
+	dccp_pr_debug("List Dump:\n");			\
+	list_for_each_entry(___entry, fn_list, node)	\
+		dccp_feat_print_entry(___entry);	\
+}
+#else	/* ! CONFIG_IP_DCCP_DEBUG */
+#define dccp_feat_print_opt(opt, feat, val, len, mandatory)
+#define dccp_feat_print_fnlist(fn_list)
+#endif
+
 static int __dccp_feat_activate(struct sock *sk, const int idx,
 				const bool is_local, dccp_feat_val const *fval)
 {
@@ -240,6 +334,10 @@ static int __dccp_feat_activate(struct s
 	/* Location is RX if this is a local-RX or remote-TX feature */
 	rx = (is_local == (dccp_feat_table[idx].rxtx == FEAT_AT_RX));
 
+	dccp_debug("   -> activating %s %s, %sval=%llu\n", rx ? "RX" : "TX",
+		   dccp_feat_fname(dccp_feat_table[idx].feat_num),
+		   fval ? "" : "default ",  (unsigned long long)val);
+
 	return dccp_feat_table[idx].activation_hdlr(sk, val, rx);
 }
 
@@ -544,6 +642,7 @@ int dccp_feat_insert_opts(struct dccp_so
 				return -1;
 			}
 		}
+		dccp_feat_print_opt(opt, pos->feat_num, ptr, len, 0);
 
 		if (dccp_insert_fn_opt(skb, opt, pos->feat_num, ptr, len, rpt))
 			return -1;
@@ -797,6 +896,7 @@ int dccp_feat_finalise_settings(struct d
 	while (i--)
 		if (ccids[i] > 0 && dccp_feat_propagate_ccid(fn, ccids[i], i))
 			return -1;
+	dccp_feat_print_fnlist(fn);
 	return 0;
 }
 
@@ -915,6 +1015,8 @@ static u8 dccp_feat_change_recv(struct l
 	if (len == 0 || type == FEAT_UNKNOWN)		/* 6.1 and 6.6.8 */
 		goto unknown_feature_or_value;
 
+	dccp_feat_print_opt(opt, feat, val, len, is_mandatory);
+
 	/*
 	 *	Negotiation of NN features: Change R is invalid, so there is no
 	 *	simultaneous negotiation; hence we do not look up in the list.
@@ -1020,6 +1122,8 @@ static u8 dccp_feat_confirm_recv(struct 
 	const bool local = (opt == DCCPO_CONFIRM_R);
 	struct dccp_feat_entry *entry = dccp_feat_list_lookup(fn, feat, local);
 
+	dccp_feat_print_opt(opt, feat, val, len, is_mandatory);
+
 	if (entry == NULL) {	/* nothing queued: ignore or handle error */
 		if (is_mandatory && type == FEAT_UNKNOWN)
 			return DCCP_RESET_CODE_MANDATORY_ERROR;
@@ -1217,9 +1321,10 @@ int dccp_feat_activate_values(struct soc
 			goto activation_failed;
 		}
 		if (cur->state != FEAT_STABLE) {
-			DCCP_CRIT("Negotiation of %s %u failed in state %u",
+			DCCP_CRIT("Negotiation of %s %s failed in state %s",
 				  cur->is_local ? "local" : "remote",
-				  cur->feat_num, cur->state);
+				  dccp_feat_fname(cur->feat_num),
+				  dccp_feat_sname[cur->state]);
 			goto activation_failed;
 		}
 		fvals[idx][cur->is_local] = &cur->val;
@@ -1260,43 +1365,3 @@ activation_failed:
 	dp->dccps_hc_rx_ackvec = NULL;
 	return -1;
 }
-
-#ifdef CONFIG_IP_DCCP_DEBUG
-const char *dccp_feat_typename(const u8 type)
-{
-	switch(type) {
-	case DCCPO_CHANGE_L:  return("ChangeL");
-	case DCCPO_CONFIRM_L: return("ConfirmL");
-	case DCCPO_CHANGE_R:  return("ChangeR");
-	case DCCPO_CONFIRM_R: return("ConfirmR");
-	/* the following case must not appear in feature negotation  */
-	default:	      dccp_pr_debug("unknown type %d [BUG!]\n", type);
-	}
-	return NULL;
-}
-
-const char *dccp_feat_name(const u8 feat)
-{
-	static const char *feature_names[] = {
-		[DCCPF_RESERVED]	= "Reserved",
-		[DCCPF_CCID]		= "CCID",
-		[DCCPF_SHORT_SEQNOS]	= "Allow Short Seqnos",
-		[DCCPF_SEQUENCE_WINDOW]	= "Sequence Window",
-		[DCCPF_ECN_INCAPABLE]	= "ECN Incapable",
-		[DCCPF_ACK_RATIO]	= "Ack Ratio",
-		[DCCPF_SEND_ACK_VECTOR]	= "Send ACK Vector",
-		[DCCPF_SEND_NDP_COUNT]	= "Send NDP Count",
-		[DCCPF_MIN_CSUM_COVER]	= "Min. Csum Coverage",
-		[DCCPF_DATA_CHECKSUM]	= "Send Data Checksum",
-	};
-	if (feat > DCCPF_DATA_CHECKSUM && feat < DCCPF_MIN_CCID_SPECIFIC)
-		return feature_names[DCCPF_RESERVED];
-
-	if (feat ==  DCCPF_SEND_LEV_RATE)
-		return "Send Loss Event Rate";
-	if (feat >= DCCPF_MIN_CCID_SPECIFIC)
-		return "CCID-specific";
-
-	return feature_names[feat];
-}
-#endif /* CONFIG_IP_DCCP_DEBUG */
--- a/net/dccp/feat.h
+++ b/net/dccp/feat.h
@@ -107,19 +107,6 @@ extern unsigned long sysctl_dccp_sequenc
 extern int	     sysctl_dccp_rx_ccid;
 extern int	     sysctl_dccp_tx_ccid;
 
-#ifdef CONFIG_IP_DCCP_DEBUG
-extern const char *dccp_feat_typename(const u8 type);
-extern const char *dccp_feat_name(const u8 feat);
-
-static inline void dccp_feat_debug(const u8 type, const u8 feat, const u8 val)
-{
-	dccp_pr_debug("%s(%s (%d), %d)\n", dccp_feat_typename(type),
-					   dccp_feat_name(feat), feat, val);
-}
-#else
-#define dccp_feat_debug(type, feat, val)
-#endif /* CONFIG_IP_DCCP_DEBUG */
-
 extern int  dccp_feat_init(struct sock *sk);
 extern void dccp_feat_initialise_sysctls(void);
 extern int  dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -498,10 +498,6 @@ int dccp_insert_fn_opt(struct sk_buff *s
 		*to++ = *val;
 	if (len)
 		memcpy(to, val, len);
-
-	dccp_pr_debug("%s(%s (%d), ...), length %d\n",
-		      dccp_feat_typename(type),
-		      dccp_feat_name(feat), feat, len);
 	return 0;
 }
 

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

* [PATCH 4/4] dccp: Debugging functions for feature negotiation
@ 2009-01-17  9:36                                       ` Gerrit Renker
  0 siblings, 0 replies; 72+ messages in thread
From: Gerrit Renker @ 2009-01-17  9:36 UTC (permalink / raw)
  To: dccp

Since all feature-negotiation processing now takes place in feat.c, functions
for producing verbose debugging output are concentrated there.

New functions to print out values, entry records, and options are provided,
and also a macro is defined to not always have the function name in the
output line.

Thanks a lot to Wei Yongjun and Giuseppe Galeota for help and discussion with an
earlier revision of this patch.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
---
 net/dccp/dccp.h    |    2 
 net/dccp/feat.c    |  149 ++++++++++++++++++++++++++++++++++++++---------------
 net/dccp/feat.h    |   13 ----
 net/dccp/options.c |    4 -
 4 files changed, 109 insertions(+), 59 deletions(-)

--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -42,9 +42,11 @@
 extern int dccp_debug;
 #define dccp_pr_debug(format, a...)	  DCCP_PR_DEBUG(dccp_debug, format, ##a)
 #define dccp_pr_debug_cat(format, a...)   DCCP_PRINTK(dccp_debug, format, ##a)
+#define dccp_debug(fmt, a...)		  dccp_pr_debug_cat(KERN_DEBUG fmt, ##a)
 #else
 #define dccp_pr_debug(format, a...)
 #define dccp_pr_debug_cat(format, a...)
+#define dccp_debug(format, a...)
 #endif
 
 extern struct inet_hashinfo dccp_hashinfo;
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -208,6 +208,100 @@ static int dccp_feat_default_value(u8 fe
 	return idx < 0 ? 0 : dccp_feat_table[idx].default_value;
 }
 
+/*
+ *	Debugging and verbose-printing section
+ */
+static const char *dccp_feat_fname(const u8 feat)
+{
+	static const char *feature_names[] = {
+		[DCCPF_RESERVED]	= "Reserved",
+		[DCCPF_CCID]		= "CCID",
+		[DCCPF_SHORT_SEQNOS]	= "Allow Short Seqnos",
+		[DCCPF_SEQUENCE_WINDOW]	= "Sequence Window",
+		[DCCPF_ECN_INCAPABLE]	= "ECN Incapable",
+		[DCCPF_ACK_RATIO]	= "Ack Ratio",
+		[DCCPF_SEND_ACK_VECTOR]	= "Send ACK Vector",
+		[DCCPF_SEND_NDP_COUNT]	= "Send NDP Count",
+		[DCCPF_MIN_CSUM_COVER]	= "Min. Csum Coverage",
+		[DCCPF_DATA_CHECKSUM]	= "Send Data Checksum",
+	};
+	if (feat > DCCPF_DATA_CHECKSUM && feat < DCCPF_MIN_CCID_SPECIFIC)
+		return feature_names[DCCPF_RESERVED];
+
+	if (feat =  DCCPF_SEND_LEV_RATE)
+		return "Send Loss Event Rate";
+	if (feat >= DCCPF_MIN_CCID_SPECIFIC)
+		return "CCID-specific";
+
+	return feature_names[feat];
+}
+
+static const char *dccp_feat_sname[] = { "DEFAULT", "INITIALISING", "CHANGING",
+					 "UNSTABLE", "STABLE" };
+
+#ifdef CONFIG_IP_DCCP_DEBUG
+static const char *dccp_feat_oname(const u8 opt)
+{
+	switch (opt) {
+	case DCCPO_CHANGE_L:  return "Change_L";
+	case DCCPO_CONFIRM_L: return "Confirm_L";
+	case DCCPO_CHANGE_R:  return "Change_R";
+	case DCCPO_CONFIRM_R: return "Confirm_R";
+	}
+	return NULL;
+}
+
+static void dccp_feat_printval(u8 feat_num, dccp_feat_val const *val)
+{
+	u8 i, type = dccp_feat_type(feat_num);
+
+	if (val = NULL || (type = FEAT_SP && val->sp.vec = NULL))
+		dccp_pr_debug_cat("(NULL)");
+	else if (type = FEAT_SP)
+		for (i = 0; i < val->sp.len; i++)
+			dccp_pr_debug_cat("%s%u", i ? " " : "", val->sp.vec[i]);
+	else if (type = FEAT_NN)
+		dccp_pr_debug_cat("%llu", (unsigned long long)val->nn);
+	else
+		dccp_pr_debug_cat("unknown type %u", type);
+}
+
+static void dccp_feat_printvals(u8 feat_num, u8 *list, u8 len)
+{
+	u8 type = dccp_feat_type(feat_num);
+	dccp_feat_val fval = { .sp.vec = list, .sp.len = len };
+
+	if (type = FEAT_NN)
+		fval.nn = dccp_decode_value_var(list, len);
+	dccp_feat_printval(feat_num, &fval);
+}
+
+static void dccp_feat_print_entry(struct dccp_feat_entry const *entry)
+{
+	dccp_debug("   * %s %s = ", entry->is_local ? "local" : "remote",
+				    dccp_feat_fname(entry->feat_num));
+	dccp_feat_printval(entry->feat_num, &entry->val);
+	dccp_pr_debug_cat(", state=%s %s\n", dccp_feat_sname[entry->state],
+			  entry->needs_confirm ? "(Confirm pending)" : "");
+}
+
+#define dccp_feat_print_opt(opt, feat, val, len, mandatory)	do {	      \
+	dccp_pr_debug("%s(%s, ", dccp_feat_oname(opt), dccp_feat_fname(feat));\
+	dccp_feat_printvals(feat, val, len);				      \
+	dccp_pr_debug_cat(") %s\n", mandatory ? "!" : "");	} while (0)
+
+#define dccp_feat_print_fnlist(fn_list)  {		\
+	const struct dccp_feat_entry *___entry;		\
+							\
+	dccp_pr_debug("List Dump:\n");			\
+	list_for_each_entry(___entry, fn_list, node)	\
+		dccp_feat_print_entry(___entry);	\
+}
+#else	/* ! CONFIG_IP_DCCP_DEBUG */
+#define dccp_feat_print_opt(opt, feat, val, len, mandatory)
+#define dccp_feat_print_fnlist(fn_list)
+#endif
+
 static int __dccp_feat_activate(struct sock *sk, const int idx,
 				const bool is_local, dccp_feat_val const *fval)
 {
@@ -240,6 +334,10 @@ static int __dccp_feat_activate(struct s
 	/* Location is RX if this is a local-RX or remote-TX feature */
 	rx = (is_local = (dccp_feat_table[idx].rxtx = FEAT_AT_RX));
 
+	dccp_debug("   -> activating %s %s, %sval=%llu\n", rx ? "RX" : "TX",
+		   dccp_feat_fname(dccp_feat_table[idx].feat_num),
+		   fval ? "" : "default ",  (unsigned long long)val);
+
 	return dccp_feat_table[idx].activation_hdlr(sk, val, rx);
 }
 
@@ -544,6 +642,7 @@ int dccp_feat_insert_opts(struct dccp_so
 				return -1;
 			}
 		}
+		dccp_feat_print_opt(opt, pos->feat_num, ptr, len, 0);
 
 		if (dccp_insert_fn_opt(skb, opt, pos->feat_num, ptr, len, rpt))
 			return -1;
@@ -797,6 +896,7 @@ int dccp_feat_finalise_settings(struct d
 	while (i--)
 		if (ccids[i] > 0 && dccp_feat_propagate_ccid(fn, ccids[i], i))
 			return -1;
+	dccp_feat_print_fnlist(fn);
 	return 0;
 }
 
@@ -915,6 +1015,8 @@ static u8 dccp_feat_change_recv(struct l
 	if (len = 0 || type = FEAT_UNKNOWN)		/* 6.1 and 6.6.8 */
 		goto unknown_feature_or_value;
 
+	dccp_feat_print_opt(opt, feat, val, len, is_mandatory);
+
 	/*
 	 *	Negotiation of NN features: Change R is invalid, so there is no
 	 *	simultaneous negotiation; hence we do not look up in the list.
@@ -1020,6 +1122,8 @@ static u8 dccp_feat_confirm_recv(struct 
 	const bool local = (opt = DCCPO_CONFIRM_R);
 	struct dccp_feat_entry *entry = dccp_feat_list_lookup(fn, feat, local);
 
+	dccp_feat_print_opt(opt, feat, val, len, is_mandatory);
+
 	if (entry = NULL) {	/* nothing queued: ignore or handle error */
 		if (is_mandatory && type = FEAT_UNKNOWN)
 			return DCCP_RESET_CODE_MANDATORY_ERROR;
@@ -1217,9 +1321,10 @@ int dccp_feat_activate_values(struct soc
 			goto activation_failed;
 		}
 		if (cur->state != FEAT_STABLE) {
-			DCCP_CRIT("Negotiation of %s %u failed in state %u",
+			DCCP_CRIT("Negotiation of %s %s failed in state %s",
 				  cur->is_local ? "local" : "remote",
-				  cur->feat_num, cur->state);
+				  dccp_feat_fname(cur->feat_num),
+				  dccp_feat_sname[cur->state]);
 			goto activation_failed;
 		}
 		fvals[idx][cur->is_local] = &cur->val;
@@ -1260,43 +1365,3 @@ activation_failed:
 	dp->dccps_hc_rx_ackvec = NULL;
 	return -1;
 }
-
-#ifdef CONFIG_IP_DCCP_DEBUG
-const char *dccp_feat_typename(const u8 type)
-{
-	switch(type) {
-	case DCCPO_CHANGE_L:  return("ChangeL");
-	case DCCPO_CONFIRM_L: return("ConfirmL");
-	case DCCPO_CHANGE_R:  return("ChangeR");
-	case DCCPO_CONFIRM_R: return("ConfirmR");
-	/* the following case must not appear in feature negotation  */
-	default:	      dccp_pr_debug("unknown type %d [BUG!]\n", type);
-	}
-	return NULL;
-}
-
-const char *dccp_feat_name(const u8 feat)
-{
-	static const char *feature_names[] = {
-		[DCCPF_RESERVED]	= "Reserved",
-		[DCCPF_CCID]		= "CCID",
-		[DCCPF_SHORT_SEQNOS]	= "Allow Short Seqnos",
-		[DCCPF_SEQUENCE_WINDOW]	= "Sequence Window",
-		[DCCPF_ECN_INCAPABLE]	= "ECN Incapable",
-		[DCCPF_ACK_RATIO]	= "Ack Ratio",
-		[DCCPF_SEND_ACK_VECTOR]	= "Send ACK Vector",
-		[DCCPF_SEND_NDP_COUNT]	= "Send NDP Count",
-		[DCCPF_MIN_CSUM_COVER]	= "Min. Csum Coverage",
-		[DCCPF_DATA_CHECKSUM]	= "Send Data Checksum",
-	};
-	if (feat > DCCPF_DATA_CHECKSUM && feat < DCCPF_MIN_CCID_SPECIFIC)
-		return feature_names[DCCPF_RESERVED];
-
-	if (feat =  DCCPF_SEND_LEV_RATE)
-		return "Send Loss Event Rate";
-	if (feat >= DCCPF_MIN_CCID_SPECIFIC)
-		return "CCID-specific";
-
-	return feature_names[feat];
-}
-#endif /* CONFIG_IP_DCCP_DEBUG */
--- a/net/dccp/feat.h
+++ b/net/dccp/feat.h
@@ -107,19 +107,6 @@ extern unsigned long sysctl_dccp_sequenc
 extern int	     sysctl_dccp_rx_ccid;
 extern int	     sysctl_dccp_tx_ccid;
 
-#ifdef CONFIG_IP_DCCP_DEBUG
-extern const char *dccp_feat_typename(const u8 type);
-extern const char *dccp_feat_name(const u8 feat);
-
-static inline void dccp_feat_debug(const u8 type, const u8 feat, const u8 val)
-{
-	dccp_pr_debug("%s(%s (%d), %d)\n", dccp_feat_typename(type),
-					   dccp_feat_name(feat), feat, val);
-}
-#else
-#define dccp_feat_debug(type, feat, val)
-#endif /* CONFIG_IP_DCCP_DEBUG */
-
 extern int  dccp_feat_init(struct sock *sk);
 extern void dccp_feat_initialise_sysctls(void);
 extern int  dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -498,10 +498,6 @@ int dccp_insert_fn_opt(struct sk_buff *s
 		*to++ = *val;
 	if (len)
 		memcpy(to, val, len);
-
-	dccp_pr_debug("%s(%s (%d), ...), length %d\n",
-		      dccp_feat_typename(type),
-		      dccp_feat_name(feat), feat, len);
 	return 0;
 }
 

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

* Re: [PATCH 1/4] dccp: Initialisation framework for feature negotiation
  2009-01-17  9:36                                 ` Gerrit Renker
@ 2009-01-19  5:39                                   ` David Miller
  -1 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2009-01-19  5:39 UTC (permalink / raw)
  To: gerrit; +Cc: dccp, netdev

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Sat, 17 Jan 2009 10:36:30 +0100

> This initialises feature negotiation from two tables, which are in turn are
> initialised from sysctls.
> 
> As a novel feature, specifics of the implementation (e.g. that short seqnos
> and ECN are not yet available) are advertised for robustness.
> 
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
> Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>

Applied for 2.6.30.

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

* Re: [PATCH 1/4] dccp: Initialisation framework for feature
@ 2009-01-19  5:39                                   ` David Miller
  0 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2009-01-19  5:39 UTC (permalink / raw)
  To: dccp

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Sat, 17 Jan 2009 10:36:30 +0100

> This initialises feature negotiation from two tables, which are in turn are
> initialised from sysctls.
> 
> As a novel feature, specifics of the implementation (e.g. that short seqnos
> and ECN are not yet available) are advertised for robustness.
> 
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
> Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>

Applied for 2.6.30.

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

* Re: [PATCH 2/4] dccp: Implement both feature-local and feature-remote Sequence Window feature
  2009-01-17  9:36                                   ` Gerrit Renker
@ 2009-01-19  5:40                                     ` David Miller
  -1 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2009-01-19  5:40 UTC (permalink / raw)
  To: gerrit; +Cc: dccp, netdev

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Sat, 17 Jan 2009 10:36:31 +0100

> This adds full support for local/remote Sequence Window feature, from which the 
>   * sequence-number-validity (W) and 
>   * acknowledgment-number-validity (W') windows 
> derive as specified in RFC 4340, 7.5.3. 
> 
> Specifically, the following is contained in this patch:
>   * integrated new socket fields into dccp_sk;
>   * updated the update_gsr/gss routines with regard to these fields;
>   * updated handler code: the Sequence Window feature is located at the TX side,
>     so the local feature is meant if the handler-rx flag is false;
>   * the initialisation of `rcv_wnd' in reqsk is removed, since
>     - rcv_wnd is not used by the code anywhere;
>     - sequence number checks are not done in the LISTEN state (cf. 7.5.3);
>     - dccp_check_req checks the Ack number validity more rigorously;
>   * the `struct dccp_minisock' became empty and is now removed.
> 
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
> Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>

Applied for 2.6.30

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

* Re: [PATCH 2/4] dccp: Implement both feature-local and
@ 2009-01-19  5:40                                     ` David Miller
  0 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2009-01-19  5:40 UTC (permalink / raw)
  To: dccp

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Sat, 17 Jan 2009 10:36:31 +0100

> This adds full support for local/remote Sequence Window feature, from which the 
>   * sequence-number-validity (W) and 
>   * acknowledgment-number-validity (W') windows 
> derive as specified in RFC 4340, 7.5.3. 
> 
> Specifically, the following is contained in this patch:
>   * integrated new socket fields into dccp_sk;
>   * updated the update_gsr/gss routines with regard to these fields;
>   * updated handler code: the Sequence Window feature is located at the TX side,
>     so the local feature is meant if the handler-rx flag is false;
>   * the initialisation of `rcv_wnd' in reqsk is removed, since
>     - rcv_wnd is not used by the code anywhere;
>     - sequence number checks are not done in the LISTEN state (cf. 7.5.3);
>     - dccp_check_req checks the Ack number validity more rigorously;
>   * the `struct dccp_minisock' became empty and is now removed.
> 
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
> Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>

Applied for 2.6.30

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

* Re: [PATCH 3/4] dccp: Initialisation and type-checking of feature sysctls
  2009-01-17  9:36                                     ` Gerrit Renker
@ 2009-01-19  5:40                                       ` David Miller
  -1 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2009-01-19  5:40 UTC (permalink / raw)
  To: gerrit; +Cc: dccp, netdev

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Sat, 17 Jan 2009 10:36:32 +0100

> This patch takes care of initialising and type-checking sysctls related to
> feature negotiation. Type checking is important since some of the sysctls
> now directly impact the feature-negotiation process.
> 
> The sysctls are initialised with the known default values for each feature.
> For the type-checking the value constraints from RFC 4340 are used:
> 
>  * Sequence Window uses the specified Wmin=32, the maximum is ulong (4 bytes),
>    tested and confirmed that it works up to 4294967295 - for Gbps speed;
>  * Ack Ratio is between 0 .. 0xffff (2-byte unsigned integer);
>  * CCIDs are between 0 .. 255;
>  * request_retries, retries1, retries2 also between 0..255 for good measure;
>  * tx_qlen is checked to be non-negative;
>  * sync_ratelimit remains as before.
 ...
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
> Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>

Applied for 2.6.30

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

* Re: [PATCH 3/4] dccp: Initialisation and type-checking of feature
@ 2009-01-19  5:40                                       ` David Miller
  0 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2009-01-19  5:40 UTC (permalink / raw)
  To: dccp

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Sat, 17 Jan 2009 10:36:32 +0100

> This patch takes care of initialising and type-checking sysctls related to
> feature negotiation. Type checking is important since some of the sysctls
> now directly impact the feature-negotiation process.
> 
> The sysctls are initialised with the known default values for each feature.
> For the type-checking the value constraints from RFC 4340 are used:
> 
>  * Sequence Window uses the specified Wmin2, the maximum is ulong (4 bytes),
>    tested and confirmed that it works up to 4294967295 - for Gbps speed;
>  * Ack Ratio is between 0 .. 0xffff (2-byte unsigned integer);
>  * CCIDs are between 0 .. 255;
>  * request_retries, retries1, retries2 also between 0..255 for good measure;
>  * tx_qlen is checked to be non-negative;
>  * sync_ratelimit remains as before.
 ...
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
> Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>

Applied for 2.6.30

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

* Re: [PATCH 4/4] dccp: Debugging functions for feature negotiation
  2009-01-17  9:36                                       ` Gerrit Renker
@ 2009-01-19  5:40                                         ` David Miller
  -1 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2009-01-19  5:40 UTC (permalink / raw)
  To: gerrit; +Cc: dccp, netdev

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Sat, 17 Jan 2009 10:36:33 +0100

> Since all feature-negotiation processing now takes place in feat.c, functions
> for producing verbose debugging output are concentrated there.
> 
> New functions to print out values, entry records, and options are provided,
> and also a macro is defined to not always have the function name in the
> output line.
> 
> Thanks a lot to Wei Yongjun and Giuseppe Galeota for help and discussion with an
> earlier revision of this patch.
> 
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
> Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>

Applied for 2.6.30

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

* Re: [PATCH 4/4] dccp: Debugging functions for feature negotiation
@ 2009-01-19  5:40                                         ` David Miller
  0 siblings, 0 replies; 72+ messages in thread
From: David Miller @ 2009-01-19  5:40 UTC (permalink / raw)
  To: dccp

From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Sat, 17 Jan 2009 10:36:33 +0100

> Since all feature-negotiation processing now takes place in feat.c, functions
> for producing verbose debugging output are concentrated there.
> 
> New functions to print out values, entry records, and options are provided,
> and also a macro is defined to not always have the function name in the
> output line.
> 
> Thanks a lot to Wei Yongjun and Giuseppe Galeota for help and discussion with an
> earlier revision of this patch.
> 
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
> Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>

Applied for 2.6.30

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

end of thread, other threads:[~2009-01-19  5:40 UTC | newest]

Thread overview: 72+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-12-17 21:46 [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation Arnaldo Carvalho de Melo
2008-12-17 21:46 ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Arnaldo Carvalho de Melo
2008-12-18  5:21 ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation David Miller
2008-12-18  5:21   ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: David Miller
2008-12-18  5:33   ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation Gerrit Renker
2008-12-18  5:33     ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Gerrit Renker
2008-12-19  3:15     ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation David Miller
2008-12-19  3:15       ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: David Miller
2008-12-19  5:24       ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation Gerrit Renker
2008-12-19  5:24         ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Gerrit Renker
2008-12-19  6:28         ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation David Miller
2008-12-19  6:28           ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: David Miller
2008-12-19  7:56           ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation gerrit
2008-12-19  7:56             ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: gerrit
2008-12-20 23:51             ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation Arnaldo Carvalho de Melo
2008-12-20 23:51               ` [RFCv2][PATCH] static builtin CCIDs was Re: [PATCH 2/5] dccp: Arnaldo Carvalho de Melo
2008-12-20  8:08           ` [RFC] [Patch 0/4] dccp: Working prototype of integrating the modules Gerrit Renker
2008-12-20  8:08             ` [RFC] [Patch 0/4] dccp: Working prototype of integrating the Gerrit Renker
2008-12-20  8:08           ` [RFC] [Patch 1/4] dccp: Remove old CCID-module references Gerrit Renker
2008-12-20  8:08             ` Gerrit Renker
2008-12-20  8:08           ` [RFC] [Patch 2/4] dccp: Lockless use of CCID blocks Gerrit Renker
2008-12-20  8:08             ` Gerrit Renker
2008-12-21  0:32             ` Arnaldo Carvalho de Melo
2008-12-21  0:32               ` Arnaldo Carvalho de Melo
2008-12-23 17:08               ` Gerrit Renker
2008-12-23 17:08                 ` Gerrit Renker
2008-12-23 17:17               ` Gerrit Renker
2008-12-23 17:17                 ` Gerrit Renker
2009-01-01 10:49                 ` Gerrit Renker
2009-01-01 10:49                   ` Gerrit Renker
2009-01-03  7:30                   ` [Patch 0/3] " Gerrit Renker
2009-01-03  7:30                     ` Gerrit Renker
2009-01-03  7:30                     ` [PATCH 1/3] dccp: Lockless integration of CCID congestion-control plugins Gerrit Renker
2009-01-03  7:30                       ` Gerrit Renker
2009-01-03  7:30                       ` [PATCH 2/3] dccp: Clean up ccid.c after integration of CCID plugins Gerrit Renker
2009-01-03  7:30                         ` Gerrit Renker
2009-01-03  7:30                         ` [PATCH 3/3] dccp: Integrate the TFRC library with DCCP Gerrit Renker
2009-01-03  7:30                           ` Gerrit Renker
2009-01-05  5:46                           ` David Miller
2009-01-05  5:46                             ` David Miller
2009-01-17  9:36                             ` [PATCH 0/4] dccp: Completing feature negotiation Gerrit Renker
2009-01-17  9:36                               ` Gerrit Renker
2009-01-17  9:36                               ` [PATCH 1/4] dccp: Initialisation framework for " Gerrit Renker
2009-01-17  9:36                                 ` Gerrit Renker
2009-01-17  9:36                                 ` [PATCH 2/4] dccp: Implement both feature-local and feature-remote Sequence Window feature Gerrit Renker
2009-01-17  9:36                                   ` Gerrit Renker
2009-01-17  9:36                                   ` [PATCH 3/4] dccp: Initialisation and type-checking of feature sysctls Gerrit Renker
2009-01-17  9:36                                     ` Gerrit Renker
2009-01-17  9:36                                     ` [PATCH 4/4] dccp: Debugging functions for feature negotiation Gerrit Renker
2009-01-17  9:36                                       ` Gerrit Renker
2009-01-19  5:40                                       ` David Miller
2009-01-19  5:40                                         ` David Miller
2009-01-19  5:40                                     ` [PATCH 3/4] dccp: Initialisation and type-checking of feature sysctls David Miller
2009-01-19  5:40                                       ` [PATCH 3/4] dccp: Initialisation and type-checking of feature David Miller
2009-01-19  5:40                                   ` [PATCH 2/4] dccp: Implement both feature-local and feature-remote Sequence Window feature David Miller
2009-01-19  5:40                                     ` [PATCH 2/4] dccp: Implement both feature-local and David Miller
2009-01-19  5:39                                 ` [PATCH 1/4] dccp: Initialisation framework for feature negotiation David Miller
2009-01-19  5:39                                   ` [PATCH 1/4] dccp: Initialisation framework for feature David Miller
2009-01-05  5:46                         ` [PATCH 2/3] dccp: Clean up ccid.c after integration of CCID plugins David Miller
2009-01-05  5:46                           ` [PATCH 2/3] dccp: Clean up ccid.c after integration of CCID David Miller
2009-01-05  5:45                       ` [PATCH 1/3] dccp: Lockless integration of CCID congestion-control plugins David Miller
2009-01-05  5:45                         ` [PATCH 1/3] dccp: Lockless integration of CCID David Miller
2008-12-20  8:08           ` [RFC] [Patch 3/4] dccp: Add unregister function Gerrit Renker
2008-12-20  8:08             ` Gerrit Renker
2008-12-21  0:35             ` Arnaldo Carvalho de Melo
2008-12-21  0:35               ` Arnaldo Carvalho de Melo
2008-12-20  8:08           ` [RFC] [Patch 4/4] dccp: Integrate the TFRC library (dependency) Gerrit Renker
2008-12-20  8:08             ` Gerrit Renker
2008-12-21  0:55             ` Arnaldo Carvalho de Melo
2008-12-21  0:55               ` Arnaldo Carvalho de Melo
2008-12-23 10:54               ` Gerrit Renker
2008-12-23 10:54                 ` Gerrit Renker

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.