Skip to content

Commit a931da6

Browse files
committed
jbd2: Change j_state_lock to be a rwlock_t
Lockstat reports have shown that j_state_lock is a major source of lock contention, especially on systems with more than 4 CPU cores. So change it to be a read/write spinlock. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
1 parent a51dca9 commit a931da6

File tree

8 files changed

+114
-110
lines changed

8 files changed

+114
-110
lines changed

fs/ext4/inode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5066,7 +5066,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
50665066
transaction_t *transaction;
50675067
tid_t tid;
50685068

5069-
spin_lock(&journal->j_state_lock);
5069+
read_lock(&journal->j_state_lock);
50705070
if (journal->j_running_transaction)
50715071
transaction = journal->j_running_transaction;
50725072
else
@@ -5075,7 +5075,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
50755075
tid = transaction->t_tid;
50765076
else
50775077
tid = journal->j_commit_sequence;
5078-
spin_unlock(&journal->j_state_lock);
5078+
read_unlock(&journal->j_state_lock);
50795079
ei->i_sync_tid = tid;
50805080
ei->i_datasync_tid = tid;
50815081
}

fs/ext4/super.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3232,7 +3232,7 @@ static void ext4_init_journal_params(struct super_block *sb, journal_t *journal)
32323232
journal->j_min_batch_time = sbi->s_min_batch_time;
32333233
journal->j_max_batch_time = sbi->s_max_batch_time;
32343234

3235-
spin_lock(&journal->j_state_lock);
3235+
write_lock(&journal->j_state_lock);
32363236
if (test_opt(sb, BARRIER))
32373237
journal->j_flags |= JBD2_BARRIER;
32383238
else
@@ -3241,7 +3241,7 @@ static void ext4_init_journal_params(struct super_block *sb, journal_t *journal)
32413241
journal->j_flags |= JBD2_ABORT_ON_SYNCDATA_ERR;
32423242
else
32433243
journal->j_flags &= ~JBD2_ABORT_ON_SYNCDATA_ERR;
3244-
spin_unlock(&journal->j_state_lock);
3244+
write_unlock(&journal->j_state_lock);
32453245
}
32463246

