The first stage of loopback-ism was implemented as part of the SMC module [1]. Now that we have the dibs layer, provide access to a dibs_loopback device to all dibs clients. This is the first step of moving loopback-ism from net/smc/smc_loopback.* to net/dibs/dibs_loopback.*. One global structure lo_dev is allocated and added to the dibs devices. Follow-on patches will move functionality. Same as smc_loopback, dibs_loopback is provided by a config option. Note that there is no way to dynamically add or remove the loopback device. That could be a future improvement. When moving code to net/dibs, replace ism_ prefix with dibs_ prefix. As this is mostly a move of existing code, copyright and authors are unchanged. Link: https://lore.kernel.org/lkml/20240428060738.60843-1-guwen@xxxxxxxxxxxxxxxxx/ [1] Signed-off-by: Alexandra Winter <wintera@xxxxxxxxxxxxx> --- net/dibs/Kconfig | 13 +++++++ net/dibs/Makefile | 1 + net/dibs/dibs_loopback.c | 77 ++++++++++++++++++++++++++++++++++++++++ net/dibs/dibs_loopback.h | 38 ++++++++++++++++++++ net/dibs/dibs_main.c | 14 ++++++-- 5 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 net/dibs/dibs_loopback.c create mode 100644 net/dibs/dibs_loopback.h diff --git a/net/dibs/Kconfig b/net/dibs/Kconfig index 968c52938708..9a6182391b25 100644 --- a/net/dibs/Kconfig +++ b/net/dibs/Kconfig @@ -12,3 +12,16 @@ config DIBS To compile as a module choose M. The module name is dibs. If unsure, choose N. + +config DIBS_LO + bool "intra-OS shortcut with dibs loopback" + depends on DIBS + default n + help + DIBS_LO enables the creation of an software-emulated dibs device + named lo which can be used for transferring data when communication + occurs within the same OS. This helps in convenient testing of + dibs clients, since dibs loopback is independent of architecture or + hardware. + + if unsure, say N. diff --git a/net/dibs/Makefile b/net/dibs/Makefile index 825dec431bfc..85805490c77f 100644 --- a/net/dibs/Makefile +++ b/net/dibs/Makefile @@ -5,3 +5,4 @@ dibs-y += dibs_main.o obj-$(CONFIG_DIBS) += dibs.o +dibs-$(CONFIG_DIBS_LO) += dibs_loopback.o \ No newline at end of file diff --git a/net/dibs/dibs_loopback.c b/net/dibs/dibs_loopback.c new file mode 100644 index 000000000000..c221b55d24a2 --- /dev/null +++ b/net/dibs/dibs_loopback.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Functions for dibs loopback/loopback-ism device. + * + * Copyright (c) 2024, Alibaba Inc. + * + * Author: Wen Gu <guwen@xxxxxxxxxxxxxxxxx> + * Tony Lu <tonylu@xxxxxxxxxxxxxxxxx> + * + */ + +#include <linux/dibs.h> +#include <linux/types.h> + +#include "dibs_loopback.h" + +/* global loopback device */ +static struct dibs_lo_dev *lo_dev; + +static void dibs_lo_dev_exit(struct dibs_lo_dev *ldev) +{ + dibs_dev_del(ldev->dibs); +} + +static int dibs_lo_dev_probe(void) +{ + struct dibs_lo_dev *ldev; + struct dibs_dev *dibs; + int ret; + + ldev = kzalloc(sizeof(*ldev), GFP_KERNEL); + if (!ldev) + return -ENOMEM; + + dibs = dibs_dev_alloc(); + if (!dibs) { + kfree(ldev); + return -ENOMEM; + } + + ldev->dibs = dibs; + + ret = dibs_dev_add(dibs); + if (ret) + goto err_reg; + lo_dev = ldev; + return 0; + +err_reg: + /* pairs with dibs_dev_alloc() */ + kfree(dibs); + kfree(ldev); + + return ret; +} + +static void dibs_lo_dev_remove(void) +{ + if (!lo_dev) + return; + + dibs_lo_dev_exit(lo_dev); + /* pairs with dibs_dev_alloc() */ + kfree(lo_dev->dibs); + kfree(lo_dev); + lo_dev = NULL; +} + +int dibs_loopback_init(void) +{ + return dibs_lo_dev_probe(); +} + +void dibs_loopback_exit(void) +{ + dibs_lo_dev_remove(); +} diff --git a/net/dibs/dibs_loopback.h b/net/dibs/dibs_loopback.h new file mode 100644 index 000000000000..fd03b6333a24 --- /dev/null +++ b/net/dibs/dibs_loopback.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * dibs loopback (aka loopback-ism) device structure definitions. + * + * Copyright (c) 2024, Alibaba Inc. + * + * Author: Wen Gu <guwen@xxxxxxxxxxxxxxxxx> + * Tony Lu <tonylu@xxxxxxxxxxxxxxxxx> + * + */ + +#ifndef _DIBS_LOOPBACK_H +#define _DIBS_LOOPBACK_H + +#include <linux/dibs.h> +#include <linux/types.h> +#include <linux/wait.h> + +#if IS_ENABLED(CONFIG_DIBS_LO) + +struct dibs_lo_dev { + struct dibs_dev *dibs; +}; + +int dibs_loopback_init(void); +void dibs_loopback_exit(void); +#else +static inline int dibs_loopback_init(void) +{ + return 0; +} + +static inline void dibs_loopback_exit(void) +{ +} +#endif + +#endif /* _DIBS_LOOPBACK_H */ diff --git a/net/dibs/dibs_main.c b/net/dibs/dibs_main.c index 5345e41ae5e4..2c213e1f8f93 100644 --- a/net/dibs/dibs_main.c +++ b/net/dibs/dibs_main.c @@ -14,6 +14,8 @@ #include <linux/err.h> #include <linux/dibs.h> +#include "dibs_loopback.h" + MODULE_DESCRIPTION("Direct Internal Buffer Sharing class"); MODULE_LICENSE("GPL"); @@ -94,15 +96,23 @@ EXPORT_SYMBOL_GPL(dibs_dev_del); static int __init dibs_init(void) { + int rc; + memset(clients, 0, sizeof(clients)); max_client = 0; - pr_info("module loaded\n"); - return 0; + rc = dibs_loopback_init(); + if (rc) + pr_err("%s fails with %d\n", __func__, rc); + else + pr_info("module loaded\n"); + + return rc; } static void __exit dibs_exit(void) { + dibs_loopback_exit(); pr_info("module unloaded\n"); } -- 2.48.1