Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 2.6.23-rc6 Resending] NETWORKING : Edge Triggered EPOLLOUT events get missed for TCP sockets
From: Eric Dumazet @ 2007-09-20  6:11 UTC (permalink / raw)
  To: Nagendra Tomar
  Cc: Davide Libenzi, David Miller, netdev, Linux Kernel Mailing List
In-Reply-To: <331107.71046.qm@web53704.mail.re2.yahoo.com>

Nagendra Tomar a écrit :
> --- Davide Libenzi <davidel@xmailserver.org> wrote:
> 
>> On Wed, 19 Sep 2007, David Miller wrote:
>>
>>> From: Nagendra Tomar <tomer_iisc@yahoo.com>
>>> Date: Wed, 19 Sep 2007 15:37:09 -0700 (PDT)
>>>
>>>> With the SOCK_NOSPACE check in tcp_check_space(), this epoll_wait call will 
>>>> not return, even when the incoming acks free the buffers.
>>>>         Note that this patch assumes that the SOCK_NOSPACE check in
>>>> tcp_check_space is a trivial optimization which can be safely removed.
>>> I already replied to your patch posting explaining that whatever is
>>> not setting SOCK_NOSPACE should be fixed instead.
>>>
>>> Please address that, thanks.
>> You're not planning of putting the notion of a SOCK_NOSPACE bit inside a 
>> completely device-unaware interface like epoll, I hope?
>>
> 
> Definitely not ! 
> 
> The point is that the "tcp write space available" 
> wakeup does not get called if SOCK_NOSPACE bit is not set. This was
> fine when the wakeup was merely a wakeup (since SOCK_NOSPACE bit 
> indicated that someone really cared abt the wakeup). Now after the
> introduction of callback'ed wakeups, we might have some work to
> do inside the callback even if there is nobody interested in the wakeup
> at that point of time. 
> 
> In this particular case the ep_poll_callback is not getting called and
> hence the socket fd is not getting added to the ready list.
> 

Does it means that with your patch each ACK on a ET managed socket will 
trigger an epoll event   ?

Maybe your very sensitive high throuput appication needs to set a flag or 
something at socket level to ask for such a behavior.

The default should stay as is. That is an event should be sent only if someone 
cared about the wakeup.


^ permalink raw reply

* Re: [PATCH] ethtool: marvell register update
From: Jeff Garzik @ 2007-09-20  6:33 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20070917140809.2c73cfc2@freepuppy.rosehill.hemminger.net>

Stephen Hemminger wrote:
> Update the decode of sky2 registers.
> 
> Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>

applied


^ permalink raw reply

* Re: [PATCH] phy: export phy_mii_ioctl
From: Jeff Garzik @ 2007-09-20  6:36 UTC (permalink / raw)
  To: Domen Puncer; +Cc: Grant Likely, netdev, linuxppc-embedded, sven
In-Reply-To: <20070917202140.GB2642@nd47.coderock.org>

Domen Puncer wrote:
> Export phy_mii_ioctl, so network drivers can use it when built
> as modules too.
> 
> Signed-off-by: Domen Puncer <domen@coderock.org>

applied



^ permalink raw reply

* Re: [PATCH] pci: Fix e100 interrupt quirk
From: Andrew Morton @ 2007-09-20  6:37 UTC (permalink / raw)
  To: Valentine Barshak; +Cc: linux-kernel, Auke Kok, netdev
In-Reply-To: <20070918111737.GA7026@ru.mvista.com>

On Tue, 18 Sep 2007 15:17:37 +0400 Valentine Barshak <vbarshak@ru.mvista.com> wrote:

> PCI memory space may have a 64-bit offset on some architectures
> (for example, PowerPC 440) and the actual PCI memory address
> has to fixed up (an offset to PCI mem space shuld be added)
> before remapping. So, pci_iomap should be used instead of
> reading and remapping PCI BAR directly. This has been tested
> on Sequoia PowerPC 440EPx board.
> 
> Signed-off-by: Valentine Barshak <vbarshak@ru.mvista.com>
> ---
> 
> --- linux-2.6.orig/drivers/pci/quirks.c	2007-09-04 21:15:43.000000000 +0400
> +++ linux-2.6.bld/drivers/pci/quirks.c	2007-09-05 20:46:14.000000000 +0400
> @@ -1444,9 +1444,9 @@
>  static void __devinit quirk_e100_interrupt(struct pci_dev *dev)
>  {
>  	u16 command;
> -	u32 bar;
>  	u8 __iomem *csr;
>  	u8 cmd_hi;
> +	int rc;
>  
>  	switch (dev->device) {
>  	/* PCI IDs taken from drivers/net/e100.c */
> @@ -1476,16 +1476,17 @@
>  	 * re-enable them when it's ready.
>  	 */
>  	pci_read_config_word(dev, PCI_COMMAND, &command);
> -	pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar);
>  
> -	if (!(command & PCI_COMMAND_MEMORY) || !bar)
> +	rc = pci_request_region(dev, 0, "e100_quirk");
> +
> +	if (!(command & PCI_COMMAND_MEMORY) || (rc < 0))
>  		return;

Really?  So if pci_request_region() failed and !(command & PCI_COMMAND_MEMORY),
we leak the region?  So the next call to this function will fail?


> -	csr = ioremap(bar, 8);
> +	csr = pci_iomap(dev, 0, 8);
>  	if (!csr) {
>  		printk(KERN_WARNING "PCI: Can't map %s e100 registers\n",
>  			pci_name(dev));
> -		return;
> +		goto e100_quirk_exit;
>  	}
>  
>  	cmd_hi = readb(csr + 3);
> @@ -1495,7 +1496,9 @@
>  		writeb(1, csr + 3);
>  	}
>  
> -	iounmap(csr);
> +	pci_iounmap(dev, csr);
> +e100_quirk_exit:
> +	pci_release_region(dev, 0);
>  }
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt);
>  
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply

* [PATCH - net-2.6.24 0/2] Introduce and use print_ip and print_ipv6
From: Joe Perches @ 2007-09-20  6:53 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Jeff Garzik, Andrew Morton

In the same vein as print_mac, the implementations
introduce declaration macros:
	DECLARE_IP_BUF(var)
	DECLARE_IPV6_BUF(var)
and functions:
	print_ip
	print_ipv6
	print_ipv6_nofmt

IPV4 Use:

	DECLARE_IP_BUF(ipbuf);
	__be32 addr;
	print_ip(ipbuf, addr);

IPV6 use:

	DECLARE_IPV6_BUF(ipv6buf);
	const struct in6_addr *addr;
	print_ipv6(ipv6buf, addr);
and
	print_ipv6_nofmt(ipv6buf, addr);

compiled x86, defconfig and allyesconfig


^ permalink raw reply

* [PATCH - net-2.6.24 1/2] Introduce and use print_ip
From: Joe Perches @ 2007-09-20  6:53 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Jeff Garzik, Andrew Morton

This removes the uses of NIPQUAD and HIPQUAD in
drivers/net and net

IPV4 Use:

	DECLARE_IP_BUF(ipbuf);
	__be32 addr;
	print_ip(ipbuf, addr)

Signed-off-by:  Joe Perches <joe@perches.com>

please pull from:
git pull http://repo.or.cz/r/linux-2.6/trivial-mods.git print_ipv4

stats for print_ipv4:

