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

Commit 277aa590 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'smc-fixes'



Ursula Braun says:

====================
net/smc: fixes 2019-02-04

here are more fixes in the smc code for the net tree:
Patch 1 fixes an IB-related problem with SMCR.
Patch 2 fixes a cursor problem for one-way traffic.
Patch 3 fixes a problem with RMB-reusage.
Patch 4 fixes a closing issue.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 53bc8d2a 84b799a2
Loading
Loading
Loading
Loading
+6 −10
Original line number Diff line number Diff line
@@ -21,13 +21,6 @@

/********************************** send *************************************/

struct smc_cdc_tx_pend {
	struct smc_connection	*conn;		/* socket connection */
	union smc_host_cursor	cursor;	/* tx sndbuf cursor sent */
	union smc_host_cursor	p_cursor;	/* rx RMBE cursor produced */
	u16			ctrl_seq;	/* conn. tx sequence # */
};

/* handler for send/transmission completion of a CDC msg */
static void smc_cdc_tx_handler(struct smc_wr_tx_pend_priv *pnd_snd,
			       struct smc_link *link,
@@ -61,12 +54,14 @@ static void smc_cdc_tx_handler(struct smc_wr_tx_pend_priv *pnd_snd,

int smc_cdc_get_free_slot(struct smc_connection *conn,
			  struct smc_wr_buf **wr_buf,
			  struct smc_rdma_wr **wr_rdma_buf,
			  struct smc_cdc_tx_pend **pend)
{
	struct smc_link *link = &conn->lgr->lnk[SMC_SINGLE_LINK];
	int rc;

	rc = smc_wr_tx_get_free_slot(link, smc_cdc_tx_handler, wr_buf,
				     wr_rdma_buf,
				     (struct smc_wr_tx_pend_priv **)pend);
	if (!conn->alert_token_local)
		/* abnormal termination */
@@ -96,6 +91,7 @@ int smc_cdc_msg_send(struct smc_connection *conn,
		     struct smc_wr_buf *wr_buf,
		     struct smc_cdc_tx_pend *pend)
{
	union smc_host_cursor cfed;
	struct smc_link *link;
	int rc;

@@ -107,10 +103,10 @@ int smc_cdc_msg_send(struct smc_connection *conn,
	conn->local_tx_ctrl.seqno = conn->tx_cdc_seq;
	smc_host_msg_to_cdc((struct smc_cdc_msg *)wr_buf,
			    &conn->local_tx_ctrl, conn);
	smc_curs_copy(&cfed, &((struct smc_host_cdc_msg *)wr_buf)->cons, conn);
	rc = smc_wr_tx_send(link, (struct smc_wr_tx_pend_priv *)pend);
	if (!rc)
		smc_curs_copy(&conn->rx_curs_confirmed,
			      &conn->local_tx_ctrl.cons, conn);
		smc_curs_copy(&conn->rx_curs_confirmed, &cfed, conn);

	return rc;
}
@@ -121,7 +117,7 @@ static int smcr_cdc_get_slot_and_msg_send(struct smc_connection *conn)
	struct smc_wr_buf *wr_buf;
	int rc;

	rc = smc_cdc_get_free_slot(conn, &wr_buf, &pend);
	rc = smc_cdc_get_free_slot(conn, &wr_buf, NULL, &pend);
	if (rc)
		return rc;

+32 −2
Original line number Diff line number Diff line
@@ -160,7 +160,9 @@ static inline void smcd_curs_copy(union smcd_cdc_cursor *tgt,
#endif
}

/* calculate cursor difference between old and new, where old <= new */
/* calculate cursor difference between old and new, where old <= new and
 * difference cannot exceed size
 */
static inline int smc_curs_diff(unsigned int size,
				union smc_host_cursor *old,
				union smc_host_cursor *new)
@@ -185,6 +187,28 @@ static inline int smc_curs_comp(unsigned int size,
	return smc_curs_diff(size, old, new);
}

/* calculate cursor difference between old and new, where old <= new and
 * difference may exceed size
 */
static inline int smc_curs_diff_large(unsigned int size,
				      union smc_host_cursor *old,
				      union smc_host_cursor *new)
{
	if (old->wrap < new->wrap)
		return min_t(int,
			     (size - old->count) + new->count +
			     (new->wrap - old->wrap - 1) * size,
			     size);

	if (old->wrap > new->wrap) /* wrap has switched from 0xffff to 0x0000 */
		return min_t(int,
			     (size - old->count) + new->count +
			     (new->wrap + 0xffff - old->wrap) * size,
			     size);

	return max_t(int, 0, (new->count - old->count));
}

static inline void smc_host_cursor_to_cdc(union smc_cdc_cursor *peer,
					  union smc_host_cursor *local,
					  struct smc_connection *conn)
@@ -270,10 +294,16 @@ static inline void smc_cdc_msg_to_host(struct smc_host_cdc_msg *local,
		smcr_cdc_msg_to_host(local, peer, conn);
}

struct smc_cdc_tx_pend;
struct smc_cdc_tx_pend {
	struct smc_connection	*conn;		/* socket connection */
	union smc_host_cursor	cursor;		/* tx sndbuf cursor sent */
	union smc_host_cursor	p_cursor;	/* rx RMBE cursor produced */
	u16			ctrl_seq;	/* conn. tx sequence # */
};

int smc_cdc_get_free_slot(struct smc_connection *conn,
			  struct smc_wr_buf **wr_buf,
			  struct smc_rdma_wr **wr_rdma_buf,
			  struct smc_cdc_tx_pend **pend);
void smc_cdc_tx_dismiss_slots(struct smc_connection *conn);
int smc_cdc_msg_send(struct smc_connection *conn, struct smc_wr_buf *wr_buf,
+1 −8
Original line number Diff line number Diff line
@@ -345,14 +345,7 @@ static void smc_close_passive_work(struct work_struct *work)

	switch (sk->sk_state) {
	case SMC_INIT:
		if (atomic_read(&conn->bytes_to_rcv) ||
		    (rxflags->peer_done_writing &&
		     !smc_cdc_rxed_any_close(conn))) {
		sk->sk_state = SMC_APPCLOSEWAIT1;
		} else {
			sk->sk_state = SMC_CLOSED;
			sock_put(sk); /* passive closing */
		}
		break;
	case SMC_ACTIVE:
		sk->sk_state = SMC_APPCLOSEWAIT1;
+1 −1
Original line number Diff line number Diff line
@@ -302,13 +302,13 @@ static void smc_buf_unuse(struct smc_connection *conn,
		conn->sndbuf_desc->used = 0;
	if (conn->rmb_desc) {
		if (!conn->rmb_desc->regerr) {
			conn->rmb_desc->used = 0;
			if (!lgr->is_smcd) {
				/* unregister rmb with peer */
				smc_llc_do_delete_rkey(
						&lgr->lnk[SMC_SINGLE_LINK],
						conn->rmb_desc);
			}
			conn->rmb_desc->used = 0;
		} else {
			/* buf registration failed, reuse not possible */
			write_lock_bh(&lgr->rmbs_lock);
+20 −0
Original line number Diff line number Diff line
@@ -52,6 +52,24 @@ enum smc_wr_reg_state {
	FAILED		/* ib_wr_reg_mr response: failure */
};

struct smc_rdma_sge {				/* sges for RDMA writes */
	struct ib_sge		wr_tx_rdma_sge[SMC_IB_MAX_SEND_SGE];
};

#define SMC_MAX_RDMA_WRITES	2		/* max. # of RDMA writes per
						 * message send
						 */

struct smc_rdma_sges {				/* sges per message send */
	struct smc_rdma_sge	tx_rdma_sge[SMC_MAX_RDMA_WRITES];
};

struct smc_rdma_wr {				/* work requests per message
						 * send
						 */
	struct ib_rdma_wr	wr_tx_rdma[SMC_MAX_RDMA_WRITES];
};

struct smc_link {
	struct smc_ib_device	*smcibdev;	/* ib-device */
	u8			ibport;		/* port - values 1 | 2 */
@@ -64,6 +82,8 @@ struct smc_link {
	struct smc_wr_buf	*wr_tx_bufs;	/* WR send payload buffers */
	struct ib_send_wr	*wr_tx_ibs;	/* WR send meta data */
	struct ib_sge		*wr_tx_sges;	/* WR send gather meta data */
	struct smc_rdma_sges	*wr_tx_rdma_sges;/*RDMA WRITE gather meta data*/
	struct smc_rdma_wr	*wr_tx_rdmas;	/* WR RDMA WRITE */
	struct smc_wr_tx_pend	*wr_tx_pends;	/* WR send waiting for CQE */
	/* above four vectors have wr_tx_cnt elements and use the same index */
	dma_addr_t		wr_tx_dma_addr;	/* DMA address of wr_tx_bufs */
Loading