aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd2/commit.c
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@redhat.com>2008-11-26 01:14:26 -0500
committerTheodore Ts'o <tytso@mit.edu>2008-11-26 01:14:26 -0500
commite07f7183a486cf9783d1f8c9d2997b5b39eeb2d4 (patch)
tree74ed3a563add5fa57e80af03f3f712f2910ac39f /fs/jbd2/commit.c
parent032115fcef837a00336ddf7bda584e89789ea498 (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.c14
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)