Skip to content

Commit 4641706

Browse files
KAGA-KOKOtytso
authored andcommitted
jbd2: Make state lock a spinlock
Bit-spinlocks are problematic on PREEMPT_RT if functions which might sleep on RT, e.g. spin_lock(), alloc/free(), are invoked inside the lock held region because bit spinlocks disable preemption even on RT. A first attempt was to replace state lock with a spinlock placed in struct buffer_head and make the locking conditional on PREEMPT_RT and DEBUG_BIT_SPINLOCKS. Jan pointed out that there is a 4 byte hole in struct journal_head where a regular spinlock fits in and he would not object to convert the state lock to a spinlock unconditionally. Aside of solving the RT problem, this also gains lockdep coverage for the journal head state lock (bit-spinlocks are not covered by lockdep as it's hard to fit a lockdep map into a single bit). The trivial change would have been to convert the jbd_*lock_bh_state() inlines, but that comes with the downside that these functions take a buffer head pointer which needs to be converted to a journal head pointer which adds another level of indirection. As almost all functions which use this lock have a journal head pointer readily available, it makes more sense to remove the lock helper inlines and write out spin_*lock() at all call sites. Fixup all locking comments as well. Suggested-by: Jan Kara <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Jan Kara <[email protected]> Cc: "Theodore Ts'o" <[email protected]> Cc: Mark Fasheh <[email protected]> Cc: Joseph Qi <[email protected]> Cc: Joel Becker <[email protected]> Cc: Jan Kara <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 2e710ff commit 4641706

File tree

6 files changed

+84
-94
lines changed

6 files changed

+84
-94
lines changed

fs/jbd2/commit.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -482,10 +482,10 @@ void jbd2_journal_commit_transaction(journal_t *journal)
482482
if (jh->b_committed_data) {
483483
struct buffer_head *bh = jh2bh(jh);
484484

485-
jbd_lock_bh_state(bh);
485+
spin_lock(&jh->b_state_lock);
486486
jbd2_free(jh->b_committed_data, bh->b_size);
487487
jh->b_committed_data = NULL;
488-
jbd_unlock_bh_state(bh);
488+
spin_unlock(&jh->b_state_lock);
489489
}
490490
jbd2_journal_refile_buffer(journal, jh);
491491
}
@@ -928,7 +928,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
928928
* done with it.
929929
*/
930930
get_bh(bh);
931-
jbd_lock_bh_state(bh);
931+
spin_lock(&jh->b_state_lock);
932932
J_ASSERT_JH(jh, jh->b_transaction == commit_transaction);
933933

934934
/*
@@ -1024,7 +1024,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
10241024
}
10251025
JBUFFER_TRACE(jh, "refile or unfile buffer");
10261026
drop_ref = __jbd2_journal_refile_buffer(jh);
1027-
jbd_unlock_bh_state(bh);
1027+
spin_unlock(&jh->b_state_lock);
10281028
if (drop_ref)
10291029
jbd2_journal_put_journal_head(jh);
10301030
if (try_to_free)

fs/jbd2/journal.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction,
363363
/* keep subsequent assertions sane */
364364
atomic_set(&new_bh->b_count, 1);
365365

366-
jbd_lock_bh_state(bh_in);
366+
spin_lock(&jh_in->b_state_lock);
367367
repeat:
368368
/*
369369
* If a new transaction has already done a buffer copy-out, then
@@ -405,13 +405,13 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction,
405405
if (need_copy_out && !done_copy_out) {
406406
char *tmp;
407407

408-
jbd_unlock_bh_state(bh_in);
408+
spin_unlock(&jh_in->b_state_lock);
409409
tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS);
410410
if (!tmp) {
411411
brelse(new_bh);
412412
return -ENOMEM;
413413
}
414-
jbd_lock_bh_state(bh_in);
414+
spin_lock(&jh_in->b_state_lock);
415415
if (jh_in->b_frozen_data) {
416416
jbd2_free(tmp, bh_in->b_size);
417417
goto repeat;
@@ -464,7 +464,7 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction,
464464
__jbd2_journal_file_buffer(jh_in, transaction, BJ_Shadow);
465465
spin_unlock(&journal->j_list_lock);
466466
set_buffer_shadow(bh_in);
467-
jbd_unlock_bh_state(bh_in);
467+
spin_unlock(&jh_in->b_state_lock);
468468

469469
return do_escape | (done_copy_out << 1);
470470
}
@@ -2410,6 +2410,8 @@ static struct journal_head *journal_alloc_journal_head(void)
24102410
ret = kmem_cache_zalloc(jbd2_journal_head_cache,
24112411
GFP_NOFS | __GFP_NOFAIL);
24122412
}
2413+
if (ret)
2414+
spin_lock_init(&ret->b_state_lock);
24132415
return ret;
24142416
}
24152417

0 commit comments

Comments
 (0)