20 Oct, 2015

1 commit


13 Oct, 2015

1 commit

  • sk->sk_refcnt is dirtied for every TCP/UDP incoming packet.
    This is a performance issue if multiple cpus hit a common socket,
    or multiple sockets are chained due to SO_REUSEPORT.

    By moving sk_refcnt 8 bytes further, first 128 bytes of sockets
    are mostly read. As they contain the lookup keys, this has
    a considerable performance impact, as cpus can cache them.

    These 8 bytes are not wasted, we use them as a place holder
    for various fields, depending on the socket type.

    Tested:
    SYN flood hitting a 16 RX queues NIC.
    TCP listener using 16 sockets and SO_REUSEPORT
    and SO_INCOMING_CPU for proper siloing.

    Could process 6.0 Mpps SYN instead of 4.2 Mpps

    Kernel profile looked like :
    11.68% [kernel] [k] sha_transform
    6.51% [kernel] [k] __inet_lookup_listener
    5.07% [kernel] [k] __inet_lookup_established
    4.15% [kernel] [k] memcpy_erms
    3.46% [kernel] [k] ipt_do_table
    2.74% [kernel] [k] fib_table_lookup
    2.54% [kernel] [k] tcp_make_synack
    2.34% [kernel] [k] tcp_conn_request
    2.05% [kernel] [k] __netif_receive_skb_core
    2.03% [kernel] [k] kmem_cache_alloc

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

05 Oct, 2015

1 commit

  • I’m using the compilation flag -Werror=old-style-declaration, which
    requires that the “inline” word would come at the beginning of the code
    line.

    $ make drivers/net/ethernet/intel/e1000e/e1000e.ko
    ...
    include/net/inet_timewait_sock.h:116:1: error: ‘inline’ is not at
    beginning of declaration [-Werror=old-style-declaration]
    static void inline inet_twsk_schedule(struct inet_timewait_sock *tw, int
    timeo)

    include/net/inet_timewait_sock.h:121:1: error: ‘inline’ is not at
    beginning of declaration [-Werror=old-style-declaration]
    static void inline inet_twsk_reschedule(struct inet_timewait_sock *tw,
    int timeo)

    Fixes: ed2e92394589 ("tcp/dccp: fix timewait races in timer handling")
    Signed-off-by: Raanan Avargil
    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Raanan Avargil
     

22 Sep, 2015

1 commit

  • When creating a timewait socket, we need to arm the timer before
    allowing other cpus to find it. The signal allowing cpus to find
    the socket is setting tw_refcnt to non zero value.

    As we set tw_refcnt in __inet_twsk_hashdance(), we therefore need to
    call inet_twsk_schedule() first.

    This also means we need to remove tw_refcnt changes from
    inet_twsk_schedule() and let the caller handle it.

    Note that because we use mod_timer_pinned(), we have the guarantee
    the timer wont expire before we set tw_refcnt as we run in BH context.

    To make things more readable I introduced inet_twsk_reschedule() helper.

    When rearming the timer, we can use mod_timer_pending() to make sure
    we do not rearm a canceled timer.

    Note: This bug can possibly trigger if packets of a flow can hit
    multiple cpus. This does not normally happen, unless flow steering
    is broken somehow. This explains this bug was spotted ~5 months after
    its introduction.

    A similar fix is needed for SYN_RECV sockets in reqsk_queue_hash_req(),
    but will be provided in a separate patch for proper tracking.

    Fixes: 789f558cfb36 ("tcp/dccp: get rid of central timewait timer")
    Signed-off-by: Eric Dumazet
    Reported-by: Ying Cai
    Signed-off-by: David S. Miller

    Eric Dumazet
     

10 Jul, 2015

2 commits

  • inet_twsk_deschedule() calls are followed by inet_twsk_put().

    Only particular case is in inet_twsk_purge() but there is no point
    to defer the inet_twsk_put() after re-enabling BH.

    Lets rename inet_twsk_deschedule() to inet_twsk_deschedule_put()
    and move the inet_twsk_put() inside.

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     
  • timewait sockets have a complex refcounting logic.
    Once we realize it should be similar to established and
    syn_recv sockets, we can use sk_nulls_del_node_init_rcu()
    and remove inet_twsk_unhash()

    In particular, deferred inet_twsk_put() added in commit
    13475a30b66cd ("tcp: connect() race with timewait reuse")
    looks unecessary : When removing a timewait socket from
    ehash or bhash, caller must own a reference on the socket
    anyway.

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

