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

net/smc: add operations to merge sndbuf with peer DMB

mainline inclusion
from mainline-v6.10-rc1
commit 4398888268582cb51b69c6ee94f551bb8d37d12f
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=4398888268582cb51b69c6ee94f551bb8d37d12f



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

In some scenarios using Emulated-ISM device, sndbuf can share the same
physical memory region with peer DMB to avoid data copy from one side
to the other. In such case the sndbuf is only a descriptor that
describes the shared memory and does not actually occupy memory, it's
more like a ghost buffer.

      +----------+                     +----------+
      | socket A |                     | socket B |
      +----------+                     +----------+
            |                               |
       +--------+                       +--------+
       | sndbuf |                       |  DMB   |
       |  desc  |                       |  desc  |
       +--------+                       +--------+
            |                               |
            |                          +----v-----+
            +-------------------------->  memory  |
                                       +----------+

So here introduces three new SMC-D device operations to check if this
feature is supported by device, and to {attach|detach} ghost sndbuf to
peer DMB. For now only loopback-ism supports this.

Signed-off-by: default avatarWen Gu <guwen@linux.alibaba.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 f7a74457
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -77,6 +77,9 @@ struct smcd_ops {
	int (*reset_vlan_required)(struct smcd_dev *dev);
	int (*signal_event)(struct smcd_dev *dev, struct smcd_gid *rgid,
			    u32 trigger_irq, u32 event_code, u64 info);
	int (*support_dmb_nocopy)(struct smcd_dev *dev);
	int (*attach_dmb)(struct smcd_dev *dev, struct smcd_dmb *dmb);
	int (*detach_dmb)(struct smcd_dev *dev, u64 token);
};

struct smcd_dev {
+40 −0
Original line number Diff line number Diff line
@@ -250,6 +250,46 @@ int smc_ism_register_dmb(struct smc_link_group *lgr, int dmb_len,
	return rc;
}

bool smc_ism_support_dmb_nocopy(struct smcd_dev *smcd)
{
	/* for now only loopback-ism supports
	 * merging sndbuf with peer DMB to avoid
	 * data copies between them.
	 */
	return (smcd->ops->support_dmb_nocopy &&
		smcd->ops->support_dmb_nocopy(smcd));
}

int smc_ism_attach_dmb(struct smcd_dev *dev, u64 token,
		       struct smc_buf_desc *dmb_desc)
{
	struct smcd_dmb dmb;
	int rc = 0;

	if (!dev->ops->attach_dmb)
		return -EINVAL;

	memset(&dmb, 0, sizeof(dmb));
	dmb.dmb_tok = token;
	rc = dev->ops->attach_dmb(dev, &dmb);
	if (!rc) {
		dmb_desc->sba_idx = dmb.sba_idx;
		dmb_desc->token = dmb.dmb_tok;
		dmb_desc->cpu_addr = dmb.cpu_addr;
		dmb_desc->dma_addr = dmb.dma_addr;
		dmb_desc->len = dmb.dmb_len;
	}
	return rc;
}

int smc_ism_detach_dmb(struct smcd_dev *dev, u64 token)
{
	if (!dev->ops->detach_dmb)
		return -EINVAL;

	return dev->ops->detach_dmb(dev, token);
}

static int smc_nl_handle_smcd_dev(struct smcd_dev *smcd,
				  struct sk_buff *skb,
				  struct netlink_callback *cb)
+4 −0
Original line number Diff line number Diff line
@@ -48,6 +48,10 @@ int smc_ism_put_vlan(struct smcd_dev *dev, unsigned short vlan_id);
int smc_ism_register_dmb(struct smc_link_group *lgr, int buf_size,
			 struct smc_buf_desc *dmb_desc);
int smc_ism_unregister_dmb(struct smcd_dev *dev, struct smc_buf_desc *dmb_desc);
bool smc_ism_support_dmb_nocopy(struct smcd_dev *smcd);
int smc_ism_attach_dmb(struct smcd_dev *dev, u64 token,
		       struct smc_buf_desc *dmb_desc);
int smc_ism_detach_dmb(struct smcd_dev *dev, u64 token);
int smc_ism_signal_shutdown(struct smc_link_group *lgr);
void smc_ism_get_system_eid(u8 **eid);
u16 smc_ism_get_chid(struct smcd_dev *dev);