static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation
Subsystems (3)
RFC PATCH v2 1/1 static builtin CCIDs was Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plugins for negotiation
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:
Quoted 17 lines
Em Wed, Dec 17, 2008 at 04:30:41PM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 7 lines
Em Wed, Dec 17, 2008 at 04:20:38PM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 6 lines
Quoted 2 lines
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:
Quoted 8 lines
Quoted 4 lines
Could not activate 0 at
/home/acme/git/net-next-2.6/net/dccp/feat.c:1176I tried doing a quick chase on this one but failed miserably, Gerrit, any ideas?
Well, without the patch the problem was that
dccp_ccid2was not being autoloaded, as soon as I manually loaded it, ttcp worked. Now to see why...
Quoted 7 lines
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, align384/+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.
net/dccp/Kconfig +0 -4
@@ -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"
net/dccp/Makefile +4 -3
@@ -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
net/dccp/ackvec.h +0 -49
59 lines not on this page · raw message
net/dccp/ccid.c +74 -19
125 lines not on this page · raw message
net/dccp/ccid.h +2 -0
@@ -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 ];
net/dccp/ccids/Kconfig +5 -30
@@ -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"
net/dccp/ccids/Makefile +0 -8
@@ -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/
net/dccp/ccids/ccid2.c +2 -19
@@ -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 <[email protected]>" ); -MODULE_DESCRIPTION ("DCCP TCP-Like (CCID2) CCID" ); -MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("net-dccp-ccid-2" );
net/dccp/ccids/ccid3.c +2 -20
@@ -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 <[email protected]>, " -"Arnaldo Carvalho de Melo <[email protected]>" ); -MODULE_DESCRIPTION ("DCCP TFRC CCID3 CCID" ); -MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("net-dccp-ccid-3" );
net/dccp/dccp.h +0 -2
@@ -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)) || -#endifinet_csk_ack_scheduled (sk); }
net/dccp/proto.c +6 -0
@@ -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 -----
David Miller
maintainerFrom: Arnaldo Carvalho de Melo <[email protected]>
Date: Wed, 17 Dec 2008 19:46:08 -0200
Quoted 10 lines
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 <[email protected]>
Gerrit, are you OK with this?
Gerrit Renker
Acked-by| > 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 <[email protected]> | | Gerrit, are you OK with this? |
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.
From: Gerrit Renker <[email protected]>
Date: Thu, 18 Dec 2008 06:33:49 +0100
Quoted 11 lines
| > 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 <[email protected]> | | Gerrit, are you OK with this? |
Quoted 1 line
Acked-by Gerrit Renker <[email protected]>
Applied, thanks everyone.
| > | Gerrit, are you OK with this? | > | | > Acked-by: Gerrit Renker <[email protected]> | | 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).
David Miller
maintainerFrom: Gerrit Renker <[email protected]>
Date: Fri, 19 Dec 2008 06:24:46 +0100
Quoted 6 lines
| > | Gerrit, are you OK with this? | > | | > Acked-by: Gerrit Renker <[email protected]> | | Applied, thanks everyone. |
Quoted 6 lines
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.
Quoted 5 lines
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
Em Fri, Dec 19, 2008 at 07:56:25AM -0000, [email protected] escreveu:
Quoted 5 lines
Quoted 5 lines
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.
Quoted 9 lines
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
cover dccp: Working prototype of integrating the modules
In reply to David MillerThis 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)
RFC PATCH 1/4 dccp: Remove old CCID-module references
In reply to David Millerdccp: Remove module references
This removes module references of CCID modules, which are no longer needed as the configured CCIDs are linked into dccp.ko.
--- 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(-)
net/dccp/ccid.h +0 -2
@@ -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,
net/dccp/ccid.c +0 -12
@@ -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)
net/dccp/ccids/ccid2.c +0 -1
@@ -771,7 +771,6 @@ static void ccid2_hc_rx_packet_recv(strustruct 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,
net/dccp/ccids/ccid3.c +0 -1
@@ -943,7 +943,6 @@ static int ccid3_hc_rx_getsockopt(structstruct 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,
RFC PATCH 2/4 dccp: Lockless use of CCID blocks
In reply to David Millerdccp: 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.
--- net/dccp/ccid.h | 10 --- net/dccp/ccid.c | 166 +++++++++++--------------------------------------------- net/dccp/feat.c | 2 3 files changed, 38 insertions(+), 140 deletions(-)
net/dccp/ccid.h +2 -8
@@ -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) {
net/dccp/ccid.c +35 -131
233 lines not on this page · raw message
net/dccp/feat.c +1 -1
@@ -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 ;
Re: [RFC] [Patch 2/4] dccp: Lockless use of CCID blocks
Em Sat, Dec 20, 2008 at 09:08:13AM +0100, Gerrit Renker escreveu:
Quoted 121 lines
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 <[email protected]>--- net/dccp/ccid.h | 10 --- net/dccp/ccid.c | 166 +++++++++++--------------------------------------------- net/dccp/feat.c | 2 3 files changed, 38 insertions(+), 140 deletions(-)net/dccp/ccid.h +2
-8@@ -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) {net/dccp/ccid.c +2
-46@@ -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(structreturn 0 ; } -int ccid_register (struct ccid_operations *ccid_ops)
net/dccp/ccid.c int ccid_getsockopt_builtin_ccids(struct · line 107
Quoted 10 lines
net/dccp/ccid.c +2
-3+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...
net/dccp/ccid.c int ccid_getsockopt_builtin_ccids(struct · line 160
Quoted 8 lines
net/dccp/ccid.c +0
-3ccid_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.
Quoted 30 lines
net/dccp/ccid.c +5
-19- 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); -
net/dccp/ccid.c int ccid_getsockopt_builtin_ccids(struct · line 128
Quoted 10 lines
net/dccp/ccid.c +1
-5-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
Quoted 29 lines
net/dccp/ccid.c +4
-7@@ -201,14 +135,12 @@ int ccid_unregister(struct ccid_operatioreturn 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) +
net/dccp/ccid.c int ccids_register_builtins(void) · line 164
Quoted 10 lines
net/dccp/ccid.c +7
-2+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];
}?
Quoted 87 lines
net/dccp/ccid.c +14
-46+} + +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)net/dccp/feat.c +1
-1@@ -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 ;
Re: [RFC] [Patch 2/4] dccp: Lockless use of CCID blocks
| > -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
Re: [RFC] [Patch 2/4] dccp: Lockless use of CCID blocks
In reply to Arnaldo Carvalho de Melo| > -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
Re: [RFC] [Patch 2/4] dccp: Lockless use of CCID blocks
| | > + 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]
cover dccp: Lockless use of CCID blocks
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;hb69e62ebcb01c4ec9e372e70aabbdd21d9c4fc
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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 1/3 dccp: Lockless integration of CCID congestion-control plugins
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.
--- 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(-)
net/dccp/ccids/Kconfig +21 -49
@@ -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"
net/dccp/Kconfig +0 -4
@@ -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"
net/dccp/Makefile +7 -2
@@ -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
net/dccp/ccids/Makefile +0 -8
@@ -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/
net/dccp/ccid.h +7 -4
@@ -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;
net/dccp/ccid.c +100 -56
233 lines not on this page · raw message
net/dccp/proto.c +7 -0
@@ -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 *
net/dccp/ccids/ccid3.c +2 -21
@@ -940,10 +940,9 @@ static int ccid3_hc_rx_getsockopt(structreturn 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 <[email protected]>, " -"Arnaldo Carvalho de Melo <[email protected]>" ); -MODULE_DESCRIPTION ("DCCP TFRC CCID3 CCID" ); -MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("net-dccp-ccid-3" );
net/dccp/ccids/ccid2.c +2 -20
@@ -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 <[email protected]>" ); -MODULE_DESCRIPTION ("DCCP TCP-Like (CCID2) CCID" ); -MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("net-dccp-ccid-2" );
net/dccp/dccp.h +0 -2
@@ -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)) || -#endifinet_csk_ack_scheduled (sk); }
net/dccp/ackvec.h +2 -2
@@ -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 ;
PATCH 2/3 dccp: Clean up ccid.c after integration of CCID plugins
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().
--- 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(-)
net/dccp/ackvec.h +0 -49
@@ -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 */
net/dccp/ccid.c +12 -124
174 lines not on this page · raw message
net/dccp/ccid.h +1 -2
@@ -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) {
net/dccp/feat.c +1 -1
@@ -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 ;
PATCH 3/3 dccp: Integrate the TFRC library with 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.
--- 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(-)
net/dccp/ccids/Kconfig +2 -7
@@ -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
net/dccp/Makefile +4 -2
@@ -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/
net/dccp/ccids/Makefile deleted +0 -1
@@ -1 +0,0 @@ -obj-y += lib/
net/dccp/ccids/lib/Makefile deleted +0 -3
@@ -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
net/dccp/ccids/lib/tfrc.h +10 -1
@@ -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_ */
net/dccp/ccids/lib/tfrc.c +4 -15
@@ -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 <[email protected]> */ -#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 <[email protected]>, " -"Ian McDonald <[email protected]>, " -"Arnaldo Carvalho de Melo <[email protected]>" ); -MODULE_DESCRIPTION ("DCCP TFRC library" ); -MODULE_LICENSE ("GPL" );
net/dccp/ccid.c +7 -1
@@ -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 *ccidint __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 (); }
net/dccp/ccids/lib/loss_interval.c +0 -3
@@ -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_losreturn (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 ) {
net/dccp/ccids/lib/packet_history.c +0 -9
@@ -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_histreturn rtt; } -EXPORT_SYMBOL_GPL (tfrc_tx_hist_rtt);/*
@@ -172,7 +169,6 @@ void tfrc_rx_hist_add_packet(struct tfrctfrc_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_rreturn 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);
net/dccp/ccids/lib/tfrc_equation.c +0 -4
@@ -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);
net/dccp/feat.c +0 -4
@@ -1214,8 +1214,6 @@ const char *dccp_feat_typename(const u8return 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 */
net/dccp/input.c +0 -2
@@ -741,5 +741,3 @@ u32 dccp_sample_rtt(struct sock *sk, lonreturn delta; } - -EXPORT_SYMBOL_GPL (dccp_sample_rtt);
Re: [PATCH 3/3] dccp: Integrate the TFRC library with DCCP
From: Gerrit Renker <[email protected]>
Date: Sat, 3 Jan 2009 08:30:49 +0100
Quoted 4 lines
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 <[email protected]>
Applied.
cover dccp: Completing feature negotiation
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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 1/4 dccp: Initialisation framework for feature negotiation
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.
--- include/linux/dccp.h | 19 -------------- net/dccp/feat.c | 67 +++++++++++++++++++++++++++++++++++++++++++-------- net/dccp/feat.h | 2 - 3 files changed, 58 insertions(+), 30 deletions(-)
net/dccp/feat.h +1 -1
@@ -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.
include/linux/dccp.h +0 -19
@@ -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);
net/dccp/feat.c +57 -10
80 lines not on this page · raw message
PATCH 2/4 dccp: Implement both feature-local and feature-remote Sequence Window feature
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.
--- 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(-)
Documentation/networking/dccp.txt +2 -1
@@ -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
include/linux/dccp.h +4 -20
@@ -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) {
net/dccp/dccp.h +7 -9
@@ -409,23 +409,21 @@ static inline void dccp_hdr_set_ack(strustatic 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)
net/dccp/feat.c +11 -2
@@ -51,8 +51,17 @@ static int dccp_hdlr_ccid(struct sock *sstatic 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 ; }
net/dccp/minisocks.c +0 -11
@@ -42,11 +42,6 @@ struct inet_timewait_death_row dccp_deatEXPORT_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(sstruct 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_sockinet_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 */
net/dccp/proto.c +0 -2
@@ -174,8 +174,6 @@ int dccp_init_sock(struct sock *sk, consstruct 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 ;
PATCH 3/4 dccp: Initialisation and type-checking of feature sysctls
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.
--- 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(-)
net/dccp/feat.h +8 -0
@@ -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);
net/dccp/feat.c +8 -3
@@ -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);
net/dccp/sysctl.c +30 -13
85 lines not on this page · raw message
include/linux/dccp.h +0 -8
@@ -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
net/dccp/dccp.h +0 -3
@@ -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;
net/dccp/options.c +0 -4
@@ -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 ;
PATCH 4/4 dccp: Debugging functions for feature negotiation
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.
--- 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(-)
net/dccp/dccp.h +2 -0
@@ -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;
net/dccp/feat.c +107 -42
195 lines not on this page · raw message
net/dccp/feat.h +0 -13
@@ -107,19 +107,6 @@ extern unsigned long sysctl_dccp_sequencextern 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,
net/dccp/options.c +0 -4
@@ -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 ; }
David Miller
maintainerRe: [PATCH 4/4] dccp: Debugging functions for feature negotiation
From: Gerrit Renker <[email protected]>
Date: Sat, 17 Jan 2009 10:36:33 +0100
Quoted 7 lines
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.
Quoted 5 lines
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 <[email protected]>Acked-by Ian McDonald <[email protected]>
Applied for 2.6.30
David Miller
maintainerRe: [PATCH 3/4] dccp: Initialisation and type-checking of feature sysctls
In reply to Gerrit RenkerFrom: Gerrit Renker <[email protected]>
Date: Sat, 17 Jan 2009 10:36:32 +0100
Quoted 14 lines
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_qlenis checked to be non-negative;
*sync_ratelimitremains as before.
...
Quoted 2 lines
Signed-off-by Gerrit Renker <[email protected]>Acked-by Ian McDonald <[email protected]>
Applied for 2.6.30
David Miller
maintainerRe: [PATCH 2/4] dccp: Implement both feature-local and feature-remote Sequence Window feature
In reply to Gerrit RenkerFrom: Gerrit Renker <[email protected]>
Date: Sat, 17 Jan 2009 10:36:31 +0100
Quoted 10 lines
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 intodccp_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;
Quoted 8 lines
* the initialisation of `rcv_wnd' in reqsk is removed, since
-rcv_wndis not used by the code anywhere;
- sequence number checks are not done in the LISTEN state (cf. 7.5.3);
-dccp_check_reqchecks the Ack number validity more rigorously;
* the `structdccp_minisock' became empty and is now removed.Signed-off-by Gerrit Renker <[email protected]>Acked-by Ian McDonald <[email protected]>
Applied for 2.6.30
David Miller
maintainerRe: [PATCH 1/4] dccp: Initialisation framework for feature negotiation
In reply to Gerrit RenkerFrom: Gerrit Renker <[email protected]>
Date: Sat, 17 Jan 2009 10:36:30 +0100
Quoted 8 lines
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 <[email protected]>Acked-by Ian McDonald <[email protected]>
Applied for 2.6.30.
Re: [PATCH 2/3] dccp: Clean up ccid.c after integration of CCID plugins
In reply to Gerrit RenkerFrom: Gerrit Renker <[email protected]>
Date: Sat, 3 Jan 2009 08:30:48 +0100
Quoted 6 lines
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 toccid_new()- since it is alwaysgfp_any().Signed-off-by Gerrit Renker <[email protected]>
Applied.
Re: [PATCH 1/3] dccp: Lockless integration of CCID congestion-control plugins
In reply to Gerrit RenkerFrom: Gerrit Renker <[email protected]>
Date: Sat, 3 Jan 2009 08:30:47 +0100
Quoted 9 lines
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);
Quoted 7 lines
* 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 <[email protected]>
Applied.
RFC PATCH 3/4 dccp: Add unregister function
In reply to David Millerdccp: Add unregister function
This adds an unregister function to facilitate unloading the DCCP module.
--- net/dccp/ccid.h | 3 ++- net/dccp/ccid.c | 48 +++++++++++++++++++++++++++--------------------- net/dccp/proto.c | 3 ++- 3 files changed, 31 insertions(+), 23 deletions(-)
net/dccp/ccid.h +2 -1
@@ -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;
net/dccp/ccid.c +27 -21
65 lines not on this page · raw message
net/dccp/proto.c +2 -1
@@ -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 *
Re: [RFC] [Patch 3/4] dccp: Add unregister function
Em Sat, Dec 20, 2008 at 09:08:21AM +0100, Gerrit Renker escreveu:
Quoted 48 lines
dccp: Add unregister function
This adds an unregister function to facilitate unloading the DCCP module.
Signed-off-by Gerrit Renker <[email protected]>--- net/dccp/ccid.h | 3 ++- net/dccp/ccid.c | 48 +++++++++++++++++++++++++++--------------------- net/dccp/proto.c | 3 ++- 3 files changed, 31 insertions(+), 23 deletions(-)net/dccp/ccid.h +2
-1@@ -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;net/dccp/ccid.c +1
-11@@ -123,7 +123,7 @@ static int ccid_register(struct ccid_opereturn 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_opr_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)
net/dccp/ccid.c static int ccid_unregister(struct ccid_o · line 135
Quoted 10 lines
net/dccp/ccid.c +0
-9- goto unwind_registrations; - } - -return 0 ; - -unwind_registrations: -while (--i >=0 ) -ccid_unregister (ccids[i]); -return err; }
Why remove this?
Quoted 16 lines
net/dccp/ccid.c +8
-1-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)
net/dccp/ccid.c void ccid_hc_tx_delete(struct ccid *ccid · line 231
Quoted 10 lines
net/dccp/ccid.c +10
-0+ goto unwind_registrations; + } + +return 0 ; + +unwind_registrations: +while (--i >=0 ) +ccid_unregister (ccids[i]); +return err; +}
Ah, just moved it around.
Quoted 19 lines
net/dccp/ccid.c +7
-0+void ccid_unregister_builtins (void ) +{ +int i; + +for (i =0 ; i <ARRAY_SIZE (ccids); i++) +ccid_unregister (ccids[i]); +}net/dccp/proto.c +1
-1@@ -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;
net/dccp/proto.c out_free_bind_bucket_cachep: · line 1154
Quoted 7 lines
net/dccp/proto.c +1
-0@@ -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:
RFC PATCH 4/4 dccp: Integrate the TFRC library (dependency)
In reply to David Millerdccp: 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.
--- 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(-)
net/dccp/ccids/Kconfig +2 -3
@@ -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
net/dccp/Makefile +5 -2
@@ -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/
net/dccp/ccids/lib/Makefile deleted +0 -3
@@ -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
net/dccp/ccids/Makefile deleted +0 -1
@@ -1 +0,0 @@ -obj-y += lib/
net/dccp/ccids/lib/tfrc.c +3 -12
@@ -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 <[email protected]>, " -"Ian McDonald <[email protected]>, " -"Arnaldo Carvalho de Melo <[email protected]>" ); -MODULE_DESCRIPTION ("DCCP TFRC library" ); -MODULE_LICENSE ("GPL" );
net/dccp/ccid.c +5 -0
@@ -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 (); }
net/dccp/ccid.h +9 -0
@@ -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 );
Re: [RFC] [Patch 4/4] dccp: Integrate the TFRC library (dependency)
Em Sat, Dec 20, 2008 at 09:08:26AM +0100, Gerrit Renker escreveu:
Quoted 8 lines
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
Kconfigmenu 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 innet/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.
net/dccp/Kconfig +0 -4
@@ -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"
net/dccp/Makefile +2 -3
@@ -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
net/dccp/ccids/Kconfig +5 -36
72 lines not on this page · raw message
net/dccp/ccids/Makefile +3 -8
@@ -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
net/dccp/ccids/lib/Makefile +1 -3
@@ -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
Re: [RFC] [Patch 4/4] dccp: Integrate the TFRC library (dependency)
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).