diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2022-10-21 15:19:08 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-01-06 19:47:55 -0500 |
commit | 28fc87184abd9043b2d17ce967bdd81a6055687e (patch) | |
tree | 115abea22effcb1708f3329415eb0fa5e29d4bcb | |
parent | ffe90405b77ef0f1f89f0c96c1ad0265400e4a81 (diff) |
bcachefs: Cacheline align & prefetch journal reservations
Writing to the new journal entries is currently a major cacheline miss
in the transaction commit path - this helps. Additionally, this patch
cacheline aligns journal reservations, so that when multiple threads are
doing transaction commits they won't conflict.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/journal.h | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/fs/bcachefs/journal.h b/fs/bcachefs/journal.h index d3caa7ea7ce9..9428f4233997 100644 --- a/fs/bcachefs/journal.h +++ b/fs/bcachefs/journal.h @@ -110,6 +110,7 @@ */ #include <linux/hash.h> +#include <linux/prefetch.h> #include "journal_types.h" @@ -304,15 +305,26 @@ static inline int journal_res_get_fast(struct journal *j, { union journal_res_state old, new; u64 v = atomic64_read(&j->reservations.counter); + unsigned u64s, offset; do { old.v = new.v = v; /* + * Round up the end of the journal reservation to the next + * cacheline boundary: + */ + u64s = res->u64s; + offset = sizeof(struct jset) / sizeof(u64) + + new.cur_entry_offset + u64s; + u64s += ((offset - 1) & ((SMP_CACHE_BYTES / sizeof(u64)) - 1)) + 1; + + + /* * Check if there is still room in the current journal * entry: */ - if (new.cur_entry_offset + res->u64s > j->cur_entry_u64s) + if (new.cur_entry_offset + u64s > j->cur_entry_u64s) return 0; EBUG_ON(!journal_state_count(new, new.idx)); @@ -320,7 +332,7 @@ static inline int journal_res_get_fast(struct journal *j, if ((flags & JOURNAL_WATERMARK_MASK) < j->watermark) return 0; - new.cur_entry_offset += res->u64s; + new.cur_entry_offset += u64s; journal_state_inc(&new); /* @@ -337,8 +349,15 @@ static inline int journal_res_get_fast(struct journal *j, res->ref = true; res->idx = old.idx; + res->u64s = u64s; res->offset = old.cur_entry_offset; res->seq = le64_to_cpu(j->buf[old.idx].data->seq); + + offset = res->offset; + while (offset < res->offset + res->u64s) { + prefetchw(vstruct_idx(j->buf[res->idx].data, offset)); + offset += SMP_CACHE_BYTES / sizeof(u64); + } return 1; } |