14 Apr, 2015

1 commit

  • Using a timer wheel for timewait sockets was nice ~15 years ago when
    memory was expensive and machines had a single processor.

    This does not scale, code is ugly and source of huge latencies
    (Typically 30 ms have been seen, cpus spinning on death_lock spinlock.)

    We can afford to use an extra 64 bytes per timewait sock and spread
    timewait load to all cpus to have better behavior.

    Tested:

    On following test, /proc/sys/net/ipv4/tcp_tw_recycle is set to 1
    on the target (lpaa24)

    Before patch :

    lpaa23:~# ./super_netperf 200 -H lpaa24 -t TCP_CC -l 60 -- -p0,0
    419594

    lpaa23:~# ./super_netperf 200 -H lpaa24 -t TCP_CC -l 60 -- -p0,0
    437171

    While test is running, we can observe 25 or even 33 ms latencies.

    lpaa24:~# ping -c 1000 -i 0.02 -qn lpaa23
    ...
    1000 packets transmitted, 1000 received, 0% packet loss, time 20601ms
    rtt min/avg/max/mdev = 0.020/0.217/25.771/1.535 ms, pipe 2

    lpaa24:~# ping -c 1000 -i 0.02 -qn lpaa23
    ...
    1000 packets transmitted, 1000 received, 0% packet loss, time 20702ms
    rtt min/avg/max/mdev = 0.019/0.183/33.761/1.441 ms, pipe 2

    After patch :

    About 90% increase of throughput :

    lpaa23:~# ./super_netperf 200 -H lpaa24 -t TCP_CC -l 60 -- -p0,0
    810442

    lpaa23:~# ./super_netperf 200 -H lpaa24 -t TCP_CC -l 60 -- -p0,0
    800992

    And latencies are kept to minimal values during this load, even
    if network utilization is 90% higher :

    lpaa24:~# ping -c 1000 -i 0.02 -qn lpaa23
    ...
    1000 packets transmitted, 1000 received, 0% packet loss, time 19991ms
    rtt min/avg/max/mdev = 0.023/0.064/0.360/0.042 ms

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

12 Mar, 2015

1 commit

  • A long standing problem in netlink socket dumps is the use
    of kernel socket addresses as cookies.

    1) It is a security concern.

    2) Sockets can be reused quite quickly, so there is
    no guarantee a cookie is used once and identify
    a flow.

    3) request sock, establish sock, and timewait socks
    for a given flow have different cookies.

    Part of our effort to bring better TCP statistics requires
    to switch to a different allocator.

    In this patch, I chose to use a per network namespace 64bit generator,
    and to use it only in the case a socket needs to be dumped to netlink.
    (This might be refined later if needed)

    Note that I tried to carry cookies from request sock, to establish sock,
    then timewait sockets.

    Signed-off-by: Eric Dumazet
    Cc: Eric Salo
    Signed-off-by: David S. Miller

    Eric Dumazet
     

02 Jul, 2014

1 commit

  • When an UDP application switches from AF_INET to AF_INET6 sockets, we
    have a small performance degradation for IPv4 communications because of
    extra cache line misses to access ipv6only information.

    This can also be noticed for TCP listeners, as ipv6_only_sock() is also
    used from __inet_lookup_listener()->compute_score()

    This is magnified when SO_REUSEPORT is used.

    Move ipv6only into struct sock_common so that it is available at
    no extra cost in lookups.

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

18 Jan, 2014

1 commit


18 Oct, 2013

1 commit


09 Oct, 2013

