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
     

11 Oct, 2007

1 commit


15 Jul, 2007

1 commit


06 Mar, 2007

1 commit


22 Nov, 2006

1 commit

  • Pass the work_struct pointer to the work function rather than context data.
    The work function can use container_of() to work out the data.

    For the cases where the container of the work_struct may go away the moment the
    pending bit is cleared, it is made possible to defer the release of the
    structure by deferring the clearing of the pending bit.

    To make this work, an extra flag is introduced into the management side of the
    work_struct. This governs auto-release of the structure upon execution.

    Ordinarily, the work queue executor would release the work_struct for further
    scheduling or deallocation by clearing the pending bit prior to jumping to the
    work function. This means that, unless the driver makes some guarantee itself
    that the work_struct won't go away, the work function may not access anything
    else in the work_struct or its container lest they be deallocated.. This is a
    problem if the auxiliary data is taken away (as done by the last patch).

    However, if the pending bit is *not* cleared before jumping to the work
    function, then the work function *may* access the work_struct and its container
    with no problems. But then the work function must itself release the
    work_struct by calling work_release().

    In most cases, automatic release is fine, so this is the default. Special
    initiators exist for the non-auto-release case (ending in _NAR).

    Signed-Off-By: David Howells

    David Howells
     

12 Oct, 2006

1 commit


29 Sep, 2006

2 commits


07 May, 2006

1 commit


30 Apr, 2006

1 commit


26 Apr, 2006

1 commit


04 Jan, 2006

3 commits

  • To help in reducing the number of include dependencies, several files were
    touched as they were getting needed headers indirectly for stuff they use.

    Thanks also to Alan Menegotto for pointing out that net/dccp/proto.c had
    linux/dccp.h include twice.

    Signed-off-by: Arnaldo Carvalho de Melo
    Signed-off-by: David S. Miller

    Arnaldo Carvalho de Melo
     
  • So that we can share several timewait sockets related functions and
    make the timewait mini sockets infrastructure closer to the request
    mini sockets one.

    Next changesets will take advantage of this, moving more code out of
    TCP and DCCP v4 and v6 to common infrastructure.

    Signed-off-by: Arnaldo Carvalho de Melo
    Signed-off-by: David S. Miller

    Arnaldo Carvalho de Melo
     
  • Out of tcp6_timewait_sock, that now is just an aggregation of
    inet_timewait_sock and inet6_timewait_sock, using tw_ipv6_offset in struct
    inet_timewait_sock, that is common to the IPv6 transport protocols that use
    timewait sockets, like DCCP and TCP.

    tw_ipv6_offset plays the struct inet_sock pinfo6 role, i.e. for the generic
    code to find the IPv6 area in a timewait sock.

    Signed-off-by: Arnaldo Carvalho de Melo
    Signed-off-by: David S. Miller

    Arnaldo Carvalho de Melo
     

11 Oct, 2005

1 commit


04 Oct, 2005

1 commit

  • Arnaldo and I agreed it could be applied now, because I have other
    pending patches depending on this one (Thank you Arnaldo)

    (The other important patch moves skc_refcnt in a separate cache line,
    so that the SMP/NUMA performance doesnt suffer from cache line ping pongs)

    1) First some performance data :
    --------------------------------

    tcp_v4_rcv() wastes a *lot* of time in __inet_lookup_established()

    The most time critical code is :

    sk_for_each(sk, node, &head->chain) {
    if (INET_MATCH(sk, acookie, saddr, daddr, ports, dif))
    goto hit; /* You sunk my battleship! */
    }

    The sk_for_each() does use prefetch() hints but only the begining of
    "struct sock" is prefetched.

    As INET_MATCH first comparison uses inet_sk(__sk)->daddr, wich is far
    away from the begining of "struct sock", it has to bring into CPU
    cache cold cache line. Each iteration has to use at least 2 cache
    lines.

    This can be problematic if some chains are very long.

    2) The goal
    -----------

    The idea I had is to change things so that INET_MATCH() may return
    FALSE in 99% of cases only using the data already in the CPU cache,
    using one cache line per iteration.

    3) Description of the patch
    ---------------------------

    Adds a new 'unsigned int skc_hash' field in 'struct sock_common',
    filling a 32 bits hole on 64 bits platform.

    struct sock_common {
    unsigned short skc_family;
    volatile unsigned char skc_state;
    unsigned char skc_reuse;
    int skc_bound_dev_if;
    struct hlist_node skc_node;
    struct hlist_node skc_bind_node;
    atomic_t skc_refcnt;
    + unsigned int skc_hash;
    struct proto *skc_prot;
    };

    Store in this 32 bits field the full hash, not masked by (ehash_size -
    1) Using this full hash as the first comparison done in INET_MATCH
    permits us immediatly skip the element without touching a second cache
    line in case of a miss.

    Suppress the sk_hashent/tw_hashent fields since skc_hash (aliased to
    sk_hash and tw_hash) already contains the slot number if we mask with
    (ehash_size - 1)

    File include/net/inet_hashtables.h

    64 bits platforms :
    #define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
    (((__sk)->sk_hash == (__hash))
    ((*((__u64 *)&(inet_sk(__sk)->daddr)))== (__cookie)) && \
    ((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports)) && \
    (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))

    32bits platforms:
    #define TCP_IPV4_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
    (((__sk)->sk_hash == (__hash)) && \
    (inet_sk(__sk)->daddr == (__saddr)) && \
    (inet_sk(__sk)->rcv_saddr == (__daddr)) && \
    (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))

    - Adds a prefetch(head->chain.first) in
    __inet_lookup_established()/__tcp_v4_check_established() and
    __inet6_lookup_established()/__tcp_v6_check_established() and
    __dccp_v4_check_established() to bring into cache the first element of the
    list, before the {read|write}_lock(&head->lock);

    Signed-off-by: Eric Dumazet
    Acked-by: Arnaldo Carvalho de Melo
    Signed-off-by: David S. Miller

    Eric Dumazet
     

30 Aug, 2005

3 commits