Message ID | 20240324135522.108564-3-guwen@linux.alibaba.com (mailing list archive) |
---|---|
State | RFC |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | net/smc: SMC intra-OS shortcut with loopback-ism | expand |
On Sun, 2024-03-24 at 21:55 +0800, Wen Gu wrote: > Configuration of this feature is managed through the config SMC_LO. Hi Wen, you could omit building smc_loopback.o if CONFIG_SMC_LO was not set if you included the following fixup-patch. I think it's cleaner to put a few parts of net/smc/af_smc.c under conditional compile rather than have most of the contents of net/smc/smc_loopback.c under #ifdef. >From 11a9cfce550f0c4df10eafdd30aa4226d4d522a8 Mon Sep 17 00:00:00 2001 From: Gerd Bayer <gbayer@linux.ibm.com> Date: Wed, 3 Apr 2024 11:43:36 +0200 Subject: [PATCH] fixup! net/smc: introduce loopback-ism for SMC intra- OS shortcut --- net/smc/Makefile | 5 +++-- net/smc/af_smc.c | 6 ++++++ net/smc/smc_loopback.c | 8 -------- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/net/smc/Makefile b/net/smc/Makefile index a8c37111abe1..3b73c9d561bb 100644 --- a/net/smc/Makefile +++ b/net/smc/Makefile @@ -4,5 +4,6 @@ obj-$(CONFIG_SMC) += smc.o obj-$(CONFIG_SMC_DIAG) += smc_diag.o smc-y := af_smc.o smc_pnet.o smc_ib.o smc_clc.o smc_core.o smc_wr.o smc_llc.o smc-y += smc_cdc.o smc_tx.o smc_rx.o smc_close.o smc_ism.o smc_netlink.o smc_stats.o -smc-y += smc_tracepoint.o smc_loopback.o -smc-$(CONFIG_SYSCTL) += smc_sysctl.o +smc-y += smc_tracepoint.o +smc-$(CONFIG_SMC_LO) += smc_loopback.o +smc-$(CONFIG_SYSCTL) += smc_sysctl.o diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index fce7a5b2ce5c..bcbf600cd271 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -3574,11 +3574,13 @@ static int __init smc_init(void) goto out_sock; } +#if IS_ENABLED(CONFIG_SMC_LO) rc = smc_loopback_init(); if (rc) { pr_err("%s: smc_loopback_init fails with %d\n", __func__, rc); goto out_ib; } +#endif rc = tcp_register_ulp(&smc_ulp_ops); if (rc) { @@ -3590,8 +3592,10 @@ static int __init smc_init(void) return 0; out_lo: +#if IS_ENABLED(CONFIG_SMC_LO) smc_loopback_exit(); out_ib: +#endif smc_ib_unregister_client(); out_sock: sock_unregister(PF_SMC); @@ -3628,7 +3632,9 @@ static void __exit smc_exit(void) tcp_unregister_ulp(&smc_ulp_ops); sock_unregister(PF_SMC); smc_core_exit(); +#if IS_ENABLED(CONFIG_SMC_LO) smc_loopback_exit(); +#endif smc_ib_unregister_client(); smc_ism_exit(); destroy_workqueue(smc_close_wq); diff --git a/net/smc/smc_loopback.c b/net/smc/smc_loopback.c index 994fe39930ad..8d0181635ded 100644 --- a/net/smc/smc_loopback.c +++ b/net/smc/smc_loopback.c @@ -19,7 +19,6 @@ #include "smc_ism.h" #include "smc_loopback.h" -#if IS_ENABLED(CONFIG_SMC_LO) #define SMC_LO_V2_CAPABLE 0x1 /* loopback-ism acts as ISMv2 */ #define SMC_LO_SUPPORT_NOCOPY 0x1 #define SMC_DMA_ADDR_INVALID (~(dma_addr_t)0) @@ -442,20 +441,13 @@ static void smc_lo_dev_remove(void) smc_lo_dev_exit(lo_dev); put_device(&lo_dev->dev); /* device_initialize in smc_lo_dev_probe */ } -#endif int smc_loopback_init(void) { -#if IS_ENABLED(CONFIG_SMC_LO) return smc_lo_dev_probe(); -#else - return 0; -#endif } void smc_loopback_exit(void) { -#if IS_ENABLED(CONFIG_SMC_LO) smc_lo_dev_remove(); -#endif }
On 2024/4/3 19:27, Gerd Bayer wrote: > On Sun, 2024-03-24 at 21:55 +0800, Wen Gu wrote: >> Configuration of this feature is managed through the config SMC_LO. > > Hi Wen, > > you could omit building smc_loopback.o if CONFIG_SMC_LO was not set if > you included the following fixup-patch. I think it's cleaner to put a > few parts of net/smc/af_smc.c under conditional compile rather than > have most of the contents of net/smc/smc_loopback.c under #ifdef. > Hi Gerd. That is a really good suggestion. It is much cleaner in this way. I will improve it in next version. Thank you very much! > From 11a9cfce550f0c4df10eafdd30aa4226d4d522a8 Mon Sep 17 00:00:00 2001 > From: Gerd Bayer <gbayer@linux.ibm.com> > Date: Wed, 3 Apr 2024 11:43:36 +0200 > Subject: [PATCH] fixup! net/smc: introduce loopback-ism for SMC intra- > OS > shortcut > > --- > net/smc/Makefile | 5 +++-- > net/smc/af_smc.c | 6 ++++++ > net/smc/smc_loopback.c | 8 -------- > 3 files changed, 9 insertions(+), 10 deletions(-) > > diff --git a/net/smc/Makefile b/net/smc/Makefile > index a8c37111abe1..3b73c9d561bb 100644 > --- a/net/smc/Makefile > +++ b/net/smc/Makefile > @@ -4,5 +4,6 @@ obj-$(CONFIG_SMC) += smc.o > obj-$(CONFIG_SMC_DIAG) += smc_diag.o > smc-y := af_smc.o smc_pnet.o smc_ib.o smc_clc.o smc_core.o smc_wr.o > smc_llc.o > smc-y += smc_cdc.o smc_tx.o smc_rx.o smc_close.o smc_ism.o > smc_netlink.o smc_stats.o > -smc-y += smc_tracepoint.o smc_loopback.o > -smc-$(CONFIG_SYSCTL) += smc_sysctl.o > +smc-y += smc_tracepoint.o > +smc-$(CONFIG_SMC_LO) += smc_loopback.o > +smc-$(CONFIG_SYSCTL) += smc_sysctl.o > diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c > index fce7a5b2ce5c..bcbf600cd271 100644 > --- a/net/smc/af_smc.c > +++ b/net/smc/af_smc.c > @@ -3574,11 +3574,13 @@ static int __init smc_init(void) > goto out_sock; > } > > +#if IS_ENABLED(CONFIG_SMC_LO) > rc = smc_loopback_init(); > if (rc) { > pr_err("%s: smc_loopback_init fails with %d\n", > __func__, rc); > goto out_ib; > } > +#endif > > rc = tcp_register_ulp(&smc_ulp_ops); > if (rc) { > @@ -3590,8 +3592,10 @@ static int __init smc_init(void) > return 0; > > out_lo: > +#if IS_ENABLED(CONFIG_SMC_LO) > smc_loopback_exit(); > out_ib: > +#endif > smc_ib_unregister_client(); > out_sock: > sock_unregister(PF_SMC); > @@ -3628,7 +3632,9 @@ static void __exit smc_exit(void) > tcp_unregister_ulp(&smc_ulp_ops); > sock_unregister(PF_SMC); > smc_core_exit(); > +#if IS_ENABLED(CONFIG_SMC_LO) > smc_loopback_exit(); > +#endif > smc_ib_unregister_client(); > smc_ism_exit(); > destroy_workqueue(smc_close_wq); > diff --git a/net/smc/smc_loopback.c b/net/smc/smc_loopback.c > index 994fe39930ad..8d0181635ded 100644 > --- a/net/smc/smc_loopback.c > +++ b/net/smc/smc_loopback.c > @@ -19,7 +19,6 @@ > #include "smc_ism.h" > #include "smc_loopback.h" > > -#if IS_ENABLED(CONFIG_SMC_LO) > #define SMC_LO_V2_CAPABLE 0x1 /* loopback-ism acts as ISMv2 */ > #define SMC_LO_SUPPORT_NOCOPY 0x1 > #define SMC_DMA_ADDR_INVALID (~(dma_addr_t)0) > @@ -442,20 +441,13 @@ static void smc_lo_dev_remove(void) > smc_lo_dev_exit(lo_dev); > put_device(&lo_dev->dev); /* device_initialize in > smc_lo_dev_probe */ > } > -#endif > > int smc_loopback_init(void) > { > -#if IS_ENABLED(CONFIG_SMC_LO) > return smc_lo_dev_probe(); > -#else > - return 0; > -#endif > } > > void smc_loopback_exit(void) > { > -#if IS_ENABLED(CONFIG_SMC_LO) > smc_lo_dev_remove(); > -#endif > }
diff --git a/net/smc/Kconfig b/net/smc/Kconfig index 746be3996768..ba5e6a2dd2fd 100644 --- a/net/smc/Kconfig +++ b/net/smc/Kconfig @@ -20,3 +20,16 @@ config SMC_DIAG smcss. if unsure, say Y. + +config SMC_LO + bool "SMC intra-OS shortcut with loopback-ism" + depends on SMC + default n + help + SMC_LO enables the creation of an Emulated-ISM device named + loopback-ism in SMC and makes use of it for transferring data + when communication occurs within the same OS. This helps in + convenient testing of SMC-D since loopback-ism is independent + of architecture or hardware. + + if unsure, say N. diff --git a/net/smc/Makefile b/net/smc/Makefile index 875efcd126a2..a8c37111abe1 100644 --- a/net/smc/Makefile +++ b/net/smc/Makefile @@ -4,5 +4,5 @@ obj-$(CONFIG_SMC) += smc.o obj-$(CONFIG_SMC_DIAG) += smc_diag.o smc-y := af_smc.o smc_pnet.o smc_ib.o smc_clc.o smc_core.o smc_wr.o smc_llc.o smc-y += smc_cdc.o smc_tx.o smc_rx.o smc_close.o smc_ism.o smc_netlink.o smc_stats.o -smc-y += smc_tracepoint.o +smc-y += smc_tracepoint.o smc_loopback.o smc-$(CONFIG_SYSCTL) += smc_sysctl.o diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 4b52b3b159c0..751a8fdd6eb0 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -53,6 +53,7 @@ #include "smc_stats.h" #include "smc_tracepoint.h" #include "smc_sysctl.h" +#include "smc_loopback.h" static DEFINE_MUTEX(smc_server_lgr_pending); /* serialize link group * creation on server @@ -3557,15 +3558,23 @@ static int __init smc_init(void) goto out_sock; } + rc = smc_loopback_init(); + if (rc) { + pr_err("%s: smc_loopback_init fails with %d\n", __func__, rc); + goto out_ib; + } + rc = tcp_register_ulp(&smc_ulp_ops); if (rc) { pr_err("%s: tcp_ulp_register fails with %d\n", __func__, rc); - goto out_ib; + goto out_lo; } static_branch_enable(&tcp_have_smc); return 0; +out_lo: + smc_loopback_exit(); out_ib: smc_ib_unregister_client(); out_sock: @@ -3603,6 +3612,7 @@ static void __exit smc_exit(void) tcp_unregister_ulp(&smc_ulp_ops); sock_unregister(PF_SMC); smc_core_exit(); + smc_loopback_exit(); smc_ib_unregister_client(); smc_ism_exit(); destroy_workqueue(smc_close_wq); diff --git a/net/smc/smc_loopback.c b/net/smc/smc_loopback.c new file mode 100644 index 000000000000..3990f689ae79 --- /dev/null +++ b/net/smc/smc_loopback.c @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Shared Memory Communications Direct over loopback-ism device. + * + * Functions for loopback-ism device. + * + * Copyright (c) 2024, Alibaba Inc. + * + * Author: Wen Gu <guwen@linux.alibaba.com> + * Tony Lu <tonylu@linux.alibaba.com> + * + */ + +#include <linux/device.h> +#include <linux/types.h> +#include <net/smc.h> + +#include "smc_ism.h" +#include "smc_loopback.h" + +#if IS_ENABLED(CONFIG_SMC_LO) +static const char smc_lo_dev_name[] = "loopback-ism"; +static struct smc_lo_dev *lo_dev; + +static const struct smcd_ops lo_ops = { + .query_remote_gid = NULL, + .register_dmb = NULL, + .unregister_dmb = NULL, + .add_vlan_id = NULL, + .del_vlan_id = NULL, + .set_vlan_required = NULL, + .reset_vlan_required = NULL, + .signal_event = NULL, + .move_data = NULL, + .supports_v2 = NULL, + .get_local_gid = NULL, + .get_chid = NULL, + .get_dev = NULL, +}; + +static struct smcd_dev *smcd_lo_alloc_dev(const struct smcd_ops *ops, + int max_dmbs) +{ + struct smcd_dev *smcd; + + smcd = kzalloc(sizeof(*smcd), GFP_KERNEL); + if (!smcd) + return NULL; + + smcd->conn = kcalloc(max_dmbs, sizeof(struct smc_connection *), + GFP_KERNEL); + if (!smcd->conn) + goto out_smcd; + + smcd->ops = ops; + + spin_lock_init(&smcd->lock); + spin_lock_init(&smcd->lgr_lock); + INIT_LIST_HEAD(&smcd->vlan); + INIT_LIST_HEAD(&smcd->lgr_list); + init_waitqueue_head(&smcd->lgrs_deleted); + return smcd; + +out_smcd: + kfree(smcd); + return NULL; +} + +static int smcd_lo_register_dev(struct smc_lo_dev *ldev) +{ + struct smcd_dev *smcd; + + smcd = smcd_lo_alloc_dev(&lo_ops, SMC_LO_MAX_DMBS); + if (!smcd) + return -ENOMEM; + ldev->smcd = smcd; + smcd->priv = ldev; + + /* TODO: + * register loopback-ism to smcd_dev list. + */ + return 0; +} + +static void smcd_lo_unregister_dev(struct smc_lo_dev *ldev) +{ + struct smcd_dev *smcd = ldev->smcd; + + /* TODO: + * unregister loopback-ism from smcd_dev list. + */ + kfree(smcd->conn); + kfree(smcd); +} + +static int smc_lo_dev_init(struct smc_lo_dev *ldev) +{ + return smcd_lo_register_dev(ldev); +} + +static void smc_lo_dev_exit(struct smc_lo_dev *ldev) +{ + smcd_lo_unregister_dev(ldev); +} + +static void smc_lo_dev_release(struct device *dev) +{ + struct smc_lo_dev *ldev = + container_of(dev, struct smc_lo_dev, dev); + + kfree(ldev); +} + +static int smc_lo_dev_probe(void) +{ + struct smc_lo_dev *ldev; + int ret; + + ldev = kzalloc(sizeof(*ldev), GFP_KERNEL); + if (!ldev) + return -ENOMEM; + + ldev->dev.parent = NULL; + ldev->dev.release = smc_lo_dev_release; + device_initialize(&ldev->dev); + dev_set_name(&ldev->dev, smc_lo_dev_name); + + ret = smc_lo_dev_init(ldev); + if (ret) + goto free_dev; + + lo_dev = ldev; /* global loopback device */ + return 0; + +free_dev: + put_device(&ldev->dev); + return ret; +} + +static void smc_lo_dev_remove(void) +{ + if (!lo_dev) + return; + + smc_lo_dev_exit(lo_dev); + put_device(&lo_dev->dev); /* device_initialize in smc_lo_dev_probe */ +} +#endif + +int smc_loopback_init(void) +{ +#if IS_ENABLED(CONFIG_SMC_LO) + return smc_lo_dev_probe(); +#else + return 0; +#endif +} + +void smc_loopback_exit(void) +{ +#if IS_ENABLED(CONFIG_SMC_LO) + smc_lo_dev_remove(); +#endif +} diff --git a/net/smc/smc_loopback.h b/net/smc/smc_loopback.h new file mode 100644 index 000000000000..77980650b2bd --- /dev/null +++ b/net/smc/smc_loopback.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Shared Memory Communications Direct over loopback-ism device. + * + * SMC-D loopback-ism device structure definitions. + * + * Copyright (c) 2024, Alibaba Inc. + * + * Author: Wen Gu <guwen@linux.alibaba.com> + * Tony Lu <tonylu@linux.alibaba.com> + * + */ + +#ifndef _SMC_LOOPBACK_H +#define _SMC_LOOPBACK_H + +#include <linux/device.h> +#include <linux/err.h> +#include <net/smc.h> + +#if IS_ENABLED(CONFIG_SMC_LO) +#define SMC_LO_MAX_DMBS 5000 + +struct smc_lo_dev { + struct smcd_dev *smcd; + struct device dev; +}; +#endif + +int smc_loopback_init(void); +void smc_loopback_exit(void); + +#endif /* _SMC_LOOPBACK_H */
This introduces a kind of Emulated-ISM device named loopback-ism for SMCv2.1. The loopback-ism device is currently exclusive for SMC usage, and aims to provide an SMC shortcut for sockets within the same kernel, leading to improved intra-OS traffic performance. Configuration of this feature is managed through the config SMC_LO. Signed-off-by: Wen Gu <guwen@linux.alibaba.com> --- net/smc/Kconfig | 13 ++++ net/smc/Makefile | 2 +- net/smc/af_smc.c | 12 ++- net/smc/smc_loopback.c | 164 +++++++++++++++++++++++++++++++++++++++++ net/smc/smc_loopback.h | 33 +++++++++ 5 files changed, 222 insertions(+), 2 deletions(-) create mode 100644 net/smc/smc_loopback.c create mode 100644 net/smc/smc_loopback.h