summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2024-06-10 20:47:03 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2024-08-22 02:07:28 -0400
commit07014284bf622f8908ce17b6383bbfcf50c888d6 (patch)
treedcfe8e04ee85d8d4f3a7be89f9a691e20c94f4c0
parent487552ae6c7e980f7e0005f149b96f330c02ab06 (diff)
rcu: lift rcu_pending from bcachefs
Generic data structure for explicitly tracking pending RCU items, allowing items to be dequeued (i.e. allocate from items pending freeing). Works with conventional RCU and SRCU, and possibly other RCU flavors in the future, meaning this can serve as a more generic replacement for SLAB_TYPESAFE_BY_RCU. Pending items are tracked in radix trees; if memory allocation fails, we fall back to linked lists. A rcu_pending is initialized with a callback, which is invoked when pending items's grace periods have expired. Two types of callback processing are handled specially: - RCU_PENDING_KVFREE_FN New backend for kvfree_rcu(). Slightly faster, and eliminates the synchronize_rcu() slowpath in kvfree_rcu_mightsleep() - instead, an rcu_head is allocated if we don't have one and can't use the radix tree TODO: - add a shrinker (as in the existing kvfree_rcu implementation) so that memory reclaim can free expired objects if callback processing isn't keeping up, and to expedite a grace period if we're under memory pressure and too much memory is stranded by RCU - add a counter for amount of memory pending - RCU_PENDING_CALL_RCU_FN Accelerated backend for call_rcu() - pending callbacks are tracked in a radix tree to eliminate linked list overhead. to serve as replacement backends for kvfree_rcu() and call_rcu(); these may be of interest to other uses (e.g. SLAB_TYPESAFE_BY_RCU users). Note: Internally, we're using a single rearming call_rcu() callback for notifications from the core RCU subsystem for notifications when objects are ready to be processed. Ideally we would be getting a callback every time a grace period completes for which we have objects, but that would require multiple rcu_heads in flight, and since the number of gp sequence numbers with uncompleted callbacks is not bounded, we can't do that yet. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/Makefile1
-rw-r--r--fs/bcachefs/btree_key_cache_types.h2
-rw-r--r--include/linux/rcu_pending.h (renamed from fs/bcachefs/rcu_pending.h)0
-rw-r--r--kernel/rcu/Makefile2
-rw-r--r--kernel/rcu/pending.c (renamed from fs/bcachefs/rcu_pending.c)3
5 files changed, 3 insertions, 5 deletions
diff --git a/fs/bcachefs/Makefile b/fs/bcachefs/Makefile
index 17e7dd13ab0e..3d477690b71e 100644
--- a/fs/bcachefs/Makefile
+++ b/fs/bcachefs/Makefile
@@ -68,7 +68,6 @@ bcachefs-y := \
printbuf.o \
quota.o \
rebalance.o \
- rcu_pending.o \
recovery.o \
recovery_passes.o \
reflink.o \
diff --git a/fs/bcachefs/btree_key_cache_types.h b/fs/bcachefs/btree_key_cache_types.h
index 722f1ed10551..739f97022d81 100644
--- a/fs/bcachefs/btree_key_cache_types.h
+++ b/fs/bcachefs/btree_key_cache_types.h
@@ -2,7 +2,7 @@
#ifndef _BCACHEFS_BTREE_KEY_CACHE_TYPES_H
#define _BCACHEFS_BTREE_KEY_CACHE_TYPES_H
-#include "rcu_pending.h"
+#include <linux/rcu_pending.h>
struct btree_key_cache {
struct rhashtable table;
diff --git a/fs/bcachefs/rcu_pending.h b/include/linux/rcu_pending.h
index a875c640da8d..a875c640da8d 100644
--- a/fs/bcachefs/rcu_pending.h
+++ b/include/linux/rcu_pending.h
diff --git a/kernel/rcu/Makefile b/kernel/rcu/Makefile
index 0cfb009a99b9..2582f0324a11 100644
--- a/kernel/rcu/Makefile
+++ b/kernel/rcu/Makefile
@@ -7,7 +7,7 @@ ifeq ($(CONFIG_KCSAN),y)
KBUILD_CFLAGS += -g -fno-omit-frame-pointer
endif
-obj-y += update.o sync.o
+obj-y += update.o sync.o pending.o
obj-$(CONFIG_TREE_SRCU) += srcutree.o
obj-$(CONFIG_TINY_SRCU) += srcutiny.o
obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
diff --git a/fs/bcachefs/rcu_pending.c b/kernel/rcu/pending.c
index 1ffec2d8b014..0e814bfd1c87 100644
--- a/fs/bcachefs/rcu_pending.c
+++ b/kernel/rcu/pending.c
@@ -5,12 +5,11 @@
#include <linux/generic-radix-tree.h>
#include <linux/mm.h>
#include <linux/percpu.h>
+#include <linux/rcu_pending.h>
#include <linux/slab.h>
#include <linux/srcu.h>
#include <linux/vmalloc.h>
-#include "rcu_pending.h"
-
#define static_array_for_each(_a, _i) \
for (typeof(&(_a)[0]) _i = _a; \
_i < (_a) + ARRAY_SIZE(_a); \