• Thomas Gleixner's avatar
    jbd2: Free journal head outside of locked region · 7855a57d
    Thomas Gleixner authored
    On PREEMPT_RT bit-spinlocks have the same semantics as on PREEMPT_RT=n,
    i.e. they disable preemption. That means functions which are not safe to be
    called in preempt disabled context on RT trigger a might_sleep() assert.
    
    The journal head bit spinlock is mostly held for short code sequences with
    trivial RT safe functionality, except for one place:
    
    jbd2_journal_put_journal_head() invokes __journal_remove_journal_head()
    with the journal head bit spinlock held. __journal_remove_journal_head()
    invokes kmem_cache_free() which must not be called with preemption disabled
    on RT.
    
    Jan suggested to rework the removal function so the actual free happens
    outside the bit-spinlocked region.
    
    Split it into two parts:
    
      - Do the sanity checks and the buffer head detach under the lock
    
      - Do the actual free after dropping the lock
    
    There is error case handling in the free part which needs to dereference
    the b_size field of the now detached buffer head. Due to paranoia (caused
    by ignorance) the size is retrieved in the detach function and handed into
    the free function. Might be over-engineered, but better safe than sorry.
    
    This makes the journal head bit-spinlock usage RT compliant and also avoids
    nested locking which is not covered by lockdep.
    Suggested-by: default avatarJan Kara <jack@suse.com>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Cc: linux-ext4@vger.kernel.org
    Cc: "Theodore Ts'o" <tytso@mit.edu>
    Cc: Jan Kara <jack@suse.com>
    Signed-off-by: default avatarJan Kara <jack@suse.cz>
    Link: https://lore.kernel.org/r/20190809124233.13277-8-jack@suse.czSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
    7855a57d
journal.c 76.3 KB