diff mbox series

[RFC,07/22] ublk: bpf: add bpf prog attach helpers

Message ID 20250107120417.1237392-8-tom.leiming@gmail.com (mailing list archive)
State RFC
Headers show
Series ublk: support bpf | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch, async

Commit Message

Ming Lei Jan. 7, 2025, 12:03 p.m. UTC
Add bpf prog attach helpers and prepare for supporting ublk bpf, in which
multiple ublk device may attach to same bpf prog, and there can be
multiple bpf progs.

`bpf_prog_consumer` will be embedded in the bpf prog user side, such as
ublk device, `bpf_prog_provider` will be embedded in the bpf struct_ops
prog side.

Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
 drivers/block/ublk/bpf_reg.h | 77 ++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)
 create mode 100644 drivers/block/ublk/bpf_reg.h
diff mbox series

Patch

diff --git a/drivers/block/ublk/bpf_reg.h b/drivers/block/ublk/bpf_reg.h
new file mode 100644
index 000000000000..79d02e93aea8
--- /dev/null
+++ b/drivers/block/ublk/bpf_reg.h
@@ -0,0 +1,77 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef UBLK_INT_BPF_REG_HEADER
+#define UBLK_INT_BPF_REG_HEADER
+
+#include <linux/types.h>
+
+struct bpf_prog_consumer;
+struct bpf_prog_provider;
+
+typedef int (*bpf_prog_attach_t)(struct bpf_prog_consumer *consumer,
+				 struct bpf_prog_provider *provider);
+typedef void (*bpf_prog_detach_t)(struct bpf_prog_consumer *consumer,
+				  bool unreg);
+
+struct bpf_prog_consumer_ops {
+	bpf_prog_attach_t		attach_fn;
+	bpf_prog_detach_t		detach_fn;
+};
+
+struct bpf_prog_consumer {
+	const struct bpf_prog_consumer_ops	*ops;
+	unsigned int				prog_id;
+	struct list_head			node;
+	struct bpf_prog_provider		*provider;
+};
+
+struct bpf_prog_provider {
+	struct list_head	list;
+};
+
+static inline void bpf_prog_provider_init(struct bpf_prog_provider *provider)
+{
+	INIT_LIST_HEAD(&provider->list);
+}
+
+static inline bool bpf_prog_provider_is_empty(
+		struct bpf_prog_provider *provider)
+{
+	return list_empty(&provider->list);
+}
+
+static inline int bpf_prog_consumer_attach(struct bpf_prog_consumer *consumer,
+					   struct bpf_prog_provider *provider)
+{
+	const struct bpf_prog_consumer_ops *ops = consumer->ops;
+
+	if (!ops || !ops->attach_fn)
+		return -EINVAL;
+
+	if (ops->attach_fn) {
+		int ret = ops->attach_fn(consumer, provider);
+
+		if (ret)
+			return ret;
+	}
+	consumer->provider = provider;
+	list_add(&consumer->node, &provider->list);
+	return 0;
+}
+
+static inline void bpf_prog_consumer_detach(struct bpf_prog_consumer *consumer,
+					    bool unreg)
+{
+	const struct bpf_prog_consumer_ops *ops = consumer->ops;
+
+	if (!consumer->provider)
+		return;
+
+	if (!list_empty(&consumer->node)) {
+		if (ops && ops->detach_fn)
+			ops->detach_fn(consumer, unreg);
+		list_del_init(&consumer->node);
+		consumer->provider = NULL;
+	}
+}
+
+#endif