Skip to content

Commit 46ac644

Browse files
Wen GuPaolo Abeni
authored andcommitted
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>
1 parent 784c46f commit 46ac644

File tree

5 files changed

+223
-1
lines changed

5 files changed

+223
-1
lines changed

net/smc/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,16 @@ config SMC_DIAG
2020
smcss.
2121

2222
if unsure, say Y.
23+
24+
config SMC_LO
25+
bool "SMC intra-OS shortcut with loopback-ism"
26+
depends on SMC
27+
default n
28+
help
29+
SMC_LO enables the creation of an Emulated-ISM device named
30+
loopback-ism in SMC and makes use of it for transferring data
31+
when communication occurs within the same OS. This helps in
32+
convenient testing of SMC-D since loopback-ism is independent
33+
of architecture or hardware.
34+
35+
if unsure, say N.

net/smc/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
66
smc-y += smc_cdc.o smc_tx.o smc_rx.o smc_close.o smc_ism.o smc_netlink.o smc_stats.o
77
smc-y += smc_tracepoint.o
88
smc-$(CONFIG_SYSCTL) += smc_sysctl.o
9+
smc-$(CONFIG_SMC_LO) += smc_loopback.o

net/smc/af_smc.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include "smc_stats.h"
5454
#include "smc_tracepoint.h"
5555
#include "smc_sysctl.h"
56+
#include "smc_loopback.h"
5657