2 commits

  • TCP listener refactoring, part 4 :

    To speed up inet lookups, we moved IPv4 addresses from inet to struct
    sock_common

    Now is time to do the same for IPv6, because it permits us to have fast
    lookups for all kind of sockets, including upcoming SYN_RECV.

    Getting IPv6 addresses in TCP lookups currently requires two extra cache
    lines, plus a dereference (and memory stall).

    inet6_sk(sk) does the dereference of inet_sk(__sk)->pinet6

    This patch is way bigger than its IPv4 counter part, because for IPv4,
    we could add aliases (inet_daddr, inet_rcv_saddr), while on IPv6,
    it's not doable easily.

    inet6_sk(sk)->daddr becomes sk->sk_v6_daddr
    inet6_sk(sk)->rcv_saddr becomes sk->sk_v6_rcv_saddr

    And timewait socket also have tw->tw_v6_daddr & tw->tw_v6_rcv_saddr
    at the same offset.

    We get rid of INET6_TW_MATCH() as INET6_MATCH() is now the generic
    macro.

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     
  • TCP listener refactoring, part 3 :

    Our goal is to hash SYN_RECV sockets into main ehash for fast lookup,
    and parallel SYN processing.

    Current inet_ehash_bucket contains two chains, one for ESTABLISH (and
    friend states) sockets, another for TIME_WAIT sockets only.

    As the hash table is sized to get at most one socket per bucket, it
    makes little sense to have separate twchain, as it makes the lookup
    slightly more complicated, and doubles hash table memory usage.

    If we make sure all socket types have the lookup keys at the same
    offsets, we can use a generic and faster lookup. It turns out TIME_WAIT
    and ESTABLISHED sockets already have common lookup fields for IPv4.

    [ INET_TW_MATCH() is no longer needed ]

    I'll provide a follow-up to factorize IPv6 lookup as well, to remove
    INET6_TW_MATCH()

    This way, SYN_RECV pseudo sockets will be supported the same.

    A new sock_gen_put() helper is added, doing either a sock_put() or
    inet_twsk_put() [ and will support SYN_RECV later ].

    Note this helper should only be called in real slow path, when rcu
    lookup found a socket that was moved to another identity (freed/reused
    immediately), but could eventually be used in other contexts, like
    sock_edemux()

    Before patch :

    dmesg | grep "TCP established"

    TCP established hash table entries: 524288 (order: 11, 8388608 bytes)

    After patch :

    TCP established hash table entries: 524288 (order: 10, 4194304 bytes)

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

04 Oct, 2013

2 commits

  • While working on tcp listener refactoring, I found that it
    would really make things easier if sock_common could include
    the IPv6 addresses needed in the lookups, instead of doing
    very complex games to get their values (depending on sock
    being SYN_RECV, ESTABLISHED, TIME_WAIT)

    For this to happen, I need to be sure that tcp6_timewait_sock
    and tcp_timewait_sock consume same number of cache lines.

    This is possible if we only use 32bits for tw_ttd, as we remove
    one 32bit hole in inet_timewait_sock

    inet_tw_time_stamp() is defined and used, even if its current
    implementation looks like tcp_time_stamp : We might need finer
    resolution for tcp_time_stamp in the future.

    Before patch : sizeof(struct tcp6_timewait_sock) = 0xc8

    After patch : sizeof(struct tcp6_timewait_sock) = 0xc0

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     
  • TCP listener refactoring, part 2 :

    We can use a generic lookup, sockets being in whatever state, if
    we are sure all relevant fields are at the same place in all socket
    types (ESTABLISH, TIME_WAIT, SYN_RECV)

    This patch removes these macros :

    inet_addrpair, inet_addrpair, tw_addrpair, tw_portpair

    And adds :

    sk_portpair, sk_addrpair, sk_daddr, sk_rcv_saddr

    Then, INET_TW_MATCH() is really the same than INET_MATCH()

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

22 Sep, 2013

1 commit

  • There are a mix of function prototypes with and without extern
    in the kernel sources. Standardize on not using extern for
    function prototypes.

    Function prototypes don't need to be written with extern.
    extern is assumed by the compiler. Its use is as unnecessary as
    using auto to declare automatic/local variables in a block.

    Signed-off-by: Joe Perches
    Signed-off-by: David S. Miller

    Joe Perches
     

28 Feb, 2013

