• Sebastian Andrzej Siewior's avatar
    net: Use this_cpu_inc() to increment net->core_stats · 6510ea97
    Sebastian Andrzej Siewior authored
    The macro dev_core_stats_##FIELD##_inc() disables preemption and invokes
    netdev_core_stats_alloc() to return a per-CPU pointer.
    netdev_core_stats_alloc() will allocate memory on its first invocation
    which breaks on PREEMPT_RT because it requires non-atomic context for
    memory allocation.
    
    This can be avoided by enabling preemption in netdev_core_stats_alloc()
    assuming the caller always disables preemption.
    
    It might be better to replace local_inc() with this_cpu_inc() now that
    dev_core_stats_##FIELD##_inc() gained a preempt-disable section and does
    not rely on already disabled preemption. This results in less
    instructions on x86-64:
    local_inc:
    |          incl %gs:__preempt_count(%rip)  # __preempt_count
    |          movq    488(%rdi), %rax # _1->core_stats, _22
    |          testq   %rax, %rax      # _22
    |          je      .L585   #,
    |          add %gs:this_cpu_off(%rip), %rax        # this_cpu_off, tcp_ptr__
    |  .L586:
    |          testq   %rax, %rax      # _27
    |          je      .L587   #,
    |          incq (%rax)            # _6->a.counter
    |  .L587:
    |          decl %gs:__preempt_count(%rip)  # __preempt_count
    
    this_cpu_inc(), this patch:
    |         movq    488(%rdi), %rax # _1->core_stats, _5
    |         testq   %rax, %rax      # _5
    |         je      .L591   #,
    | .L585:
    |         incq %gs:(%rax) # _18->rx_dropped
    
    Use unsigned long as type for the counter. Use this_cpu_inc() to
    increment the counter. Use a plain read of the counter.
    Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
    Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
    Link: https://lore.kernel.org/r/YmbO0pxgtKpCw4SY@linutronix.deSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
    6510ea97
dev.c 284 KB