diff options
| author | Theodore Ts'o <tytso@mit.edu> | 2014-03-09 04:51:16 +0400 | 
|---|---|---|
| committer | Theodore Ts'o <tytso@mit.edu> | 2014-03-09 04:51:16 +0400 | 
| commit | 42cf3452d5f5b0817d27c93e4e7d7eab6e89077d (patch) | |
| tree | 106d8e934c1c930d4fae822c76ff18d493492729 /fs/jbd2/commit.c | |
| parent | 3469a32a1e948c54204b5dd6f7476a7d11349e9e (diff) | |
| download | linux-42cf3452d5f5b0817d27c93e4e7d7eab6e89077d.tar.xz | |
jbd2: calculate statistics without holding j_state_lock and j_list_lock
The two hottest locks, and thus the biggest scalability bottlenecks,
in the jbd2 layer, are the j_list_lock and j_state_lock.  This has
inspired some people to do some truly unnatural things[1].
[1] https://www.usenix.org/system/files/conference/fast14/fast14-paper_kang.pdf
We don't need to be holding both j_state_lock and j_list_lock while
calculating the journal statistics, so move those calculations to the
very end of jbd2_journal_commit_transaction.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/jbd2/commit.c')
| -rw-r--r-- | fs/jbd2/commit.c | 36 | 
1 files changed, 18 insertions, 18 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 765b31da4029..af36252b5b2d 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -1083,24 +1083,7 @@ restart_loop:  		atomic_read(&commit_transaction->t_handle_count);  	trace_jbd2_run_stats(journal->j_fs_dev->bd_dev,  			     commit_transaction->t_tid, &stats.run); - -	/* -	 * Calculate overall stats -	 */ -	spin_lock(&journal->j_history_lock); -	journal->j_stats.ts_tid++; -	if (commit_transaction->t_requested) -		journal->j_stats.ts_requested++; -	journal->j_stats.run.rs_wait += stats.run.rs_wait; -	journal->j_stats.run.rs_request_delay += stats.run.rs_request_delay; -	journal->j_stats.run.rs_running += stats.run.rs_running; -	journal->j_stats.run.rs_locked += stats.run.rs_locked; -	journal->j_stats.run.rs_flushing += stats.run.rs_flushing; -	journal->j_stats.run.rs_logging += stats.run.rs_logging; -	journal->j_stats.run.rs_handle_count += stats.run.rs_handle_count; -	journal->j_stats.run.rs_blocks += stats.run.rs_blocks; -	journal->j_stats.run.rs_blocks_logged += stats.run.rs_blocks_logged; -	spin_unlock(&journal->j_history_lock); +	stats.ts_requested = (commit_transaction->t_requested) ? 1 : 0;  	commit_transaction->t_state = T_COMMIT_CALLBACK;  	J_ASSERT(commit_transaction == journal->j_committing_transaction); @@ -1157,4 +1140,21 @@ restart_loop:  	spin_unlock(&journal->j_list_lock);  	write_unlock(&journal->j_state_lock);  	wake_up(&journal->j_wait_done_commit); + +	/* +	 * Calculate overall stats +	 */ +	spin_lock(&journal->j_history_lock); +	journal->j_stats.ts_tid++; +	journal->j_stats.ts_requested += stats.ts_requested; +	journal->j_stats.run.rs_wait += stats.run.rs_wait; +	journal->j_stats.run.rs_request_delay += stats.run.rs_request_delay; +	journal->j_stats.run.rs_running += stats.run.rs_running; +	journal->j_stats.run.rs_locked += stats.run.rs_locked; +	journal->j_stats.run.rs_flushing += stats.run.rs_flushing; +	journal->j_stats.run.rs_logging += stats.run.rs_logging; +	journal->j_stats.run.rs_handle_count += stats.run.rs_handle_count; +	journal->j_stats.run.rs_blocks += stats.run.rs_blocks; +	journal->j_stats.run.rs_blocks_logged += stats.run.rs_blocks_logged; +	spin_unlock(&journal->j_history_lock);  }  | 