--

 drivers/net/bonding/bond_main.c                |   35 +++++++-----
 drivers/net/bonding/bond_sysfs.c               |   31 ++++++-----
 include/linux/ip.h                             |    8 +++
 include/net/ip_vs.h                            |   36 +++++++------
 include/net/sctp/sctp.h                        |    5 +-
 net/atm/clip.c                                 |    5 +-
 net/atm/mpc.c                                  |   28 ++++++----
 net/atm/mpoa_caches.c                          |   20 +++++---
 net/bridge/netfilter/ebt_log.c                 |   21 ++++----
 net/core/netpoll.c                             |   15 +++--
 net/core/utils.c                               |   14 +++++
 net/dccp/ipv4.c                                |   10 ++--
 net/dccp/probe.c                               |   14 +++--
 net/ipv4/af_inet.c                             |    8 ++-
 net/ipv4/arp.c                                 |    9 ++--
 net/ipv4/fib_trie.c                            |    7 ++-
 net/ipv4/icmp.c                                |   26 +++++----
 net/ipv4/ip_fragment.c                         |    5 +-
 net/ipv4/ip_input.c                            |    8 ++-
 net/ipv4/ipcomp.c                              |    5 +-
 net/ipv4/ipconfig.c                            |   46 +++++++++-------
 net/ipv4/ipvs/ip_vs_conn.c                     |   63 ++++++++++++++--------
 net/ipv4/ipvs/ip_vs_core.c                     |   51 +++++++++++-------
 net/ipv4/ipvs/ip_vs_ctl.c                      |   35 +++++++-----
 net/ipv4/ipvs/ip_vs_dh.c                       |   10 ++--
 net/ipv4/ipvs/ip_vs_ftp.c                      |   19 ++++---
 net/ipv4/ipvs/ip_vs_lblc.c                     |   14 +++--
 net/ipv4/ipvs/ip_vs_lblcr.c                    |   34 +++++++-----
 net/ipv4/ipvs/ip_vs_lc.c                       |    5 +-
 net/ipv4/ipvs/ip_vs_nq.c                       |    5 +-
 net/ipv4/ipvs/ip_vs_proto.c                    |   20 ++++---
 net/ipv4/ipvs/ip_vs_proto_ah.c                 |   24 +++++---
 net/ipv4/ipvs/ip_vs_proto_esp.c                |   24 +++++---
 net/ipv4/ipvs/ip_vs_proto_tcp.c                |   20 ++++---
 net/ipv4/ipvs/ip_vs_proto_udp.c                |   10 ++--
 net/ipv4/ipvs/ip_vs_rr.c                       |    5 +-
 net/ipv4/ipvs/ip_vs_sed.c                      |    5 +-
 net/ipv4/ipvs/ip_vs_sh.c                       |   10 ++--
 net/ipv4/ipvs/ip_vs_sync.c                     |    5 +-
 net/ipv4/ipvs/ip_vs_wlc.c                      |    5 +-
 net/ipv4/ipvs/ip_vs_wrr.c                      |    5 +-
 net/ipv4/ipvs/ip_vs_xmit.c                     |   16 +++---
 net/ipv4/netfilter/arp_tables.c                |   20 ++++---
 net/ipv4/netfilter/ip_tables.c                 |   19 ++++---
 net/ipv4/netfilter/ipt_CLUSTERIP.c             |   16 +++---
 net/ipv4/netfilter/ipt_LOG.c                   |   10 ++--
 net/ipv4/netfilter/ipt_SAME.c                  |   21 +++++---
 net/ipv4/netfilter/ipt_iprange.c               |   21 ++++----
 net/ipv4/netfilter/ipt_recent.c                |    5 +-
 net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c |   20 ++++---
 net/ipv4/netfilter/nf_nat_ftp.c                |    3 +-
 net/ipv4/netfilter/nf_nat_h323.c               |   68 ++++++++++++++---------
 net/ipv4/netfilter/nf_nat_irc.c                |    5 +-
 net/ipv4/netfilter/nf_nat_rule.c               |   16 ++++--
 net/ipv4/netfilter/nf_nat_sip.c                |   12 +++--
 net/ipv4/netfilter/nf_nat_snmp_basic.c         |   13 +++--
 net/ipv4/route.c                               |   58 +++++++++++++--------
 net/ipv4/tcp_input.c                           |    5 +-
 net/ipv4/tcp_ipv4.c                            |   25 +++++----
 net/ipv4/tcp_probe.c                           |    8 ++-
 net/ipv4/tcp_timer.c                           |    5 +-
 net/ipv4/udp.c                                 |   14 +++--
 net/ipv6/netfilter/ip6t_LOG.c                  |    9 ++-
 net/netfilter/nf_conntrack_ftp.c               |   10 ++--
 net/netfilter/nf_conntrack_irc.c               |   18 ++++---
 net/netfilter/xt_hashlimit.c                   |   10 ++--
 net/rxrpc/af_rxrpc.c                           |    7 ++-
 net/rxrpc/ar-error.c                           |    5 +-
 net/rxrpc/ar-local.c                           |   19 ++++---
 net/rxrpc/ar-peer.c                            |    9 ++--
 net/rxrpc/ar-proc.c                            |   23 +++++---
 net/rxrpc/ar-transport.c                       |   17 ++++--
 net/rxrpc/rxkad.c                              |    4 +-
 net/sctp/protocol.c                            |   26 ++++++---
 net/sctp/sm_statefuns.c                        |    6 +-
 net/sunrpc/clnt.c                              |    6 ++-
 net/sunrpc/rpcb_clnt.c                         |    8 ++-
 net/sunrpc/svcsock.c                           |   16 ++++--
 net/sunrpc/xprtsock.c                          |   15 +++--
 net/xfrm/xfrm_policy.c                         |    9 ++-
 82 files changed, 805 insertions(+), 525 deletions(-)



^ permalink raw reply

* [PATCH - net-2.6.24 2/2] Introduce and use print_ipv6
From: Joe Perches @ 2007-09-20  6:54 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Jeff Garzik, Andrew Morton

This removes the uses of NIP6_FMT and NIP6_SEQFMT in net

IPV6 uses 2 different formats, colon separated and contiguous.
The contiguous form is used in seq_print

	"%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
	"%04x%04x%04x%04x%04x%04x%04x%04x"	
	 
IPV6 use:

	DECLARE_IPV6_BUF(ipv6buf);
	const struct in6_addr *addr;
	print_ipv6(ipv6buf, addr);
and
	print_ipv6_nofmt(ipv6buf, addr);

Signed-off-by:  Joe Perches <joe@perches.com>

please pull from:
git pull http://repo.or.cz/r/linux-2.6/trivial-mods.git print_ipv6

stats for print_ipv6:

--

 include/linux/ipv6.h                           |    4 ++
 include/net/netfilter/nf_conntrack_tuple.h     |   17 +++++++---
 include/net/sctp/sctp.h                        |    7 +++-
 net/core/utils.c                               |   32 +++++++++++++++++
 net/ipv4/netfilter/nf_nat_pptp.c               |    1 +
 net/ipv6/addrconf.c                            |    6 ++--
 net/ipv6/ah6.c                                 |    5 ++-
 net/ipv6/anycast.c                             |    5 ++-
 net/ipv6/esp6.c                                |    5 ++-
 net/ipv6/exthdrs.c                             |    4 ++-
 net/ipv6/icmp.c                                |    7 +++-
 net/ipv6/ip6_flowlabel.c                       |    5 ++-
 net/ipv6/ipcomp6.c                             |    5 ++-
 net/ipv6/mcast.c                               |   13 ++++---
 net/ipv6/ndisc.c                               |    5 ++-
 net/ipv6/netfilter/ip6t_LOG.c                  |    4 ++-
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |    8 +++--
 net/ipv6/route.c                               |   13 ++++---
 net/ipv6/tcp_ipv6.c                            |   26 ++++++++-------
 net/netfilter/nf_conntrack_core.c              |    1 +
 net/netfilter/nf_conntrack_ftp.c               |   12 ++++---
 net/netfilter/nf_conntrack_h323_main.c         |   14 ++++---
 net/netfilter/nf_conntrack_proto_gre.c         |    1 +
 net/netfilter/xt_hashlimit.c                   |   10 +++--
 net/sctp/ipv6.c                                |   43 ++++++++++++++---------
 net/sctp/sm_statefuns.c                        |    6 ++--
 net/sunrpc/svcsock.c                           |    5 ++-
 net/xfrm/xfrm_policy.c                         |   18 ++++------
 net/xfrm/xfrm_state.c                          |   17 +++------
 29 files changed, 188 insertions(+), 111 deletions(-)



^ permalink raw reply

* [git patches] net driver updates
From: Jeff Garzik @ 2007-09-20  7:26 UTC (permalink / raw)
  To: netdev; +Cc: LKML


[this, sans patch which was too big for netdev, was just sent upstream.
 the patch can be recreated via 'git diff net-2.6.24..upstream']



NOTE that sky2 will also be going upstream for 2.6.23-rc, as just posted
on netdev.

Please pull from the 'upstream' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream

to receive the following changes:

Al Viro (20):
      8139cp: trivial endianness annotations
      endianness annotations drivers/net/bonding/
      fix vlan in 8139cp on big-endian
      3c59x: trivial endianness annotations, NULL noise removal
      amd8111e: trivial endianness annotations, NULL noise removal
      amd8111e big-endian fix
      arcnet endianness annotations
      tulip: endianness annotations
      typhoon: trivial endianness annotations
      pcnet32: endianness
      ixgb: endianness
      drivers/net/irda: endianness, NULL noise
      starfire: trivial endianness annotations
      r8169: endianness
      via-rhine: endianness
      pppoe: endianness
      tms380tr: trivial endianness annotations
      drivers/net/appletalk: endianness
      3c509: endianness
      cxgb3: trivial endianness annotations

Alex Landau (1):
      Blackfin EMAC driver: add function to change the MAC address

Bryan Wu (3):
      Blackfin EMAC driver: add power management interface and change the bf537mac_reset to bf537mac_disable
      Blackfin EMAC driver: Add phy abstraction layer supporting in bfin_emac driver
      Blackfin EMAC driver: add a select for the PHYLIB of this driver

David Gibson (1):
      Device tree aware EMAC driver

Dhananjay Phadke (1):
      netxen: ethtool fixes

Jeff Garzik (1):
      [netdrvr] Stop using legacy hooks ->self_test_count, ->get_stats_count

Maciej W. Rozycki (3):
      sb1250-mac.c: Fix "stats" references
      NET_SB1250_MAC: Update Kconfig entry
      NET_SB1250_MAC: Rename to SB1250_MAC

Sivakumar Subramani (4):
      S2io: Change kmalloc+memset to k[zc]alloc
      S2io: Removed unused feature - bimodal interrupts
      S2io: Added support set_mac_address driver entry point
      S2io: Updating transceiver information in ethtool function

Stephen Hemminger (3):
      sky2: fix VLAN receive processing (resend)
      sky2: ethtool speed report bug
      sky2: version 1.18

Ursula Braun (1):
      s390 networking MAINTAINERS

