Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d8fb617 authored by Ursula Braun's avatar Ursula Braun Committed by David S. Miller
Browse files

net/smc: introduce sg-logic for send buffers



SMC send buffers are processed the same way as RMBs. Since RMBs have
been converted to sg-logic, do the same for send buffers.

Signed-off-by: default avatarUrsula Braun <ubraun@linux.vnet.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d5b361b0
Loading
Loading
Loading
Loading
+35 −11
Original line number Original line Diff line number Diff line
@@ -248,6 +248,7 @@ static void smc_link_clear(struct smc_link *lnk)


static void smc_lgr_free_sndbufs(struct smc_link_group *lgr)
static void smc_lgr_free_sndbufs(struct smc_link_group *lgr)
{
{
	struct smc_link *lnk = &lgr->lnk[SMC_SINGLE_LINK];
	struct smc_buf_desc *sndbuf_desc, *bf_desc;
	struct smc_buf_desc *sndbuf_desc, *bf_desc;
	int i;
	int i;


@@ -255,10 +256,11 @@ static void smc_lgr_free_sndbufs(struct smc_link_group *lgr)
		list_for_each_entry_safe(sndbuf_desc, bf_desc, &lgr->sndbufs[i],
		list_for_each_entry_safe(sndbuf_desc, bf_desc, &lgr->sndbufs[i],
					 list) {
					 list) {
			list_del(&sndbuf_desc->list);
			list_del(&sndbuf_desc->list);
			smc_ib_buf_unmap(lgr->lnk[SMC_SINGLE_LINK].smcibdev,
			smc_ib_buf_unmap_sg(lnk->smcibdev, sndbuf_desc,
					 smc_uncompress_bufsize(i),
					    DMA_TO_DEVICE);
					 sndbuf_desc, DMA_TO_DEVICE);
			sg_free_table(&sndbuf_desc->sgt[SMC_SINGLE_LINK]);
			kfree(sndbuf_desc->cpu_addr);
			free_pages((unsigned long)sndbuf_desc->cpu_addr,
				   sndbuf_desc->order);
			kfree(sndbuf_desc);
			kfree(sndbuf_desc);
		}
		}
	}
	}
