[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250306230203.1550314-3-nikolay@enfabrica.net>
Date: Fri, 7 Mar 2025 01:01:52 +0200
From: Nikolay Aleksandrov <nikolay@...abrica.net>
To: netdev@...r.kernel.org
Cc: shrijeet@...abrica.net,
alex.badea@...sight.com,
eric.davis@...adcom.com,
rip.sohan@....com,
dsahern@...nel.org,
bmt@...ich.ibm.com,
roland@...abrica.net,
nikolay@...abrica.net,
winston.liu@...sight.com,
dan.mihailescu@...sight.com,
kheib@...hat.com,
parth.v.parikh@...sight.com,
davem@...hat.com,
ian.ziemba@....com,
andrew.tauferner@...nelisnetworks.com,
welch@....com,
rakhahari.bhunia@...sight.com,
kingshuk.mandal@...sight.com,
linux-rdma@...r.kernel.org,
kuba@...nel.org,
pabeni@...hat.com
Subject: [RFC PATCH 02/13] drivers: ultraeth: add context support
The ultra ethernet context is at the root and must be created first. UET
contexts are identified by host unique assigned ids on creation and are
protected by a ref counter.
Signed-off-by: Nikolay Aleksandrov <nikolay@...abrica.net>
Signed-off-by: Alex Badea <alex.badea@...sight.com>
---
drivers/ultraeth/Makefile | 2 +-
drivers/ultraeth/uet_context.c | 149 +++++++++++++++++++++++++++++
drivers/ultraeth/uet_main.c | 2 +
include/net/ultraeth/uet_context.h | 27 ++++++
4 files changed, 179 insertions(+), 1 deletion(-)
create mode 100644 drivers/ultraeth/uet_context.c
create mode 100644 include/net/ultraeth/uet_context.h
diff --git a/drivers/ultraeth/Makefile b/drivers/ultraeth/Makefile
index e30373d4b5dc..dc0c07eeef65 100644
--- a/drivers/ultraeth/Makefile
+++ b/drivers/ultraeth/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_ULTRAETH) += ultraeth.o
-ultraeth-objs := uet_main.o
+ultraeth-objs := uet_main.o uet_context.o
diff --git a/drivers/ultraeth/uet_context.c b/drivers/ultraeth/uet_context.c
new file mode 100644
index 000000000000..1c74cd8bbd56
--- /dev/null
+++ b/drivers/ultraeth/uet_context.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
+
+#include <net/ultraeth/uet_context.h>
+
+#define MAX_CONTEXT_ID 256
+static DECLARE_BITMAP(uet_context_ids, MAX_CONTEXT_ID);
+static LIST_HEAD(uet_context_list);
+static DEFINE_MUTEX(uet_context_lock);
+
+static int uet_context_get_new_id(int id)
+{
+ if (WARN_ON(id < -1 || id >= MAX_CONTEXT_ID))
+ return -EINVAL;
+
+ mutex_lock(&uet_context_lock);
+ if (id == -1)
+ id = find_first_zero_bit(uet_context_ids, MAX_CONTEXT_ID);
+ if (id < MAX_CONTEXT_ID) {
+ if (test_and_set_bit(id, uet_context_ids))
+ id = -EBUSY;
+ } else {
+ id = -ENOSPC;
+ }
+ mutex_unlock(&uet_context_lock);
+
+ return id;
+}
+
+static void uet_context_put_id(struct uet_context *ctx)
+{
+ clear_bit(ctx->id, uet_context_ids);
+}
+
+static void uet_context_link(struct uet_context *ctx)
+{
+ WARN_ON(!list_empty(&ctx->list));
+ list_add(&ctx->list, &uet_context_list);
+}
+
+static void uet_context_unlink(struct uet_context *ctx)
+{
+ list_del_init(&ctx->list);
+ if (refcount_dec_and_test(&ctx->refcnt))
+ return;
+
+ mutex_unlock(&uet_context_lock);
+ wait_event(ctx->refcnt_wait, refcount_read(&ctx->refcnt) == 0);
+ mutex_lock(&uet_context_lock);
+ WARN_ON(refcount_read(&ctx->refcnt) > 0);
+}
+
+static struct uet_context *uet_context_find(int id)
+{
+ struct uet_context *ctx;
+
+ if (!test_bit(id, uet_context_ids))
+ return NULL;
+
+ list_for_each_entry(ctx, &uet_context_list, list)
+ if (ctx->id == id)
+ return ctx;
+
+ return NULL;
+}
+
+struct uet_context *uet_context_get_by_id(int id)
+{
+ struct uet_context *ctx;
+
+ mutex_lock(&uet_context_lock);
+ ctx = uet_context_find(id);
+ if (ctx)
+ refcount_inc(&ctx->refcnt);
+ mutex_unlock(&uet_context_lock);
+
+ return ctx;
+}
+
+void uet_context_put(struct uet_context *ctx)
+{
+ if (refcount_dec_and_test(&ctx->refcnt))
+ wake_up(&ctx->refcnt_wait);
+}
+
+int uet_context_create(int id)
+{
+ struct uet_context *ctx;
+ int err = -ENOMEM;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return err;
+
+ INIT_LIST_HEAD(&ctx->list);
+ init_waitqueue_head(&ctx->refcnt_wait);
+ refcount_set(&ctx->refcnt, 1);
+
+ ctx->id = uet_context_get_new_id(id);
+ if (ctx->id < 0) {
+ err = ctx->id;
+ goto ctx_id_err;
+ }
+
+ uet_context_link(ctx);
+
+ return 0;
+
+ctx_id_err:
+ kfree(ctx);
+
+ return err;
+}
+
+static void __uet_context_destroy(struct uet_context *ctx)
+{
+ uet_context_unlink(ctx);
+ uet_context_put_id(ctx);
+ kfree(ctx);
+}
+
+bool uet_context_destroy(int id)
+{
+ struct uet_context *ctx;
+ bool found = false;
+
+ mutex_lock(&uet_context_lock);
+ ctx = uet_context_find(id);
+ if (ctx) {
+ __uet_context_destroy(ctx);
+ found = true;
+ }
+ mutex_unlock(&uet_context_lock);
+
+ return found;
+}
+
+void uet_context_destroy_all(void)
+{
+ struct uet_context *ctx;
+
+ mutex_lock(&uet_context_lock);
+ while ((ctx = list_first_entry_or_null(&uet_context_list,
+ struct uet_context,
+ list)))
+ __uet_context_destroy(ctx);
+
+ WARN_ON(!list_empty(&uet_context_list));
+ mutex_unlock(&uet_context_lock);
+}
diff --git a/drivers/ultraeth/uet_main.c b/drivers/ultraeth/uet_main.c
index 0d74175fc047..0f8383c6aba0 100644
--- a/drivers/ultraeth/uet_main.c
+++ b/drivers/ultraeth/uet_main.c
@@ -3,6 +3,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
+#include <net/ultraeth/uet_context.h>
static int __init uet_init(void)
{
@@ -11,6 +12,7 @@ static int __init uet_init(void)
static void __exit uet_exit(void)
{
+ uet_context_destroy_all();
}
module_init(uet_init);
diff --git a/include/net/ultraeth/uet_context.h b/include/net/ultraeth/uet_context.h
new file mode 100644
index 000000000000..150ad2c9b456
--- /dev/null
+++ b/include/net/ultraeth/uet_context.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
+
+#ifndef _UET_CONTEXT_H
+#define _UET_CONTEXT_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/refcount.h>
+#include <linux/wait.h>
+
+struct uet_context {
+ int id;
+ refcount_t refcnt;
+ wait_queue_head_t refcnt_wait;
+ struct list_head list;
+};
+
+struct uet_context *uet_context_get_by_id(int id);
+void uet_context_put(struct uet_context *ses_pl);
+
+int uet_context_create(int id);
+bool uet_context_destroy(int id);
+void uet_context_destroy_all(void);
+
+#endif /* _UET_CONTEXT_H */
--
2.48.1
Powered by blists - more mailing lists