1 commit

  • I'm not sure why, but the hlist for each entry iterators were conceived

    list_for_each_entry(pos, head, member)

    The hlist ones were greedy and wanted an extra parameter:

    hlist_for_each_entry(tpos, pos, head, member)

    Why did they need an extra pos parameter? I'm not quite sure. Not only
    they don't really need it, it also prevents the iterator from looking
    exactly like the list iterator, which is unfortunate.

    Besides the semantic patch, there was some manual work required:

    - Fix up the actual hlist iterators in linux/list.h
    - Fix up the declaration of other iterators based on the hlist ones.
    - A very small amount of places were using the 'node' parameter, this
    was modified to use 'obj->member' instead.
    - Coccinelle didn't handle the hlist_for_each_entry_safe iterator
    properly, so those had to be fixed up manually.

    The semantic patch which is mostly the work of Peter Senna Tschudin is here:

    @@
    iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;

    type T;
    expression a,c,d,e;
    identifier b;
    statement S;
    @@

    -T b;

    [akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
    [akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
    [akpm@linux-foundation.org: checkpatch fixes]
    [akpm@linux-foundation.org: fix warnings]
    [akpm@linux-foudnation.org: redo intrusive kvm changes]
    Tested-by: Peter Senna Tschudin
    Acked-by: Paul E. McKenney
    Signed-off-by: Sasha Levin
    Cc: Wu Fengguang
    Cc: Marcelo Tosatti
    Cc: Gleb Natapov
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Sasha Levin
     

01 Dec, 2012

1 commit

  • commit 68835aba4d9b (net: optimize INET input path further)
    moved some fields used for tcp/udp sockets lookup in the first cache
    line of struct sock_common.

    This patch moves inet_dport/inet_num as well, filling a 32bit hole
    on 64 bit arches and reducing number of cache line misses in lookups.

    Also change INET_MATCH()/INET_TW_MATCH() to perform the ports match
    before addresses match, as this check is more discriminant.

    Remove the hash check from MATCH() macros because we dont need to
    re validate the hash value after taking a refcount on socket, and
    use likely/unlikely compiler hints, as the sk_hash/hash check
    makes the following conditional tests 100% predicted by cpu.

    Introduce skc_addrpair/skc_portpair pair values to better
    document the alignment requirements of the port/addr pairs
    used in the various MATCH() macros, and remove some casts.

    The namespace check can also be done at last.

    This slightly improves TCP/UDP lookup times.

    IP/TCP early demux needs inet->rx_dst_ifindex and
    TCP needs inet->min_ttl, lets group them together in same cache line.

    With help from Ben Hutchings & Joe Perches.

    Idea of this patch came after Ling Ma proposal to move skc_hash
    to the beginning of struct sock_common, and should allow him
    to submit a final version of his patch. My tests show an improvement
    doing so.

    Signed-off-by: Eric Dumazet
    Cc: Ben Hutchings
    Cc: Joe Perches
    Cc: Ling Ma
    Signed-off-by: David S. Miller

    Eric Dumazet
     

15 Dec, 2011

1 commit

  • commit b099ce2602d806 (net: Batch inet_twsk_purge) added rcu protection
    on tw_net for no obvious reason.

    struct net are refcounted anyway since timewait sockets escape from rcu
    protected sections. tw_net stay valid for the whole timwait lifetime.

    This also removes a lot of sparse errors.

    Signed-off-by: Eric Dumazet
    CC: Eric W. Biederman
    Signed-off-by: David S. Miller

    Eric Dumazet
     

07 Nov, 2011

1 commit

  • * 'modsplit-Oct31_2011' of git://git.kernel.org/pub/scm/linux/kernel/git/paulg/linux: (230 commits)
    Revert "tracing: Include module.h in define_trace.h"
    irq: don't put module.h into irq.h for tracking irqgen modules.
    bluetooth: macroize two small inlines to avoid module.h
    ip_vs.h: fix implicit use of module_get/module_put from module.h
    nf_conntrack.h: fix up fallout from implicit moduleparam.h presence
    include: replace linux/module.h with "struct module" wherever possible
    include: convert various register fcns to macros to avoid include chaining
    crypto.h: remove unused crypto_tfm_alg_modname() inline
    uwb.h: fix implicit use of asm/page.h for PAGE_SIZE
    pm_runtime.h: explicitly requires notifier.h
    linux/dmaengine.h: fix implicit use of bitmap.h and asm/page.h
    miscdevice.h: fix up implicit use of lists and types
    stop_machine.h: fix implicit use of smp.h for smp_processor_id
    of: fix implicit use of errno.h in include/linux/of.h
    of_platform.h: delete needless include
    acpi: remove module.h include from platform/aclinux.h
    miscdevice.h: delete unnecessary inclusion of module.h
    device_cgroup.h: delete needless include
    net: sch_generic remove redundant use of
    net: inet_timewait_sock doesnt need
    ...

    Fix up trivial conflicts (other header files, and removal of the ab3550 mfd driver) in
    - drivers/media/dvb/frontends/dibx000_common.c
    - drivers/media/video/{mt9m111.c,ov6650.c}
    - drivers/mfd/ab3550-core.c
    - include/linux/dmaengine.h

    Linus Torvalds
     

01 Nov, 2011

1 commit


27 Oct, 2011

1 commit

  • commit 66b13d99d96a (ipv4: tcp: fix TOS value in ACK messages sent from
    TIME_WAIT) fixed IPv4 only.

    This part is for the IPv6 side, adding a tclass param to ip6_xmit()

    We alias tw_tclass and tw_tos, if socket family is INET6.

    [ if sockets is ipv4-mapped, only IP_TOS socket option is used to fill
    TOS field, TCLASS is not taken into account ]

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

24 Oct, 2011

1 commit

  • There is a long standing bug in linux tcp stack, about ACK messages sent
    on behalf of TIME_WAIT sockets.

    In the IP header of the ACK message, we choose to reflect TOS field of
    incoming message, and this might break some setups.

    Example of things that were broken :
    - Routing using TOS as a selector
    - Firewalls
    - Trafic classification / shaping

    We now remember in timewait structure the inet tos field and use it in
    ACK generation, and route lookup.

    Notes :
    - We still reflect incoming TOS in RST messages.
    - We could extend MuraliRaja Muniraju patch to report TOS value in
    netlink messages for TIME_WAIT sockets.
    - A patch is needed for IPv6

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

27 Jul, 2011

1 commit

  • This allows us to move duplicated code in
    (atomic_inc_not_zero() for now) to

    Signed-off-by: Arun Sharma
    Reviewed-by: Eric Dumazet
    Cc: Ingo Molnar
    Cc: David Miller
    Cc: Eric Dumazet
    Acked-by: Mike Frysinger
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Arun Sharma
     

10 Dec, 2010

1 commit

  • Followup of commit b178bb3dfc30 (net: reorder struct sock fields)

    Optimize INET input path a bit further, by :

    1) moving sk_refcnt close to sk_lock.

    This reduces number of dirtied cache lines by one on 64bit arches (and
    64 bytes cache line size).

    2) moving inet_daddr & inet_rcv_saddr at the beginning of sk

    (same cache line than hash / family / bound_dev_if / nulls_node)

    This reduces number of accessed cache lines in lookups by one, and dont
    increase size of inet and timewait socks.
    inet and tw sockets now share same place-holder for these fields.

    Before patch :

    offsetof(struct sock, sk_refcnt) = 0x10
    offsetof(struct sock, sk_lock) = 0x40
    offsetof(struct sock, sk_receive_queue) = 0x60
    offsetof(struct inet_sock, inet_daddr) = 0x270
    offsetof(struct inet_sock, inet_rcv_saddr) = 0x274

    After patch :

    offsetof(struct sock, sk_refcnt) = 0x44
    offsetof(struct sock, sk_lock) = 0x48
    offsetof(struct sock, sk_receive_queue) = 0x68
    offsetof(struct inet_sock, inet_daddr) = 0x0
    offsetof(struct inet_sock, inet_rcv_saddr) = 0x4

    compute_score() (udp or tcp) now use a single cache line per ignored
    item, instead of two.

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

