On Mon 20-05-24 21:18:31, Zhang Yi wrote: > From: Zhang Yi <yi.zhang@xxxxxxxxxx> > > jbd2_transaction_committed() is used to check whether a transaction with > the given tid has already committed, it holds j_state_lock in read mode > and check the tid of current running transaction and committing > transaction, but holding the j_state_lock is expensive. > > We have already stored the sequence number of the most recently > committed transaction in journal t->j_commit_sequence, we could do this > check by comparing it with the given tid instead. If the given tid isn't > smaller than j_commit_sequence, we can ensure that the given transaction > has been committed. That way we could drop the expensive lock and > achieve about 10% ~ 20% performance gains in concurrent DIOs on may > virtual machine with 100G ramdisk. > > fio -filename=/mnt/foo -direct=1 -iodepth=10 -rw=$rw -ioengine=libaio \ > -bs=4k -size=10G -numjobs=10 -runtime=60 -overwrite=1 -name=test \ > -group_reporting > > Before: > overwrite IOPS=88.2k, BW=344MiB/s > read IOPS=95.7k, BW=374MiB/s > rand overwrite IOPS=98.7k, BW=386MiB/s > randread IOPS=102k, BW=397MiB/s > > After: > overwrite IOPS=105k, BW=410MiB/s > read IOPS=112k, BW=436MiB/s > rand overwrite IOPS=104k, BW=404MiB/s > randread IOPS=111k, BW=432MiB/s > > CC: Dave Chinner <david@xxxxxxxxxxxxx> > Suggested-by: Dave Chinner <david@xxxxxxxxxxxxx> > Link: https://lore.kernel.org/linux-ext4/ZjILCPNZRHeazSqV@xxxxxxxxxxxxxxxxxxx/ > Signed-off-by: Zhang Yi <yi.zhang@xxxxxxxxxx> Thanks! The patch looks good. Feel free to add: Reviewed-by: Jan Kara <jack@xxxxxxx> Honza > --- > v1->v2: > - Add READ_ONCE and WRITE_ONCE to access ->j_commit_sequence > concurrently. > - Keep the jbd2_transaction_committed() helper. > > fs/jbd2/commit.c | 2 +- > fs/jbd2/journal.c | 12 +----------- > 2 files changed, 2 insertions(+), 12 deletions(-) > > diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c > index 5e122586e06e..8244cab17688 100644 > --- a/fs/jbd2/commit.c > +++ b/fs/jbd2/commit.c > @@ -1108,7 +1108,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) > > commit_transaction->t_state = T_COMMIT_CALLBACK; > J_ASSERT(commit_transaction == journal->j_committing_transaction); > - journal->j_commit_sequence = commit_transaction->t_tid; > + WRITE_ONCE(journal->j_commit_sequence, commit_transaction->t_tid); > journal->j_committing_transaction = NULL; > commit_time = ktime_to_ns(ktime_sub(ktime_get(), start_time)); > > diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c > index b6c114c11b97..cc586e3c4ee1 100644 > --- a/fs/jbd2/journal.c > +++ b/fs/jbd2/journal.c > @@ -789,17 +789,7 @@ EXPORT_SYMBOL(jbd2_fc_end_commit_fallback); > /* Return 1 when transaction with given tid has already committed. */ > int jbd2_transaction_committed(journal_t *journal, tid_t tid) > { > - int ret = 1; > - > - read_lock(&journal->j_state_lock); > - if (journal->j_running_transaction && > - journal->j_running_transaction->t_tid == tid) > - ret = 0; > - if (journal->j_committing_transaction && > - journal->j_committing_transaction->t_tid == tid) > - ret = 0; > - read_unlock(&journal->j_state_lock); > - return ret; > + return tid_geq(READ_ONCE(journal->j_commit_sequence), tid); > } > EXPORT_SYMBOL(jbd2_transaction_committed); > > -- > 2.39.2 > -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR