mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:46:16 +00:00
net/smc: introduce loopback-ism for SMC intra-OS shortcut
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> Reviewed-by: Gerd Bayer <gbayer@linux.ibm.com> Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com> Reviewed-and-tested-by: Jan Karcher <jaka@linux.ibm.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
784c46f546
commit
46ac64419d
@ -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.
|
||||
|
@ -6,3 +6,4 @@ 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-$(CONFIG_SYSCTL) += smc_sysctl.o
|
||||
smc-$(CONFIG_SMC_LO) += smc_loopback.o
|
||||
|
@ -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
|
||||
@ -3555,15 +3556,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:
|
||||
@ -3601,6 +3610,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);
|
||||
|
156
net/smc/smc_loopback.c
Normal file
156
net/smc/smc_loopback.c
Normal file
@ -0,0 +1,156 @@
|
||||
// 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"
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
int smc_loopback_init(void)
|
||||
{
|
||||
return smc_lo_dev_probe();
|
||||
}
|
||||
|
||||
void smc_loopback_exit(void)
|
||||
{
|
||||
smc_lo_dev_remove();
|
||||
}
|
42
net/smc/smc_loopback.h
Normal file
42
net/smc/smc_loopback.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* 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;
|
||||
};
|
||||
|
||||
int smc_loopback_init(void);
|
||||
void smc_loopback_exit(void);
|
||||
#else
|
||||
static inline int smc_loopback_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void smc_loopback_exit(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SMC_LOOPBACK_H */
|
Loading…
Reference in New Issue
Block a user