32473247
static journal_t *ext4_get_journal(struct super_block *sb,

fs/jbd2/checkpoint.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,13 @@ static int __try_to_free_cp_buf(struct journal_head *jh)
118118
void __jbd2_log_wait_for_space(journal_t *journal)
119119
{
120120
int nblocks, space_left;
121-
assert_spin_locked(&journal->j_state_lock);
121+
/* assert_spin_locked(&journal->j_state_lock); */
122122

123123
nblocks = jbd_space_needed(journal);
124124
while (__jbd2_log_space_left(journal) < nblocks) {
125125
if (journal->j_flags & JBD2_ABORT)
126126
return;
127-
spin_unlock(&journal->j_state_lock);
127+
write_unlock(&journal->j_state_lock);
128128
mutex_lock(&journal->j_checkpoint_mutex);
129129

130130
/*
@@ -138,7 +138,7 @@ void __jbd2_log_wait_for_space(journal_t *journal)
138138
* filesystem, so abort the journal and leave a stack
139139
* trace for forensic evidence.
140140
*/
141-
spin_lock(&journal->j_state_lock);
141+
write_lock(&journal->j_state_lock);
142142
spin_lock(&journal->j_list_lock);
143143
nblocks = jbd_space_needed(journal);
144144
space_left = __jbd2_log_space_left(journal);
@@ -149,7 +149,7 @@ void __jbd2_log_wait_for_space(journal_t *journal)
149149
if (journal->j_committing_transaction)
150150
tid = journal->j_committing_transaction->t_tid;
151151
spin_unlock(&journal->j_list_lock);
152-
spin_unlock(&journal->j_state_lock);
152+
write_unlock(&journal->j_state_lock);
153153
if (chkpt) {
154154
jbd2_log_do_checkpoint(journal);
155155
} else if (jbd2_cleanup_journal_tail(journal) == 0) {
@@ -167,7 +167,7 @@ void __jbd2_log_wait_for_space(journal_t *journal)
167167
WARN_ON(1);
168168
jbd2_journal_abort(journal, 0);
169169
}
170-
spin_lock(&journal->j_state_lock);
170+
write_lock(&journal->j_state_lock);
171171
} else {
172172
spin_unlock(&journal->j_list_lock);
173173
}
@@ -474,7 +474,7 @@ int jbd2_cleanup_journal_tail(journal_t *journal)
474474
* next transaction ID we will write, and where it will
475475
* start. */
476476

477-
spin_lock(&journal->j_state_lock);
477+
write_lock(&journal->j_state_lock);
478478
spin_lock(&journal->j_list_lock);
479479
transaction = journal->j_checkpoint_transactions;
480480
if (transaction) {
@@ -496,7 +496,7 @@ int jbd2_cleanup_journal_tail(journal_t *journal)
496496
/* If the oldest pinned transaction is at the tail of the log
497497
already then there's not much we can do right now. */
498498
if (journal->j_tail_sequence == first_tid) {
499-
spin_unlock(&journal->j_state_lock);
499+
write_unlock(&journal->j_state_lock);
500500
return 1;
501501
}
502502

@@ -516,7 +516,7 @@ int jbd2_cleanup_journal_tail(journal_t *journal)
516516
journal->j_free += freed;
517517
journal->j_tail_sequence = first_tid;
518518
journal->j_tail = blocknr;
519-
spin_unlock(&journal->j_state_lock);
519+
write_unlock(&journal->j_state_lock);
520520

521521
/*
522522
* If there is an external journal, we need to make sure that

fs/jbd2/commit.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,9 @@ static int journal_submit_commit_record(journal_t *journal,
152152
printk(KERN_WARNING
153153
"JBD2: Disabling barriers on %s, "
154154
"not supported by device\n", journal->j_devname);
155-
spin_lock(&journal->j_state_lock);
155+
write_lock(&journal->j_state_lock);
156156
journal->j_flags &= ~JBD2_BARRIER;
157-
spin_unlock(&journal->j_state_lock);
157+
write_unlock(&journal->j_state_lock);
158158

159159
/* And try again, without the barrier */
160160
lock_buffer(bh);
@@ -182,9 +182,9 @@ static int journal_wait_on_commit_record(journal_t *journal,
182182
printk(KERN_WARNING
183183
"JBD2: %s: disabling barries on %s - not supported "
184184
"by device\n", __func__, journal->j_devname);
185-
spin_lock(&journal->j_state_lock);
185+
write_lock(&journal->j_state_lock);
186186
journal->j_flags &= ~JBD2_BARRIER;
187-
spin_unlock(&journal->j_state_lock);
187+
write_unlock(&journal->j_state_lock);
188188

189189
lock_buffer(bh);
190190
clear_buffer_dirty(bh);
@@ -400,7 +400,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
400400
jbd_debug(1, "JBD: starting commit of transaction %d\n",
401401
commit_transaction->t_tid);
402402

403-
spin_lock(&journal->j_state_lock);
403+
write_lock(&journal->j_state_lock);
404404
commit_transaction->t_state = T_LOCKED;
405405

406406
/*
@@ -424,9 +424,9 @@ void jbd2_journal_commit_transaction(journal_t *journal)
424424
TASK_UNINTERRUPTIBLE);
425425
if (atomic_read(&commit_transaction->t_updates)) {
426426
spin_unlock(&commit_transaction->t_handle_lock);
427-
spin_unlock(&journal->j_state_lock);
427+
write_unlock(&journal->j_state_lock);
428428
schedule();
429-
spin_lock(&journal->j_state_lock);
429+
write_lock(&journal->j_state_lock);
430430
spin_lock(&commit_transaction->t_handle_lock);
431431
}
432432
finish_wait(&journal->j_wait_updates, &wait);
@@ -497,7 +497,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
497497
start_time = ktime_get();
498498
commit_transaction->t_log_start = journal->j_head;
499499
wake_up(&journal->j_wait_transaction_locked);
500-
spin_unlock(&journal->j_state_lock);
500+
write_unlock(&journal->j_state_lock);
501501

502502
jbd_debug (3, "JBD: commit phase 2\n");
503503

@@ -519,9 +519,9 @@ void jbd2_journal_commit_transaction(journal_t *journal)
519519
* transaction! Now comes the tricky part: we need to write out
520520
* metadata. Loop over the transaction's entire buffer list:
521521
*/
522-
spin_lock(&journal->j_state_lock);
522+
write_lock(&journal->j_state_lock);
523523
commit_transaction->t_state = T_COMMIT;
524-
spin_unlock(&journal->j_state_lock);
524+
write_unlock(&journal->j_state_lock);
525525

526526
trace_jbd2_commit_logging(journal, commit_transaction);
527527
stats.run.rs_logging = jiffies;
@@ -978,15 +978,15 @@ void jbd2_journal_commit_transaction(journal_t *journal)
978978
* __jbd2_journal_drop_transaction(). Otherwise we could race with
979979
* other checkpointing code processing the transaction...
980980
*/
981-
spin_lock(&journal->j_state_lock);
981+
write_lock(&journal->j_state_lock);
982982
spin_lock(&journal->j_list_lock);
983983
/*
984984
* Now recheck if some buffers did not get attached to the transaction
985985
* while the lock was dropped...
986986
*/
987987
if (commit_transaction->t_forget) {
988988
spin_unlock(&journal->j_list_lock);
989-
spin_unlock(&journal->j_state_lock);
989+
write_unlock(&journal->j_state_lock);
990990
goto restart_loop;
991991
}
992992

@@ -1038,7 +1038,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
10381038
journal->j_average_commit_time*3) / 4;
10391039
else
10401040
journal->j_average_commit_time = commit_time;
1041-
spin_unlock(&journal->j_state_lock);
1041+
write_unlock(&journal->j_state_lock);
10421042

10431043
if (commit_transaction->t_checkpoint_list == NULL &&
10441044
commit_transaction->t_checkpoint_io_list == NULL) {

0 commit comments

Comments
 (0)