* Re: [PATCH net-2.6.25 10/11][INET] Eliminate difference in actions of sysctl and proc handler for conf.all.forwarding
From: David Miller @ 2007-12-05 10:06 UTC (permalink / raw)
To: xemul; +Cc: netdev, devel
In-Reply-To: <47567638.9080208@openvz.org>
From: Pavel Emelyanov <xemul@openvz.org>
Date: Wed, 05 Dec 2007 12:58:16 +0300
> David Miller wrote:
> > The 'default' influences future settings, it should not modify
> > existing devices. That's the job of 'all'.
>
> I thought the same, and I saw that this is true for ipv6, but
> ipv4 works differently :( -- changing default for some sysctls
> will cause some devices to be changed as well.
>
> I mean - devinet_copy_dflt_conf() copies the changed bit on
> those devices, that have not this but marked in the "state" field.
> It is called for such entries as "accept_redirects", "shared_media"
> and many others. But not for "forwarding" one. That's what seemed
> strange to me. Sorry, that I didn't express the idea more cleanly.
>
> So what's the right behavior -- to propagate the default for all the
> ctls on all the devices (according to their "state"), not to propagate
> for all the ctls, or to keep things as they are now?
Grrr, good question.
I remember we had all kinds of issues wrt. this which we
had to cleanup in IPV6 in particular.
People complained that once a device was loaded and present,
you couldn't set the 'default' and expect it to influence
the settings.
The user is pretty much screwed in one way or the other.
For example:
1) If 'default' propagates to all devices, any specific
setting for a device is lost.
2) If 'default' does not propagate, there is no way to
have 'default' influence devices which have already
been loaded.
I think both behaviors are bad, and the whole problem is that sysctls
acting as defaults cannot have sane semantics because devices get
loaded before userspace can sanely start making changes to such sysctl
'defaults'.
^ permalink raw reply
* Re: [PATCH 2/3] [UDP]: Restore missing inDatagrams increments
From: David Miller @ 2007-12-05 10:08 UTC (permalink / raw)
To: herbert; +Cc: dada1, wangchen, netdev
In-Reply-To: <20071205100452.GA18026@gondor.apana.org.au>
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 5 Dec 2007 21:04:52 +1100
> On Wed, Dec 05, 2007 at 02:02:48AM -0800, David Miller wrote:
> >
> > Herbert, I applied the buggered patch and pushed it out
> > already, can you send me this fix relative?
> >
> > I'll combine them on my next rebase, thanks.
>
> Sure, here it is.
Applied, thanks a lot.
^ permalink raw reply
* Re: [PATCH 1/4] netns: Tag the network flow with the network namespace it is in (v2)
From: David Miller @ 2007-12-05 10:10 UTC (permalink / raw)
To: den; +Cc: shemminger, den, devel, netdev, containers
In-Reply-To: <47559FA9.2080109@sw.ru>
From: "Denis V. Lunev" <den@sw.ru>
Date: Tue, 04 Dec 2007 21:42:49 +0300
> Stephen Hemminger wrote:
> > Can this be made conditional on network namespaces being configured on?
> > That way the flow structure won't have to grow taking more space.
> > It matters in DoS attacks where flow cache becomes a critical resource.
>
> could you exactly point me out the flow cache your are talking about.
> Is this dst entry cache or struct flow_cache described in the
> net/core/flow.c
>
> For the latter case, there is completely no difference in the size on my
> x86_64 host with SLAB allocator, i.e. there are 30 objects per slab
> with/without fl_net (objsize = 128).
This may be true, but another thing to consider is that flow
objects sit on the stack in many call sites.
I won't let this block your patch, but I want you to be cognizant
of this issue in the future, it's not all about SLAB.
You should also BTW consider how this change will effect D-cache
access patterns and L2 cache utilization. Some object access
patterns may not fit in the cache, which did beforehand, which
can kill performance. We're talking about something which gets
touched multiple times per packet at routing rates in the
million packet per second range.
^ permalink raw reply
* config_aneg for phy not supporting autonegotiation
From: Uwe Kleine-König @ 2007-12-05 10:11 UTC (permalink / raw)
To: netdev; +Cc: Andy Fleming, Jeff Garzik
Hello,
I added a driver for a phy that doesn't support autonegotiation (see
below).
I didn't add SUPPORTED_Autoneg to hirschmannrs422_driver.features. I
expected that this results in hirschmannrs422_config_aneg never being
called, but that's wrong. So I wonder what it should do.
Moreover that phy only supports 10MBit/Half but still it seems to use
something different first and short after bringing the device up I get a
printk saying:
Trying 10/HALF
I didn't investigate that yet.
I couldn't find a place in the generic phy code that uses
driver.features, probably it's just that that needs fixing?
Best regards
Uwe
--->8---
From: Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
add Hirschmann RS422 phy
Signed-off-by: Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
---
drivers/net/phy/Kconfig | 3 ++
drivers/net/phy/Makefile | 1 +
drivers/net/phy/hirschmann-rs422.c | 55 ++++++++++++++++++++++++++++++++++++
3 files changed, 59 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/phy/hirschmann-rs422.c
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 54b2ba9..39d4905 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -90,6 +90,9 @@ config FIXED_MII_AMNT
This control will have specified number allocated for each fixed
PHY type enabled.
+config HIRSCHMANNRS422_PHY
+ tristate "Driver for Hirschmann's RS422 PHY"
+
config MDIO_BITBANG
tristate "Support for bitbanged MDIO buses"
help
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 3d6cc7b..748d69f 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -13,4 +13,5 @@ obj-$(CONFIG_VITESSE_PHY) += vitesse.o
obj-$(CONFIG_BROADCOM_PHY) += broadcom.o
obj-$(CONFIG_ICPLUS_PHY) += icplus.o
obj-$(CONFIG_FIXED_PHY) += fixed.o
+obj-$(CONFIG_HIRSCHMANNRS422_PHY) += hirschmann-rs422.o
obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o
diff --git a/drivers/net/phy/hirschmann-rs422.c b/drivers/net/phy/hirschmann-rs422.c
new file mode 100644
index 0000000..f9bc326
--- /dev/null
+++ b/drivers/net/phy/hirschmann-rs422.c
@@ -0,0 +1,55 @@
+/*
+ * drivers/net/phy/hirschmann-rs422.c
+ *
+ * Copyright (C) 2007 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+
+int hirschmannrs422_config_aneg(struct phy_device *phydev)
+{
+ /* XXX */
+ dev_warn(&phydev->dev, "I cannot autonegotiate (called from %p)\n",
+ __builtin_return_address(0));
+
+ dev_warn(&phydev->dev, "speed = %d, duplex = %d\n",
+ phydev->speed, phydev->duplex);
+ /* XXX: should better return -Esomething? */
+ return genphy_config_aneg(phydev);
+}
+
+static struct phy_driver hirschmannrs422_driver = {
+ .phy_id = 0x00071810,
+ .name = "Hirschmann_rs422",
+ .phy_id_mask = 0xfffffff0,
+ /* XXX: SUPPORTED_TP? */
+ .features = SUPPORTED_10baseT_Half | SUPPORTED_MII,
+ .read_status = genphy_read_status,
+ .config_aneg = hirschmannrs422_config_aneg,
+ .driver = { .owner = THIS_MODULE,},
+};
+
+static int __init hirschmannrs422_init(void)
+{
+ return phy_driver_register(&hirschmannrs422_driver);
+}
+
+static void __exit hirschmannrs422_exit(void)
+{
+ phy_driver_unregister(&hirschmannrs422_driver);
+}
+
+module_init(hirschmannrs422_init);
+module_exit(hirschmannrs422_exit);
+
+MODULE_AUTHOR("Uwe Kleine-Koenig");
+MODULE_DESCRIPTION("Hirschmann RS422 PHY driver");
+MODULE_LICENSE("GPL");
+
--
1.5.3.6
--
Uwe Kleine-König, Software Engineer
Digi International GmbH Branch Breisach, Küferstrasse 8, 79206 Breisach, Germany
Tax: 315/5781/0242 / VAT: DE153662976 / Reg. Amtsgericht Dortmund HRB 13962
^ permalink raw reply related
* Re: [PATCH 1/4] netns: Tag the network flow with the network namespace it is in (v2)
From: David Miller @ 2007-12-05 10:13 UTC (permalink / raw)
To: den; +Cc: devel, netdev, containers
In-Reply-To: <20071204095333.GA6029@iris.sw.ru>
From: "Denis V. Lunev" <den@openvz.org>
Date: Tue, 4 Dec 2007 12:53:33 +0300
> As well as marking flows this indirectly marks the ipv4 routing cache
> as every routing entry contains a flow.
>
> It is useful to add the network namespace into flows as frequently
> the routing information for ingoing and outgoing network packets is
> collected into a flow structure which is then used for several functions
> as it sorts out what is going on.
>
> Changes from v1:
> - remove flow.h dependency from net_namespace.h
>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Hmmm, actually I change my mind.
> @@ -10,7 +10,9 @@
> #include <linux/in6.h>
> #include <asm/atomic.h>
>
> +struct net;
> struct flowi {
> + struct net *fl_net;
> int oif;
> int iif;
> __u32 mark;
I'm not applying this, it's going to have a negative impact on routing
performance.
It also changes the semantics of the flowi object in a way I very
much dislike, in that there is now non-clobberable state in there.
Previously only addressing identifying objects were present in the
flow, you could use it any context, and there were no pointer
dereferencing or object references from this thing. It was very
simple.
That is no longer the case after your patch and I don't want us
to go down this path.
Please find another way to implement this.
^ permalink raw reply
* Re: [PATCH][ROSE] Trivial compilation CONFIG_INET=n case
From: David Miller @ 2007-12-05 10:17 UTC (permalink / raw)
To: xemul; +Cc: ralf, linux-hams, netdev, devel
In-Reply-To: <47556E09.1050007@openvz.org>
From: Pavel Emelyanov <xemul@openvz.org>
Date: Tue, 04 Dec 2007 18:11:05 +0300
> The rose_rebuild_header() consists only of some variables in
> case INET=n, and gcc will warn us about it.
>
> Fits both net-2.6 and net-2.6.25.
>
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Applied to net-2.6, thanks.
^ permalink raw reply
* Re: [PATCH][IRDA] Move ircomm_tty_line_info() under #ifdef CONFIG_PROC_FS
From: David Miller @ 2007-12-05 10:19 UTC (permalink / raw)
To: xemul-GEFAQzZX7r8dnm+yROfE0A
Cc: irda-users-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
samuel-jcdQHdrhKHMdnm+yROfE0A, devel-GEFAQzZX7r8dnm+yROfE0A,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <47556EE8.1000605-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
From: Pavel Emelyanov <xemul-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
Date: Tue, 04 Dec 2007 18:14:48 +0300
> The function in question is called only from ircomm_tty_read_proc,
> which is under this option. Move this helper to the same place.
>
> Fits both net-2.6 and net-2.6.25
>
> Signed-off-by: Pavel Emelyanov <xemul-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
Also applied to net-2.6, thanks!
-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper
from Novell. From the desktop to the data center, Linux is going
mainstream. Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4
^ permalink raw reply
* [PATCH net-2.6.25] [TCP]: Create tcp_mark_head_lost_single for NewReno
From: Ilpo Järvinen @ 2007-12-05 10:19 UTC (permalink / raw)
To: David Miller; +Cc: Netdev
[-- Attachment #1: Type: TEXT/PLAIN, Size: 2176 bytes --]
Fixes NewReno breakage that got introduced because reno ended up
into RFC3517 counting branch in tcp_mark_head_lost after the
split space tweaks. The fack branch would have worked, however,
coming lost marker updates would eventually add this anyway.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
net/ipv4/tcp_input.c | 20 ++++++++++++++++++--
1 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index f1eee2d..e410c21 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2120,6 +2120,21 @@ static void tcp_verify_retransmit_hint(struct tcp_sock *tp,
tp->retransmit_skb_hint = NULL;
}
+/* Simple NewReno thing: Mark head LOST if it wasn't yet and it's below
+ * high_seq, stop. That's all.
+ */
+static void tcp_mark_head_lost_single(struct sock *sk)
+{
+ struct tcp_sock *tp = tcp_sk(sk);
+ struct sk_buff *skb = tcp_write_queue_head(sk);
+
+ if (!(TCP_SKB_CB(skb)->sacked & TCPCB_LOST) &&
+ before(tp->snd_una, tp->high_seq)) {
+ TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
+ tp->lost_out += tcp_skb_pcount(skb);
+ }
+}
+
/* Mark head of queue up as lost. With RFC3517 SACK, the packets is
* is against sacked "cnt", otherwise it's against facked "cnt"
*/
@@ -2172,7 +2187,6 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int fast_rexmit)
tcp_verify_retransmit_hint(tp, skb);
}
}
- tcp_verify_left_out(tp);
}
/* Account newly detected lost packet(s) */
@@ -2182,7 +2196,7 @@ static void tcp_update_scoreboard(struct sock *sk, int fast_rexmit)
struct tcp_sock *tp = tcp_sk(sk);
if (tcp_is_reno(tp)) {
- tcp_mark_head_lost(sk, 1, fast_rexmit);
+ tcp_mark_head_lost_single(sk);
} else if (tcp_is_fack(tp)) {
int lost = tp->fackets_out - tp->reordering;
if (lost <= 0)
@@ -2195,6 +2209,8 @@ static void tcp_update_scoreboard(struct sock *sk, int fast_rexmit)
tcp_mark_head_lost(sk, sacked_upto, fast_rexmit);
}
+ tcp_verify_left_out(tp);
+
/* New heuristics: it is possible only after we switched
* to restart timer each time when something is ACKed.
* Hence, we can detect timed out packets during fast
--
1.5.0.6
^ permalink raw reply related
* Re: [PATCH 1/3] [TCP] FRTO: Use of existing funcs make code more obvious & robust
From: David Miller @ 2007-12-05 10:21 UTC (permalink / raw)
To: ilpo.jarvinen; +Cc: netdev
In-Reply-To: <11967869303567-git-send-email-ilpo.jarvinen@helsinki.fi>
From: "Ilpo_Järvinen" <ilpo.jarvinen@helsinki.fi>
Date: Tue, 4 Dec 2007 18:48:48 +0200
> Though there's little need for everything that tcp_may_send_now
> does (actually, even the state had to be adjusted to pass some
> checks FRTO does not want to occur), it's more robust to let it
> make the decision if sending is allowed. State adjustments
> needed:
> - Make sure snd_cwnd limit is not hit in there
> - Disable nagle (if necessary) through the frto_counter == 2
>
> The result of check for frto_counter in argument to call for
> tcp_enter_frto_loss can just be open coded, therefore there
> isn't need to store the previous frto_counter past
> tcp_may_send_now.
>
> In addition, returns can then be combined.
>
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Applied.
^ permalink raw reply
* Re: [PATCH 2/3] [TCP]: Move prior_in_flight collect to more robust place
From: David Miller @ 2007-12-05 10:21 UTC (permalink / raw)
To: ilpo.jarvinen; +Cc: netdev
In-Reply-To: <11967869303709-git-send-email-ilpo.jarvinen@helsinki.fi>
From: "Ilpo_Järvinen" <ilpo.jarvinen@helsinki.fi>
Date: Tue, 4 Dec 2007 18:48:49 +0200
> The previous location is after sacktag processing, which affects
> counters tcp_packets_in_flight depends on. This may manifest as
> wrong behavior if new SACK blocks are present and all is clear
> for call to tcp_cong_avoid, which in the case of
> tcp_reno_cong_avoid bails out early because it thinks that
> TCP is not limited by cwnd.
>
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Applied.
^ permalink raw reply
* Re: cassini driver skb->truesize bug
From: Balazs Scheidler @ 2007-12-05 10:23 UTC (permalink / raw)
To: panther; +Cc: netdev
In-Reply-To: <475561DB.7080404@balabit.hu>
Some more investigation revealed that the cassini driver leaks the data
portion of all RXed packets, this makes the driver completely unusable.
We've tested the following combinations:
* 2.6.17 (patched, but no cassini related patches)
* 2.6.22 Ubuntu Gutsy.
It still worked in 2.6.12 where we originally backported the driver from
2.6.14.
The sk_buff count in slabinfo stays normal, so the skbs are properly
freed. I'm suspicious about all this cas_page_t wrappers.
Is there a maintainer for this driver? All our previous questions went
unanswered.
On Tue, 2007-12-04 at 15:19 +0100, Laszlo Attila Toth wrote:
> Hello,
>
> we got the following message:
> SKB BUG: Invalid truesize (376) len=514, sizeof(sk_buff)=248
>
> It only occurs on larger traffic (at speed 100 Mbps: always), but not
> when downloading a small web page.
>
> In cas_rx_process_pkt() the the skb's truesize is only set via skb_put()
> but it is not used if there are fragments, also skb->len is increased by
> the fragment's size, but the truesize member is unchanged. I compared it
> to the implementation in e1000 where all of the len, datalen and
> trusize members are increased.
>
> If I modify the code to add the fragment's size to the truesize member,
> the driver allocates all available memory after a while.
>
> Regards,
> Attila
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
Bazsi
^ permalink raw reply
* Re: [PATCH 3/3] [TCP]: NAGLE_PUSH seems to be a wrong way around
From: David Miller @ 2007-12-05 10:26 UTC (permalink / raw)
To: ilpo.jarvinen; +Cc: netdev
In-Reply-To: <1196786930388-git-send-email-ilpo.jarvinen@helsinki.fi>
From: "Ilpo_Järvinen" <ilpo.jarvinen@helsinki.fi>
Date: Tue, 4 Dec 2007 18:48:50 +0200
> The comment in tcp_nagle_test suggests that. This bug is very
> very old, even 2.4.0 seems to have it.
>
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Wow, I can't believed I missed this during the TSO output
path rewrite.
I will have to double check the history, because I stated
at these conditionals many times during that work and I
wonder if I inverted a "!" somewhere along the line.
Thanks for the fix, applied!
^ permalink raw reply
* Re: [RFC][PATCHES 0/7]: Reorganization of RX history patches
From: Gerrit Renker @ 2007-12-05 10:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, netdev, dccp, Ingo Molnar
In-Reply-To: <20071203145443.GE15034@ghostprotocols.net>
Today being Wednesday, below is some feedback after working through the patch set.
Hope this is helpful.
Patch #1:
---------
Several new good points are introduced:
- IP_DCCP_TFRC_DEBUG is made dependent on IP_DCCP_TFRC_DEBUG which is useful
- the select from CONFIG_IP_DCCP_CCID3 => CONFIG_DCCP_TFRC_LIB
- the cleanup action in tfrc_module_init() (when packet_history_init() fails)
was previously missing, this is a good catch.
Also a note: tfrc_pr_debug() is not currently used (but may be later should the
code common to both CCID3 and CCID4 be shared).
Patches #2/#6:
--------------
Separated from main patch, no problems (were initially submitted in this format).
I wonder whether switching back to smaller patch sizes is better?
Patch #3:
---------
Renames s/tfrc_tx_hist/tfrc_tx_hist_slab/g; no problems.
Patch #4:
---------
packet_history_init() initialises both RX and TX history and is later called by the module_init()
function in net/dccp/ccids/lib/tfrc.c. Just a suggestion, it is possible to simplify this further,
by doing all the initialisation / cleanup in tfrc.c:
int __init {rx,tx}_packet_history_init()
{
tfrc_{rx,tx}_hist_slab = kmem_cache_create("tfrc_{rx,tx}_hist", ...);
return tfrc_{rx,tx}_hist_slab == NULL ? - ENOBUFS : 0;
}
and then call these successively in tfrc_module_init().
Patch #5:
---------
The naming scheme introduced here is
s/dccp_rx/tfrc_rx/g;
s/dccphrx/tfrchrx/g;
I wonder, while at it, would it be possible to extend this and extend this to other parts
of the code? Basically this is the same discussion as earlier on dccp@vger with Leandro,
who first came up with this naming scheme. There the same question came up and the result
of the discussion was that a prefix of `tfrchrx' is cryptic; if something simpler is
possible then it would be great.
Patch #7:
---------
* ccid3_hc_rx_detect_loss() can be fully removed since no other code references it any
further.
* bytes_recv also counts the payload_size's of non-data packets, which is wrong (it should only
sum up the sum of bytes transferred as data packets)
* loss handling is not correctly taken care of: unlike in the other part, both data and non-data
packets are used to detect loss (this is not correctly handled in the current Linux implementation).
* tfrc_rx_hist_entry_data_packet() is not needed:
- a similar function, called dccp_data_packet(), was introduced in patch 2/7
- code compiles cleanly without tfrc_rx_hist_entry_data_packet()
- all references to this function are deleted by patch 7/7
* is another header file (net/dccp/ccids/lib/packet_history_internal.h) really necessary?
- net/dccp/ccids/lib has already 3 x header file, 4 x source file
- with the removal of tfrc_rx_hist_entry_data_packet(), only struct tfrc_rx_hist_entry
remains as the sole occupant of that file
- how about hiding the internals of struct tfrc_rx_hist_entry by putting it into packet_history.c,
as it was done previously in a similar way for the TX packet history?
* in ccid3_hc_rx_insert_options(), due to hunk-shifting or something else, there is still the
call to dccp_insert_option_timestamp(sk, skb)
--> this was meant to be removed by an earlier patch (which also removed the Elapsed Time option);
--> in the original submission of this patch the call to dccp_insert_option_timestamp() did no
longer appear (as can be found in the dccp@vger mailing list archives), and the test tree
likewise does not use it;
--> it can be removed with full confidence since no part of the code uses timestamps sent by the
HC-receiver (only the HC-sender timestamps are used); and it is further not required by the
spec to send HC-receiver timestamps (RFC 4342, section 6)
* one of the two variables ccid3hcrx_tstamp_last_feedback and ccid3hcrx_tstamp_last_ack is
redundant and can be removed (this may be part of a later patch); the variable ccid3hcrx_tstamp_last_feedback
is very long (function is clear due to type of ktime_t).
* the inlines are a good idea regarding type safety, but I take it that we can now throw overboard the old rule
of 80 characters per line? Due to the longer names of the inlines, some expressions end at column 98 (cf.
tfrc_rx_hist_sample_rtt(); but to be honest I'd rather get rid of that function since the receiver-RTT
sampling is notoriously inaccurate (wrong place to measure) and then there is little left to argue with the inlines).
* with regard to RX history initialisation, would you be amicable to the idea of performing the RX/TX history, and
loss intervals history in tfrc.c, as suggested for patch 1/7 (shortens the routines)?
* tfrc_rx_hist_entry is lacking documentation (my fault, had been forgotten in the initial submission):
/**
* tfrc_rx_hist_entry - Store information about a single received packet
* @ptype: the type (5.1) of the packet
...
*/
* is it really necessary to give the field members of known structures long names such as
tfrc_rx_hist_loss_prev(h)->tfrchrx_seqno?
This is the same comment as per patch 5/7 and there has been an earlier discussion on dccp@vger where
other developers (not just me) agreed that such long names are a burden to write; but we could leave that also for later.
^ permalink raw reply
* Re: [PATCH net-2.6 0/3]: Three TCP fixes
From: David Miller @ 2007-12-05 10:30 UTC (permalink / raw)
To: jheffner; +Cc: ilpo.jarvinen, netdev
In-Reply-To: <47559FA1.2090104@psc.edu>
From: John Heffner <jheffner@psc.edu>
Date: Tue, 04 Dec 2007 13:42:41 -0500
> Ilpo Järvinen wrote:
> > ...I'm still to figure out why tcp_cwnd_down uses snd_ssthresh/2
> > as lower bound even though the ssthresh was already halved,
> > so snd_ssthresh should suffice.
>
> I remember this coming up at least once before, so it's probably worth a
> comment in the code. Rate-halving attempts to actually reduce cwnd to
> half the delivered window. Here, cwnd/4 (ssthresh/2) is a lower bound
> on how far rate-halving can reduce cwnd. See the "Bounding Parameters"
> section of <http://www.psc.edu/networking/papers/FACKnotes/current/>.
I assume we're talking about the tcp_cwnd_min() usage in
tcp_cwnd_down(), I don't see where it's dividing by two
there.
Anyways, someone please enlighten me and please also cook
up a patch to add the descriptive comment :-)
Thanks!
^ permalink raw reply
* Re: [PATCH (resubmit)]: fix lro_gen_skb() alignment
From: David Miller @ 2007-12-05 10:32 UTC (permalink / raw)
To: gallatin; +Cc: ossthema, netdev
In-Reply-To: <4755B09A.10508@myri.com>
From: Andrew Gallatin <gallatin@myri.com>
Date: Tue, 04 Dec 2007 14:55:06 -0500
>
> Add a field to the lro_mgr struct so that drivers can specify how much
> padding is required to align layer 3 headers when a packet is copied
> into a freshly allocated skb by inet_lro.c:lro_gen_skb(). Without
> padding, skbs generated by LRO will cause alignment warnings on
> architectures which require strict alignment (seen on sparc64).
>
> Myri10GE is updated to use this field.
>
> Signed off by: Andrew Gallatin <gallatin@myri.com>
Applied, thanks Andrew.
^ permalink raw reply
* Re: [PATCH net-2.6.25] [TCP]: Create tcp_mark_head_lost_single for NewReno
From: David Miller @ 2007-12-05 10:39 UTC (permalink / raw)
To: ilpo.jarvinen; +Cc: netdev
In-Reply-To: <Pine.LNX.4.64.0712051217380.18529@kivilampi-30.cs.helsinki.fi>
From: "Ilpo_Järvinen" <ilpo.jarvinen@helsinki.fi>
Date: Wed, 5 Dec 2007 12:19:04 +0200 (EET)
>
> Fixes NewReno breakage that got introduced because reno ended up
> into RFC3517 counting branch in tcp_mark_head_lost after the
> split space tweaks. The fack branch would have worked, however,
> coming lost marker updates would eventually add this anyway.
>
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Applied, thanks Ilpo.
^ permalink raw reply
* Re: cassini driver skb->truesize bug
From: David Miller @ 2007-12-05 10:41 UTC (permalink / raw)
To: bazsi; +Cc: panther, netdev
In-Reply-To: <1196850226.9713.33.camel@bzorp.balabit>
From: Balazs Scheidler <bazsi@balabit.hu>
Date: Wed, 05 Dec 2007 11:23:46 +0100
> Is there a maintainer for this driver? All our previous questions went
> unanswered.
There is a rewrite pending and I have some cards arriving soon in the
mail.
Meanwhile, either find a way to diagnose and fix this problem yourself
or use a different network card.
Thanks.
^ permalink raw reply
* [PATCH] correct typo in __xfrm4_bundle_create()
From: Ian Brown @ 2007-12-05 10:49 UTC (permalink / raw)
To: David Miller, netdev
Hello,
This is a typo correction in net/ipv4/xfrm4_policy.c; it should be
"Copy neighbour" instead "Copy neighbout",
Regards,
Ian Brown
Signed-off-by: ianbrn@gmail.com
diff --git a/a/net/ipv4/xfrm4_policy.c b/b/net/ipv4/xfrm4_policy.c
index cc86fb1..390dc7c 100644
--- a/a/net/ipv4/xfrm4_policy.c
+++ b/b/net/ipv4/xfrm4_policy.c
@@ -165,7 +165,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy,
struct xfrm_state **xfrm, int
dst_prev->trailer_len = trailer_len;
memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics));
- /* Copy neighbout for reachability confirmation */
+ /* Copy neighbour for reachability confirmation */
dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour);
dst_prev->input = rt->u.dst.input;
dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
^ permalink raw reply related
* Re: [PATCH net-2.6 0/3]: Three TCP fixes
From: Alexey Kuznetsov @ 2007-12-05 11:17 UTC (permalink / raw)
To: Ilpo J?rvinen; +Cc: John Heffner, David Miller, Netdev, Matt Mathis
In-Reply-To: <Pine.LNX.4.64.0712042319160.12072@kivilampi-30.cs.helsinki.fi>
Hello!
> My theory is that it could relate to tcp_cwnd_restart and
> tcp_cwnd_application_limited using it and the others are just then
> accidently changed as well. Perhaps I'll have to dig once again to
> changelog history to see if there's some clue (unless Alexey shed
> some light to this)...
Yes, it is RFC2861. There is some rationale in preamble to section 3.
But even for this case it can be set to full cwnd instead.
Also, I used it to calculate prior_ssthresh to restore ssthresh
in the case when we detect false retransmission. It is not an accident.
I really mean that tcp_current_sshresh() is correct estimate
for "current ssthresh" and this should be the same as in restart
situation. Of course, rationale of RFC2861 does not apply
to this case _directly_. But it was at the end of chain of syllogisms.
Look:
If we have not infinite ssthresh and cwnd > ssthresh, we are already
in congestion avoidance mode and we can set prior_ssthresh to any value
in the range ssthresh...cwnd without significant changes in behaviour
wrt congestion avoidance.
ssthresh would be an obvious underestimate.
cwnd can be an overestimate, because the path is surely congested
(cwnd > ssthresh) and cwnd is not a measure of current capacity.
Behavioral changes happen, when final cwnd is too low, because pipe
was drained during recovery. We allow to slow start to sshresh,
but value of ssthresh should be the same as we use for restart case.
Alexey
^ permalink raw reply
* Re: [PATCH 3/3] [TCP]: NAGLE_PUSH seems to be a wrong way around
From: Ilpo Järvinen @ 2007-12-05 11:18 UTC (permalink / raw)
To: David Miller; +Cc: Netdev
In-Reply-To: <20071205.022634.114614917.davem@davemloft.net>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 6173 bytes --]
On Wed, 5 Dec 2007, David Miller wrote:
> From: "Ilpo_Järvinen" <ilpo.jarvinen@helsinki.fi>
> Date: Tue, 4 Dec 2007 18:48:50 +0200
>
> > The comment in tcp_nagle_test suggests that. This bug is very
> > very old, even 2.4.0 seems to have it.
> >
> > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
>
> Wow, I can't believed I missed this during the TSO output
> path rewrite.
>
> I will have to double check the history, because I stated
> at these conditionals many times during that work and I
> wonder if I inverted a "!" somewhere along the line.
...No need, I mostly digged this up already because I was bit unsure
how it should be, your conversions didn't invert anything significant,
at least before 2.4.0 :-). ...Unless you first fixed it and then
broke it again (in your private working tree)... :-/
...If I understood the very old history correctly, this bug was introduced
in 2.4.0-test12 which inverted !tail incorrectly to nonagle==1.
You can check include/net/tcp.h diffs from this commit:
http://www.linux-mips.org/git?p=linux.git;a=commitdiff;h=c9c06167e7933d93a6e396174c68abf242294abb
...Though it's very large one. So I included only the relevant portion
here below.
--
i.
c9c06167e7933d93a6e396174c68abf242294abb
diff --git a/include/net/tcp.h b/include/net/tcp.h
index dd8e74c..ccdff5a 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -328,9 +328,13 @@ static __inline__ int tcp_sk_listen_hashfn(struct sock *sk)
*/
#define TCP_DELACK_MAX (HZ/5) /* maximal time to delay before sending an ACK */
-#define TCP_DELACK_MIN (2) /* minimal time to delay before sending an ACK,
- * 2 scheduler ticks, not depending on HZ. */
-#define TCP_ATO_MIN 2
+#if HZ >= 100
+#define TCP_DELACK_MIN (HZ/25) /* minimal time to delay before sending an ACK */
+#define TCP_ATO_MIN (HZ/25)
+#else
+#define TCP_DELACK_MIN 4
+#define TCP_ATO_MIN 4
+#endif
#define TCP_RTO_MAX (120*HZ)
#define TCP_RTO_MIN (HZ/5)
#define TCP_TIMEOUT_INIT (3*HZ) /* RFC 1122 initial RTO value */
@@ -688,6 +692,10 @@ static __inline__ void tcp_delack_init(struct tcp_opt *tp)
memset(&tp->ack, 0, sizeof(tp->ack));
}
+static inline void tcp_clear_options(struct tcp_opt *tp)
+{
+ tp->tstamp_ok = tp->sack_ok = tp->wscale_ok = tp->snd_wscale = 0;
+}
enum tcp_tw_status
{
@@ -734,7 +742,8 @@ extern int tcp_recvmsg(struct sock *sk,
extern int tcp_listen_start(struct sock *sk);
extern void tcp_parse_options(struct sk_buff *skb,
- struct tcp_opt *tp);
+ struct tcp_opt *tp,
+ int estab);
/*
* TCP v4 functions exported for the inet6 API
@@ -997,6 +1006,9 @@ struct tcp_skb_cb {
#define TCPCB_EVER_RETRANS 0x80 /* Ever retransmitted frame */
#define TCPCB_RETRANS (TCPCB_SACKED_RETRANS|TCPCB_EVER_RETRANS)
+#define TCPCB_URG 0x20 /* Urgent pointer advenced here */
+
+#define TCPCB_AT_TAIL (TCPCB_URG)
__u16 urg_ptr; /* Valid w/URG flags is set. */
__u32 ack_seq; /* Sequence number ACK'd */
@@ -1134,18 +1146,19 @@ static __inline__ void tcp_minshall_update(struct tcp_opt *tp, int mss, struct s
/* Return 0, if packet can be sent now without violation Nagle's rules:
1. It is full sized.
- 2. Or it contains FIN or URG.
+ 2. Or it contains FIN.
3. Or TCP_NODELAY was set.
4. Or TCP_CORK is not set, and all sent packets are ACKed.
With Minshall's modification: all sent small packets are ACKed.
*/
-static __inline__ int tcp_nagle_check(struct tcp_opt *tp, struct sk_buff *skb, unsigned mss_now)
+static __inline__ int
+tcp_nagle_check(struct tcp_opt *tp, struct sk_buff *skb, unsigned mss_now, int nonagle)
{
return (skb->len < mss_now &&
- !(TCP_SKB_CB(skb)->flags & (TCPCB_FLAG_URG|TCPCB_FLAG_FIN)) &&
- (tp->nonagle == 2 ||
- (!tp->nonagle &&
+ !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) &&
+ (nonagle == 2 ||
+ (!nonagle &&
tp->packets_out &&
tcp_minshall_check(tp))));
}
@@ -1154,7 +1167,7 @@ static __inline__ int tcp_nagle_check(struct tcp_opt *tp, struct sk_buff *skb, u
* should be put on the wire right now.
*/
static __inline__ int tcp_snd_test(struct tcp_opt *tp, struct sk_buff *skb,
- unsigned cur_mss, int tail)
+ unsigned cur_mss, int nonagle)
{
/* RFC 1122 - section 4.2.3.4
*
@@ -1180,8 +1193,8 @@ static __inline__ int tcp_snd_test(struct tcp_opt *tp, struct sk_buff *skb,
/* Don't be strict about the congestion window for the
* final FIN frame. -DaveM
*/
- return ((!tail || !tcp_nagle_check(tp, skb, cur_mss) ||
- skb_tailroom(skb) < 32) &&
+ return ((nonagle==1 || tp->urg_mode
+ || !tcp_nagle_check(tp, skb, cur_mss, nonagle)) &&
((tcp_packets_in_flight(tp) < tp->snd_cwnd) ||
(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) &&
!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd));
@@ -1204,12 +1217,15 @@ static __inline__ int tcp_skb_is_last(struct sock *sk, struct sk_buff *skb)
*/
static __inline__ void __tcp_push_pending_frames(struct sock *sk,
struct tcp_opt *tp,
- unsigned cur_mss)
+ unsigned cur_mss,
+ int nonagle)
{
struct sk_buff *skb = tp->send_head;
if (skb) {
- if (!tcp_snd_test(tp, skb, cur_mss, tcp_skb_is_last(sk, skb)) ||
+ if (!tcp_skb_is_last(sk, skb))
+ nonagle = 1;
+ if (!tcp_snd_test(tp, skb, cur_mss, nonagle) ||
tcp_write_xmit(sk))
tcp_check_probe_timer(sk, tp);
}
@@ -1219,7 +1235,7 @@ static __inline__ void __tcp_push_pending_frames(struct sock *sk,
static __inline__ void tcp_push_pending_frames(struct sock *sk,
struct tcp_opt *tp)
{
- __tcp_push_pending_frames(sk, tp, tcp_current_mss(sk));
+ __tcp_push_pending_frames(sk, tp, tcp_current_mss(sk), tp->nonagle);
}
static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_opt *tp)
@@ -1227,7 +1243,8 @@ static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_opt *tp)
struct sk_buff *skb = tp->send_head;
return (skb &&
- tcp_snd_test(tp, skb, tcp_current_mss(sk), tcp_skb_is_last(sk, skb)));
+ tcp_snd_test(tp, skb, tcp_current_mss(sk),
+ tcp_skb_is_last(sk, skb) ? 1 : tp->nonagle));
}
static __inline__ void tcp_init_wl(struct tcp_opt *tp, u32 ack, u32 seq)
^ permalink raw reply related
* [NETLINK]: Mark attribute construction exception unlikely
From: Patrick McHardy @ 2007-12-05 11:19 UTC (permalink / raw)
To: David S. Miller; +Cc: Linux Netdev List
[-- Attachment #1: Type: text/plain, Size: 0 bytes --]
[-- Attachment #2: x --]
[-- Type: text/plain, Size: 1482 bytes --]
[NETLINK]: Mark attribute construction exception unlikely
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 9fce717f589c67137fbfc3b202d3d107dd613ad7
tree efc61e4abeeb2a89cad629c719e528364fb8dcdd
parent d426bc47b4c14d6d60b35d1b79c7d598704bbf04
author Patrick McHardy <kaber@trash.net> Tue, 04 Dec 2007 10:48:28 +0100
committer Patrick McHardy <kaber@trash.net> Wed, 05 Dec 2007 12:17:13 +0100
include/linux/netlink.h | 2 +-
include/net/netlink.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index d5bfaba..2aee0f5 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -245,7 +245,7 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
}
#define NLMSG_NEW(skb, pid, seq, type, len, flags) \
-({ if (skb_tailroom(skb) < (int)NLMSG_SPACE(len)) \
+({ if (unlikely(skb_tailroom(skb) < (int)NLMSG_SPACE(len))) \
goto nlmsg_failure; \
__nlmsg_put(skb, pid, seq, type, len, flags); })
diff --git a/include/net/netlink.h b/include/net/netlink.h
index 9298218..db4b935 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -862,7 +862,7 @@ static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
#define NLA_PUT(skb, attrtype, attrlen, data) \
do { \
- if (nla_put(skb, attrtype, attrlen, data) < 0) \
+ if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \
goto nla_put_failure; \
} while(0)
^ permalink raw reply related
* [PATCH v2 0/3][BUG-FIX]: Test tree updates and bug fixes
From: Gerrit Renker @ 2007-12-05 11:19 UTC (permalink / raw)
To: dccp; +Cc: netdev
Orthogonal to the ongoing discussion of patches, here are updates
of existing ones. This is mainly to keep the test tree in synch;
I'd like to upload the new test tree since -rc4 is out.
Arnaldo has actually pointed out more bugs than I have given him credit for,
these are contained in this patch set.
Patch #1: Fixes the allocation of per-socket RX history array elements
(implements the solution contributed by Arnaldo).
Patch #2: Fixes a similar problem in the tfrc_module.c -- this solution
is also present in Arnaldo's patch set, but he did not explicitly
point it out. The update fixes this problem (it used to disappear
later in the patch set, when the full initialisation was made for
TX/RX histories and Loss Intervals; so it is only temporary).
Patch #3: Removes the redundant test "len > 0", as a result one inline function
becomes obsolete. Thanks is again due to Arnaldo.
I have not yet updated the CCID4 subtree with regard to patch#3 but will do
as soon as work here permits.
The updates to the tree are now available at
git://eden-feed.erg.abdn.ac.uk/dccp_exp {dccp,ccid4}
^ permalink raw reply
* [PATCH v2 0/3][BUG-FIX]: Test tree updates and bug fixes
From: Gerrit Renker @ 2007-12-05 11:19 UTC (permalink / raw)
To: dccp; +Cc: netdev, Gerrit Renker
In-Reply-To: <11968535861091-git-send-email-gerrit@erg.abdn.ac.uk>
This patch removes the following redundancies:
* ccid3_hc_rx_update_s() is only called for data packets (that is what it should be called for);
* each call to ccid3_hc_rx_update_s() is wrapped inside a "if (is_data_packet)" test';
* therefore testing each time if "len > 0" is redundant (pointed out by Arnaldo);
* no other code calls this function, hence the inline function can go.
Also replaced the first call to updating s with direct assignment of `payload_size'; this has also
been pointed out by Arnaldo.
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
net/dccp/ccids/ccid3.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -654,12 +654,6 @@ static void ccid3_hc_rx_set_state(struct
hcrx->ccid3hcrx_state = state;
}
-static inline void ccid3_hc_rx_update_s(struct ccid3_hc_rx_sock *hcrx, int len)
-{
- if (likely(len > 0)) /* don't update on empty packets (e.g. ACKs) */
- hcrx->ccid3hcrx_s = tfrc_ewma(hcrx->ccid3hcrx_s, len, 9);
-}
-
static void ccid3_hc_rx_send_feedback(struct sock *sk, struct sk_buff *skb,
enum ccid3_fback_type fbtype)
{
@@ -788,8 +782,8 @@ static void ccid3_hc_rx_packet_recv(stru
if (unlikely(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)) {
if (is_data_packet) {
do_feedback = FBACK_INITIAL;
+ hcrx->ccid3hcrx_s = payload_size;
ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
- ccid3_hc_rx_update_s(hcrx, payload_size);
}
goto update_records;
}
@@ -798,7 +792,10 @@ static void ccid3_hc_rx_packet_recv(stru
goto done_receiving;
if (is_data_packet) {
- ccid3_hc_rx_update_s(hcrx, payload_size);
+ /*
+ * Update moving-average of s and the sum of received payload bytes
+ */
+ hcrx->ccid3hcrx_s = tfrc_ewma(hcrx->ccid3hcrx_s, payload_size, 9);
hcrx->ccid3hcrx_bytes_recv += payload_size;
}
^ permalink raw reply
* [PATCH v2 0/3][BUG-FIX]: Test tree updates and bug fixes
From: Gerrit Renker @ 2007-12-05 11:19 UTC (permalink / raw)
To: dccp; +Cc: netdev, Gerrit Renker
In-Reply-To: <11968535864083-git-send-email-gerrit@erg.abdn.ac.uk>
This fixes a problem in the initial revision of the patch: The loss interval
history was not de-allocated when the initialisation of the packet history
failed. The identification of this problem is also thanks due to Arnaldo.
The interdiff to the previous revision is:
--- b/net/dccp/ccids/lib/tfrc_module.c
+++ b/net/dccp/ccids/lib/tfrc_module.c
@@ -26,7 +26,12 @@
if (rc == 0)
rc = packet_history_init();
+ if (rc == 0)
+ goto out;
+out_free_loss_intervals:
+ dccp_li_exit();
+out:
return rc;
}
-------------------------> Patch v2 <---------------------------------------
[TFRC]: Provide central source file and debug facility
This patch changes the tfrc_lib module in the following manner:
(1) a dedicated tfrc_module source file (this is later populated
with TX/RX hist and LI Database routines);
(2) a dedicated tfrc_pr_debug macro with toggle switch `tfrc_debug'.
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Signed-off-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
---
net/dccp/ccids/Kconfig | 12 +++++---
net/dccp/ccids/lib/Makefile | 3 +-
net/dccp/ccids/lib/loss_interval.c | 2 -
net/dccp/ccids/lib/packet_history.c | 28 ++------------------
net/dccp/ccids/lib/packet_history.h | 3 --
net/dccp/ccids/lib/tfrc.h | 17 +++++++++---
net/dccp/ccids/lib/tfrc_module.c | 50 ++++++++++++++++++++++++++++++++++++
7 files changed, 78 insertions(+), 37 deletions(-)
--- a/net/dccp/ccids/lib/packet_history.h
+++ b/net/dccp/ccids/lib/packet_history.h
@@ -39,8 +39,7 @@
#include <linux/ktime.h>
#include <linux/list.h>
#include <linux/slab.h>
-
-#include "../../dccp.h"
+#include "tfrc.h"
/* Number of later packets received before one is considered lost */
#define TFRC_RECV_NUM_LATE_LOSS 3
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -35,7 +35,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/module.h>
#include <linux/string.h>
#include "packet_history.h"
@@ -277,39 +276,18 @@ void dccp_rx_hist_purge(struct dccp_rx_h
EXPORT_SYMBOL_GPL(dccp_rx_hist_purge);
-extern int __init dccp_li_init(void);
-extern void dccp_li_exit(void);
-
-static __init int packet_history_init(void)
+int __init packet_history_init(void)
{
- if (dccp_li_init() != 0)
- goto out;
-
tfrc_tx_hist = kmem_cache_create("tfrc_tx_hist",
sizeof(struct tfrc_tx_hist_entry), 0,
SLAB_HWCACHE_ALIGN, NULL);
- if (tfrc_tx_hist == NULL)
- goto out_li_exit;
-
- return 0;
-out_li_exit:
- dccp_li_exit();
-out:
- return -ENOBUFS;
+ return tfrc_tx_hist == NULL ? -ENOBUFS : 0;
}
-module_init(packet_history_init);
-static __exit void packet_history_exit(void)
+void __exit packet_history_exit(void)
{
if (tfrc_tx_hist != NULL) {
kmem_cache_destroy(tfrc_tx_hist);
tfrc_tx_hist = NULL;
}
- dccp_li_exit();
}
-module_exit(packet_history_exit);
-
-MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>, "
- "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
-MODULE_DESCRIPTION("DCCP TFRC library");
-MODULE_LICENSE("GPL");
--- a/net/dccp/ccids/lib/tfrc.h
+++ b/net/dccp/ccids/lib/tfrc.h
@@ -3,10 +3,11 @@
/*
* net/dccp/ccids/lib/tfrc.h
*
- * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
- * Copyright (c) 2005 Ian McDonald <ian.mcdonald@jandi.co.nz>
- * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- * Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon
+ * Copyright (c) 2007 The University of Aberdeen, Scotland, UK
+ * Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand.
+ * Copyright (c) 2005-6 Ian McDonald <ian.mcdonald@jandi.co.nz>
+ * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,6 +16,14 @@
*/
#include <linux/types.h>
#include <asm/div64.h>
+#include "../../dccp.h"
+
+#ifdef CONFIG_IP_DCCP_TFRC_DEBUG
+extern int tfrc_debug;
+#define tfrc_pr_debug(format, a...) DCCP_PR_DEBUG(tfrc_debug, format, ##a)
+#else
+#define tfrc_pr_debug(format, a...)
+#endif
/* integer-arithmetic divisions of type (a * 1000000)/b */
static inline u64 scaled_div(u64 a, u32 b)
--- /dev/null
+++ b/net/dccp/ccids/lib/tfrc_module.c
@@ -0,0 +1,50 @@
+/*
+ * TFRC: main module holding the pieces of the TFRC library together
+ *
+ * Copyright (c) 2007 The University of Aberdeen, Scotland, UK
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include "tfrc.h"
+
+/* Initialisation / Clean-up routines */
+extern int packet_history_init(void);
+extern void packet_history_exit(void);
+
+extern int dccp_li_init(void);
+extern void dccp_li_exit(void);
+
+#ifdef CONFIG_IP_DCCP_TFRC_DEBUG
+int tfrc_debug;
+module_param(tfrc_debug, bool, 0444);
+MODULE_PARM_DESC(tfrc_debug, "Enable debug messages");
+#endif
+
+static int __init tfrc_module_init(void)
+{
+ int rc = dccp_li_init();
+
+ if (rc == 0)
+ rc = packet_history_init();
+ if (rc == 0)
+ goto out;
+
+out_free_loss_intervals:
+ dccp_li_exit();
+out:
+ return rc;
+}
+module_init(tfrc_module_init);
+
+static void __exit tfrc_module_exit(void)
+{
+ packet_history_exit();
+ dccp_li_exit();
+}
+module_exit(tfrc_module_exit);
+
+MODULE_AUTHOR("Gerrit Renker <gerrit@erg.abdn.ac.uk>, "
+ "Ian McDonald <ian.mcdonald@jandi.co.nz>, "
+ "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
+MODULE_DESCRIPTION("DCCP TFRC library");
+MODULE_LICENSE("GPL");
--- a/net/dccp/ccids/lib/Makefile
+++ b/net/dccp/ccids/lib/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_IP_DCCP_TFRC_LIB) += dccp_tfrc_lib.o
-dccp_tfrc_lib-y := loss_interval.o packet_history.o tfrc_equation.o
+dccp_tfrc_lib-y := tfrc_module.o tfrc_equation.o \
+ packet_history.o loss_interval.o
--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -63,10 +63,6 @@ config IP_DCCP_CCID3
If in doubt, say M.
-config IP_DCCP_TFRC_LIB
- depends on IP_DCCP_CCID3
- def_tristate IP_DCCP_CCID3
-
config IP_DCCP_CCID3_DEBUG
bool "CCID3 debugging messages"
depends on IP_DCCP_CCID3
@@ -110,5 +106,13 @@ config IP_DCCP_CCID3_RTO
is serious network congestion: experimenting with larger values should
therefore not be performed on WANs.
+# The TFRC Library: currently only has CCID 3 as customer
+config IP_DCCP_TFRC_LIB
+ depends on IP_DCCP_CCID3
+ def_tristate IP_DCCP_CCID3
+
+config IP_DCCP_TFRC_DEBUG
+ bool
+ default y if IP_DCCP_CCID3_DEBUG
endmenu
--- a/net/dccp/ccids/lib/loss_interval.c
+++ b/net/dccp/ccids/lib/loss_interval.c
@@ -285,7 +285,7 @@ int __init dccp_li_init(void)
return dccp_li_cachep == NULL ? -ENOBUFS : 0;
}
-void dccp_li_exit(void)
+void __exit dccp_li_exit(void)
{
if (dccp_li_cachep != NULL) {
kmem_cache_destroy(dccp_li_cachep);
^ permalink raw reply
* [PATCH v2 0/3][BUG-FIX]: Test tree updates and bug fixes
From: Gerrit Renker @ 2007-12-05 11:19 UTC (permalink / raw)
To: dccp; +Cc: netdev, Gerrit Renker
In-Reply-To: <11968535863312-git-send-email-gerrit@erg.abdn.ac.uk>
This revision fixes a bug present in the per-socket allocation of RX history
entries; identification of this bug is thanks to Arnaldo Carvalho de Melo.
The bug was in not deallocating history entries when the allocation of
one array element failed. The solution in this revised patch set is the
original one written by Arnaldo.
----------------------> Patch v2 <---------------------------------------------
[TFRC]: New RX history implementation
This provides a new, self-contained and generic RX history service for TFRC
based protocols.
Details:
* new data structure, initialisation and cleanup routines;
* allocation of dccp_rx_hist entries local to packet_history.c,
as a service exported by the dccp_tfrc_lib module.
* interface to automatically track highest-received seqno;
* receiver-based RTT estimation (needed for instance by RFC 3448, 6.3.1);
* a generic function to test for `data packets' as per RFC 4340, sec. 7.7.
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Signed-off-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
---
net/dccp/ccids/lib/packet_history.c | 126 ++++++++++++++++++++++++++++---
net/dccp/ccids/lib/packet_history.h | 144 +++++++++++++++++++++++++++++++++++-
net/dccp/ccids/lib/tfrc_module.c | 26 ++++--
net/dccp/dccp.h | 12 +++
4 files changed, 285 insertions(+), 23 deletions(-)
--- a/net/dccp/ccids/lib/packet_history.h
+++ b/net/dccp/ccids/lib/packet_history.h
@@ -1,3 +1,5 @@
+#ifndef _DCCP_PKT_HIST_
+#define _DCCP_PKT_HIST_
/*
* Packet RX/TX history data structures and routines for TFRC-based protocols.
*
@@ -32,10 +34,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
-#ifndef _DCCP_PKT_HIST_
-#define _DCCP_PKT_HIST_
-
#include <linux/ktime.h>
#include <linux/list.h>
#include <linux/slab.h>
@@ -43,9 +41,13 @@
/* Number of later packets received before one is considered lost */
#define TFRC_RECV_NUM_LATE_LOSS 3
+/* Number of packets to wait after a missing packet (RFC 4342, 6.1) */
+#define NDUPACK 3
#define TFRC_WIN_COUNT_PER_RTT 4
#define TFRC_WIN_COUNT_LIMIT 16
+/* Subtraction a-b modulo-16, respects circular wrap-around */
+#define SUB16(a,b) (((a) + 16 - (b)) & 0xF)
struct tfrc_tx_hist_entry;
@@ -66,6 +68,23 @@ struct dccp_rx_hist_entry {
ktime_t dccphrx_tstamp;
};
+
+/**
+ * tfrc_rx_hist_entry - Store information about a single received packet
+ * @seqno: DCCP packet sequence number
+ * @ccval: window counter value of packet (RFC 4342, 8.1)
+ * @ptype: the type (5.1) of the packet
+ * @ndp: the NDP count (if any) of the packet
+ * @stamp: actual receive time of packet
+ */
+struct tfrc_rx_hist_entry {
+ u64 seqno:48,
+ ccval:4,
+ ptype:4;
+ u32 ndp;
+ ktime_t stamp;
+};
+
struct dccp_rx_hist {
struct kmem_cache *dccprxh_slab;
};
@@ -73,6 +92,123 @@ struct dccp_rx_hist {
extern struct dccp_rx_hist *dccp_rx_hist_new(const char *name);
extern void dccp_rx_hist_delete(struct dccp_rx_hist *hist);
+/**
+ * tfrc_rx_hist - RX history structure for TFRC-based protocols
+ *
+ * @ring: Packet history for RTT sampling and loss detection
+ * @loss_count: Number of entries in circular history
+ * @loss_start: Movable index (for loss detection)
+ * @rtt_sample_prev: Used during RTT sampling, points to candidate entry
+ */
+struct tfrc_rx_hist {
+ struct tfrc_rx_hist_entry *ring[NDUPACK + 1];
+ u8 loss_count:2,
+ loss_start:2;
+#define rtt_sample_prev loss_start
+};
+
+/*
+ * Macros for loss detection.
+ * @loss_prev: entry with highest-received-seqno before loss was detected
+ * @hist_index: index to reach n-th entry after loss_start
+ * @hist_entry: return the n-th history entry after loss_start
+ * @last_rcv: entry with highest-received-seqno so far
+ */
+#define loss_prev(h) (h)->ring[(h)->loss_start]
+#define hist_index(h, n) (((h)->loss_start + (n)) & NDUPACK)
+#define hist_entry(h, n) (h)->ring[hist_index(h, n)]
+#define last_rcv(h) (h)->ring[hist_index(h, (h)->loss_count)]
+
+/*
+ * Macros to access history entries for RTT sampling.
+ * @rtt_last_s: reference entry to compute RTT samples against
+ * @rtt_prev_s: previously suitable (wrt rtt_last_s) RTT-sampling entry
+ */
+#define rtt_last_s(h) (h)->ring[0]
+#define rtt_prev_s(h) (h)->ring[(h)->rtt_sample_prev]
+
+/* initialise loss detection and disable RTT sampling */
+static inline void tfrc_rx_hist_loss_indicated(struct tfrc_rx_hist *h)
+{
+ h->loss_count = 1;
+}
+
+/* indicate whether previously a packet was detected missing */
+static inline int tfrc_rx_loss_pending(struct tfrc_rx_hist *h)
+{
+ return h->loss_count;
+}
+
+/* any data packets missing between last reception and skb ? */
+static inline int tfrc_rx_new_loss_indicated(struct tfrc_rx_hist *h,
+ struct sk_buff *skb, u32 ndp)
+{
+ int delta = dccp_delta_seqno(last_rcv(h)->seqno,
+ DCCP_SKB_CB(skb)->dccpd_seq);
+
+ if (delta > 1 && ndp < delta)
+ tfrc_rx_hist_loss_indicated(h);
+
+ return tfrc_rx_loss_pending(h);
+}
+
+/* has the packet contained in skb been seen before ? */
+static inline int tfrc_rx_duplicate(struct tfrc_rx_hist *h, struct sk_buff *skb)
+{
+ const u64 seq = DCCP_SKB_CB(skb)->dccpd_seq;
+ int i;
+
+ if (dccp_delta_seqno(loss_prev(h)->seqno, seq) <= 0)
+ return 1;
+
+ for (i = 1; i <= h->loss_count; i++)
+ if (hist_entry(h, i)->seqno == seq)
+ return 1;
+
+ return 0;
+}
+
+/* return the signed modulo-2^48 sequence number distance from entry e1 to e2 */
+static inline s64 tfrc_rx_hist_delta_seqno(struct tfrc_rx_hist *h, u8 e1, u8 e2)
+{
+ DCCP_BUG_ON(e1 > h->loss_count || e2 > h->loss_count);
+
+ return dccp_delta_seqno(hist_entry(h, e1)->seqno,
+ hist_entry(h, e2)->seqno);
+}
+
+static inline void tfrc_rx_hist_swap(struct tfrc_rx_hist_entry **a,
+ struct tfrc_rx_hist_entry **b)
+{
+ struct tfrc_rx_hist_entry *tmp = *a;
+
+ *a = *b;
+ *b = tmp;
+}
+
+static inline void tfrc_rx_hist_entry_from_skb(struct tfrc_rx_hist_entry *new,
+ struct sk_buff *skb, u32 ndp)
+{
+ const struct dccp_hdr *dh = dccp_hdr(skb);
+
+ new->seqno = DCCP_SKB_CB(skb)->dccpd_seq;
+ new->ccval = dh->dccph_ccval;
+ new->ptype = dh->dccph_type;
+ new->ndp = ndp;
+ new->stamp = ktime_get_real();
+}
+
+/* commit packet details of skb to history (record highest received seqno) */
+static inline void tfrc_rx_hist_update(struct tfrc_rx_hist *h,
+ struct sk_buff *skb, u32 ndp)
+{
+ tfrc_rx_hist_entry_from_skb(last_rcv(h), skb, ndp);
+}
+
+extern u32 tfrc_rx_sample_rtt(struct tfrc_rx_hist *, struct sk_buff *);
+extern int tfrc_rx_hist_init(struct tfrc_rx_hist *);
+extern void tfrc_rx_hist_cleanup(struct tfrc_rx_hist *);
+
static inline struct dccp_rx_hist_entry *
dccp_rx_hist_entry_new(struct dccp_rx_hist *hist,
const u32 ndp,
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -34,7 +34,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
#include <linux/string.h>
#include "packet_history.h"
@@ -55,6 +54,22 @@ struct tfrc_tx_hist_entry {
*/
static struct kmem_cache *tfrc_tx_hist;
+int __init tx_packet_history_init(void)
+{
+ tfrc_tx_hist = kmem_cache_create("tfrc_tx_hist",
+ sizeof(struct tfrc_tx_hist_entry), 0,
+ SLAB_HWCACHE_ALIGN, NULL);
+ return tfrc_tx_hist == NULL ? -ENOBUFS : 0;
+}
+
+void tx_packet_history_cleanup(void)
+{
+ if (tfrc_tx_hist != NULL) {
+ kmem_cache_destroy(tfrc_tx_hist);
+ tfrc_tx_hist = NULL;
+ }
+}
+
static struct tfrc_tx_hist_entry *
tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 seqno)
{
@@ -264,6 +279,55 @@ void dccp_rx_hist_add_packet(struct dccp
EXPORT_SYMBOL_GPL(dccp_rx_hist_add_packet);
+static struct kmem_cache *tfrc_rxh_cache;
+
+int __init rx_packet_history_init(void)
+{
+ tfrc_rxh_cache = kmem_cache_create("tfrc_rxh_cache",
+ sizeof(struct tfrc_rx_hist_entry),
+ 0, SLAB_HWCACHE_ALIGN, NULL);
+ return tfrc_rxh_cache == NULL ? -ENOBUFS : 0;
+}
+
+void rx_packet_history_cleanup(void)
+{
+ if (tfrc_rxh_cache != NULL) {
+ kmem_cache_destroy(tfrc_rxh_cache);
+ tfrc_rxh_cache = NULL;
+ }
+}
+
+int tfrc_rx_hist_init(struct tfrc_rx_hist *h)
+{
+ int i;
+
+ for (i = 0; i <= NDUPACK; i++) {
+ h->ring[i] = kmem_cache_alloc(tfrc_rxh_cache, GFP_ATOMIC);
+ if (h->ring[i] == NULL)
+ goto out_free;
+ }
+ h->loss_count = h->loss_start = 0;
+ return 0;
+
+out_free:
+ while (i-- != 0) {
+ kmem_cache_free(tfrc_rxh_cache, h->ring[i]);
+ h->ring[i] = 0;
+ }
+ return -ENOBUFS;
+}
+EXPORT_SYMBOL_GPL(tfrc_rx_hist_init);
+
+void tfrc_rx_hist_cleanup(struct tfrc_rx_hist *h)
+{
+ int i;
+
+ for (i=0; i <= NDUPACK; i++)
+ if (h->ring[i] != NULL)
+ kmem_cache_free(tfrc_rxh_cache, h->ring[i]);
+}
+EXPORT_SYMBOL_GPL(tfrc_rx_hist_cleanup);
+
void dccp_rx_hist_purge(struct dccp_rx_hist *hist, struct list_head *list)
{
struct dccp_rx_hist_entry *entry, *next;
@@ -276,18 +340,56 @@ void dccp_rx_hist_purge(struct dccp_rx_h
EXPORT_SYMBOL_GPL(dccp_rx_hist_purge);
-int __init packet_history_init(void)
+/**
+ * tfrc_rx_sample_rtt - Sample RTT from timestamp / CCVal
+ * Based on ideas presented in RFC 4342, 8.1. Returns 0 if it was not able
+ * to compute a sample with given data - calling function should check this.
+ */
+u32 tfrc_rx_sample_rtt(struct tfrc_rx_hist *h, struct sk_buff *skb)
{
- tfrc_tx_hist = kmem_cache_create("tfrc_tx_hist",
- sizeof(struct tfrc_tx_hist_entry), 0,
- SLAB_HWCACHE_ALIGN, NULL);
- return tfrc_tx_hist == NULL ? -ENOBUFS : 0;
-}
+ u32 sample = 0,
+ delta_v = SUB16(dccp_hdr(skb)->dccph_ccval, rtt_last_s(h)->ccval);
-void __exit packet_history_exit(void)
-{
- if (tfrc_tx_hist != NULL) {
- kmem_cache_destroy(tfrc_tx_hist);
- tfrc_tx_hist = NULL;
+ if (delta_v < 1 || delta_v > 4) { /* unsuitable CCVal delta */
+
+ if (h->rtt_sample_prev == 2) { /* previous candidate stored */
+ sample = SUB16(rtt_prev_s(h)->ccval,
+ rtt_last_s(h)->ccval);
+ if (sample)
+ sample = 4 / sample
+ * ktime_us_delta(rtt_prev_s(h)->stamp,
+ rtt_last_s(h)->stamp);
+ else /*
+ * FIXME: This condition is in principle not
+ * possible but occurs when CCID is used for
+ * two-way data traffic. I have tried to trace
+ * it, but the cause does not seem to be here.
+ */
+ DCCP_BUG("please report to dccp@vger.kernel.org"
+ " => prev = %u, last = %u",
+ rtt_prev_s(h)->ccval,
+ rtt_last_s(h)->ccval);
+ } else if (delta_v < 1) {
+ h->rtt_sample_prev = 1;
+ goto keep_ref_for_next_time;
+ }
+
+ } else if (delta_v == 4) { /* optimal match */
+ sample = ktime_to_us(net_timedelta(rtt_last_s(h)->stamp));
+
+ } else { /* suboptimal match */
+ h->rtt_sample_prev = 2;
+ goto keep_ref_for_next_time;
+ }
+
+ if (unlikely(sample > DCCP_SANE_RTT_MAX)) {
+ DCCP_WARN("RTT sample %u too large, using max\n", sample);
+ sample = DCCP_SANE_RTT_MAX;
}
+
+ h->rtt_sample_prev = 0; /* use current entry as next reference */
+keep_ref_for_next_time:
+
+ return sample;
}
+EXPORT_SYMBOL_GPL(tfrc_rx_sample_rtt);
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -334,6 +334,7 @@ struct dccp_skb_cb {
#define DCCP_SKB_CB(__skb) ((struct dccp_skb_cb *)&((__skb)->cb[0]))
+/* RFC 4340, sec. 7.7 */
static inline int dccp_non_data_packet(const struct sk_buff *skb)
{
const __u8 type = DCCP_SKB_CB(skb)->dccpd_type;
@@ -346,6 +347,17 @@ static inline int dccp_non_data_packet(c
type == DCCP_PKT_SYNCACK;
}
+/* RFC 4340, sec. 7.7 */
+static inline int dccp_data_packet(const struct sk_buff *skb)
+{
+ const __u8 type = DCCP_SKB_CB(skb)->dccpd_type;
+
+ return type == DCCP_PKT_DATA ||
+ type == DCCP_PKT_DATAACK ||
+ type == DCCP_PKT_REQUEST ||
+ type == DCCP_PKT_RESPONSE;
+}
+
static inline int dccp_packet_without_ack(const struct sk_buff *skb)
{
const __u8 type = DCCP_SKB_CB(skb)->dccpd_type;
--- a/net/dccp/ccids/lib/tfrc_module.c
+++ b/net/dccp/ccids/lib/tfrc_module.c
@@ -8,8 +8,10 @@
#include "tfrc.h"
/* Initialisation / Clean-up routines */
-extern int packet_history_init(void);
-extern void packet_history_exit(void);
+extern int tx_packet_history_init(void);
+extern int rx_packet_history_init(void);
+extern void tx_packet_history_cleanup(void);
+extern void rx_packet_history_cleanup(void);
extern int dccp_li_init(void);
extern void dccp_li_exit(void);
@@ -24,11 +26,20 @@ static int __init tfrc_module_init(void)
{
int rc = dccp_li_init();
- if (rc == 0)
- rc = packet_history_init();
- if (rc == 0)
+ if (rc)
goto out;
+ rc = tx_packet_history_init();
+ if (rc)
+ goto out_free_loss_intervals;
+
+ rc = rx_packet_history_init();
+ if (rc)
+ goto out_free_tx_history;
+ return 0;
+
+out_free_tx_history:
+ tx_packet_history_cleanup();
out_free_loss_intervals:
dccp_li_exit();
out:
@@ -38,8 +49,9 @@ module_init(tfrc_module_init);
static void __exit tfrc_module_exit(void)
{
- packet_history_exit();
- dccp_li_exit();
+ rx_packet_history_cleanup();
+ tx_packet_history_cleanup();
+ dccp_li_exit();
}
module_exit(tfrc_module_exit);
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox