diff options
-rw-r--r-- | fs/bcachefs/btree_update_interior.c | 34 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_interior.h | 12 | ||||
-rw-r--r-- | fs/bcachefs/extents.c | 12 | ||||
-rw-r--r-- | fs/bcachefs/extents.h | 1 | ||||
-rw-r--r-- | include/linux/workqueue.h | 12 | ||||
-rw-r--r-- | kernel/workqueue.c | 14 |
6 files changed, 57 insertions, 28 deletions
diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c index 8e3d3db2c53b..ebdb4d2f1be9 100644 --- a/fs/bcachefs/btree_update_interior.c +++ b/fs/bcachefs/btree_update_interior.c @@ -285,7 +285,7 @@ static struct btree *__bch2_btree_node_alloc(struct btree_trans *trans, struct closure *cl, bool interior_node, unsigned target, - unsigned flags) + enum bch_trans_commit_flags flags) { struct bch_fs *c = trans->c; struct write_point *wp; @@ -305,13 +305,18 @@ static struct btree *__bch2_btree_node_alloc(struct btree_trans *trans, mutex_lock(&c->btree_reserve_cache_lock); if (c->btree_reserve_cache_nr > nr_reserve) { - struct btree_alloc *a = - &c->btree_reserve_cache[--c->btree_reserve_cache_nr]; - - bkey_copy(&b->key, &a->k); - b->ob = a->ob; - mutex_unlock(&c->btree_reserve_cache_lock); - goto out; + for (struct btree_alloc *a = c->btree_reserve_cache; + a < c->btree_reserve_cache + c->btree_reserve_cache_nr; + a++) { + if (target && !bch2_bkey_in_target(c, bkey_i_to_s_c(&a->k), target)) + continue; + + bkey_copy(&b->key, &a->k); + b->ob = a->ob; + *a = c->btree_reserve_cache[--c->btree_reserve_cache_nr]; + mutex_unlock(&c->btree_reserve_cache_lock); + goto out; + } } mutex_unlock(&c->btree_reserve_cache_lock); retry: @@ -1139,7 +1144,8 @@ static const char * const btree_node_reawrite_reason_strs[] = { static struct btree_update * bch2_btree_update_start(struct btree_trans *trans, struct btree_path *path, unsigned level_start, bool split, - unsigned target, unsigned flags) + unsigned target, + enum bch_trans_commit_flags flags) { struct bch_fs *c = trans->c; struct btree_update *as; @@ -2222,7 +2228,7 @@ int bch2_btree_node_rewrite(struct btree_trans *trans, struct btree_iter *iter, struct btree *b, unsigned target, - unsigned flags) + enum bch_trans_commit_flags flags) { struct bch_fs *c = trans->c; struct btree *n, *parent; @@ -2287,7 +2293,8 @@ err: int bch2_btree_node_rewrite_key(struct btree_trans *trans, enum btree_id btree, unsigned level, - struct bkey_i *k, unsigned flags) + struct bkey_i *k, + enum bch_trans_commit_flags flags) { struct btree_iter iter; bch2_trans_node_iter_init(trans, &iter, @@ -2311,7 +2318,7 @@ int bch2_btree_node_rewrite_pos(struct btree_trans *trans, enum btree_id btree, unsigned level, struct bpos pos, unsigned target, - unsigned flags) + enum bch_trans_commit_flags flags) { BUG_ON(!level); @@ -2330,7 +2337,8 @@ err: } int bch2_btree_node_rewrite_key_get_iter(struct btree_trans *trans, - struct btree *b, unsigned flags) + struct btree *b, + enum bch_trans_commit_flags flags) { struct btree_iter iter; int ret = get_iter_to_node(trans, &iter, b); diff --git a/fs/bcachefs/btree_update_interior.h b/fs/bcachefs/btree_update_interior.h index ac04e45a8515..6ed049f19a9a 100644 --- a/fs/bcachefs/btree_update_interior.h +++ b/fs/bcachefs/btree_update_interior.h @@ -175,15 +175,19 @@ static inline int bch2_foreground_maybe_merge(struct btree_trans *trans, } int bch2_btree_node_rewrite(struct btree_trans *, struct btree_iter *, - struct btree *, unsigned, unsigned); + struct btree *, unsigned, + enum bch_trans_commit_flags); int bch2_btree_node_rewrite_key(struct btree_trans *, enum btree_id, unsigned, - struct bkey_i *, unsigned); + struct bkey_i *, + enum bch_trans_commit_flags); int bch2_btree_node_rewrite_pos(struct btree_trans *, enum btree_id, unsigned, - struct bpos, unsigned, unsigned); + struct bpos, unsigned, + enum bch_trans_commit_flags); int bch2_btree_node_rewrite_key_get_iter(struct btree_trans *, - struct btree *, unsigned); + struct btree *, + enum bch_trans_commit_flags); void bch2_btree_node_rewrite_async(struct bch_fs *, struct btree *); diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c index 83cbd77dcb9c..ec0951fbddea 100644 --- a/fs/bcachefs/extents.c +++ b/fs/bcachefs/extents.c @@ -1023,6 +1023,18 @@ bool bch2_bkey_has_target(struct bch_fs *c, struct bkey_s_c k, unsigned target) return false; } +bool bch2_bkey_in_target(struct bch_fs *c, struct bkey_s_c k, unsigned target) +{ + struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k); + + guard(rcu)(); + bkey_for_each_ptr(ptrs, ptr) + if (!bch2_dev_in_target(c, ptr->dev, target)) + return false; + + return true; +} + bool bch2_bkey_matches_ptr(struct bch_fs *c, struct bkey_s_c k, struct bch_extent_ptr m, u64 offset) { diff --git a/fs/bcachefs/extents.h b/fs/bcachefs/extents.h index b8590e51b76e..f212f91c278d 100644 --- a/fs/bcachefs/extents.h +++ b/fs/bcachefs/extents.h @@ -615,6 +615,7 @@ static inline struct bch_extent_ptr *bch2_bkey_has_device(struct bkey_s k, unsig } bool bch2_bkey_has_target(struct bch_fs *, struct bkey_s_c, unsigned); +bool bch2_bkey_in_target(struct bch_fs *, struct bkey_s_c, unsigned); void bch2_bkey_extent_entry_drop(struct bkey_i *, union bch_extent_entry *); diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 6e30f275da77..e907c9bb840c 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -6,6 +6,7 @@ #ifndef _LINUX_WORKQUEUE_H #define _LINUX_WORKQUEUE_H +#include <linux/alloc_tag.h> #include <linux/timer.h> #include <linux/linkage.h> #include <linux/bitops.h> @@ -505,7 +506,8 @@ void workqueue_softirq_dead(unsigned int cpu); * Pointer to the allocated workqueue on success, %NULL on failure. */ __printf(1, 4) struct workqueue_struct * -alloc_workqueue(const char *fmt, unsigned int flags, int max_active, ...); +alloc_workqueue_noprof(const char *fmt, unsigned int flags, int max_active, ...); +#define alloc_workqueue(...) alloc_hooks(alloc_workqueue_noprof(__VA_ARGS__)) #ifdef CONFIG_LOCKDEP /** @@ -544,8 +546,8 @@ alloc_workqueue_lockdep_map(const char *fmt, unsigned int flags, int max_active, * Pointer to the allocated workqueue on success, %NULL on failure. */ #define alloc_ordered_workqueue_lockdep_map(fmt, flags, lockdep_map, args...) \ - alloc_workqueue_lockdep_map(fmt, WQ_UNBOUND | __WQ_ORDERED | (flags), \ - 1, lockdep_map, ##args) + alloc_hooks(alloc_workqueue_lockdep_map(fmt, WQ_UNBOUND | __WQ_ORDERED | (flags),\ + 1, lockdep_map, ##args)) #endif /** @@ -577,7 +579,9 @@ alloc_workqueue_lockdep_map(const char *fmt, unsigned int flags, int max_active, extern void destroy_workqueue(struct workqueue_struct *wq); -struct workqueue_attrs *alloc_workqueue_attrs(void); +struct workqueue_attrs *alloc_workqueue_attrs_noprof(void); +#define alloc_workqueue_attrs(...) alloc_hooks(alloc_workqueue_attrs_noprof(__VA_ARGS__)) + void free_workqueue_attrs(struct workqueue_attrs *attrs); int apply_workqueue_attrs(struct workqueue_struct *wq, const struct workqueue_attrs *attrs); diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 97f37b5bae66..bd195d4db685 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -4629,7 +4629,7 @@ void free_workqueue_attrs(struct workqueue_attrs *attrs) * * Return: The allocated new workqueue_attr on success. %NULL on failure. */ -struct workqueue_attrs *alloc_workqueue_attrs(void) +struct workqueue_attrs *alloc_workqueue_attrs_noprof(void) { struct workqueue_attrs *attrs; @@ -5682,12 +5682,12 @@ static struct workqueue_struct *__alloc_workqueue(const char *fmt, else wq_size = sizeof(*wq); - wq = kzalloc(wq_size, GFP_KERNEL); + wq = kzalloc_noprof(wq_size, GFP_KERNEL); if (!wq) return NULL; if (flags & WQ_UNBOUND) { - wq->unbound_attrs = alloc_workqueue_attrs(); + wq->unbound_attrs = alloc_workqueue_attrs_noprof(); if (!wq->unbound_attrs) goto err_free_wq; } @@ -5777,9 +5777,9 @@ err_destroy: } __printf(1, 4) -struct workqueue_struct *alloc_workqueue(const char *fmt, - unsigned int flags, - int max_active, ...) +struct workqueue_struct *alloc_workqueue_noprof(const char *fmt, + unsigned int flags, + int max_active, ...) { struct workqueue_struct *wq; va_list args; @@ -5794,7 +5794,7 @@ struct workqueue_struct *alloc_workqueue(const char *fmt, return wq; } -EXPORT_SYMBOL_GPL(alloc_workqueue); +EXPORT_SYMBOL_GPL(alloc_workqueue_noprof); #ifdef CONFIG_LOCKDEP __printf(1, 5) |