Commit 9f96d04e authored by Wen Gu's avatar Wen Gu Committed by Zhengchao Shao
Browse files

net/smc: introduce loopback-ism for SMC intra-OS shortcut

mainline inclusion
from mainline-v6.10-rc1
commit 46ac64419ded7bcbe1fb8d0f4df3258384a425c2
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IACM52

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=46ac64419ded7bcbe1fb8d0f4df3258384a425c2



--------------------------------

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: default avatarWen Gu <guwen@linux.alibaba.com>
Reviewed-by: default avatarGerd Bayer <gbayer@linux.ibm.com>
Reviewed-by: default avatarWenjia Zhang <wenjia@linux.ibm.com>
Reviewed-and-tested-by: default avatarJan Karcher <jaka@linux.ibm.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarZhengchao Shao <shaozhengchao@huawei.com>
parent 5b9d311a
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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.
+1 −0
Original line number Diff line number Diff line
@@ -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
+11 −1
Original line number Diff line number Diff line
@@ -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
@@ -3556,15 +3557,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:
@@ -3602,6 +3611,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);

net/smc/smc_loopback.c

0 → 100644
+156 −0
Original line number Diff line number Diff line
// 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();
}

net/smc/smc_loopback.h

0 → 100644
+42 −0
Original line number Diff line number Diff line
/* 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 */