28 Apr, 2010

1 commit

  • Calls to twsk_net() are in some cases protected by reference counting
    as an alternative to RCU protection. Cases covered by reference counts
    include __inet_twsk_kill(), inet_twsk_free(), inet_twdr_do_twkill_work(),
    inet_twdr_twcal_tick(), and tcp_timewait_state_process(). RCU is used
    by inet_twsk_purge(). Locking is used by established_get_first()
    and established_get_next(). Finally, __inet_twsk_hashdance() is an
    initialization case.

    It appears to be non-trivial to locate the appropriate locks and
    reference counts from within twsk_net(), so used rcu_dereference_raw().

    Signed-off-by: Paul E. McKenney
    Acked-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Paul E. McKenney
     

09 Dec, 2009

1 commit

  • When we find a timewait connection in __inet_hash_connect() and reuse
    it for a new connection request, we have a race window, releasing bind
    list lock and reacquiring it in __inet_twsk_kill() to remove timewait
    socket from list.

    Another thread might find the timewait socket we already chose, leading to
    list corruption and crashes.

    Fix is to remove timewait socket from bind list before releasing the bind lock.

    Note: This problem happens if sysctl_tcp_tw_reuse is set.

    Reported-by: kapil dakhane
    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

04 Dec, 2009

2 commits

  • Its currently possible that several threads issuing a connect() find
    the same timewait socket and try to reuse it, leading to list
    corruptions.

    Condition for bug is that these threads bound their socket on same
    address/port of to-be-find timewait socket, and connected to same
    target. (SO_REUSEADDR needed)

    To fix this problem, we could unhash timewait socket while holding
    ehash lock, to make sure lookups/changes will be serialized. Only
    first thread finds the timewait socket, other ones find the
    established socket and return an EADDRNOTAVAIL error.

    This second version takes into account Evgeniy's review and makes sure
    inet_twsk_put() is called outside of locked sections.

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     
  • This function walks the whole hashtable so there is no point in
    passing it a network namespace. Instead I purge all timewait
    sockets from dead network namespaces that I find. If the namespace
    is one of the once I am trying to purge I am guaranteed no new timewait
    sockets can be formed so this will get them all. If the namespace
    is one I am not acting for it might form a few more but I will
    call inet_twsk_purge again and shortly to get rid of them. In
    any even if the network namespace is dead timewait sockets are
    useless.

    Move the calls of inet_twsk_purge into batch_exit routines so
    that if I am killing a bunch of namespaces at once I will just
    call inet_twsk_purge once and save a lot of redundant unnecessary
    work.

    My simple 4k network namespace exit test the cleanup time dropped from
    roughly 8.2s to 1.6s. While the time spent running inet_twsk_purge fell
    to about 2ms. 1ms for ipv4 and 1ms for ipv6.

    Signed-off-by: Eric W. Biederman
    Signed-off-by: David S. Miller

    Eric W. Biederman
     