5758
static DEFINE_MUTEX(smc_server_lgr_pending); /* serialize link group
5859
* creation on server
@@ -3555,15 +3556,23 @@ static int __init smc_init(void)
35553556
goto out_sock;
35563557
}
35573558

3559+
rc = smc_loopback_init();
3560+
if (rc) {
3561+
pr_err("%s: smc_loopback_init fails with %d\n", __func__, rc);
3562+
goto out_ib;
3563+
}
3564+
35583565
rc = tcp_register_ulp(&smc_ulp_ops);
35593566
if (rc) {
35603567
pr_err("%s: tcp_ulp_register fails with %d\n", __func__, rc);
3561-
goto out_ib;
3568+
goto out_lo;
35623569
}
35633570

35643571
static_branch_enable(&tcp_have_smc);
35653572
return 0;
35663573

3574+
out_lo:
3575+
smc_loopback_exit();
35673576
out_ib:
35683577
smc_ib_unregister_client();
35693578
out_sock:
@@ -3601,6 +3610,7 @@ static void __exit smc_exit(void)
36013610
tcp_unregister_ulp(&smc_ulp_ops);
36023611
sock_unregister(PF_SMC);
36033612
smc_core_exit();
3613+
smc_loopback_exit();
36043614
smc_ib_unregister_client();
36053615
smc_ism_exit();
36063616
destroy_workqueue(smc_close_wq);

net/smc/smc_loopback.c

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Shared Memory Communications Direct over loopback-ism device.
4+
*
5+
* Functions for loopback-ism device.
6+
*
7+
* Copyright (c) 2024, Alibaba Inc.
8+
*
9+
* Author: Wen Gu <guwen@linux.alibaba.com>
10+
* Tony Lu <tonylu@linux.alibaba.com>
11+
*
12+
*/
13+
14+
#include <linux/device.h>
15+
#include <linux/types.h>
16+
#include <net/smc.h>
17+
18+
#include "smc_ism.h"
19+
#include "smc_loopback.h"
20+
21+
static const char smc_lo_dev_name[] = "loopback-ism";
22+
static struct smc_lo_dev *lo_dev;
23+
24+
static const struct smcd_ops lo_ops = {
25+
.query_remote_gid = NULL,
26+
.register_dmb = NULL,
27+
.unregister_dmb = NULL,
28+
.add_vlan_id = NULL,
29+
.del_vlan_id = NULL,
30+
.set_vlan_required = NULL,
31+
.reset_vlan_required = NULL,
32+
.signal_event = NULL,
33+
.move_data = NULL,
34+
.supports_v2 = NULL,
35+
.get_local_gid = NULL,
36+
.get_chid = NULL,
37+
.get_dev = NULL,
38+
};
39+
40+
static struct smcd_dev *smcd_lo_alloc_dev(const struct smcd_ops *ops,
41+
int max_dmbs)
42+
{
43+
struct smcd_dev *smcd;
44+
45+
smcd = kzalloc(sizeof(*smcd), GFP_KERNEL);
46+
if (!smcd)
47+
return NULL;
48+
49+
smcd->conn = kcalloc(max_dmbs, sizeof(struct smc_connection *),
50+
GFP_KERNEL);
51+
if (!smcd->conn)
52+
goto out_smcd;
53+
54+
smcd->ops = ops;
55+
56+
spin_lock_init(&smcd->lock);
57+
spin_lock_init(&smcd->lgr_lock);
58+
INIT_LIST_HEAD(&smcd->vlan);
59+
INIT_LIST_HEAD(&smcd->lgr_list);
60+
init_waitqueue_head(&smcd->lgrs_deleted);
61+
return smcd;
62+
63+
out_smcd:
64+
kfree(smcd);
65+
return NULL;
66+
}
67+
68+
static int smcd_lo_register_dev(struct smc_lo_dev *ldev)
69+
{
70+
struct smcd_dev *smcd;
71+
72+
smcd = smcd_lo_alloc_dev(&lo_ops, SMC_LO_MAX_DMBS);
73+
if (!smcd)
74+
return -ENOMEM;
75+
ldev->smcd = smcd;
76+
smcd->priv = ldev;
77+
78+
/* TODO:
79+
* register loopback-ism to smcd_dev list.
80+
*/
81+
return 0;
82+
}
83+
84+
static void smcd_lo_unregister_dev(struct smc_lo_dev *ldev)
85+
{
86+
struct smcd_dev *smcd = ldev->smcd;
87+
88+
/* TODO:
89+
* unregister loopback-ism from smcd_dev list.
90+
*/
91+
kfree(smcd->conn);
92+
kfree(smcd);
93+
}
94+
95+
static int smc_lo_dev_init(struct smc_lo_dev *ldev)
96+
{
97+
return smcd_lo_register_dev(ldev);
98+
}
99+
100+
static void smc_lo_dev_exit(struct smc_lo_dev *ldev)
101+
{
102+
smcd_lo_unregister_dev(ldev);
103+
}
104+
105+
static void smc_lo_dev_release(struct device *dev)
106+
{
107+
struct smc_lo_dev *ldev =
108+
container_of(dev, struct smc_lo_dev, dev);
109+
110+
kfree(ldev);
111+
}
112+
113+
static int smc_lo_dev_probe(void)
114+
{
115+
struct smc_lo_dev *ldev;
116+
int ret;
117+
118+
ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
119+
if (!ldev)
120+
return -ENOMEM;
121+
122+
ldev->dev.parent = NULL;
123+
ldev->dev.release = smc_lo_dev_release;
124+
device_initialize(&ldev->dev);
125+
dev_set_name(&ldev->dev, smc_lo_dev_name);
126+
127+
ret = smc_lo_dev_init(ldev);
128+
if (ret)
129+
goto free_dev;
130+
131+
lo_dev = ldev; /* global loopback device */
132+
return 0;
133+
134+
free_dev:
135+
put_device(&ldev->dev);
136+
return ret;
137+
}
138+
139+
static void smc_lo_dev_remove(void)
140+
{
141+
if (!lo_dev)
142+
return;
143+
144+
smc_lo_dev_exit(lo_dev);
145+
put_device(&lo_dev->dev); /* device_initialize in smc_lo_dev_probe */
146+
}
147+
148+
int smc_loopback_init(void)
149+
{
150+
return smc_lo_dev_probe();
151+
}
152+
153+
void smc_loopback_exit(void)
154+
{
155+
smc_lo_dev_remove();
156+
}

net/smc/smc_loopback.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* Shared Memory Communications Direct over loopback-ism device.
4+
*
5+
* SMC-D loopback-ism device structure definitions.
6+
*
7+
* Copyright (c) 2024, Alibaba Inc.
8+
*
9+
* Author: Wen Gu <guwen@linux.alibaba.com>
10+
* Tony Lu <tonylu@linux.alibaba.com>
11+
*
12+
*/
13+
14+
#ifndef _SMC_LOOPBACK_H
15+
#define _SMC_LOOPBACK_H
16+
17+
#include <linux/device.h>
18+
#include <linux/err.h>
19+
#include <net/smc.h>
20+
21+
#if IS_ENABLED(CONFIG_SMC_LO)
22+
#define SMC_LO_MAX_DMBS 5000
23+
24+
struct smc_lo_dev {
25+
struct smcd_dev *smcd;
26+
struct device dev;
27+
};
28+
29+
int smc_loopback_init(void);
30+
void smc_loopback_exit(void);
31+
#else
32+
static inline int smc_loopback_init(void)
33+
{
34+
return 0;
35+
}
36+
37+
static inline void smc_loopback_exit(void)
38+
{
39+
}
40+
#endif
41+
42+
#endif /* _SMC_LOOPBACK_H */

0 commit comments

Comments
 (0)