Vitaly Bordug (2):
      FS_ENET: TX stuff should use fep->tx_lock, instead of fep->lock.
      FS_ENET: Add polling support

 Documentation/powerpc/booting-without-of.txt |  156 +
 MAINTAINERS                                  |   12 
 arch/mips/configs/bigsur_defconfig           |    2 
 arch/mips/configs/sb1250-swarm_defconfig     |    2 
 arch/powerpc/platforms/44x/Kconfig           |    3 
 arch/powerpc/platforms/cell/Kconfig          |    4 
 drivers/net/3c509.c                          |    4 
 drivers/net/3c59x.c                          |   39 
 drivers/net/8139cp.c                         |   59 
 drivers/net/8139too.c                        |   11 
 drivers/net/Kconfig                          |   89 
 drivers/net/Makefile                         |    3 
 drivers/net/amd8111e.c                       |    9 
 drivers/net/amd8111e.h                       |   24 
 drivers/net/appletalk/ipddp.c                |    2 
 drivers/net/appletalk/ipddp.h                |    2 
 drivers/net/arcnet/rfc1051.c                 |    4 
 drivers/net/arcnet/rfc1201.c                 |    6 
 drivers/net/atl1/atl1_ethtool.c              |   11 
 drivers/net/b44.c                            |   11 
 drivers/net/bfin_mac.c                       |  347 ++-
 drivers/net/bfin_mac.h                       |   53 
 drivers/net/bnx2.c                           |   20 
 drivers/net/bonding/bond_3ad.c               |   42 
 drivers/net/bonding/bond_3ad.h               |   20 
 drivers/net/bonding/bond_alb.c               |   19 
 drivers/net/bonding/bond_alb.h               |    4 
 drivers/net/bonding/bond_main.c              |   22 
 drivers/net/bonding/bond_sysfs.c             |    8 
 drivers/net/bonding/bonding.h                |    6 
 drivers/net/cassini.c                        |   11 
 drivers/net/chelsio/cxgb2.c                  |   11 
 drivers/net/cxgb3/common.h                   |    4 
 drivers/net/cxgb3/cxgb3_main.c               |   11 
 drivers/net/cxgb3/sge.c                      |    6 
 drivers/net/e100.c                           |   19 
 drivers/net/e1000/e1000_ethtool.c            |   22 
 drivers/net/e1000e/ethtool.c                 |   21 
 drivers/net/ehea/ehea_ethtool.c              |   13 
 drivers/net/forcedeth.c                      |   45 
 drivers/net/fs_enet/fs_enet-main.c           |   77 
 drivers/net/fs_enet/mac-fcc.c                |   12 
 drivers/net/fs_enet/mac-fec.c                |   30 
 drivers/net/fs_enet/mac-scc.c                |   20 
 drivers/net/fs_enet/mii-bitbang.c            |   10 
 drivers/net/gianfar_ethtool.c                |   20 
 drivers/net/ibm_emac/Kconfig                 |   70 
 drivers/net/ibm_emac/ibm_emac_core.c         |   12 
 drivers/net/ibm_newemac/Kconfig              |   63 
 drivers/net/ibm_newemac/Makefile             |   11 
 drivers/net/ibm_newemac/core.c               | 2907 +++++++++++++++++++++++++++
 drivers/net/ibm_newemac/core.h               |  355 +++
 drivers/net/ibm_newemac/debug.c              |  238 ++
 drivers/net/ibm_newemac/debug.h              |   78 
 drivers/net/ibm_newemac/emac.h               |  268 ++
 drivers/net/ibm_newemac/mal.c                |  728 ++++++
 drivers/net/ibm_newemac/mal.h                |  276 ++
 drivers/net/ibm_newemac/phy.c                |  373 +++
 drivers/net/ibm_newemac/phy.h                |   80 
 drivers/net/ibm_newemac/rgmii.c              |  323 +++
 drivers/net/ibm_newemac/rgmii.h              |   76 
 drivers/net/ibm_newemac/tah.c                |  173 +
 drivers/net/ibm_newemac/tah.h                |   90 
 drivers/net/ibm_newemac/zmii.c               |  322 ++
 drivers/net/ibm_newemac/zmii.h               |   73 
 drivers/net/ibmveth.c                        |   11 
 drivers/net/irda/mcs7780.c                   |    2 
 drivers/net/irda/sir_dev.c                   |    2 
 drivers/net/irda/stir4200.c                  |    2 
 drivers/net/irda/vlsi_ir.h                   |    6 
 drivers/net/ixgb/ixgb_ee.c                   |   16 
 drivers/net/ixgb/ixgb_ee.h                   |   28 
 drivers/net/ixgb/ixgb_ethtool.c              |   15 
 drivers/net/ixgb/ixgb_hw.h                   |    4 
 drivers/net/ixgbe/ixgbe_ethtool.c            |   11 
 drivers/net/mv643xx_eth.c                    |   12 
 drivers/net/myri10ge/myri10ge.c              |   11 
 drivers/net/netxen/netxen_nic.h              |    2 
 drivers/net/netxen/netxen_nic_ethtool.c      |   48 
 drivers/net/netxen/netxen_nic_init.c         |    7 
 drivers/net/netxen/netxen_nic_main.c         |    1 
 drivers/net/pcnet32.c                        |  109 -
 drivers/net/pppoe.c                          |   18 
 drivers/net/qla3xxx.c                        |    2 
 drivers/net/r8169.c                          |   37 
 drivers/net/s2io.c                           |  404 +--
 drivers/net/s2io.h                           |    3 
 drivers/net/sb1250-mac.c                     |    2 
 drivers/net/sc92031.c                        |   11 
 drivers/net/skge.c                           |   11 
 drivers/net/sky2.c                           |   34 
 drivers/net/sky2.h                           |    2 
 drivers/net/spider_net_ethtool.c             |   11 
 drivers/net/starfire.c                       |   88 
 drivers/net/tc35815.c                        |   12 
 drivers/net/tg3.c                            |   19 
 drivers/net/tokenring/tms380tr.c             |    4 
 drivers/net/tokenring/tms380tr.h             |   18 
 drivers/net/tulip/de2104x.c                  |   12 
 drivers/net/tulip/de4x5.c                    |   10 
 drivers/net/tulip/tulip.h                    |   16 
 drivers/net/tulip/tulip_core.c               |   10 
 drivers/net/tulip/uli526x.c                  |    6 
 drivers/net/tulip/winbond-840.c              |    2 
 drivers/net/typhoon.c                        |   36 
 drivers/net/typhoon.h                        |  190 -
 drivers/net/ucc_geth_ethtool.c               |   26 
 drivers/net/veth.c                           |   11 
 drivers/net/via-rhine.c                      |   16 
 drivers/net/wireless/libertas/ethtool.c      |   72 
 include/linux/arcdevice.h                    |    4 
 include/linux/if_arcnet.h                    |    2 
 include/linux/if_pppox.h                     |   12 
 113 files changed, 7993 insertions(+), 1237 deletions(-)


^ permalink raw reply

* Re: [PATCH 2.6.23-rc6 Resending] NETWORKING : Edge Triggered EPOLLOUT events get missed for TCP sockets
From: Nagendra Tomar @ 2007-09-20  8:02 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Davide Libenzi, David Miller, netdev, Linux Kernel Mailing List
In-Reply-To: <46F20F24.1020900@cosmosbay.com>


--- Eric Dumazet <dada1@cosmosbay.com> wrote:

> Nagendra Tomar a écrit :
> > --- Davide Libenzi <davidel@xmailserver.org> wrote:
> > 
> >> On Wed, 19 Sep 2007, David Miller wrote:
> >>
> >>> From: Nagendra Tomar <tomer_iisc@yahoo.com>
> >>> Date: Wed, 19 Sep 2007 15:37:09 -0700 (PDT)
> >>>
> >>>> With the SOCK_NOSPACE check in tcp_check_space(), this epoll_wait call will 
> >>>> not return, even when the incoming acks free the buffers.
> >>>>         Note that this patch assumes that the SOCK_NOSPACE check in
> >>>> tcp_check_space is a trivial optimization which can be safely removed.
> >>> I already replied to your patch posting explaining that whatever is
> >>> not setting SOCK_NOSPACE should be fixed instead.
> >>>
> >>> Please address that, thanks.
> >> You're not planning of putting the notion of a SOCK_NOSPACE bit inside a 
> >> completely device-unaware interface like epoll, I hope?
> >>
> > 
> > Definitely not ! 
> > 
> > The point is that the "tcp write space available" 
> > wakeup does not get called if SOCK_NOSPACE bit is not set. This was
> > fine when the wakeup was merely a wakeup (since SOCK_NOSPACE bit 
> > indicated that someone really cared abt the wakeup). Now after the
> > introduction of callback'ed wakeups, we might have some work to
> > do inside the callback even if there is nobody interested in the wakeup
> > at that point of time. 
> > 
> > In this particular case the ep_poll_callback is not getting called and
> > hence the socket fd is not getting added to the ready list.
> > 
> 
> Does it means that with your patch each ACK on a ET managed socket will 
> trigger an epoll event   ?
> 
> Maybe your very sensitive high throuput appication needs to set a flag or 
> something at socket level to ask for such a behavior.
> 
> The default should stay as is. That is an event should be sent only if someone 
> cared about the wakeup.
> 

A high throughput app will always care about the wakeup, or else it will 
not be a high throughput app in the first place. An application that
occasionaly writes and then goes to slumber and then writes again will
not be a high throughput app. 
    
My point is that the SOCK_NOSPACE check does not save us much. For
high throughput app it will almost always be set, thus making the 
check insignificant, and for the low throughput case we care less.

Thanx,
Tomar



      ___________________________________________________________
Yahoo! Answers - Got a question? Someone out there knows the answer. Try it
now.
http://uk.answers.yahoo.com/ 

^ permalink raw reply

* Re: [PATCH 2/7] CAN: Add PF_CAN core module
From: Urs Thuermann @ 2007-09-20  8:53 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: netdev, David Miller, Thomas Gleixner, Oliver Hartkopp,
	Oliver Hartkopp, Urs Thuermann
In-Reply-To: <46F0DD8E.8070808@trash.net>

Hi Patrick,

I have done allmost all changes to the code as you suggested.  The
changes to use the return value of can_rx_register() also fixed a
minor flax with failing bind() and setsockopt() on raw sockets.

But there are two things left I would like to ask/understand:

Patrick McHardy <kaber@trash.net> writes:

> > When the module is unloaded it calls can_proto_unregister() which
> > clears the pointer.  Do you see a race condition here?
> 
> Yes, you do request_module, load the module, get the cp pointer
> from proto_tab, the module is unloaded again. cp points to
> stable memory. Using module references would fix this.

How would I use the module reference counter?  Somehow with
try_module_get()?  I have thought something like

        cp = proto_tab[protocol];
        if (!cp ...)
                return ...;

        if (!try_module_get(cp->prot->owner))
                return ...;

        sk = sk_alloc(...)

        module_put(...);
        return ret;

But here I see two problems:

1. Between the check !cp...  and referencing cp->prot->owner the
   module could get unloaded and the reference be invalid.  Is there
   some lock I can hold that prevents module unloading?  I haven't
   found something like this in include/linux/module.h