27 Oct, 2009

1 commit


20 Oct, 2009

1 commit


19 Oct, 2009

1 commit

  • In order to have better cache layouts of struct sock (separate zones
    for rx/tx paths), we need this preliminary patch.

    Goal is to transfert fields used at lookup time in the first
    read-mostly cache line (inside struct sock_common) and move sk_refcnt
    to a separate cache line (only written by rx path)

    This patch adds inet_ prefix to daddr, rcv_saddr, dport, num, saddr,
    sport and id fields. This allows a future patch to define these
    fields as macros, like sk_refcnt, without name clashes.

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

15 Jun, 2009

1 commit


17 Nov, 2008

1 commit

  • RCU was added to UDP lookups, using a fast infrastructure :
    - sockets kmem_cache use SLAB_DESTROY_BY_RCU and dont pay the
    price of call_rcu() at freeing time.
    - hlist_nulls permits to use few memory barriers.

    This patch uses same infrastructure for TCP/DCCP established
    and timewait sockets.

    Thanks to SLAB_DESTROY_BY_RCU, no slowdown for applications
    using short lived TCP connections. A followup patch, converting
    rwlocks to spinlocks will even speedup this case.

    __inet_lookup_established() is pretty fast now we dont have to
    dirty a contended cache line (read_lock/read_unlock)

    Only established and timewait hashtable are converted to RCU
    (bind table and listen table are still using traditional locking)

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

01 Oct, 2008

1 commit


09 Sep, 2008

