Josef Bacik
2007-Aug-09 08:03 UTC
[Btrfs-devel] [PATCH] delay commit if work is done while we're asleep
Hello, Ok this one works I promise :). Cleaned a few things up and such, but basically same idea as before, I keep the waitqueue, I use schedule_timeout which keeps us from deadlocking. This speeds us up a decent amount, without the patch I usually get 70-75 files/sec. With this patch I get between 85-115 files/sec. The reason there is such a wide spread depends mostly on when the transaction cleaner runs while I'm running the test, as this is only single threaded. Feedback is appreciated. Thank you, Josef diff -r f6da57af2473 transaction.c --- a/transaction.c Wed Aug 08 20:17:12 2007 -0400 +++ b/transaction.c Thu Aug 09 11:06:25 2007 -0400 @@ -55,7 +55,8 @@ static int join_transaction(struct btrfs BUG_ON(!cur_trans); root->fs_info->generation++; root->fs_info->running_transaction = cur_trans; - cur_trans->num_writers = 0; + cur_trans->num_writers = 1; + cur_trans->num_joined = 0; cur_trans->transid = root->fs_info->generation; init_waitqueue_head(&cur_trans->writer_wait); init_waitqueue_head(&cur_trans->commit_wait); @@ -65,8 +66,11 @@ static int join_transaction(struct btrfs cur_trans->start_time = get_seconds(); list_add_tail(&cur_trans->list, &root->fs_info->trans_list); init_bit_radix(&cur_trans->dirty_pages); - } - cur_trans->num_writers++; + } else { + cur_trans->num_writers++; + cur_trans->num_joined++; + } + return 0; } @@ -426,7 +430,7 @@ int btrfs_commit_transaction(struct btrf int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct btrfs_root *root) { - int ret = 0; + int ret = 0, joined = 0; struct btrfs_transaction *cur_trans; struct btrfs_transaction *prev_trans = NULL; struct list_head dirty_fs_roots; @@ -467,19 +471,24 @@ int btrfs_commit_transaction(struct btrf mutex_lock(&root->fs_info->trans_mutex); } } - while (trans->transaction->num_writers > 1) { + + do { + joined = cur_trans->num_joined; WARN_ON(cur_trans != trans->transaction); - prepare_to_wait(&trans->transaction->writer_wait, &wait, + prepare_to_wait(&cur_trans->writer_wait, &wait, TASK_UNINTERRUPTIBLE); - if (trans->transaction->num_writers <= 1) + if (cur_trans->num_writers <= 1 && + (cur_trans->num_joined != joined)) break; mutex_unlock(&root->fs_info->fs_mutex); mutex_unlock(&root->fs_info->trans_mutex); - schedule(); + schedule_timeout(1); mutex_lock(&root->fs_info->fs_mutex); mutex_lock(&root->fs_info->trans_mutex); - finish_wait(&trans->transaction->writer_wait, &wait); - } + finish_wait(&cur_trans->writer_wait, &wait); + } while (cur_trans->num_writers > 1 || + (cur_trans->num_joined != joined)); + finish_wait(&trans->transaction->writer_wait, &wait); WARN_ON(cur_trans != trans->transaction); ret = add_dirty_roots(trans, &root->fs_info->fs_roots_radix, diff -r f6da57af2473 transaction.h --- a/transaction.h Wed Aug 08 20:17:12 2007 -0400 +++ b/transaction.h Thu Aug 09 10:52:31 2007 -0400 @@ -23,6 +23,7 @@ struct btrfs_transaction { struct btrfs_transaction { u64 transid; unsigned long num_writers; + unsigned long num_joined; int in_commit; int use_count; int commit_done;
Chris Mason
2007-Aug-09 08:21 UTC
[Btrfs-devel] [PATCH] delay commit if work is done while we're asleep
On Thu, 9 Aug 2007 11:07:39 -0400 Josef Bacik <jwhiter@redhat.com> wrote:> Hello, > > Ok this one works I promise :). Cleaned a few things up and such, > but basically same idea as before, I keep the waitqueue, I use > schedule_timeout which keeps us from deadlocking. This speeds us up > a decent amount, without the patch I usually get 70-75 files/sec. > With this patch I get between 85-115 files/sec. The reason there is > such a wide spread depends mostly on when the transaction cleaner > runs while I'm running the test, as this is only single threaded. > Feedback is appreciated. Thank you,It looks great to me, thanks for working on this. One change I'll probably make here is to do something like this: prepare_to_wait if (trans->transaction->num_writers > 1) timeout = MAX_SCHEDULE_TIMEOUT else timeout = 1 drop locks schedule_timeout(timeout); This way we don't loop in schedule when there are writers around who will wake us. I'll give it a try this afternoon. -chris