lkml.org 
[lkml]   [2021]   [Mar]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 038/221] u64_stats,lockdep: Fix u64_stats_init() vs lockdep
    Date
    From: Peter Zijlstra <peterz@infradead.org>

    [ Upstream commit d5b0e0677bfd5efd17c5bbb00156931f0d41cb85 ]

    Jakub reported that:

    static struct net_device *rtl8139_init_board(struct pci_dev *pdev)
    {
    ...
    u64_stats_init(&tp->rx_stats.syncp);
    u64_stats_init(&tp->tx_stats.syncp);
    ...
    }

    results in lockdep getting confused between the RX and TX stats lock.
    This is because u64_stats_init() is an inline calling seqcount_init(),
    which is a macro using a static variable to generate a lockdep class.

    By wrapping that in an inline, we negate the effect of the macro and
    fold the static key variable, hence the confusion.

    Fix by also making u64_stats_init() a macro for the case where it
    matters, leaving the other case an inline for argument validation
    etc.

    Reported-by: Jakub Kicinski <kuba@kernel.org>
    Debugged-by: "Ahmed S. Darwish" <a.darwish@linutronix.de>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Tested-by: "Erhard F." <erhard_f@mailbox.org>
    Link: https://lkml.kernel.org/r/YEXicy6+9MksdLZh@hirez.programming.kicks-ass.net
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    include/linux/u64_stats_sync.h | 7 ++++---
    1 file changed, 4 insertions(+), 3 deletions(-)

    diff --git a/include/linux/u64_stats_sync.h b/include/linux/u64_stats_sync.h
    index c6abb79501b3..e81856c0ba13 100644
    --- a/include/linux/u64_stats_sync.h
    +++ b/include/linux/u64_stats_sync.h
    @@ -115,12 +115,13 @@ static inline void u64_stats_inc(u64_stats_t *p)
    }
    #endif

    +#if BITS_PER_LONG == 32 && defined(CONFIG_SMP)
    +#define u64_stats_init(syncp) seqcount_init(&(syncp)->seq)
    +#else
    static inline void u64_stats_init(struct u64_stats_sync *syncp)
    {
    -#if BITS_PER_LONG == 32 && defined(CONFIG_SMP)
    - seqcount_init(&syncp->seq);
    -#endif
    }
    +#endif

    static inline void u64_stats_update_begin(struct u64_stats_sync *syncp)
    {
    --
    2.30.1


    \
     
     \ /
      Last update: 2021-03-29 10:40    [W:3.493 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site