diff options
Diffstat (limited to 'net/smc')
-rw-r--r-- | net/smc/af_smc.c | 11 | ||||
-rw-r--r-- | net/smc/smc_cdc.c | 21 | ||||
-rw-r--r-- | net/smc/smc_cdc.h | 34 | ||||
-rw-r--r-- | net/smc/smc_clc.c | 2 | ||||
-rw-r--r-- | net/smc/smc_close.c | 9 | ||||
-rw-r--r-- | net/smc/smc_core.c | 6 | ||||
-rw-r--r-- | net/smc/smc_core.h | 20 | ||||
-rw-r--r-- | net/smc/smc_ib.c | 6 | ||||
-rw-r--r-- | net/smc/smc_llc.c | 3 | ||||
-rw-r--r-- | net/smc/smc_pnet.c | 2 | ||||
-rw-r--r-- | net/smc/smc_tx.c | 64 | ||||
-rw-r--r-- | net/smc/smc_wr.c | 46 | ||||
-rw-r--r-- | net/smc/smc_wr.h | 1 |
13 files changed, 158 insertions, 67 deletions
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index c4e56602e0c6..b04a813fc865 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c | |||
@@ -1505,6 +1505,11 @@ static int smc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | |||
1505 | 1505 | ||
1506 | smc = smc_sk(sk); | 1506 | smc = smc_sk(sk); |
1507 | lock_sock(sk); | 1507 | lock_sock(sk); |
1508 | if (sk->sk_state == SMC_CLOSED && (sk->sk_shutdown & RCV_SHUTDOWN)) { | ||
1509 | /* socket was connected before, no more data to read */ | ||
1510 | rc = 0; | ||
1511 | goto out; | ||
1512 | } | ||
1508 | if ((sk->sk_state == SMC_INIT) || | 1513 | if ((sk->sk_state == SMC_INIT) || |
1509 | (sk->sk_state == SMC_LISTEN) || | 1514 | (sk->sk_state == SMC_LISTEN) || |
1510 | (sk->sk_state == SMC_CLOSED)) | 1515 | (sk->sk_state == SMC_CLOSED)) |
@@ -1840,7 +1845,11 @@ static ssize_t smc_splice_read(struct socket *sock, loff_t *ppos, | |||
1840 | 1845 | ||
1841 | smc = smc_sk(sk); | 1846 | smc = smc_sk(sk); |
1842 | lock_sock(sk); | 1847 | lock_sock(sk); |
1843 | 1848 | if (sk->sk_state == SMC_CLOSED && (sk->sk_shutdown & RCV_SHUTDOWN)) { | |
1849 | /* socket was connected before, no more data to read */ | ||
1850 | rc = 0; | ||
1851 | goto out; | ||
1852 | } | ||
1844 | if (sk->sk_state == SMC_INIT || | 1853 | if (sk->sk_state == SMC_INIT || |
1845 | sk->sk_state == SMC_LISTEN || | 1854 | sk->sk_state == SMC_LISTEN || |
1846 | sk->sk_state == SMC_CLOSED) | 1855 | sk->sk_state == SMC_CLOSED) |
diff --git a/net/smc/smc_cdc.c b/net/smc/smc_cdc.c index db83332ac1c8..a712c9f8699b 100644 --- a/net/smc/smc_cdc.c +++ b/net/smc/smc_cdc.c | |||
@@ -21,13 +21,6 @@ | |||
21 | 21 | ||
22 | /********************************** send *************************************/ | 22 | /********************************** send *************************************/ |
23 | 23 | ||
24 | struct smc_cdc_tx_pend { | ||
25 | struct smc_connection *conn; /* socket connection */ | ||
26 | union smc_host_cursor cursor; /* tx sndbuf cursor sent */ | ||
27 | union smc_host_cursor p_cursor; /* rx RMBE cursor produced */ | ||
28 | u16 ctrl_seq; /* conn. tx sequence # */ | ||
29 | }; | ||
30 | |||
31 | /* handler for send/transmission completion of a CDC msg */ | 24 | /* handler for send/transmission completion of a CDC msg */ |
32 | static void smc_cdc_tx_handler(struct smc_wr_tx_pend_priv *pnd_snd, | 25 | static void smc_cdc_tx_handler(struct smc_wr_tx_pend_priv *pnd_snd, |
33 | struct smc_link *link, | 26 | struct smc_link *link, |
@@ -61,12 +54,14 @@ static void smc_cdc_tx_handler(struct smc_wr_tx_pend_priv *pnd_snd, | |||
61 | 54 | ||
62 | int smc_cdc_get_free_slot(struct smc_connection *conn, | 55 | int smc_cdc_get_free_slot(struct smc_connection *conn, |
63 | struct smc_wr_buf **wr_buf, | 56 | struct smc_wr_buf **wr_buf, |
57 | struct smc_rdma_wr **wr_rdma_buf, | ||
64 | struct smc_cdc_tx_pend **pend) | 58 | struct smc_cdc_tx_pend **pend) |
65 | { | 59 | { |
66 | struct smc_link *link = &conn->lgr->lnk[SMC_SINGLE_LINK]; | 60 | struct smc_link *link = &conn->lgr->lnk[SMC_SINGLE_LINK]; |
67 | int rc; | 61 | int rc; |
68 | 62 | ||
69 | rc = smc_wr_tx_get_free_slot(link, smc_cdc_tx_handler, wr_buf, | 63 | rc = smc_wr_tx_get_free_slot(link, smc_cdc_tx_handler, wr_buf, |
64 | wr_rdma_buf, | ||
70 | (struct smc_wr_tx_pend_priv **)pend); | 65 | (struct smc_wr_tx_pend_priv **)pend); |
71 | if (!conn->alert_token_local) | 66 | if (!conn->alert_token_local) |
72 | /* abnormal termination */ | 67 | /* abnormal termination */ |
@@ -96,6 +91,7 @@ int smc_cdc_msg_send(struct smc_connection *conn, | |||
96 | struct smc_wr_buf *wr_buf, | 91 | struct smc_wr_buf *wr_buf, |
97 | struct smc_cdc_tx_pend *pend) | 92 | struct smc_cdc_tx_pend *pend) |
98 | { | 93 | { |
94 | union smc_host_cursor cfed; | ||
99 | struct smc_link *link; | 95 | struct smc_link *link; |
100 | int rc; | 96 | int rc; |
101 | 97 | ||
@@ -107,10 +103,10 @@ int smc_cdc_msg_send(struct smc_connection *conn, | |||
107 | conn->local_tx_ctrl.seqno = conn->tx_cdc_seq; | 103 | conn->local_tx_ctrl.seqno = conn->tx_cdc_seq; |
108 | smc_host_msg_to_cdc((struct smc_cdc_msg *)wr_buf, | 104 | smc_host_msg_to_cdc((struct smc_cdc_msg *)wr_buf, |
109 | &conn->local_tx_ctrl, conn); | 105 | &conn->local_tx_ctrl, conn); |
106 | smc_curs_copy(&cfed, &((struct smc_host_cdc_msg *)wr_buf)->cons, conn); | ||
110 | rc = smc_wr_tx_send(link, (struct smc_wr_tx_pend_priv *)pend); | 107 | rc = smc_wr_tx_send(link, (struct smc_wr_tx_pend_priv *)pend); |
111 | if (!rc) | 108 | if (!rc) |
112 | smc_curs_copy(&conn->rx_curs_confirmed, | 109 | smc_curs_copy(&conn->rx_curs_confirmed, &cfed, conn); |
113 | &conn->local_tx_ctrl.cons, conn); | ||
114 | 110 | ||
115 | return rc; | 111 | return rc; |
116 | } | 112 | } |
@@ -121,11 +117,14 @@ static int smcr_cdc_get_slot_and_msg_send(struct smc_connection *conn) | |||
121 | struct smc_wr_buf *wr_buf; | 117 | struct smc_wr_buf *wr_buf; |
122 | int rc; | 118 | int rc; |
123 | 119 | ||
124 | rc = smc_cdc_get_free_slot(conn, &wr_buf, &pend); | 120 | rc = smc_cdc_get_free_slot(conn, &wr_buf, NULL, &pend); |
125 | if (rc) | 121 | if (rc) |
126 | return rc; | 122 | return rc; |
127 | 123 | ||
128 | return smc_cdc_msg_send(conn, wr_buf, pend); | 124 | spin_lock_bh(&conn->send_lock); |
125 | rc = smc_cdc_msg_send(conn, wr_buf, pend); | ||
126 | spin_unlock_bh(&conn->send_lock); | ||
127 | return rc; | ||
129 | } | 128 | } |
130 | 129 | ||
131 | int smc_cdc_get_slot_and_msg_send(struct smc_connection *conn) | 130 | int smc_cdc_get_slot_and_msg_send(struct smc_connection *conn) |
diff --git a/net/smc/smc_cdc.h b/net/smc/smc_cdc.h index b5bfe38c7f9b..271e2524dc8f 100644 --- a/net/smc/smc_cdc.h +++ b/net/smc/smc_cdc.h | |||
@@ -160,7 +160,9 @@ static inline void smcd_curs_copy(union smcd_cdc_cursor *tgt, | |||
160 | #endif | 160 | #endif |
161 | } | 161 | } |
162 | 162 | ||
163 | /* calculate cursor difference between old and new, where old <= new */ | 163 | /* calculate cursor difference between old and new, where old <= new and |
164 | * difference cannot exceed size | ||
165 | */ | ||
164 | static inline int smc_curs_diff(unsigned int size, | 166 | static inline int smc_curs_diff(unsigned int size, |
165 | union smc_host_cursor *old, | 167 | union smc_host_cursor *old, |
166 | union smc_host_cursor *new) | 168 | union smc_host_cursor *new) |
@@ -185,6 +187,28 @@ static inline int smc_curs_comp(unsigned int size, | |||
185 | return smc_curs_diff(size, old, new); | 187 | return smc_curs_diff(size, old, new); |
186 | } | 188 | } |
187 | 189 | ||
190 | /* calculate cursor difference between old and new, where old <= new and | ||
191 | * difference may exceed size | ||
192 | */ | ||
193 | static inline int smc_curs_diff_large(unsigned int size, | ||
194 | union smc_host_cursor *old, | ||
195 | union smc_host_cursor *new) | ||
196 | { | ||
197 | if (old->wrap < new->wrap) | ||
198 | return min_t(int, | ||
199 | (size - old->count) + new->count + | ||
200 | (new->wrap - old->wrap - 1) * size, | ||
201 | size); | ||
202 | |||
203 | if (old->wrap > new->wrap) /* wrap has switched from 0xffff to 0x0000 */ | ||
204 | return min_t(int, | ||
205 | (size - old->count) + new->count + | ||
206 | (new->wrap + 0xffff - old->wrap) * size, | ||
207 | size); | ||
208 | |||
209 | return max_t(int, 0, (new->count - old->count)); | ||
210 | } | ||
211 | |||
188 | static inline void smc_host_cursor_to_cdc(union smc_cdc_cursor *peer, | 212 | static inline void smc_host_cursor_to_cdc(union smc_cdc_cursor *peer, |
189 | union smc_host_cursor *local, | 213 | union smc_host_cursor *local, |
190 | struct smc_connection *conn) | 214 | struct smc_connection *conn) |
@@ -270,10 +294,16 @@ static inline void smc_cdc_msg_to_host(struct smc_host_cdc_msg *local, | |||
270 | smcr_cdc_msg_to_host(local, peer, conn); | 294 | smcr_cdc_msg_to_host(local, peer, conn); |
271 | } | 295 | } |
272 | 296 | ||
273 | struct smc_cdc_tx_pend; | 297 | struct smc_cdc_tx_pend { |
298 | struct smc_connection *conn; /* socket connection */ | ||
299 | union smc_host_cursor cursor; /* tx sndbuf cursor sent */ | ||
300 | union smc_host_cursor p_cursor; /* rx RMBE cursor produced */ | ||
301 | u16 ctrl_seq; /* conn. tx sequence # */ | ||
302 | }; | ||
274 | 303 | ||
275 | int smc_cdc_get_free_slot(struct smc_connection *conn, | 304 | int smc_cdc_get_free_slot(struct smc_connection *conn, |
276 | struct smc_wr_buf **wr_buf, | 305 | struct smc_wr_buf **wr_buf, |
306 | struct smc_rdma_wr **wr_rdma_buf, | ||
277 | struct smc_cdc_tx_pend **pend); | 307 | struct smc_cdc_tx_pend **pend); |
278 | void smc_cdc_tx_dismiss_slots(struct smc_connection *conn); | 308 | void smc_cdc_tx_dismiss_slots(struct smc_connection *conn); |
279 | int smc_cdc_msg_send(struct smc_connection *conn, struct smc_wr_buf *wr_buf, | 309 | int smc_cdc_msg_send(struct smc_connection *conn, struct smc_wr_buf *wr_buf, |
diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c index 776e9dfc915d..d53fd588d1f5 100644 --- a/net/smc/smc_clc.c +++ b/net/smc/smc_clc.c | |||
@@ -378,7 +378,7 @@ int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info) | |||
378 | vec.iov_len = sizeof(struct smc_clc_msg_decline); | 378 | vec.iov_len = sizeof(struct smc_clc_msg_decline); |
379 | len = kernel_sendmsg(smc->clcsock, &msg, &vec, 1, | 379 | len = kernel_sendmsg(smc->clcsock, &msg, &vec, 1, |
380 | sizeof(struct smc_clc_msg_decline)); | 380 | sizeof(struct smc_clc_msg_decline)); |
381 | if (len < sizeof(struct smc_clc_msg_decline)) | 381 | if (len < 0 || len < sizeof(struct smc_clc_msg_decline)) |
382 | len = -EPROTO; | 382 | len = -EPROTO; |
383 | return len > 0 ? 0 : len; | 383 | return len > 0 ? 0 : len; |
384 | } | 384 | } |
diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c index ea2b87f29469..e39cadda1bf5 100644 --- a/net/smc/smc_close.c +++ b/net/smc/smc_close.c | |||
@@ -345,14 +345,7 @@ static void smc_close_passive_work(struct work_struct *work) | |||
345 | 345 | ||
346 | switch (sk->sk_state) { | 346 | switch (sk->sk_state) { |
347 | case SMC_INIT: | 347 | case SMC_INIT: |
348 | if (atomic_read(&conn->bytes_to_rcv) || | 348 | sk->sk_state = SMC_APPCLOSEWAIT1; |
349 | (rxflags->peer_done_writing && | ||
350 | !smc_cdc_rxed_any_close(conn))) { | ||
351 | sk->sk_state = SMC_APPCLOSEWAIT1; | ||
352 | } else { | ||
353 | sk->sk_state = SMC_CLOSED; | ||
354 | sock_put(sk); /* passive closing */ | ||
355 | } | ||
356 | break; | 349 | break; |
357 | case SMC_ACTIVE: | 350 | case SMC_ACTIVE: |
358 | sk->sk_state = SMC_APPCLOSEWAIT1; | 351 | sk->sk_state = SMC_APPCLOSEWAIT1; |
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index 35c1cdc93e1c..aa1c551cee81 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c | |||
@@ -128,6 +128,8 @@ static void smc_lgr_unregister_conn(struct smc_connection *conn) | |||
128 | { | 128 | { |
129 | struct smc_link_group *lgr = conn->lgr; | 129 | struct smc_link_group *lgr = conn->lgr; |
130 | 130 | ||
131 | if (!lgr) | ||
132 | return; | ||
131 | write_lock_bh(&lgr->conns_lock); | 133 | write_lock_bh(&lgr->conns_lock); |
132 | if (conn->alert_token_local) { | 134 | if (conn->alert_token_local) { |
133 | __smc_lgr_unregister_conn(conn); | 135 | __smc_lgr_unregister_conn(conn); |
@@ -300,13 +302,13 @@ static void smc_buf_unuse(struct smc_connection *conn, | |||
300 | conn->sndbuf_desc->used = 0; | 302 | conn->sndbuf_desc->used = 0; |
301 | if (conn->rmb_desc) { | 303 | if (conn->rmb_desc) { |
302 | if (!conn->rmb_desc->regerr) { | 304 | if (!conn->rmb_desc->regerr) { |
303 | conn->rmb_desc->used = 0; | ||
304 | if (!lgr->is_smcd) { | 305 | if (!lgr->is_smcd) { |
305 | /* unregister rmb with peer */ | 306 | /* unregister rmb with peer */ |
306 | smc_llc_do_delete_rkey( | 307 | smc_llc_do_delete_rkey( |
307 | &lgr->lnk[SMC_SINGLE_LINK], | 308 | &lgr->lnk[SMC_SINGLE_LINK], |
308 | conn->rmb_desc); | 309 | conn->rmb_desc); |
309 | } | 310 | } |
311 | conn->rmb_desc->used = 0; | ||
310 | } else { | 312 | } else { |
311 | /* buf registration failed, reuse not possible */ | 313 | /* buf registration failed, reuse not possible */ |
312 | write_lock_bh(&lgr->rmbs_lock); | 314 | write_lock_bh(&lgr->rmbs_lock); |
@@ -628,6 +630,8 @@ int smc_conn_create(struct smc_sock *smc, bool is_smcd, int srv_first_contact, | |||
628 | local_contact = SMC_REUSE_CONTACT; | 630 | local_contact = SMC_REUSE_CONTACT; |
629 | conn->lgr = lgr; | 631 | conn->lgr = lgr; |
630 | smc_lgr_register_conn(conn); /* add smc conn to lgr */ | 632 | smc_lgr_register_conn(conn); /* add smc conn to lgr */ |
633 | if (delayed_work_pending(&lgr->free_work)) | ||
634 | cancel_delayed_work(&lgr->free_work); | ||
631 | write_unlock_bh(&lgr->conns_lock); | 635 | write_unlock_bh(&lgr->conns_lock); |
632 | break; | 636 | break; |
633 | } | 637 | } |
diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h index b00287989a3d..8806d2afa6ed 100644 --- a/net/smc/smc_core.h +++ b/net/smc/smc_core.h | |||
@@ -52,6 +52,24 @@ enum smc_wr_reg_state { | |||
52 | FAILED /* ib_wr_reg_mr response: failure */ | 52 | FAILED /* ib_wr_reg_mr response: failure */ |
53 | }; | 53 | }; |
54 | 54 | ||
55 | struct smc_rdma_sge { /* sges for RDMA writes */ | ||
56 | struct ib_sge wr_tx_rdma_sge[SMC_IB_MAX_SEND_SGE]; | ||
57 | }; | ||
58 | |||
59 | #define SMC_MAX_RDMA_WRITES 2 /* max. # of RDMA writes per | ||
60 | * message send | ||
61 | */ | ||
62 | |||
63 | struct smc_rdma_sges { /* sges per message send */ | ||
64 | struct smc_rdma_sge tx_rdma_sge[SMC_MAX_RDMA_WRITES]; | ||
65 | }; | ||
66 | |||
67 | struct smc_rdma_wr { /* work requests per message | ||
68 | * send | ||
69 | */ | ||
70 | struct ib_rdma_wr wr_tx_rdma[SMC_MAX_RDMA_WRITES]; | ||
71 | }; | ||
72 | |||
55 | struct smc_link { | 73 | struct smc_link { |
56 | struct smc_ib_device *smcibdev; /* ib-device */ | 74 | struct smc_ib_device *smcibdev; /* ib-device */ |
57 | u8 ibport; /* port - values 1 | 2 */ | 75 | u8 ibport; /* port - values 1 | 2 */ |
@@ -64,6 +82,8 @@ struct smc_link { | |||
64 | struct smc_wr_buf *wr_tx_bufs; /* WR send payload buffers */ | 82 | struct smc_wr_buf *wr_tx_bufs; /* WR send payload buffers */ |
65 | struct ib_send_wr *wr_tx_ibs; /* WR send meta data */ | 83 | struct ib_send_wr *wr_tx_ibs; /* WR send meta data */ |
66 | struct ib_sge *wr_tx_sges; /* WR send gather meta data */ | 84 | struct ib_sge *wr_tx_sges; /* WR send gather meta data */ |
85 | struct smc_rdma_sges *wr_tx_rdma_sges;/*RDMA WRITE gather meta data*/ | ||
86 | struct smc_rdma_wr *wr_tx_rdmas; /* WR RDMA WRITE */ | ||
67 | struct smc_wr_tx_pend *wr_tx_pends; /* WR send waiting for CQE */ | 87 | struct smc_wr_tx_pend *wr_tx_pends; /* WR send waiting for CQE */ |
68 | /* above four vectors have wr_tx_cnt elements and use the same index */ | 88 | /* above four vectors have wr_tx_cnt elements and use the same index */ |
69 | dma_addr_t wr_tx_dma_addr; /* DMA address of wr_tx_bufs */ | 89 | dma_addr_t wr_tx_dma_addr; /* DMA address of wr_tx_bufs */ |
diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c index e519ef29c0ff..76487a16934e 100644 --- a/net/smc/smc_ib.c +++ b/net/smc/smc_ib.c | |||
@@ -289,8 +289,8 @@ int smc_ib_create_protection_domain(struct smc_link *lnk) | |||
289 | 289 | ||
290 | static void smc_ib_qp_event_handler(struct ib_event *ibevent, void *priv) | 290 | static void smc_ib_qp_event_handler(struct ib_event *ibevent, void *priv) |
291 | { | 291 | { |
292 | struct smc_ib_device *smcibdev = | 292 | struct smc_link *lnk = (struct smc_link *)priv; |
293 | (struct smc_ib_device *)ibevent->device; | 293 | struct smc_ib_device *smcibdev = lnk->smcibdev; |
294 | u8 port_idx; | 294 | u8 port_idx; |
295 | 295 | ||
296 | switch (ibevent->event) { | 296 | switch (ibevent->event) { |
@@ -298,7 +298,7 @@ static void smc_ib_qp_event_handler(struct ib_event *ibevent, void *priv) | |||
298 | case IB_EVENT_GID_CHANGE: | 298 | case IB_EVENT_GID_CHANGE: |
299 | case IB_EVENT_PORT_ERR: | 299 | case IB_EVENT_PORT_ERR: |
300 | case IB_EVENT_QP_ACCESS_ERR: | 300 | case IB_EVENT_QP_ACCESS_ERR: |
301 | port_idx = ibevent->element.port_num - 1; | 301 | port_idx = ibevent->element.qp->port - 1; |
302 | set_bit(port_idx, &smcibdev->port_event_mask); | 302 | set_bit(port_idx, &smcibdev->port_event_mask); |
303 | schedule_work(&smcibdev->port_event_work); | 303 | schedule_work(&smcibdev->port_event_work); |
304 | break; | 304 | break; |
diff --git a/net/smc/smc_llc.c b/net/smc/smc_llc.c index a6d3623d06f4..4fd60c522802 100644 --- a/net/smc/smc_llc.c +++ b/net/smc/smc_llc.c | |||
@@ -166,7 +166,8 @@ static int smc_llc_add_pending_send(struct smc_link *link, | |||
166 | { | 166 | { |
167 | int rc; | 167 | int rc; |
168 | 168 | ||
169 | rc = smc_wr_tx_get_free_slot(link, smc_llc_tx_handler, wr_buf, pend); | 169 | rc = smc_wr_tx_get_free_slot(link, smc_llc_tx_handler, wr_buf, NULL, |
170 | pend); | ||
170 | if (rc < 0) | 171 | if (rc < 0) |
171 | return rc; | 172 | return rc; |
172 | BUILD_BUG_ON_MSG( | 173 | BUILD_BUG_ON_MSG( |
diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c index 7cb3e4f07c10..632c3109dee5 100644 --- a/net/smc/smc_pnet.c +++ b/net/smc/smc_pnet.c | |||
@@ -27,7 +27,7 @@ | |||
27 | static struct nla_policy smc_pnet_policy[SMC_PNETID_MAX + 1] = { | 27 | static struct nla_policy smc_pnet_policy[SMC_PNETID_MAX + 1] = { |
28 | [SMC_PNETID_NAME] = { | 28 | [SMC_PNETID_NAME] = { |
29 | .type = NLA_NUL_STRING, | 29 | .type = NLA_NUL_STRING, |
30 | .len = SMC_MAX_PNETID_LEN - 1 | 30 | .len = SMC_MAX_PNETID_LEN |
31 | }, | 31 | }, |
32 | [SMC_PNETID_ETHNAME] = { | 32 | [SMC_PNETID_ETHNAME] = { |
33 | .type = NLA_NUL_STRING, | 33 | .type = NLA_NUL_STRING, |
diff --git a/net/smc/smc_tx.c b/net/smc/smc_tx.c index d8366ed51757..f93f3580c100 100644 --- a/net/smc/smc_tx.c +++ b/net/smc/smc_tx.c | |||
@@ -165,12 +165,11 @@ int smc_tx_sendmsg(struct smc_sock *smc, struct msghdr *msg, size_t len) | |||
165 | conn->local_tx_ctrl.prod_flags.urg_data_pending = 1; | 165 | conn->local_tx_ctrl.prod_flags.urg_data_pending = 1; |
166 | 166 | ||
167 | if (!atomic_read(&conn->sndbuf_space) || conn->urg_tx_pend) { | 167 | if (!atomic_read(&conn->sndbuf_space) || conn->urg_tx_pend) { |
168 | if (send_done) | ||
169 | return send_done; | ||
168 | rc = smc_tx_wait(smc, msg->msg_flags); | 170 | rc = smc_tx_wait(smc, msg->msg_flags); |
169 | if (rc) { | 171 | if (rc) |
170 | if (send_done) | ||
171 | return send_done; | ||
172 | goto out_err; | 172 | goto out_err; |
173 | } | ||
174 | continue; | 173 | continue; |
175 | } | 174 | } |
176 | 175 | ||
@@ -267,27 +266,23 @@ int smcd_tx_ism_write(struct smc_connection *conn, void *data, size_t len, | |||
267 | 266 | ||
268 | /* sndbuf consumer: actual data transfer of one target chunk with RDMA write */ | 267 | /* sndbuf consumer: actual data transfer of one target chunk with RDMA write */ |
269 | static int smc_tx_rdma_write(struct smc_connection *conn, int peer_rmbe_offset, | 268 | static int smc_tx_rdma_write(struct smc_connection *conn, int peer_rmbe_offset, |
270 | int num_sges, struct ib_sge sges[]) | 269 | int num_sges, struct ib_rdma_wr *rdma_wr) |
271 | { | 270 | { |
272 | struct smc_link_group *lgr = conn->lgr; | 271 | struct smc_link_group *lgr = conn->lgr; |
273 | struct ib_rdma_wr rdma_wr; | ||
274 | struct smc_link *link; | 272 | struct smc_link *link; |
275 | int rc; | 273 | int rc; |
276 | 274 | ||
277 | memset(&rdma_wr, 0, sizeof(rdma_wr)); | ||
278 | link = &lgr->lnk[SMC_SINGLE_LINK]; | 275 | link = &lgr->lnk[SMC_SINGLE_LINK]; |
279 | rdma_wr.wr.wr_id = smc_wr_tx_get_next_wr_id(link); | 276 | rdma_wr->wr.wr_id = smc_wr_tx_get_next_wr_id(link); |
280 | rdma_wr.wr.sg_list = sges; | 277 | rdma_wr->wr.num_sge = num_sges; |
281 | rdma_wr.wr.num_sge = num_sges; | 278 | rdma_wr->remote_addr = |
282 | rdma_wr.wr.opcode = IB_WR_RDMA_WRITE; | ||
283 | rdma_wr.remote_addr = | ||
284 | lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].dma_addr + | 279 | lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].dma_addr + |
285 | /* RMBE within RMB */ | 280 | /* RMBE within RMB */ |
286 | conn->tx_off + | 281 | conn->tx_off + |
287 | /* offset within RMBE */ | 282 | /* offset within RMBE */ |
288 | peer_rmbe_offset; | 283 | peer_rmbe_offset; |
289 | rdma_wr.rkey = lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].rkey; | 284 | rdma_wr->rkey = lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].rkey; |
290 | rc = ib_post_send(link->roce_qp, &rdma_wr.wr, NULL); | 285 | rc = ib_post_send(link->roce_qp, &rdma_wr->wr, NULL); |
291 | if (rc) { | 286 | if (rc) { |
292 | conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1; | 287 | conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1; |
293 | smc_lgr_terminate(lgr); | 288 | smc_lgr_terminate(lgr); |
@@ -314,24 +309,25 @@ static inline void smc_tx_advance_cursors(struct smc_connection *conn, | |||
314 | /* SMC-R helper for smc_tx_rdma_writes() */ | 309 | /* SMC-R helper for smc_tx_rdma_writes() */ |
315 | static int smcr_tx_rdma_writes(struct smc_connection *conn, size_t len, | 310 | static int smcr_tx_rdma_writes(struct smc_connection *conn, size_t len, |
316 | size_t src_off, size_t src_len, | 311 | size_t src_off, size_t src_len, |
317 | size_t dst_off, size_t dst_len) | 312 | size_t dst_off, size_t dst_len, |
313 | struct smc_rdma_wr *wr_rdma_buf) | ||
318 | { | 314 | { |
319 | dma_addr_t dma_addr = | 315 | dma_addr_t dma_addr = |
320 | sg_dma_address(conn->sndbuf_desc->sgt[SMC_SINGLE_LINK].sgl); | 316 | sg_dma_address(conn->sndbuf_desc->sgt[SMC_SINGLE_LINK].sgl); |
321 | struct smc_link *link = &conn->lgr->lnk[SMC_SINGLE_LINK]; | ||
322 | int src_len_sum = src_len, dst_len_sum = dst_len; | 317 | int src_len_sum = src_len, dst_len_sum = dst_len; |
323 | struct ib_sge sges[SMC_IB_MAX_SEND_SGE]; | ||
324 | int sent_count = src_off; | 318 | int sent_count = src_off; |
325 | int srcchunk, dstchunk; | 319 | int srcchunk, dstchunk; |
326 | int num_sges; | 320 | int num_sges; |
327 | int rc; | 321 | int rc; |
328 | 322 | ||
329 | for (dstchunk = 0; dstchunk < 2; dstchunk++) { | 323 | for (dstchunk = 0; dstchunk < 2; dstchunk++) { |
324 | struct ib_sge *sge = | ||
325 | wr_rdma_buf->wr_tx_rdma[dstchunk].wr.sg_list; | ||
326 | |||
330 | num_sges = 0; | 327 | num_sges = 0; |
331 | for (srcchunk = 0; srcchunk < 2; srcchunk++) { | 328 | for (srcchunk = 0; srcchunk < 2; srcchunk++) { |
332 | sges[srcchunk].addr = dma_addr + src_off; | 329 | sge[srcchunk].addr = dma_addr + src_off; |
333 | sges[srcchunk].length = src_len; | 330 | sge[srcchunk].length = src_len; |
334 | sges[srcchunk].lkey = link->roce_pd->local_dma_lkey; | ||
335 | num_sges++; | 331 | num_sges++; |
336 | 332 | ||
337 | src_off += src_len; | 333 | src_off += src_len; |
@@ -344,7 +340,8 @@ static int smcr_tx_rdma_writes(struct smc_connection *conn, size_t len, | |||
344 | src_len = dst_len - src_len; /* remainder */ | 340 | src_len = dst_len - src_len; /* remainder */ |
345 | src_len_sum += src_len; | 341 | src_len_sum += src_len; |
346 | } | 342 | } |
347 | rc = smc_tx_rdma_write(conn, dst_off, num_sges, sges); | 343 | rc = smc_tx_rdma_write(conn, dst_off, num_sges, |
344 | &wr_rdma_buf->wr_tx_rdma[dstchunk]); | ||
348 | if (rc) | 345 | if (rc) |
349 | return rc; | 346 | return rc; |
350 | if (dst_len_sum == len) | 347 | if (dst_len_sum == len) |
@@ -403,7 +400,8 @@ static int smcd_tx_rdma_writes(struct smc_connection *conn, size_t len, | |||
403 | /* sndbuf consumer: prepare all necessary (src&dst) chunks of data transmit; | 400 | /* sndbuf consumer: prepare all necessary (src&dst) chunks of data transmit; |
404 | * usable snd_wnd as max transmit | 401 | * usable snd_wnd as max transmit |
405 | */ | 402 | */ |
406 | static int smc_tx_rdma_writes(struct smc_connection *conn) | 403 | static int smc_tx_rdma_writes(struct smc_connection *conn, |
404 | struct smc_rdma_wr *wr_rdma_buf) | ||
407 | { | 405 | { |
408 | size_t len, src_len, dst_off, dst_len; /* current chunk values */ | 406 | size_t len, src_len, dst_off, dst_len; /* current chunk values */ |
409 | union smc_host_cursor sent, prep, prod, cons; | 407 | union smc_host_cursor sent, prep, prod, cons; |
@@ -464,7 +462,7 @@ static int smc_tx_rdma_writes(struct smc_connection *conn) | |||
464 | dst_off, dst_len); | 462 | dst_off, dst_len); |
465 | else | 463 | else |
466 | rc = smcr_tx_rdma_writes(conn, len, sent.count, src_len, | 464 | rc = smcr_tx_rdma_writes(conn, len, sent.count, src_len, |
467 | dst_off, dst_len); | 465 | dst_off, dst_len, wr_rdma_buf); |
468 | if (rc) | 466 | if (rc) |
469 | return rc; | 467 | return rc; |
470 | 468 | ||
@@ -485,31 +483,30 @@ static int smc_tx_rdma_writes(struct smc_connection *conn) | |||
485 | static int smcr_tx_sndbuf_nonempty(struct smc_connection *conn) | 483 | static int smcr_tx_sndbuf_nonempty(struct smc_connection *conn) |
486 | { | 484 | { |
487 | struct smc_cdc_producer_flags *pflags; | 485 | struct smc_cdc_producer_flags *pflags; |
486 | struct smc_rdma_wr *wr_rdma_buf; | ||
488 | struct smc_cdc_tx_pend *pend; | 487 | struct smc_cdc_tx_pend *pend; |
489 | struct smc_wr_buf *wr_buf; | 488 | struct smc_wr_buf *wr_buf; |
490 | int rc; | 489 | int rc; |
491 | 490 | ||
492 | spin_lock_bh(&conn->send_lock); | 491 | rc = smc_cdc_get_free_slot(conn, &wr_buf, &wr_rdma_buf, &pend); |
493 | rc = smc_cdc_get_free_slot(conn, &wr_buf, &pend); | ||
494 | if (rc < 0) { | 492 | if (rc < 0) { |
495 | if (rc == -EBUSY) { | 493 | if (rc == -EBUSY) { |
496 | struct smc_sock *smc = | 494 | struct smc_sock *smc = |
497 | container_of(conn, struct smc_sock, conn); | 495 | container_of(conn, struct smc_sock, conn); |
498 | 496 | ||
499 | if (smc->sk.sk_err == ECONNABORTED) { | 497 | if (smc->sk.sk_err == ECONNABORTED) |
500 | rc = sock_error(&smc->sk); | 498 | return sock_error(&smc->sk); |
501 | goto out_unlock; | ||
502 | } | ||
503 | rc = 0; | 499 | rc = 0; |
504 | if (conn->alert_token_local) /* connection healthy */ | 500 | if (conn->alert_token_local) /* connection healthy */ |
505 | mod_delayed_work(system_wq, &conn->tx_work, | 501 | mod_delayed_work(system_wq, &conn->tx_work, |
506 | SMC_TX_WORK_DELAY); | 502 | SMC_TX_WORK_DELAY); |
507 | } | 503 | } |
508 | goto out_unlock; | 504 | return rc; |
509 | } | 505 | } |
510 | 506 | ||
507 | spin_lock_bh(&conn->send_lock); | ||
511 | if (!conn->local_tx_ctrl.prod_flags.urg_data_present) { | 508 | if (!conn->local_tx_ctrl.prod_flags.urg_data_present) { |
512 | rc = smc_tx_rdma_writes(conn); | 509 | rc = smc_tx_rdma_writes(conn, wr_rdma_buf); |
513 | if (rc) { | 510 | if (rc) { |
514 | smc_wr_tx_put_slot(&conn->lgr->lnk[SMC_SINGLE_LINK], | 511 | smc_wr_tx_put_slot(&conn->lgr->lnk[SMC_SINGLE_LINK], |
515 | (struct smc_wr_tx_pend_priv *)pend); | 512 | (struct smc_wr_tx_pend_priv *)pend); |
@@ -536,7 +533,7 @@ static int smcd_tx_sndbuf_nonempty(struct smc_connection *conn) | |||
536 | 533 | ||
537 | spin_lock_bh(&conn->send_lock); | 534 | spin_lock_bh(&conn->send_lock); |
538 | if (!pflags->urg_data_present) | 535 | if (!pflags->urg_data_present) |
539 | rc = smc_tx_rdma_writes(conn); | 536 | rc = smc_tx_rdma_writes(conn, NULL); |
540 | if (!rc) | 537 | if (!rc) |
541 | rc = smcd_cdc_msg_send(conn); | 538 | rc = smcd_cdc_msg_send(conn); |
542 | 539 | ||
@@ -598,7 +595,8 @@ void smc_tx_consumer_update(struct smc_connection *conn, bool force) | |||
598 | if (to_confirm > conn->rmbe_update_limit) { | 595 | if (to_confirm > conn->rmbe_update_limit) { |
599 | smc_curs_copy(&prod, &conn->local_rx_ctrl.prod, conn); | 596 | smc_curs_copy(&prod, &conn->local_rx_ctrl.prod, conn); |
600 | sender_free = conn->rmb_desc->len - | 597 | sender_free = conn->rmb_desc->len - |
601 | smc_curs_diff(conn->rmb_desc->len, &prod, &cfed); | 598 | smc_curs_diff_large(conn->rmb_desc->len, |
599 | &cfed, &prod); | ||
602 | } | 600 | } |
603 | 601 | ||
604 | if (conn->local_rx_ctrl.prod_flags.cons_curs_upd_req || | 602 | if (conn->local_rx_ctrl.prod_flags.cons_curs_upd_req || |
diff --git a/net/smc/smc_wr.c b/net/smc/smc_wr.c index c2694750a6a8..253aa75dc2b6 100644 --- a/net/smc/smc_wr.c +++ b/net/smc/smc_wr.c | |||
@@ -160,6 +160,7 @@ static inline int smc_wr_tx_get_free_slot_index(struct smc_link *link, u32 *idx) | |||
160 | * @link: Pointer to smc_link used to later send the message. | 160 | * @link: Pointer to smc_link used to later send the message. |
161 | * @handler: Send completion handler function pointer. | 161 | * @handler: Send completion handler function pointer. |
162 | * @wr_buf: Out value returns pointer to message buffer. | 162 | * @wr_buf: Out value returns pointer to message buffer. |
163 | * @wr_rdma_buf: Out value returns pointer to rdma work request. | ||
163 | * @wr_pend_priv: Out value returns pointer serving as handler context. | 164 | * @wr_pend_priv: Out value returns pointer serving as handler context. |
164 | * | 165 | * |
165 | * Return: 0 on success, or -errno on error. | 166 | * Return: 0 on success, or -errno on error. |
@@ -167,6 +168,7 @@ static inline int smc_wr_tx_get_free_slot_index(struct smc_link *link, u32 *idx) | |||
167 | int smc_wr_tx_get_free_slot(struct smc_link *link, | 168 | int smc_wr_tx_get_free_slot(struct smc_link *link, |
168 | smc_wr_tx_handler handler, | 169 | smc_wr_tx_handler handler, |
169 | struct smc_wr_buf **wr_buf, | 170 | struct smc_wr_buf **wr_buf, |
171 | struct smc_rdma_wr **wr_rdma_buf, | ||
170 | struct smc_wr_tx_pend_priv **wr_pend_priv) | 172 | struct smc_wr_tx_pend_priv **wr_pend_priv) |
171 | { | 173 | { |
172 | struct smc_wr_tx_pend *wr_pend; | 174 | struct smc_wr_tx_pend *wr_pend; |
@@ -204,6 +206,8 @@ int smc_wr_tx_get_free_slot(struct smc_link *link, | |||
204 | wr_ib = &link->wr_tx_ibs[idx]; | 206 | wr_ib = &link->wr_tx_ibs[idx]; |
205 | wr_ib->wr_id = wr_id; | 207 | wr_ib->wr_id = wr_id; |
206 | *wr_buf = &link->wr_tx_bufs[idx]; | 208 | *wr_buf = &link->wr_tx_bufs[idx]; |
209 | if (wr_rdma_buf) | ||
210 | *wr_rdma_buf = &link->wr_tx_rdmas[idx]; | ||
207 | *wr_pend_priv = &wr_pend->priv; | 211 | *wr_pend_priv = &wr_pend->priv; |
208 | return 0; | 212 | return 0; |
209 | } | 213 | } |
@@ -218,10 +222,10 @@ int smc_wr_tx_put_slot(struct smc_link *link, | |||
218 | u32 idx = pend->idx; | 222 | u32 idx = pend->idx; |
219 | 223 | ||
220 | /* clear the full struct smc_wr_tx_pend including .priv */ | 224 | /* clear the full struct smc_wr_tx_pend including .priv */ |
221 | memset(&link->wr_tx_pends[pend->idx], 0, | 225 | memset(&link->wr_tx_pends[idx], 0, |
222 | sizeof(link->wr_tx_pends[pend->idx])); | 226 | sizeof(link->wr_tx_pends[idx])); |
223 | memset(&link->wr_tx_bufs[pend->idx], 0, | 227 | memset(&link->wr_tx_bufs[idx], 0, |
224 | sizeof(link->wr_tx_bufs[pend->idx])); | 228 | sizeof(link->wr_tx_bufs[idx])); |
225 | test_and_clear_bit(idx, link->wr_tx_mask); | 229 | test_and_clear_bit(idx, link->wr_tx_mask); |
226 | return 1; | 230 | return 1; |
227 | } | 231 | } |
@@ -465,12 +469,26 @@ static void smc_wr_init_sge(struct smc_link *lnk) | |||
465 | lnk->wr_tx_dma_addr + i * SMC_WR_BUF_SIZE; | 469 | lnk->wr_tx_dma_addr + i * SMC_WR_BUF_SIZE; |
466 | lnk->wr_tx_sges[i].length = SMC_WR_TX_SIZE; | 470 | lnk->wr_tx_sges[i].length = SMC_WR_TX_SIZE; |
467 | lnk->wr_tx_sges[i].lkey = lnk->roce_pd->local_dma_lkey; | 471 | lnk->wr_tx_sges[i].lkey = lnk->roce_pd->local_dma_lkey; |
472 | lnk->wr_tx_rdma_sges[i].tx_rdma_sge[0].wr_tx_rdma_sge[0].lkey = | ||
473 | lnk->roce_pd->local_dma_lkey; | ||
474 | lnk->wr_tx_rdma_sges[i].tx_rdma_sge[0].wr_tx_rdma_sge[1].lkey = | ||
475 | lnk->roce_pd->local_dma_lkey; | ||
476 | lnk->wr_tx_rdma_sges[i].tx_rdma_sge[1].wr_tx_rdma_sge[0].lkey = | ||
477 | lnk->roce_pd->local_dma_lkey; | ||
478 | lnk->wr_tx_rdma_sges[i].tx_rdma_sge[1].wr_tx_rdma_sge[1].lkey = | ||
479 | lnk->roce_pd->local_dma_lkey; | ||
468 | lnk->wr_tx_ibs[i].next = NULL; | 480 | lnk->wr_tx_ibs[i].next = NULL; |
469 | lnk->wr_tx_ibs[i].sg_list = &lnk->wr_tx_sges[i]; | 481 | lnk->wr_tx_ibs[i].sg_list = &lnk->wr_tx_sges[i]; |
470 | lnk->wr_tx_ibs[i].num_sge = 1; | 482 | lnk->wr_tx_ibs[i].num_sge = 1; |
471 | lnk->wr_tx_ibs[i].opcode = IB_WR_SEND; | 483 | lnk->wr_tx_ibs[i].opcode = IB_WR_SEND; |
472 | lnk->wr_tx_ibs[i].send_flags = | 484 | lnk->wr_tx_ibs[i].send_flags = |
473 | IB_SEND_SIGNALED | IB_SEND_SOLICITED; | 485 | IB_SEND_SIGNALED | IB_SEND_SOLICITED; |
486 | lnk->wr_tx_rdmas[i].wr_tx_rdma[0].wr.opcode = IB_WR_RDMA_WRITE; | ||
487 | lnk->wr_tx_rdmas[i].wr_tx_rdma[1].wr.opcode = IB_WR_RDMA_WRITE; | ||
488 | lnk->wr_tx_rdmas[i].wr_tx_rdma[0].wr.sg_list = | ||
489 | lnk->wr_tx_rdma_sges[i].tx_rdma_sge[0].wr_tx_rdma_sge; | ||
490 | lnk->wr_tx_rdmas[i].wr_tx_rdma[1].wr.sg_list = | ||
491 | lnk->wr_tx_rdma_sges[i].tx_rdma_sge[1].wr_tx_rdma_sge; | ||
474 | } | 492 | } |
475 | for (i = 0; i < lnk->wr_rx_cnt; i++) { | 493 | for (i = 0; i < lnk->wr_rx_cnt; i++) { |
476 | lnk->wr_rx_sges[i].addr = | 494 | lnk->wr_rx_sges[i].addr = |
@@ -521,8 +539,12 @@ void smc_wr_free_link_mem(struct smc_link *lnk) | |||
521 | lnk->wr_tx_mask = NULL; | 539 | lnk->wr_tx_mask = NULL; |
522 | kfree(lnk->wr_tx_sges); | 540 | kfree(lnk->wr_tx_sges); |
523 | lnk->wr_tx_sges = NULL; | 541 | lnk->wr_tx_sges = NULL; |
542 | kfree(lnk->wr_tx_rdma_sges); | ||
543 | lnk->wr_tx_rdma_sges = NULL; | ||
524 | kfree(lnk->wr_rx_sges); | 544 | kfree(lnk->wr_rx_sges); |
525 | lnk->wr_rx_sges = NULL; | 545 | lnk->wr_rx_sges = NULL; |
546 | kfree(lnk->wr_tx_rdmas); | ||
547 | lnk->wr_tx_rdmas = NULL; | ||
526 | kfree(lnk->wr_rx_ibs); | 548 | kfree(lnk->wr_rx_ibs); |
527 | lnk->wr_rx_ibs = NULL; | 549 | lnk->wr_rx_ibs = NULL; |
528 | kfree(lnk->wr_tx_ibs); | 550 | kfree(lnk->wr_tx_ibs); |
@@ -552,10 +574,20 @@ int smc_wr_alloc_link_mem(struct smc_link *link) | |||
552 | GFP_KERNEL); | 574 | GFP_KERNEL); |
553 | if (!link->wr_rx_ibs) | 575 | if (!link->wr_rx_ibs) |
554 | goto no_mem_wr_tx_ibs; | 576 | goto no_mem_wr_tx_ibs; |
577 | link->wr_tx_rdmas = kcalloc(SMC_WR_BUF_CNT, | ||
578 | sizeof(link->wr_tx_rdmas[0]), | ||
579 | GFP_KERNEL); | ||
580 | if (!link->wr_tx_rdmas) | ||
581 | goto no_mem_wr_rx_ibs; | ||
582 | link->wr_tx_rdma_sges = kcalloc(SMC_WR_BUF_CNT, | ||
583 | sizeof(link->wr_tx_rdma_sges[0]), | ||
584 | GFP_KERNEL); | ||
585 | if (!link->wr_tx_rdma_sges) | ||
586 | goto no_mem_wr_tx_rdmas; | ||
555 | link->wr_tx_sges = kcalloc(SMC_WR_BUF_CNT, sizeof(link->wr_tx_sges[0]), | 587 | link->wr_tx_sges = kcalloc(SMC_WR_BUF_CNT, sizeof(link->wr_tx_sges[0]), |
556 | GFP_KERNEL); | 588 | GFP_KERNEL); |
557 | if (!link->wr_tx_sges) | 589 | if (!link->wr_tx_sges) |
558 | goto no_mem_wr_rx_ibs; | 590 | goto no_mem_wr_tx_rdma_sges; |
559 | link->wr_rx_sges = kcalloc(SMC_WR_BUF_CNT * 3, | 591 | link->wr_rx_sges = kcalloc(SMC_WR_BUF_CNT * 3, |
560 | sizeof(link->wr_rx_sges[0]), | 592 | sizeof(link->wr_rx_sges[0]), |
561 | GFP_KERNEL); | 593 | GFP_KERNEL); |
@@ -579,6 +611,10 @@ no_mem_wr_rx_sges: | |||
579 | kfree(link->wr_rx_sges); | 611 | kfree(link->wr_rx_sges); |
580 | no_mem_wr_tx_sges: | 612 | no_mem_wr_tx_sges: |
581 | kfree(link->wr_tx_sges); | 613 | kfree(link->wr_tx_sges); |
614 | no_mem_wr_tx_rdma_sges: | ||
615 | kfree(link->wr_tx_rdma_sges); | ||
616 | no_mem_wr_tx_rdmas: | ||
617 | kfree(link->wr_tx_rdmas); | ||
582 | no_mem_wr_rx_ibs: | 618 | no_mem_wr_rx_ibs: |
583 | kfree(link->wr_rx_ibs); | 619 | kfree(link->wr_rx_ibs); |
584 | no_mem_wr_tx_ibs: | 620 | no_mem_wr_tx_ibs: |
diff --git a/net/smc/smc_wr.h b/net/smc/smc_wr.h index 1d85bb14fd6f..09bf32fd3959 100644 --- a/net/smc/smc_wr.h +++ b/net/smc/smc_wr.h | |||
@@ -85,6 +85,7 @@ void smc_wr_add_dev(struct smc_ib_device *smcibdev); | |||
85 | 85 | ||
86 | int smc_wr_tx_get_free_slot(struct smc_link *link, smc_wr_tx_handler handler, | 86 | int smc_wr_tx_get_free_slot(struct smc_link *link, smc_wr_tx_handler handler, |
87 | struct smc_wr_buf **wr_buf, | 87 | struct smc_wr_buf **wr_buf, |
88 | struct smc_rdma_wr **wrs, | ||
88 | struct smc_wr_tx_pend_priv **wr_pend_priv); | 89 | struct smc_wr_tx_pend_priv **wr_pend_priv); |
89 | int smc_wr_tx_put_slot(struct smc_link *link, | 90 | int smc_wr_tx_put_slot(struct smc_link *link, |
90 | struct smc_wr_tx_pend_priv *wr_pend_priv); | 91 | struct smc_wr_tx_pend_priv *wr_pend_priv); |