2. If the module gets unloaded after the first check and
   request_module() but before the call to try_module_get() the
   socket() syscall will return with error, although module auto
   loading would normally be successful.  How can I prevent that?

> > find_dev_rcv_lists() is called in one place from can_rcv() with RCU
> > lock held, as you write.  The other two calls to find_dev_rcv_lists()
> > are from can_rx_register/unregister() functions which change the
> > receive lists.  Therefore, we can't only use RCU but need protection
> > against simultanous writes.  We do this with the spin_lock_bh().  The
> > _bh variant, because can_rcv() runs in interrupt and we need to block
> > that.  I thought this is pretty standard.
> > 
> > I'll check this again tomorrow, but I have put much time in these
> > locking issues already, changed it quite a few times and hoped to have
> > got it right finally.
> 
> 
> I'm not saying you should use *only* RCU, you need the lock
> for additions/removal of course, but since the receive path
> doesn't take that lock and relies on RCU, you need to use
> the _rcu list walking variant to avoid races with concurrent
> list changes.

I have no objections to add the _rcu suffix for the code changing the
receive lists, but I don't see why it's necessary.  When I do a
spin_lock_bh() before writing, can't I be sure that there is no
interrupt routine running in parallel while I hold this spinlock?  If
so, there is no reader in parallel because the can_rcv() function runs
in a softirq.  I'd really like to understand why you think the writers
should also use the _rcu variant.  I'm sorry if I miss something
obvious here, but could you try to explain it to me?

urs

^ permalink raw reply

* Re: [2.6.23-rc4-mm1][Bug] kernel BUG at include/linux/netdevice.h:339!
From: Kamalesh Babulal @ 2007-09-20  9:38 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, netdev
In-Reply-To: <20070917141622.330b27b8.akpm@linux-foundation.org>

Andrew Morton wrote:
> On Mon, 17 Sep 2007 17:46:38 +0530
> Kamalesh Babulal <kamalesh@linux.vnet.ibm.com> wrote:
>
>   
>> Kernel Bug is hit with 2.6.23-rc4-mm1 kernel on ppc64 machine.
>>
>> kernel BUG at include/linux/netdevice.h:339!
>>     
>
> (please cc netdev@vger.kernel.org on networking-related matters)
>
> You died here:
>
> static inline void napi_complete(struct napi_struct *n)
> {
>         BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state));
>
> The NAPI changes have had a few problems and hopefully things have
> been fixed up since then.  I'll try to get rc6-mm1 out this evening,
> so please retest that?
>   
Hi Andrew,

I don't see this bug in the 2.6.23-rc6-mm1, till now.

-- 
Thanks & Regards,
Kamalesh Babulal,
Linux Technology Center,
IBM, ISTL.


^ permalink raw reply

* Re: [PATCH 2/7] CAN: Add PF_CAN core module
From: Patrick McHardy @ 2007-09-20 10:33 UTC (permalink / raw)
  To: Urs Thuermann
  Cc: netdev, David Miller, Thomas Gleixner, Oliver Hartkopp,
	Oliver Hartkopp
In-Reply-To: <ygfy7f1g1l0.fsf@janus.isnogud.escape.de>

Urs Thuermann wrote:
> Patrick McHardy <kaber@trash.net> writes:
> 
>>>When the module is unloaded it calls can_proto_unregister() which
>>>clears the pointer.  Do you see a race condition here?
>>
>>Yes, you do request_module, load the module, get the cp pointer
>>from proto_tab, the module is unloaded again. cp points to
>>stable memory. Using module references would fix this.
> 
> 
> How would I use the module reference counter?  Somehow with
> try_module_get()?  I have thought something like
> 
>         cp = proto_tab[protocol];
>         if (!cp ...)
>                 return ...;
> 
>         if (!try_module_get(cp->prot->owner))
>                 return ...;
> 
>         sk = sk_alloc(...)
> 
>         module_put(...);
>         return ret;
> 
> But here I see two problems:
> 
> 1. Between the check !cp...  and referencing cp->prot->owner the
>    module could get unloaded and the reference be invalid.  Is there
>    some lock I can hold that prevents module unloading?  I haven't
>    found something like this in include/linux/module.h


No, you need to add your own locking to prevent this, something
list this:

registration/unregistration:

take lock
change proto_tab[]
release lock

lookup:

take lock
cp = proto_tab[]
if (cp && !try_module_get(cp->owner))
	cp = NULL
release lock

> 2. If the module gets unloaded after the first check and
>    request_module() but before the call to try_module_get() the
>    socket() syscall will return with error, although module auto
>    loading would normally be successful.  How can I prevent that?


Why do you want to prevent it? The admin unloaded the module,
so he apparently doesn't want the operation to succeed.

>>>find_dev_rcv_lists() is called in one place from can_rcv() with RCU
>>>lock held, as you write.  The other two calls to find_dev_rcv_lists()
>>>are from can_rx_register/unregister() functions which change the
>>>receive lists.  Therefore, we can't only use RCU but need protection
>>>against simultanous writes.  We do this with the spin_lock_bh().  The
>>>_bh variant, because can_rcv() runs in interrupt and we need to block
>>>that.  I thought this is pretty standard.
>>>
>>>I'll check this again tomorrow, but I have put much time in these
>>>locking issues already, changed it quite a few times and hoped to have
>>>got it right finally.
>>
>>
>>I'm not saying you should use *only* RCU, you need the lock
>>for additions/removal of course, but since the receive path
>>doesn't take that lock and relies on RCU, you need to use
>>the _rcu list walking variant to avoid races with concurrent
>>list changes.
> 
> 
> I have no objections to add the _rcu suffix for the code changing the
> receive lists, but I don't see why it's necessary.  When I do a
> spin_lock_bh() before writing, can't I be sure that there is no
> interrupt routine running in parallel while I hold this spinlock?  If
> so, there is no reader in parallel because the can_rcv() function runs
> in a softirq.  I'd really like to understand why you think the writers
> should also use the _rcu variant. 


I'm saying you need _rcu for the *read side*. All operations changing
the list already use the _rcu variants.

> I'm sorry if I miss something
> obvious here, but could you try to explain it to me?


spin_lock_bh only disables BHs locally, other CPUs can still process
softirqs. And since rcv_lists_lock is only used in process context,
the BH disabling is actually not even necessary.


^ permalink raw reply

* Re: [PATCH] pci: Fix e100 interrupt quirk
From: Valentine Barshak @ 2007-09-20 11:33 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, Auke Kok, netdev
In-Reply-To: <20070919233726.9d81b674.akpm@linux-foundation.org>

Andrew Morton wrote:
> On Tue, 18 Sep 2007 15:17:37 +0400 Valentine Barshak <vbarshak@ru.mvista.com> wrote:
> 
>> PCI memory space may have a 64-bit offset on some architectures
>> (for example, PowerPC 440) and the actual PCI memory address
>> has to fixed up (an offset to PCI mem space shuld be added)
>> before remapping. So, pci_iomap should be used instead of
>> reading and remapping PCI BAR directly. This has been tested
>> on Sequoia PowerPC 440EPx board.
>>
>> Signed-off-by: Valentine Barshak <vbarshak@ru.mvista.com>
>> ---
>>
>> --- linux-2.6.orig/drivers/pci/quirks.c	2007-09-04 21:15:43.000000000 +0400
>> +++ linux-2.6.bld/drivers/pci/quirks.c	2007-09-05 20:46:14.000000000 +0400
>> @@ -1444,9 +1444,9 @@
>>  static void __devinit quirk_e100_interrupt(struct pci_dev *dev)
>>  {
>>  	u16 command;
>> -	u32 bar;
>>  	u8 __iomem *csr;
>>  	u8 cmd_hi;
>> +	int rc;
>>  
>>  	switch (dev->device) {
>>  	/* PCI IDs taken from drivers/net/e100.c */
>> @@ -1476,16 +1476,17 @@
>>  	 * re-enable them when it's ready.
>>  	 */
>>  	pci_read_config_word(dev, PCI_COMMAND, &command);
>> -	pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar);
>>  
>> -	if (!(command & PCI_COMMAND_MEMORY) || !bar)
>> +	rc = pci_request_region(dev, 0, "e100_quirk");
>> +
>> +	if (!(command & PCI_COMMAND_MEMORY) || (rc < 0))
>>  		return;
> 
> Really?  So if pci_request_region() failed and !(command & PCI_COMMAND_MEMORY),
> we leak the region?  So the next call to this function will fail?
> 

I've split command and request region checks and submitted new patch:
http://lkml.org/lkml/2007/9/19/106
Please, take a look,
Thanks,
Valentine.

> 
>> -	csr = ioremap(bar, 8);
>> +	csr = pci_iomap(dev, 0, 8);
>>  	if (!csr) {
>>  		printk(KERN_WARNING "PCI: Can't map %s e100 registers\n",
>>  			pci_name(dev));
>> -		return;
>> +		goto e100_quirk_exit;
>>  	}
>>  
>>  	cmd_hi = readb(csr + 3);
>> @@ -1495,7 +1496,9 @@
>>  		writeb(1, csr + 3);
>>  	}
>>  
>> -	iounmap(csr);
>> +	pci_iounmap(dev, csr);
>> +e100_quirk_exit:
>> +	pci_release_region(dev, 0);
>>  }
>>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt);
>>  
>> -
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at  http://www.tux.org/lkml/


^ permalink raw reply

* Re: [PATCH 2/7] CAN: Add PF_CAN core module
From: Urs Thuermann @ 2007-09-20 11:30 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: netdev, David Miller, Thomas Gleixner, Oliver Hartkopp,
	Oliver Hartkopp
In-Reply-To: <46F24C8D.2020804@trash.net>

Patrick McHardy <kaber@trash.net> writes:

> No, you need to add your own locking to prevent this, something
> list this:
> 
> registration/unregistration:
> 
> take lock
> change proto_tab[]
> release lock
> 
> lookup:
> 
> take lock
> cp = proto_tab[]
> if (cp && !try_module_get(cp->owner))
> 	cp = NULL
> release lock

Ah, ok.  Thanks for that hint.  I will add it that way.

> > 2. If the module gets unloaded after the first check and
> >    request_module() but before the call to try_module_get() the
> >    socket() syscall will return with error, although module auto
> >    loading would normally be successful.  How can I prevent that?
> 
> 
> Why do you want to prevent it? The admin unloaded the module,
> so he apparently doesn't want the operation to succeed.

Well, unloading a module doesn't usually cause to operation to fail
when auto loading is enabled.  It only wouldn't succeed when the
unload happens in the small window between test/request-module and
call to try_module_get().  This looks ugly to me.  But the lock you
described above would also solve this.

> I'm saying you need _rcu for the *read side*. All operations changing
> the list already use the _rcu variants.
> 
> > I'm sorry if I miss something
> > obvious here, but could you try to explain it to me?
> 
> 
> spin_lock_bh only disables BHs locally, other CPUs can still process
> softirqs. And since rcv_lists_lock is only used in process context,
> the BH disabling is actually not even necessary.

Well, I finally (hopefully) got it and I have changed the code
accordingly.  Thanks for your explanation.

I will post our updated code again, probably today.  The issues still
left are

* module parameter for loopback, but we want to keep that.
* configure option for allowing normal users access to raw and bcm CAN
  sockets.  I'll check how easily an (embedded) system can be set up
  to run relevant/all processes with the CAP_NEW_RAW capability.  I
  would like to kill that configure option.
* seq_files for proc fs.  On my TODO list.

urs

^ permalink raw reply

* Re: [PATCH 2/7] CAN: Add PF_CAN core module
From: Patrick McHardy @ 2007-09-20 11:43 UTC (permalink / raw)
  To: Urs Thuermann
  Cc: netdev, David Miller, Thomas Gleixner, Oliver Hartkopp,
	Oliver Hartkopp
In-Reply-To: <ygftzppfuab.fsf@janus.isnogud.escape.de>

Urs Thuermann wrote:
> I will post our updated code again, probably today.  The issues still
> left are
> 
> * module parameter for loopback, but we want to keep that.

No objections.

> * configure option for allowing normal users access to raw and bcm CAN
>   sockets.  I'll check how easily an (embedded) system can be set up
>   to run relevant/all processes with the CAP_NEW_RAW capability.  I
>   would like to kill that configure option.

Great.

> * seq_files for proc fs.  On my TODO list.

Sounds good, thanks.

^ permalink raw reply

* Re: [LARTC] ifb and ppp
From: Patrick McHardy @ 2007-09-20 11:55 UTC (permalink / raw)
  To: Frithjof Hammer; +Cc: lartc, Linux Netdev List, jamal
In-Reply-To: <200709192342.03646.mail@frithjof-hammer.de>

Please keep netdev and myself CCed.

Frithjof Hammer wrote:
>>Does this patch help?
> 
> 
> A further examiniation:
> [...]
> printk ("fri: mein type %x\n",dev->type);
>                 switch (dev->type) {
> 
> [...]
> shows this:
> 
> root@router:/usr/src/linux-source-2.6.21# dmesg | grep fri
> fri: mein type 1
> 
> that is defined as ARPHRD_ETHER in include/linux/if_arp.h.
> 
> As far as i understand this means, that my ppp0 device is recognized as 
> Ethernetinterface.
> 
> Any further help/ideas?


I misread the code, the device it looks at in tcf_mirred_init is
the target device (ifb). So what it does is check whether the
target device wants a link layer header and if it does restores
the one from the source device. So currently it seems impossible
to get rid of the PPP(oE) header.

Jamal, is that how its supposed to work?

^ permalink raw reply

* [PATCH net-2.6.24 0/9]: TCP improvements & cleanups
From: Ilpo Järvinen @ 2007-09-20 12:17 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Hi Dave,

Just in case you're short on what to do ;-) here are some TCP
related cleanups & improvements to net-2.6.24. Including FRTO
undo fix which finally should allow FRTO to be turned on, and
some simple fastpath tweaks simple enough to the 2.6.24
schedule. ...I've a larger fastpath_hint removal patch coming
up later too but it's really a monster which needs more time
though I guess it could really cut down the SACK processing
latencies people are experience with high-speed flows (I'll
probably post it with RFC once you've picked these up).

These were boot (& couple of hours) tested on the top of
net-2.6.24 (something after the first "large" rebase you did,
so you could count that as success report of it too :-)).
Not sure if all those fragment/collapse paths I modified got
executed though.

--
 i.



^ permalink raw reply

* [PATCH 1/9] [TCP]: Maintain highest_sack accurately to the highest skb
From: Ilpo Järvinen @ 2007-09-20 12:17 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <11902906724088-git-send-email-ilpo.jarvinen@helsinki.fi>

In general, it should not be necessary to call tcp_fragment for
already SACKed skbs, but it's better to be safe than sorry. And
indeed, it can be called from sacktag when a DSACK arrives or
some ACK (with SACK) reordering occurs (sacktag could be made
to avoid the call in the latter case though I'm not sure if it's
worth of the trouble and added complexity to cover such marginal
case).

The collapse case has return for SACKED_ACKED case earlier, so
just WARN_ON if internal inconsistency is detected for some
reason.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
 net/ipv4/tcp_output.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index d65d17b..9df5b2a 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -692,6 +692,9 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
 	TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq;
 	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq;
 
+	if (tp->sacked_out && (TCP_SKB_CB(skb)->seq == tp->highest_sack))
+		tp->highest_sack = TCP_SKB_CB(buff)->seq;
+
 	/* PSH and FIN should only be set in the second packet. */
 	flags = TCP_SKB_CB(skb)->flags;
 	TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN|TCPCB_FLAG_PSH);
@@ -1723,6 +1726,10 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m
 		/* Update sequence range on original skb. */
 		TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(next_skb)->end_seq;
 
+		if (WARN_ON(tp->sacked_out &&
+		    (TCP_SKB_CB(next_skb)->seq == tp->highest_sack)))
+			return;
+
 		/* Merge over control information. */
 		flags |= TCP_SKB_CB(next_skb)->flags; /* This moves PSH/FIN etc. over */
 		TCP_SKB_CB(skb)->flags = flags;
-- 
1.5.0.6


^ permalink raw reply related

* [PATCH 2/9] [TCP]: Make fackets_out accurate
From: Ilpo Järvinen @ 2007-09-20 12:17 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <11902906721846-git-send-email-ilpo.jarvinen@helsinki.fi>

Substraction for fackets_out is unconditional when snd_una
advances, thus there's no need to do it inside the loop. Just
make sure correct bounds are honored.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
 net/ipv4/tcp_input.c  |   10 +++-------
 net/ipv4/tcp_output.c |   44 ++++++++++++++++++++++++++------------------
 2 files changed, 29 insertions(+), 25 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index fd0ae4d..09b6b1d 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2302,8 +2302,8 @@ tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag)
 	 * 1. Reno does not count dupacks (sacked_out) automatically. */
 	if (!tp->packets_out)
 		tp->sacked_out = 0;
-	/* 2. SACK counts snd_fack in packets inaccurately. */
-	if (tp->sacked_out == 0)
+
+	if (WARN_ON(!tp->sacked_out && tp->fackets_out))
 		tp->fackets_out = 0;
 
 	/* Now state machine starts.
@@ -2571,10 +2571,6 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
 		} else if (*seq_rtt < 0)
 			*seq_rtt = now - scb->when;
 
-		if (tp->fackets_out) {
-			__u32 dval = min(tp->fackets_out, packets_acked);
-			tp->fackets_out -= dval;
-		}
 		tp->packets_out -= packets_acked;
 
 		BUG_ON(tcp_skb_pcount(skb) == 0);
@@ -2657,7 +2653,6 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
 			seq_rtt = now - scb->when;
 			last_ackt = skb->tstamp;
 		}
-		tcp_dec_pcount_approx(&tp->fackets_out, skb);
 		tp->packets_out -= tcp_skb_pcount(skb);
 		tcp_unlink_write_queue(skb, sk);
 		sk_stream_free_skb(sk, skb);
@@ -2672,6 +2667,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
 		tcp_ack_update_rtt(sk, acked, seq_rtt);
 		tcp_rearm_rto(sk);
 
+		tp->fackets_out -= min(pkts_acked, tp->fackets_out);
 		if (tcp_is_reno(tp))
 			tcp_remove_reno_sacks(sk, pkts_acked);
 
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 9df5b2a..cbe8bf6 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -652,6 +652,26 @@ static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned
 	}
 }
 
+/* When a modification to fackets out becomes necessary, we need to check
+ * skb is counted to fackets_out or not. Another important thing is to
+ * tweak SACK fastpath hint too as it would overwrite all changes unless
+ * hint is also changed.
+ */
+static void tcp_adjust_fackets_out(struct tcp_sock *tp, struct sk_buff *skb,
+				   int decr)
+{
+	if (!tp->sacked_out)
+		return;
+
+	if (!before(tp->highest_sack, TCP_SKB_CB(skb)->seq))
+		tp->fackets_out -= decr;
+
+	/* cnt_hint is "off-by-one" compared with fackets_out (see sacktag) */
+	if (tp->fastpath_skb_hint != NULL &&
+	    after(TCP_SKB_CB(tp->fastpath_skb_hint)->seq, TCP_SKB_CB(skb)->seq))
+		tp->fastpath_cnt_hint -= decr;
+}
+
 /* Function to create two new TCP segments.  Shrinks the given segment
  * to the specified size and appends a new segment with the rest of the
  * packet to the list.  This won't be called frequently, I hope.
@@ -746,21 +766,12 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
 		if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST)
 			tp->lost_out -= diff;
 
-		if (diff > 0) {
-			/* Adjust Reno SACK estimate. */
-			if (tcp_is_reno(tp)) {
-				tcp_dec_pcount_approx_int(&tp->sacked_out, diff);
-				tcp_verify_left_out(tp);
-			}
-
-			tcp_dec_pcount_approx_int(&tp->fackets_out, diff);
-			/* SACK fastpath might overwrite it unless dealt with */
-			if (tp->fastpath_skb_hint != NULL &&
-			    after(TCP_SKB_CB(tp->fastpath_skb_hint)->seq,
-				  TCP_SKB_CB(skb)->seq)) {
-				tcp_dec_pcount_approx_int(&tp->fastpath_cnt_hint, diff);
-			}
+		/* Adjust Reno SACK estimate. */
+		if (tcp_is_reno(tp) && diff > 0) {
+			tcp_dec_pcount_approx_int(&tp->sacked_out, diff);
+			tcp_verify_left_out(tp);
 		}
