summaryrefslogtreecommitdiff
path: root/fs/bcachefs/alloc_types.h
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2022-10-31 16:13:05 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:09:29 -0400
commitb17d3cec14b487924df709dbeffb900f124a2607 (patch)
treee3a5ce061e8e294d8d0570a7916996cebefb9d8d /fs/bcachefs/alloc_types.h
parent5f417394033a0d8bfb31d02b3becf7381dc13867 (diff)
bcachefs: Run btree updates after write out of write_point
In the write path, after the write to the block device(s) complete we have to punt to process context to do the btree update. Instead of using the work item embedded in op->cl, this patch switches to a per write-point work item. This helps with two different issues: - lock contention: btree updates to the same writepoint will (usually) be updating the same alloc keys - context switch overhead: when we're bottlenecked on btree updates, having a thread (running out of a work item) checking the write point for completed ops is cheaper than queueing up a new work item and waking up a kworker. In an arbitrary benchmark, 4k random writes with fio running inside a VM, this patch resulted in a 10% improvement in total iops. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/alloc_types.h')
-rw-r--r--fs/bcachefs/alloc_types.h46
1 files changed, 37 insertions, 9 deletions
diff --git a/fs/bcachefs/alloc_types.h b/fs/bcachefs/alloc_types.h
index e3a3eb271158..9e00afb17559 100644
--- a/fs/bcachefs/alloc_types.h
+++ b/fs/bcachefs/alloc_types.h
@@ -81,18 +81,46 @@ struct dev_stripe_state {
u64 next_alloc[BCH_SB_MEMBERS_MAX];
};
+#define WRITE_POINT_STATES() \
+ x(stopped) \
+ x(waiting_io) \
+ x(waiting_work) \
+ x(running)
+
+enum write_point_state {
+#define x(n) WRITE_POINT_##n,
+ WRITE_POINT_STATES()
+#undef x
+ WRITE_POINT_STATE_NR
+};
+
struct write_point {
- struct hlist_node node;
- struct mutex lock;
- u64 last_used;
- unsigned long write_point;
- enum bch_data_type data_type;
+ struct {
+ struct hlist_node node;
+ struct mutex lock;
+ u64 last_used;
+ unsigned long write_point;
+ enum bch_data_type data_type;
- /* calculated based on how many pointers we're actually going to use: */
- unsigned sectors_free;
+ /* calculated based on how many pointers we're actually going to use: */
+ unsigned sectors_free;
+
+ struct open_buckets ptrs;
+ struct dev_stripe_state stripe;
+
+ u64 sectors_allocated;
+ } __attribute__((__aligned__(SMP_CACHE_BYTES)));
+
+ struct {
+ struct work_struct index_update_work;
+
+ struct list_head writes;
+ spinlock_t writes_lock;
- struct open_buckets ptrs;
- struct dev_stripe_state stripe;
+ enum write_point_state state;
+ u64 last_state_change;
+ u64 time[WRITE_POINT_STATE_NR];
+ } __attribute__((__aligned__(SMP_CACHE_BYTES)));
};
struct write_point_specifier {