@@ -517,6 +519,9 @@ int smc_sndbuf_create(struct smc_sock *smc)
	for (bufsize_short = smc_compress_bufsize(smc->sk.sk_sndbuf / 2);
	for (bufsize_short = smc_compress_bufsize(smc->sk.sk_sndbuf / 2);
	     bufsize_short >= 0; bufsize_short--) {
	     bufsize_short >= 0; bufsize_short--) {
		bufsize = smc_uncompress_bufsize(bufsize_short);
		bufsize = smc_uncompress_bufsize(bufsize_short);
		if ((1 << get_order(bufsize)) > SG_MAX_SINGLE_ALLOC)
			continue;

		/* check for reusable sndbuf_slot in the link group */
		/* check for reusable sndbuf_slot in the link group */
		sndbuf_desc = smc_sndbuf_get_slot(lgr, bufsize_short);
		sndbuf_desc = smc_sndbuf_get_slot(lgr, bufsize_short);
		if (sndbuf_desc) {
		if (sndbuf_desc) {
@@ -527,10 +532,12 @@ int smc_sndbuf_create(struct smc_sock *smc)
		sndbuf_desc = kzalloc(sizeof(*sndbuf_desc), GFP_KERNEL);
		sndbuf_desc = kzalloc(sizeof(*sndbuf_desc), GFP_KERNEL);
		if (!sndbuf_desc)
		if (!sndbuf_desc)
			break; /* give up with -ENOMEM */
			break; /* give up with -ENOMEM */
		sndbuf_desc->cpu_addr = kzalloc(bufsize,

						GFP_KERNEL | __GFP_NOWARN |
		sndbuf_desc->cpu_addr =
			(void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN |
						 __GFP_NOMEMALLOC |
						 __GFP_NOMEMALLOC |
						__GFP_NORETRY);
						 __GFP_NORETRY | __GFP_ZERO,
						 get_order(bufsize));
		if (!sndbuf_desc->cpu_addr) {
		if (!sndbuf_desc->cpu_addr) {
			kfree(sndbuf_desc);
			kfree(sndbuf_desc);
			sndbuf_desc = NULL;
			sndbuf_desc = NULL;
@@ -539,14 +546,31 @@ int smc_sndbuf_create(struct smc_sock *smc)
			 */
			 */
			continue;
			continue;
		}
		}
		rc = smc_ib_buf_map(lgr->lnk[SMC_SINGLE_LINK].smcibdev,
		sndbuf_desc->order = get_order(bufsize);
				    bufsize, sndbuf_desc, DMA_TO_DEVICE);

		rc = sg_alloc_table(&sndbuf_desc->sgt[SMC_SINGLE_LINK], 1,
				    GFP_KERNEL);
		if (rc) {
		if (rc) {
			kfree(sndbuf_desc->cpu_addr);
			free_pages((unsigned long)sndbuf_desc->cpu_addr,
				   sndbuf_desc->order);
			kfree(sndbuf_desc);
			sndbuf_desc = NULL;
			continue;
		}
		sg_set_buf(sndbuf_desc->sgt[SMC_SINGLE_LINK].sgl,
			   sndbuf_desc->cpu_addr, bufsize);

		rc = smc_ib_buf_map_sg(lgr->lnk[SMC_SINGLE_LINK].smcibdev,
				       sndbuf_desc, DMA_TO_DEVICE);
		if (rc != 1) {
			sg_free_table(&sndbuf_desc->sgt[SMC_SINGLE_LINK]);
			free_pages((unsigned long)sndbuf_desc->cpu_addr,
				   sndbuf_desc->order);
			kfree(sndbuf_desc);
			kfree(sndbuf_desc);
			sndbuf_desc = NULL;
			sndbuf_desc = NULL;
			continue; /* if mapping failed, try smaller one */
			continue; /* if mapping failed, try smaller one */
		}
		}

		sndbuf_desc->used = 1;
		sndbuf_desc->used = 1;
		write_lock_bh(&lgr->sndbufs_lock);
		write_lock_bh(&lgr->sndbufs_lock);
		list_add(&sndbuf_desc->list, &lgr->sndbufs[bufsize_short]);
		list_add(&sndbuf_desc->list, &lgr->sndbufs[bufsize_short]);
+0 −2
Original line number Original line Diff line number Diff line
@@ -102,8 +102,6 @@ struct smc_link {
/* tx/rx buffer list element for sndbufs list and rmbs list of a lgr */
/* tx/rx buffer list element for sndbufs list and rmbs list of a lgr */
struct smc_buf_desc {
struct smc_buf_desc {
	struct list_head	list;
	struct list_head	list;
	u64			dma_addr[SMC_LINKS_PER_LGR_MAX];
						/* mapped address of buffer */
	void			*cpu_addr;	/* virtual address of buffer */
	void			*cpu_addr;	/* virtual address of buffer */
	struct sg_table		sgt[SMC_LINKS_PER_LGR_MAX];/* virtual buffer */
	struct sg_table		sgt[SMC_LINKS_PER_LGR_MAX];/* virtual buffer */
	struct ib_mr		*mr_rx[SMC_LINKS_PER_LGR_MAX];
	struct ib_mr		*mr_rx[SMC_LINKS_PER_LGR_MAX];
+0 −29
Original line number Original line Diff line number Diff line
@@ -295,35 +295,6 @@ int smc_ib_get_memory_region(struct ib_pd *pd, int access_flags,
	return 0;
	return 0;
}
}


/* map a new TX or RX buffer to DMA */
int smc_ib_buf_map(struct smc_ib_device *smcibdev, int buf_size,
		   struct smc_buf_desc *buf_slot,
		   enum dma_data_direction data_direction)
{
	int rc = 0;

	if (buf_slot->dma_addr[SMC_SINGLE_LINK])
		return rc; /* already mapped */
	buf_slot->dma_addr[SMC_SINGLE_LINK] =
		ib_dma_map_single(smcibdev->ibdev, buf_slot->cpu_addr,
				  buf_size, data_direction);
	if (ib_dma_mapping_error(smcibdev->ibdev,
				 buf_slot->dma_addr[SMC_SINGLE_LINK]))
		rc = -EIO;
	return rc;
}

void smc_ib_buf_unmap(struct smc_ib_device *smcibdev, int buf_size,
		      struct smc_buf_desc *buf_slot,
		      enum dma_data_direction data_direction)
{
	if (!buf_slot->dma_addr[SMC_SINGLE_LINK])
		return; /* already unmapped */
	ib_dma_unmap_single(smcibdev->ibdev, *buf_slot->dma_addr, buf_size,
			    data_direction);
	buf_slot->dma_addr[SMC_SINGLE_LINK] = 0;
}

/* Map a new TX or RX buffer SG-table to DMA */
/* Map a new TX or RX buffer SG-table to DMA */
int smc_ib_buf_map_sg(struct smc_ib_device *smcibdev,
int smc_ib_buf_map_sg(struct smc_ib_device *smcibdev,
		      struct smc_buf_desc *buf_slot,
		      struct smc_buf_desc *buf_slot,
+0 −6
Original line number Original line Diff line number Diff line
@@ -51,12 +51,6 @@ int smc_ib_register_client(void) __init;
void smc_ib_unregister_client(void);
void smc_ib_unregister_client(void);
bool smc_ib_port_active(struct smc_ib_device *smcibdev, u8 ibport);
bool smc_ib_port_active(struct smc_ib_device *smcibdev, u8 ibport);
int smc_ib_remember_port_attr(struct smc_ib_device *smcibdev, u8 ibport);
int smc_ib_remember_port_attr(struct smc_ib_device *smcibdev, u8 ibport);
int smc_ib_buf_map(struct smc_ib_device *smcibdev, int buf_size,
		   struct smc_buf_desc *buf_slot,
		   enum dma_data_direction data_direction);
void smc_ib_buf_unmap(struct smc_ib_device *smcibdev, int bufsize,
		      struct smc_buf_desc *buf_slot,
		      enum dma_data_direction data_direction);
int smc_ib_buf_map_sg(struct smc_ib_device *smcibdev,
int smc_ib_buf_map_sg(struct smc_ib_device *smcibdev,
		      struct smc_buf_desc *buf_slot,
		      struct smc_buf_desc *buf_slot,
		      enum dma_data_direction data_direction);
		      enum dma_data_direction data_direction);
+3 −3
Original line number Original line Diff line number Diff line
@@ -277,6 +277,7 @@ static int smc_tx_rdma_writes(struct smc_connection *conn)
	struct smc_link_group *lgr = conn->lgr;
	struct smc_link_group *lgr = conn->lgr;
	int to_send, rmbespace;
	int to_send, rmbespace;
	struct smc_link *link;
	struct smc_link *link;
	dma_addr_t dma_addr;
	int num_sges;
	int num_sges;
	int rc;
	int rc;


@@ -334,12 +335,11 @@ static int smc_tx_rdma_writes(struct smc_connection *conn)
		src_len = conn->sndbuf_size - sent.count;
		src_len = conn->sndbuf_size - sent.count;
	}
	}
	src_len_sum = src_len;
	src_len_sum = src_len;
	dma_addr = sg_dma_address(conn->sndbuf_desc->sgt[SMC_SINGLE_LINK].sgl);
	for (dstchunk = 0; dstchunk < 2; dstchunk++) {
	for (dstchunk = 0; dstchunk < 2; dstchunk++) {
		num_sges = 0;
		num_sges = 0;
		for (srcchunk = 0; srcchunk < 2; srcchunk++) {
		for (srcchunk = 0; srcchunk < 2; srcchunk++) {
			sges[srcchunk].addr =
			sges[srcchunk].addr = dma_addr + src_off;
				conn->sndbuf_desc->dma_addr[SMC_SINGLE_LINK] +
				src_off;
			sges[srcchunk].length = src_len;
			sges[srcchunk].length = src_len;
			sges[srcchunk].lkey = link->roce_pd->local_dma_lkey;
			sges[srcchunk].lkey = link->roce_pd->local_dma_lkey;
			num_sges++;
			num_sges++;