+		tcp_adjust_fackets_out(tp, skb, diff);
 	}
 
 	/* Link BUFF into the send queue. */
@@ -1746,10 +1757,7 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m
 		if (tcp_is_reno(tp) && tp->sacked_out)
 			tcp_dec_pcount_approx(&tp->sacked_out, next_skb);
 
-		/* Not quite right: it can be > snd.fack, but
-		 * it is better to underestimate fackets.
-		 */
-		tcp_dec_pcount_approx(&tp->fackets_out, next_skb);
+		tcp_adjust_fackets_out(tp, skb, tcp_skb_pcount(next_skb));
 		tp->packets_out -= tcp_skb_pcount(next_skb);
 		sk_stream_free_skb(sk, next_skb);
 	}
-- 
1.5.0.6


^ permalink raw reply related

* [PATCH 3/9] [TCP]: clear_all_retrans_hints prefixed by tcp_
From: Ilpo Järvinen @ 2007-09-20 12:17 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <11902906723619-git-send-email-ilpo.jarvinen@helsinki.fi>

In addition, fix its function comment spacing.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
 include/net/tcp.h     |    4 ++--
 net/ipv4/tcp_input.c  |   10 +++++-----
 net/ipv4/tcp_output.c |    6 +++---
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index f28f382..16dfe3c 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1066,8 +1066,8 @@ static inline void tcp_mib_init(void)
 	TCP_ADD_STATS_USER(TCP_MIB_MAXCONN, -1);
 }
 
-/*from STCP */
-static inline void clear_all_retrans_hints(struct tcp_sock *tp){
+/* from STCP */
+static inline void tcp_clear_all_retrans_hints(struct tcp_sock *tp) {
 	tp->lost_skb_hint = NULL;
 	tp->scoreboard_skb_hint = NULL;
 	tp->retransmit_skb_hint = NULL;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 09b6b1d..89162a9 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1670,7 +1670,7 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
 	tp->high_seq = tp->frto_highmark;
 	TCP_ECN_queue_cwr(tp);
 
-	clear_all_retrans_hints(tp);
+	tcp_clear_all_retrans_hints(tp);
 }
 
 void tcp_clear_retrans(struct tcp_sock *tp)
@@ -1741,7 +1741,7 @@ void tcp_enter_loss(struct sock *sk, int how)
 	/* Abort FRTO algorithm if one is in progress */
 	tp->frto_counter = 0;
 
-	clear_all_retrans_hints(tp);
+	tcp_clear_all_retrans_hints(tp);
 }
 
 static int tcp_check_sack_reneging(struct sock *sk)
@@ -2106,7 +2106,7 @@ static void tcp_undo_cwr(struct sock *sk, const int undo)
 
 	/* There is something screwy going on with the retrans hints after
 	   an undo */
-	clear_all_retrans_hints(tp);
+	tcp_clear_all_retrans_hints(tp);
 }
 
 static inline int tcp_may_undo(struct tcp_sock *tp)
@@ -2199,7 +2199,7 @@ static int tcp_try_undo_loss(struct sock *sk)
 			TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
 		}
 
-		clear_all_retrans_hints(tp);
+		tcp_clear_all_retrans_hints(tp);
 
 		DBGUNDO(sk, "partial loss");
 		tp->lost_out = 0;
@@ -2656,7 +2656,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
 		tp->packets_out -= tcp_skb_pcount(skb);
 		tcp_unlink_write_queue(skb, sk);
 		sk_stream_free_skb(sk, skb);
-		clear_all_retrans_hints(tp);
+		tcp_clear_all_retrans_hints(tp);
 	}
 
 	if (acked&FLAG_ACKED) {
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index cbe8bf6..f46d24b 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -687,7 +687,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
 
 	BUG_ON(len > skb->len);
 
-	clear_all_retrans_hints(tp);
+	tcp_clear_all_retrans_hints(tp);
 	nsize = skb_headlen(skb) - len;
 	if (nsize < 0)
 		nsize = 0;
@@ -1719,7 +1719,7 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m
 		       tcp_skb_pcount(next_skb) != 1);
 
 		/* changing transmit queue under us so clear hints */
-		clear_all_retrans_hints(tp);
+		tcp_clear_all_retrans_hints(tp);
 
 		/* Ok.	We will be able to collapse the packet. */
 		tcp_unlink_write_queue(next_skb, sk);
@@ -1792,7 +1792,7 @@ void tcp_simple_retransmit(struct sock *sk)
 		}
 	}
 
-	clear_all_retrans_hints(tp);
+	tcp_clear_all_retrans_hints(tp);
 
 	if (!lost)
 		return;
-- 
1.5.0.6


^ permalink raw reply related

* [PATCH 6/9] [TCP] FRTO: Improve interoperability with other undo_marker users
From: Ilpo Järvinen @ 2007-09-20 12:17 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <11902906721671-git-send-email-ilpo.jarvinen@helsinki.fi>

Basically this change enables it, previously other undo_marker
users were left with nothing. Reverse undo_marker logic
completely to get it set right in CA_Loss. On the other hand,
when spurious RTO is detected, clear it. Clearing might be too
heavy for some scenarios but seems safe enough starting point
for now and shouldn't have much effect except in majority of
cases (if in any).

By adding a new FLAG_ we avoid looping through write_queue when
RTO occurs.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
 net/ipv4/tcp_input.c |   42 +++++++++++++++++++++++++++---------------
 1 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 74accb0..948e79a 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -104,6 +104,7 @@ int sysctl_tcp_abc __read_mostly;
 #define FLAG_ONLY_ORIG_SACKED	0x200 /* SACKs only non-rexmit sent before RTO */
 #define FLAG_SND_UNA_ADVANCED	0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */
 #define FLAG_DSACKING_ACK	0x800 /* SACK blocks contained DSACK info */
+#define FLAG_NONHEAD_RETRANS_ACKED	0x1000 /* Non-head rexmitted data was ACKed */
 
 #define FLAG_ACKED		(FLAG_DATA_ACKED|FLAG_SYN_ACKED)
 #define FLAG_NOT_DUP		(FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED)
@@ -1597,6 +1598,8 @@ void tcp_enter_frto(struct sock *sk)
 	tp->undo_retrans = 0;
 
 	skb = tcp_write_queue_head(sk);
+	if (TCP_SKB_CB(skb)->sacked & TCPCB_RETRANS)
+		tp->undo_marker = 0;
 	if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) {
 		TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
 		tp->retrans_out -= tcp_skb_pcount(skb);
@@ -1646,6 +1649,8 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
 			/* ...enter this if branch just for the first segment */
 			flag |= FLAG_DATA_ACKED;
 		} else {
+			if (TCP_SKB_CB(skb)->sacked & TCPCB_RETRANS)
+				tp->undo_marker = 0;
 			TCP_SKB_CB(skb)->sacked &= ~(TCPCB_LOST|TCPCB_SACKED_RETRANS);
 		}
 
@@ -1661,7 +1666,6 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
 	tp->snd_cwnd = tcp_packets_in_flight(tp) + allowed_segments;
 	tp->snd_cwnd_cnt = 0;
 	tp->snd_cwnd_stamp = tcp_time_stamp;
-	tp->undo_marker = 0;
 	tp->frto_counter = 0;
 
 	tp->reordering = min_t(unsigned int, tp->reordering,
@@ -2587,20 +2591,6 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p)
 			end_seq = scb->end_seq;
 		}
 
-		/* Initial outgoing SYN's get put onto the write_queue
-		 * just like anything else we transmit.  It is not
-		 * true data, and if we misinform our callers that
-		 * this ACK acks real data, we will erroneously exit
-		 * connection startup slow start one packet too
-		 * quickly.  This is severely frowned upon behavior.
-		 */
-		if (!(scb->flags & TCPCB_FLAG_SYN)) {
-			flag |= FLAG_DATA_ACKED;
-		} else {
-			flag |= FLAG_SYN_ACKED;
-			tp->retrans_stamp = 0;
-		}
-
 		/* MTU probing checks */
 		if (fully_acked && icsk->icsk_mtup.probe_size &&
 		    !after(tp->mtu_probe.probe_seq_end, scb->end_seq)) {
@@ -2613,6 +2603,9 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p)
 					tp->retrans_out -= packets_acked;
 				flag |= FLAG_RETRANS_DATA_ACKED;
 				seq_rtt = -1;
+				if ((flag & FLAG_DATA_ACKED) ||
+				    (packets_acked > 1))
+					flag |= FLAG_NONHEAD_RETRANS_ACKED;
 			} else if (seq_rtt < 0) {
 				seq_rtt = now - scb->when;
 				if (fully_acked)
@@ -2634,6 +2627,20 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p)
 		}
 		tp->packets_out -= packets_acked;
 
