diff options
author | Josef Bacik <jbacik@redhat.com> | 2008-11-26 01:14:26 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2008-11-26 01:14:26 -0500 |
commit | e07f7183a486cf9783d1f8c9d2997b5b39eeb2d4 (patch) | |
tree | 74ed3a563add5fa57e80af03f3f712f2910ac39f /fs/jbd2/commit.c | |
parent | 032115fcef837a00336ddf7bda584e89789ea498 (diff) |
jbd2: improve jbd2 fsync batching
This patch removes the static sleep time in favor of a more self
optimizing approach where we measure the average amount of time it
takes to commit a transaction to disk and the ammount of time a
transaction has been running. If somebody does a sync write or an
fsync() traditionally we would sleep for 1 jiffies, which depending on
the value of HZ could be a significant amount of time compared to how
long it takes to commit a transaction to the underlying storage. With
this patch instead of sleeping for a jiffie, we check to see if the
amount of time this transaction has been running is less than the
average commit time, and if it is we sleep for the delta using
schedule_hrtimeout to give us a higher precision sleep time. This
greatly benefits high end storage where you could end up sleeping for
longer than it takes to commit the transaction and therefore sitting
idle instead of allowing the transaction to be committed by keeping
the sleep time to a minimum so you are sure to always be doing
something.
Signed-off-by: Josef Bacik <jbacik@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/jbd2/commit.c')
-rw-r--r-- | fs/jbd2/commit.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 6393fd0d804e..f22d1828ea85 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -355,6 +355,8 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
355 | int flags; | 355 | int flags; |
356 | int err; | 356 | int err; |
357 | unsigned long long blocknr; | 357 | unsigned long long blocknr; |
358 | ktime_t start_time; | ||
359 | u64 commit_time; | ||
358 | char *tagp = NULL; | 360 | char *tagp = NULL; |
359 | journal_header_t *header; | 361 | journal_header_t *header; |
360 | journal_block_tag_t *tag = NULL; | 362 | journal_block_tag_t *tag = NULL; |
@@ -481,6 +483,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
481 | commit_transaction->t_state = T_FLUSH; | 483 | commit_transaction->t_state = T_FLUSH; |
482 | journal->j_committing_transaction = commit_transaction; | 484 | journal->j_committing_transaction = commit_transaction; |
483 | journal->j_running_transaction = NULL; | 485 | journal->j_running_transaction = NULL; |
486 | start_time = ktime_get(); | ||
484 | commit_transaction->t_log_start = journal->j_head; | 487 | commit_transaction->t_log_start = journal->j_head; |
485 | wake_up(&journal->j_wait_transaction_locked); | 488 | wake_up(&journal->j_wait_transaction_locked); |
486 | spin_unlock(&journal->j_state_lock); | 489 | spin_unlock(&journal->j_state_lock); |
@@ -995,6 +998,17 @@ restart_loop: | |||
995 | J_ASSERT(commit_transaction == journal->j_committing_transaction); | 998 | J_ASSERT(commit_transaction == journal->j_committing_transaction); |
996 | journal->j_commit_sequence = commit_transaction->t_tid; | 999 | journal->j_commit_sequence = commit_transaction->t_tid; |
997 | journal->j_committing_transaction = NULL; | 1000 | journal->j_committing_transaction = NULL; |
1001 | commit_time = ktime_to_ns(ktime_sub(ktime_get(), start_time)); | ||
1002 | |||
1003 | /* | ||
1004 | * weight the commit time higher than the average time so we don't | ||
1005 | * react too strongly to vast changes in the commit time | ||
1006 | */ | ||
1007 | if (likely(journal->j_average_commit_time)) | ||
1008 | journal->j_average_commit_time = (commit_time + | ||
1009 | journal->j_average_commit_time*3) / 4; | ||
1010 | else | ||
1011 | journal->j_average_commit_time = commit_time; | ||
998 | spin_unlock(&journal->j_state_lock); | 1012 | spin_unlock(&journal->j_state_lock); |
999 | 1013 | ||
1000 | if (journal->j_commit_callback) | 1014 | if (journal->j_commit_callback) |