1 commit

  • How to reproduce ?
    - create a network namespace
    - use tcp protocol and get timewait socket
    - exit the network namespace
    - after a moment (when the timewait socket is destroyed), the kernel
    panics.

    # BUG: unable to handle kernel NULL pointer dereference at
    0000000000000007
    IP: [] inet_twdr_do_twkill_work+0x6e/0xb8
    PGD 119985067 PUD 11c5c0067 PMD 0
    Oops: 0000 [1] SMP
    CPU 1
    Modules linked in: ipv6 button battery ac loop dm_mod tg3 libphy ext3 jbd
    edd fan thermal processor thermal_sys sg sata_svw libata dock serverworks
    sd_mod scsi_mod ide_disk ide_core [last unloaded: freq_table]
    Pid: 0, comm: swapper Not tainted 2.6.27-rc2 #3
    RIP: 0010:[] []
    inet_twdr_do_twkill_work+0x6e/0xb8
    RSP: 0018:ffff88011ff7fed0 EFLAGS: 00010246
    RAX: ffffffffffffffff RBX: ffffffff82339420 RCX: ffff88011ff7ff30
    RDX: 0000000000000001 RSI: ffff88011a4d03c0 RDI: ffff88011ac2fc00
    RBP: ffffffff823392e0 R08: 0000000000000000 R09: ffff88002802a200
    R10: ffff8800a5c4b000 R11: ffffffff823e4080 R12: ffff88011ac2fc00
    R13: 0000000000000001 R14: 0000000000000001 R15: 0000000000000000
    FS: 0000000041cbd940(0000) GS:ffff8800bff839c0(0000)
    knlGS:0000000000000000
    CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
    CR2: 0000000000000007 CR3: 00000000bd87c000 CR4: 00000000000006e0
    DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
    Process swapper (pid: 0, threadinfo ffff8800bff9e000, task
    ffff88011ff76690)
    Stack: ffffffff823392e0 0000000000000100 ffffffff821e3a3a
    0000000000000008
    0000000000000000 ffffffff821e3a61 ffff8800bff7c000 ffffffff8203c7e7
    ffff88011ff7ff10 ffff88011ff7ff10 0000000000000021 ffffffff82351108
    Call Trace:
    [] ? inet_twdr_hangman+0x0/0x9e
    [] ? inet_twdr_hangman+0x27/0x9e
    [] ? run_timer_softirq+0x12c/0x193
    [] ? __do_softirq+0x5e/0xcd
    [] ? call_softirq+0x1c/0x28
    [] ? do_softirq+0x2c/0x68
    [] ? smp_apic_timer_interrupt+0x8e/0xa9
    [] ? apic_timer_interrupt+0x66/0x70
    [] ? default_idle+0x27/0x3b
    [] ? cpu_idle+0x5f/0x7d

    Code: e8 01 00 00 4c 89 e7 41 ff c5 e8 8d fd ff ff 49 8b 44 24 38 4c 89 e7
    65 8b 14 25 24 00 00 00 89 d2 48 8b 80 e8 00 00 00 48 f7 d0 8b 04 d0
    48 ff 40 58 e8 fc fc ff ff 48 89 df e8 c0 5f 04 00
    RIP [] inet_twdr_do_twkill_work+0x6e/0xb8
    RSP
    CR2: 0000000000000007

    This patch provides a function to purge all timewait sockets related
    to a network namespace. The timewait sockets life cycle is not tied with
    the network namespace, that means the timewait sockets stay alive while
    the network namespace dies. The timewait sockets are for avoiding to
    receive a duplicate packet from the network, if the network namespace is
    freed, the network stack is removed, so no chance to receive any packets
    from the outside world. Furthermore, having a pending destruction timer
    on these sockets with a network namespace freed is not safe and will lead
    to an oops if the timer callback which try to access data belonging to
    the namespace like for example in:
    inet_twdr_do_twkill_work
    -> NET_INC_STATS_BH(twsk_net(tw), LINUX_MIB_TIMEWAITED);

    Purging the timewait sockets at the network namespace destruction will:
    1) speed up memory freeing for the namespace
    2) fix kernel panic on asynchronous timewait destruction

    Signed-off-by: Daniel Lezcano
    Acked-by: Denis V. Lunev
    Acked-by: Eric W. Biederman
    Signed-off-by: David S. Miller

    Daniel Lezcano
     

26 Mar, 2008

2 commits


03 Feb, 2008

1 commit


29 Jan, 2008

1 commit

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

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

    Export it for ipv6 module.

    Signed-off-by: Pavel Emelyanov
    Signed-off-by: David S. Miller

    Pavel Emelyanov