+		/* Initial outgoing SYN's get put onto the write_queue
+		 * just like anything else we transmit.  It is not
+		 * true data, and if we misinform our callers that
+		 * this ACK acks real data, we will erroneously exit
+		 * connection startup slow start one packet too
+		 * quickly.  This is severely frowned upon behavior.
+		 */
+		if (!(scb->flags & TCPCB_FLAG_SYN)) {
+			flag |= FLAG_DATA_ACKED;
+		} else {
+			flag |= FLAG_SYN_ACKED;
+			tp->retrans_stamp = 0;
+		}
+
 		if (!fully_acked)
 			break;
 
@@ -2852,6 +2859,10 @@ static int tcp_process_frto(struct sock *sk, int flag)
 	if (flag&FLAG_DATA_ACKED)
 		inet_csk(sk)->icsk_retransmits = 0;
 
+	if ((flag & FLAG_NONHEAD_RETRANS_ACKED) ||
+	    ((tp->frto_counter >= 2) && (flag & FLAG_RETRANS_DATA_ACKED)))
+		tp->undo_marker = 0;
+
 	if (!before(tp->snd_una, tp->frto_highmark)) {
 		tcp_enter_frto_loss(sk, (tp->frto_counter == 1 ? 2 : 3), flag);
 		return 1;
@@ -2916,6 +2927,7 @@ static int tcp_process_frto(struct sock *sk, int flag)
 			break;
 		}
 		tp->frto_counter = 0;
+		tp->undo_marker = 0;
 	}
 	return 0;
 }
-- 
1.5.0.6


^ permalink raw reply related

* [PATCH 4/9] [TCP]: Move accounting from tso_acked to clean_rtx_queue
From: Ilpo Järvinen @ 2007-09-20 12:17 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <11902906723822-git-send-email-ilpo.jarvinen@helsinki.fi>

The accounting code is pretty much the same, so it's a shame
we do it in two places.

I'm not too sure if added fully_acked check in MTU probing is
really what we want perhaps the added end_seq could be used in
the after() comparison.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
 net/ipv4/tcp_input.c |   75 +++++++++++++++++++++----------------------------
 1 files changed, 32 insertions(+), 43 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 89162a9..d340fd5 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2528,14 +2528,12 @@ static void tcp_rearm_rto(struct sock *sk)
 	}
 }
 
-static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
-			 __u32 now, __s32 *seq_rtt)
+static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct tcp_skb_cb *scb = TCP_SKB_CB(skb);
 	__u32 seq = tp->snd_una;
 	__u32 packets_acked;
-	int acked = 0;
 
 	/* If we get here, the whole TSO packet has not been
 	 * acked.
@@ -2548,36 +2546,11 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
 	packets_acked -= tcp_skb_pcount(skb);
 
 	if (packets_acked) {
-		__u8 sacked = scb->sacked;
-
-		acked |= FLAG_DATA_ACKED;
-		if (sacked) {
-			if (sacked & TCPCB_RETRANS) {
-				if (sacked & TCPCB_SACKED_RETRANS)
-					tp->retrans_out -= packets_acked;
-				acked |= FLAG_RETRANS_DATA_ACKED;
-				*seq_rtt = -1;
-			} else if (*seq_rtt < 0)
-				*seq_rtt = now - scb->when;
-			if (sacked & TCPCB_SACKED_ACKED)
-				tp->sacked_out -= packets_acked;
-			if (sacked & TCPCB_LOST)
-				tp->lost_out -= packets_acked;
-			if (sacked & TCPCB_URG) {
-				if (tp->urg_mode &&
-				    !before(seq, tp->snd_up))
-					tp->urg_mode = 0;
-			}
-		} else if (*seq_rtt < 0)
-			*seq_rtt = now - scb->when;
-
-		tp->packets_out -= packets_acked;
-
 		BUG_ON(tcp_skb_pcount(skb) == 0);
 		BUG_ON(!before(scb->seq, scb->end_seq));
 	}
 
-	return acked;
+	return packets_acked;
 }
 
 /* Remove acknowledged frames from the retransmission queue. */
@@ -2587,6 +2560,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
 	const struct inet_connection_sock *icsk = inet_csk(sk);
 	struct sk_buff *skb;
 	__u32 now = tcp_time_stamp;
+	int fully_acked = 1;
 	int acked = 0;
 	int prior_packets = tp->packets_out;
 	__s32 seq_rtt = -1;
@@ -2595,6 +2569,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
 	while ((skb = tcp_write_queue_head(sk)) &&
 	       skb != tcp_send_head(sk)) {
 		struct tcp_skb_cb *scb = TCP_SKB_CB(skb);
+		u32 end_seq;
+		u32 packets_acked;
 		__u8 sacked = scb->sacked;
 
 		/* If our packet is before the ack sequence we can
@@ -2602,11 +2578,19 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
 		 * the other end.
 		 */
 		if (after(scb->end_seq, tp->snd_una)) {
-			if (tcp_skb_pcount(skb) > 1 &&
-			    after(tp->snd_una, scb->seq))
-				acked |= tcp_tso_acked(sk, skb,
-						       now, &seq_rtt);
-			break;
+			if (tcp_skb_pcount(skb) == 1 ||
+			    !after(tp->snd_una, scb->seq))
+				break;
+
+			packets_acked = tcp_tso_acked(sk, skb);
+			if (!packets_acked)
+				break;
+
+			fully_acked = 0;
+			end_seq = tp->snd_una;
+		} else {
+			packets_acked = tcp_skb_pcount(skb);
+			end_seq = scb->end_seq;
 		}
 
 		/* Initial outgoing SYN's get put onto the write_queue
@@ -2624,7 +2608,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
 		}
 
 		/* MTU probing checks */
-		if (icsk->icsk_mtup.probe_size) {
+		if (fully_acked && icsk->icsk_mtup.probe_size) {
 			if (!after(tp->mtu_probe.probe_seq_end, TCP_SKB_CB(skb)->end_seq)) {
 				tcp_mtup_probe_success(sk, skb);
 			}
@@ -2633,27 +2617,32 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
 		if (sacked) {
 			if (sacked & TCPCB_RETRANS) {
 				if (sacked & TCPCB_SACKED_RETRANS)
-					tp->retrans_out -= tcp_skb_pcount(skb);
+					tp->retrans_out -= packets_acked;
 				acked |= FLAG_RETRANS_DATA_ACKED;
 				seq_rtt = -1;
 			} else if (seq_rtt < 0) {
 				seq_rtt = now - scb->when;
-				last_ackt = skb->tstamp;
+				if (fully_acked)
+					last_ackt = skb->tstamp;
 			}
 			if (sacked & TCPCB_SACKED_ACKED)
-				tp->sacked_out -= tcp_skb_pcount(skb);
+				tp->sacked_out -= packets_acked;
 			if (sacked & TCPCB_LOST)
-				tp->lost_out -= tcp_skb_pcount(skb);
+				tp->lost_out -= packets_acked;
 			if (sacked & TCPCB_URG) {
-				if (tp->urg_mode &&
-				    !before(scb->end_seq, tp->snd_up))
+				if (tp->urg_mode && !before(end_seq, tp->snd_up))
 					tp->urg_mode = 0;
 			}
 		} else if (seq_rtt < 0) {
 			seq_rtt = now - scb->when;
-			last_ackt = skb->tstamp;
+			if (fully_acked)
+				last_ackt = skb->tstamp;
 		}
-		tp->packets_out -= tcp_skb_pcount(skb);
+		tp->packets_out -= packets_acked;
+
+		if (!fully_acked)
+			break;
+
 		tcp_unlink_write_queue(skb, sk);
 		sk_stream_free_skb(sk, skb);
 		tcp_clear_all_retrans_hints(tp);
-- 
1.5.0.6


^ permalink raw reply related

* [PATCH 7/9] [TCP] FRTO: Update sysctl documentation
From: Ilpo Järvinen @ 2007-09-20 12:17 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <11902906723159-git-send-email-ilpo.jarvinen@helsinki.fi>

Since the SACK enhanced FRTO was added, the code has been
under test numerous times so remove "experimental" claim
from the documentation. Also be a bit more verbose about
the usage.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
 Documentation/networking/ip-sysctl.txt |   17 ++++++++++++-----
 1 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 32c2e9d..6ae2fef 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -180,13 +180,20 @@ tcp_fin_timeout - INTEGER
 	to live longer.	Cf. tcp_max_orphans.
 
 tcp_frto - INTEGER
-	Enables F-RTO, an enhanced recovery algorithm for TCP retransmission
+	Enables Forward RTO-Recovery (F-RTO) defined in RFC4138.
+	F-RTO is an enhanced recovery algorithm for TCP retransmission
 	timeouts.  It is particularly beneficial in wireless environments
 	where packet loss is typically due to random radio interference
-	rather than intermediate router congestion. If set to 1, basic
-	version is enabled. 2 enables SACK enhanced F-RTO, which is
-	EXPERIMENTAL. The basic version can be used also when SACK is
-	enabled for a flow through tcp_sack sysctl.
+	rather than intermediate router congestion.  FRTO is sender-side
+	only modification.  Therefore it does not require any support from
+	the peer, but in a typical case, however, where wireless link is
+	the local access link and most of the data flows downlink, the
+	faraway servers should have FRTO enabled to take advantage of it.
+	If set to 1, basic version is enabled.  2 enables SACK enhanced
+	F-RTO if flow uses SACK.  The basic version can be used also when
+	SACK is in use though scenario(s) with it exists where FRTO
+	interacts badly with the packet counting of the SACK enabled TCP
+	flow.
 
 tcp_frto_response - INTEGER
 	When F-RTO has detected that a TCP retransmission timeout was
-- 
1.5.0.6


^ permalink raw reply related

* [PATCH 5/9] [TCP]: Cleanup tcp_tso_acked and tcp_clean_rtx_queue
From: Ilpo Järvinen @ 2007-09-20 12:17 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <1190290672770-git-send-email-ilpo.jarvinen@helsinki.fi>

Implements following cleanups:
- Comment re-placement (CodingStyle)
- tcp_tso_acked() local (wrapper-like) variable removal
  (readability)
- __-types removed (IMHO they make local variables jumpy looking
  and just was space)
- acked -> flag (naming conventions elsewhere in TCP code)
- linebreak adjustments (readability)
- nested if()s combined (reduced indentation)
- clarifying newlines added

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
 net/ipv4/tcp_input.c |   66 ++++++++++++++++++++++---------------------------
 1 files changed, 30 insertions(+), 36 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index d340fd5..74accb0 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2528,55 +2528,49 @@ static void tcp_rearm_rto(struct sock *sk)
 	}
 }
 
+/* If we get here, the whole TSO packet has not been acked. */
 static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_skb_cb *scb = TCP_SKB_CB(skb);
-	__u32 seq = tp->snd_una;
-	__u32 packets_acked;
+	u32 packets_acked;
 
-	/* If we get here, the whole TSO packet has not been
-	 * acked.
-	 */
-	BUG_ON(!after(scb->end_seq, seq));
+	BUG_ON(!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una));
 
 	packets_acked = tcp_skb_pcount(skb);
