summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2022-10-21 15:19:08 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2025-04-29 13:44:33 -0400
commitbc2c8600105f4f5148efe0344cba3f9871bb6a62 (patch)
tree3d32c7e1fe2322fe1a7490ba12c618331962e863
parent60ad88ee7cfa42e9490b0dd01eb14b277bf7f37b (diff)
bcachefs: Cacheline align & prefetch journal reservationsbcachefs-garbage
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.h17
1 files changed, 14 insertions, 3 deletions
diff --git a/fs/bcachefs/journal.h b/fs/bcachefs/journal.h
index 8d17330aea99..54446580ac5d 100644
--- a/fs/bcachefs/journal.h
+++ b/fs/bcachefs/journal.h
@@ -344,19 +344,29 @@ static inline int journal_res_get_fast(struct journal *j,
unsigned flags)
{
union journal_res_state old, new;
- unsigned offset;
+ unsigned u64s, offset;
old.v = atomic64_read(&j->reservations.counter);
do {
new.v = old.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, smp_rmb() guarantees that reads from reservations.counter
* occur before accessing cur_entry_u64s:
*/
smp_rmb();
- 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));
@@ -364,7 +374,7 @@ static inline int journal_res_get_fast(struct journal *j,
if ((flags & BCH_WATERMARK_MASK) < j->watermark)
return 0;
- new.cur_entry_offset += res->u64s;
+ new.cur_entry_offset += u64s;
journal_state_inc(&new);
/*
@@ -380,6 +390,7 @@ static inline int journal_res_get_fast(struct journal *j,
&old.v, new.v));
res->ref = true;
+ res->u64s = u64s;
res->offset = old.cur_entry_offset;
res->seq = journal_cur_seq(j);
res->seq -= (res->seq - old.idx) & JOURNAL_STATE_BUF_MASK;