• Wangyang Guo's avatar
    net: dst: Prevent false sharing vs. dst_entry:: __refcnt · d288a162
    Wangyang Guo authored
    dst_entry::__refcnt is highly contended in scenarios where many connections
    happen from and to the same IP. The reference count is an atomic_t, so the
    reference count operations have to take the cache-line exclusive.
    
    Aside of the unavoidable reference count contention there is another
    significant problem which is caused by that: False sharing.
    
    perf top identified two affected read accesses. dst_entry::lwtstate and
    rtable::rt_genid.
    
    dst_entry:__refcnt is located at offset 64 of dst_entry, which puts it into
    a seperate cacheline vs. the read mostly members located at the beginning
    of the struct.
    
    That prevents false sharing vs. the struct members in the first 64
    bytes of the structure, but there is also
    
      dst_entry::lwtstate
    
    which is located after the reference count and in the same cache line. This
    member is read after a reference count has been acquired.
    
    struct rtable embeds a struct dst_entry at offset 0. struct dst_entry has a
    size of 112 bytes, which means that the struct members of rtable which
    follow the dst member share the same cache line as dst_entry::__refcnt.
    Especially
    
      rtable::rt_genid
    
    is also read by the contexts which have a reference count acquired
    already.
    
    When dst_entry:__refcnt is incremented or decremented via an atomic
    operation these read accesses stall. This was found when analysing the
    memtier benchmark in 1:100 mode, which amplifies the problem extremly.
    
    Move the rt[6i]_uncached[_list] members out of struct rtable and struct
    rt6_info into struct dst_entry to provide padding and move the lwtstate
    member after that so it ends up in the same cache line.
    
    The resulting improvement depends on the micro-architecture and the number
    of CPUs. It ranges from +20% to +120% with a localhost memtier/memcached
    benchmark.
    
    [ tglx: Rearrange struct ]
    Signed-off-by: default avatarWangyang Guo <wangyang.guo@intel.com>
    Signed-off-by: default avatarArjan van de Ven <arjan@linux.intel.com>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
    Reviewed-by: default avatarDavid Ahern <dsahern@kernel.org>
    Link: https://lore.kernel.org/r/20230323102800.042297517@linutronix.deSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
    d288a162
xfrm6_policy.c 6.79 KB