-	if (tcp_trim_head(sk, skb, seq - scb->seq))
+	if (tcp_trim_head(sk, skb, tp->snd_una - TCP_SKB_CB(skb)->seq))
 		return 0;
 	packets_acked -= tcp_skb_pcount(skb);
 
 	if (packets_acked) {
 		BUG_ON(tcp_skb_pcount(skb) == 0);
-		BUG_ON(!before(scb->seq, scb->end_seq));
+		BUG_ON(!before(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq));
 	}
 
 	return packets_acked;
 }
 
-/* Remove acknowledged frames from the retransmission queue. */
-static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
+/* Remove acknowledged frames from the retransmission queue. If our packet
+ * is before the ack sequence we can discard it as it's confirmed to have
+ * arrived at the other end.
+ */
+static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	const struct inet_connection_sock *icsk = inet_csk(sk);
 	struct sk_buff *skb;
-	__u32 now = tcp_time_stamp;
+	u32 now = tcp_time_stamp;
 	int fully_acked = 1;
-	int acked = 0;
+	int flag = 0;
 	int prior_packets = tp->packets_out;
-	__s32 seq_rtt = -1;
+	s32 seq_rtt = -1;
 	ktime_t last_ackt = net_invalid_timestamp();
 
-	while ((skb = tcp_write_queue_head(sk)) &&
-	       skb != tcp_send_head(sk)) {
+	while ((skb = tcp_write_queue_head(sk)) && skb != tcp_send_head(sk)) {
 		struct tcp_skb_cb *scb = TCP_SKB_CB(skb);
 		u32 end_seq;
 		u32 packets_acked;
-		__u8 sacked = scb->sacked;
+		u8 sacked = scb->sacked;
 
-		/* If our packet is before the ack sequence we can
-		 * discard it as it's confirmed to have arrived at
-		 * the other end.
-		 */
 		if (after(scb->end_seq, tp->snd_una)) {
 			if (tcp_skb_pcount(skb) == 1 ||
 			    !after(tp->snd_una, scb->seq))
@@ -2601,38 +2595,38 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
 		 * quickly.  This is severely frowned upon behavior.
 		 */
 		if (!(scb->flags & TCPCB_FLAG_SYN)) {
-			acked |= FLAG_DATA_ACKED;
+			flag |= FLAG_DATA_ACKED;
 		} else {
-			acked |= FLAG_SYN_ACKED;
+			flag |= FLAG_SYN_ACKED;
 			tp->retrans_stamp = 0;
 		}
 
 		/* MTU probing checks */
-		if (fully_acked && icsk->icsk_mtup.probe_size) {
-			if (!after(tp->mtu_probe.probe_seq_end, TCP_SKB_CB(skb)->end_seq)) {
-				tcp_mtup_probe_success(sk, skb);
-			}
+		if (fully_acked && icsk->icsk_mtup.probe_size &&
+		    !after(tp->mtu_probe.probe_seq_end, scb->end_seq)) {
+			tcp_mtup_probe_success(sk, skb);
 		}
 
 		if (sacked) {
 			if (sacked & TCPCB_RETRANS) {
 				if (sacked & TCPCB_SACKED_RETRANS)
 					tp->retrans_out -= packets_acked;
-				acked |= FLAG_RETRANS_DATA_ACKED;
+				flag |= FLAG_RETRANS_DATA_ACKED;
 				seq_rtt = -1;
 			} else if (seq_rtt < 0) {
 				seq_rtt = now - scb->when;
 				if (fully_acked)
 					last_ackt = skb->tstamp;
 			}
+
 			if (sacked & TCPCB_SACKED_ACKED)
 				tp->sacked_out -= packets_acked;
 			if (sacked & TCPCB_LOST)
 				tp->lost_out -= packets_acked;
-			if (sacked & TCPCB_URG) {
-				if (tp->urg_mode && !before(end_seq, tp->snd_up))
-					tp->urg_mode = 0;
-			}
+
+			if ((sacked & TCPCB_URG) && tp->urg_mode &&
+			    !before(end_seq, tp->snd_up))
+				tp->urg_mode = 0;
 		} else if (seq_rtt < 0) {
 			seq_rtt = now - scb->when;
 			if (fully_acked)
@@ -2648,12 +2642,12 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
 		tcp_clear_all_retrans_hints(tp);
 	}
 
-	if (acked&FLAG_ACKED) {
+	if (flag & FLAG_ACKED) {
 		u32 pkts_acked = prior_packets - tp->packets_out;
 		const struct tcp_congestion_ops *ca_ops
 			= inet_csk(sk)->icsk_ca_ops;
 
-		tcp_ack_update_rtt(sk, acked, seq_rtt);
+		tcp_ack_update_rtt(sk, flag, seq_rtt);
 		tcp_rearm_rto(sk);
 
 		tp->fackets_out -= min(pkts_acked, tp->fackets_out);
@@ -2664,7 +2658,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
 			s32 rtt_us = -1;
 
 			/* Is the ACK triggering packet unambiguous? */
-			if (!(acked & FLAG_RETRANS_DATA_ACKED)) {
+			if (!(flag & FLAG_RETRANS_DATA_ACKED)) {
 				/* High resolution needed and available? */
 				if (ca_ops->flags & TCP_CONG_RTT_STAMP &&
 				    !ktime_equal(last_ackt,
@@ -2703,7 +2697,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
 	}
 #endif
 	*seq_rtt_p = seq_rtt;
-	return acked;
+	return flag;
 }
 
 static void tcp_ack_probe(struct sock *sk)
-- 
1.5.0.6


^ permalink raw reply related

* [PATCH 8/9] [TCP]: Enable SACK enhanced FRTO (RFC4138) by default
From: Ilpo Järvinen @ 2007-09-20 12:17 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <1190290672980-git-send-email-ilpo.jarvinen@helsinki.fi>

Most of the description that follows comes from my mail to
netdev (some editing done):

Main obstacle to FRTO use is its deployment as it has to be on
the sender side where as wireless link is often the receiver's
access link. Take initiative on behalf of unlucky receivers and
enable it by default in future Linux TCP senders. Also IETF
seems to interested in advancing FRTO from experimental [1].

How does FRTO help?
===================

FRTO detects spurious RTOs and avoids a number of unnecessary
retransmissions and a couple of other problems that can arise
due to incorrect guess made at RTO (i.e., that segments were
lost when they actually got delayed which is likely to occur
e.g. in wireless environments with link-layer retransmission).
Though FRTO cannot prevent the first (potentially unnecessary)
retransmission at RTO, I suspect that it won't cost that much
even if you have to pay for each bit (won't be that high
percentage out of all packets after all :-)). However, usually
when you have a spurious RTO, not only the first segment
unnecessarily retransmitted but the *whole window*. It goes like
this: all cumulative ACKs got delayed due to in-order delivery,
then TCP will actually send 1.5*original cwnd worth of data in
the RTO's slow-start when the delayed ACKs arrive (basically the
original cwnd worth of it unnecessarily). In case one is
interested in minimizing unnecessary retransmissions e.g. due to
cost, those rexmissions must never see daylight. Besides, in the
worst case the generated burst overloads the bottleneck buffers
which is likely to significantly delay the further progress of
the flow. In case of ll rexmissions, ACK compression often
occurs at the same time making the burst very "sharp edged" (in
that case TCP often loses most of the segments above high_seq
=> very bad performance too). When FRTO is enabled, those
unnecessary retransmissions are fully avoided except for the
first segment and the cwnd behavior after detected spurious RTO
is determined by the response (one can tune that by sysctl).

Basic version (non-SACK enhanced one), FRTO can fail to detect
spurious RTO as spurious and falls back to conservative
behavior. ACK lossage is much less significant than reordering,
usually the FRTO can detect spurious RTO if at least 2
cumulative ACKs from original window are preserved (excluding
the ACK that advances to high_seq). With SACK-enhanced version,
the detection is quite robust.

FRTO should remove the need to set a high lower bound for the
RTO estimator due to delay spikes that occur relatively common
in some environments (esp. in wireless/cellular ones).

[1] http://www1.ietf.org/mail-archive/web/tcpm/current/msg02862.html

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
 net/ipv4/tcp_input.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 948e79a..02b549b 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -85,7 +85,7 @@ int sysctl_tcp_adv_win_scale __read_mostly = 2;
 int sysctl_tcp_stdurg __read_mostly;
 int sysctl_tcp_rfc1337 __read_mostly;
 int sysctl_tcp_max_orphans __read_mostly = NR_FILE;
-int sysctl_tcp_frto __read_mostly;
+int sysctl_tcp_frto __read_mostly = 2;
 int sysctl_tcp_frto_response __read_mostly;
 int sysctl_tcp_nometrics_save __read_mostly;
 
-- 
1.5.0.6


^ permalink raw reply related


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