.. | .. |
---|
48 | 48 | struct smc_cdc_producer_flags prod_flags; |
---|
49 | 49 | struct smc_cdc_conn_state_flags conn_state_flags; |
---|
50 | 50 | u8 reserved[18]; |
---|
51 | | -} __packed; /* format defined in RFC7609 */ |
---|
| 51 | +}; |
---|
| 52 | + |
---|
| 53 | +/* SMC-D cursor format */ |
---|
| 54 | +union smcd_cdc_cursor { |
---|
| 55 | + struct { |
---|
| 56 | + u16 wrap; |
---|
| 57 | + u32 count; |
---|
| 58 | + struct smc_cdc_producer_flags prod_flags; |
---|
| 59 | + struct smc_cdc_conn_state_flags conn_state_flags; |
---|
| 60 | + } __packed; |
---|
| 61 | +#ifdef KERNEL_HAS_ATOMIC64 |
---|
| 62 | + atomic64_t acurs; /* for atomic processing */ |
---|
| 63 | +#else |
---|
| 64 | + u64 acurs; /* for atomic processing */ |
---|
| 65 | +#endif |
---|
| 66 | +} __aligned(8); |
---|
52 | 67 | |
---|
53 | 68 | /* CDC message for SMC-D */ |
---|
54 | 69 | struct smcd_cdc_msg { |
---|
55 | 70 | struct smc_wr_rx_hdr common; /* Type = 0xFE */ |
---|
56 | 71 | u8 res1[7]; |
---|
57 | | - u16 prod_wrap; |
---|
58 | | - u32 prod_count; |
---|
59 | | - u8 res2[2]; |
---|
60 | | - u16 cons_wrap; |
---|
61 | | - u32 cons_count; |
---|
62 | | - struct smc_cdc_producer_flags prod_flags; |
---|
63 | | - struct smc_cdc_conn_state_flags conn_state_flags; |
---|
| 72 | + union smcd_cdc_cursor prod; |
---|
| 73 | + union smcd_cdc_cursor cons; |
---|
64 | 74 | u8 res3[8]; |
---|
65 | | -} __packed; |
---|
| 75 | +} __aligned(8); |
---|
66 | 76 | |
---|
67 | 77 | static inline bool smc_cdc_rxed_any_close(struct smc_connection *conn) |
---|
68 | 78 | { |
---|
.. | .. |
---|
87 | 97 | } |
---|
88 | 98 | } |
---|
89 | 99 | |
---|
90 | | -/* SMC cursors are 8 bytes long and require atomic reading and writing */ |
---|
91 | | -static inline u64 smc_curs_read(union smc_host_cursor *curs, |
---|
92 | | - struct smc_connection *conn) |
---|
93 | | -{ |
---|
94 | | -#ifndef KERNEL_HAS_ATOMIC64 |
---|
95 | | - unsigned long flags; |
---|
96 | | - u64 ret; |
---|
97 | | - |
---|
98 | | - spin_lock_irqsave(&conn->acurs_lock, flags); |
---|
99 | | - ret = curs->acurs; |
---|
100 | | - spin_unlock_irqrestore(&conn->acurs_lock, flags); |
---|
101 | | - return ret; |
---|
102 | | -#else |
---|
103 | | - return atomic64_read(&curs->acurs); |
---|
104 | | -#endif |
---|
105 | | -} |
---|
106 | | - |
---|
107 | 100 | /* Copy cursor src into tgt */ |
---|
108 | 101 | static inline void smc_curs_copy(union smc_host_cursor *tgt, |
---|
109 | 102 | union smc_host_cursor *src, |
---|
.. | .. |
---|
123 | 116 | static inline void smc_curs_copy_net(union smc_cdc_cursor *tgt, |
---|
124 | 117 | union smc_cdc_cursor *src, |
---|
125 | 118 | struct smc_connection *conn) |
---|
| 119 | +{ |
---|
| 120 | +#ifndef KERNEL_HAS_ATOMIC64 |
---|
| 121 | + unsigned long flags; |
---|
| 122 | + |
---|
| 123 | + spin_lock_irqsave(&conn->acurs_lock, flags); |
---|
| 124 | + tgt->acurs = src->acurs; |
---|
| 125 | + spin_unlock_irqrestore(&conn->acurs_lock, flags); |
---|
| 126 | +#else |
---|
| 127 | + atomic64_set(&tgt->acurs, atomic64_read(&src->acurs)); |
---|
| 128 | +#endif |
---|
| 129 | +} |
---|
| 130 | + |
---|
| 131 | +static inline void smcd_curs_copy(union smcd_cdc_cursor *tgt, |
---|
| 132 | + union smcd_cdc_cursor *src, |
---|
| 133 | + struct smc_connection *conn) |
---|
126 | 134 | { |
---|
127 | 135 | #ifndef KERNEL_HAS_ATOMIC64 |
---|
128 | 136 | unsigned long flags; |
---|
.. | .. |
---|
245 | 253 | } |
---|
246 | 254 | |
---|
247 | 255 | static inline void smcd_cdc_msg_to_host(struct smc_host_cdc_msg *local, |
---|
248 | | - struct smcd_cdc_msg *peer) |
---|
| 256 | + struct smcd_cdc_msg *peer, |
---|
| 257 | + struct smc_connection *conn) |
---|
249 | 258 | { |
---|
250 | | - local->prod.wrap = peer->prod_wrap; |
---|
251 | | - local->prod.count = peer->prod_count; |
---|
252 | | - local->cons.wrap = peer->cons_wrap; |
---|
253 | | - local->cons.count = peer->cons_count; |
---|
254 | | - local->prod_flags = peer->prod_flags; |
---|
255 | | - local->conn_state_flags = peer->conn_state_flags; |
---|
| 259 | + union smc_host_cursor temp; |
---|
| 260 | + |
---|
| 261 | + temp.wrap = peer->prod.wrap; |
---|
| 262 | + temp.count = peer->prod.count; |
---|
| 263 | + smc_curs_copy(&local->prod, &temp, conn); |
---|
| 264 | + |
---|
| 265 | + temp.wrap = peer->cons.wrap; |
---|
| 266 | + temp.count = peer->cons.count; |
---|
| 267 | + smc_curs_copy(&local->cons, &temp, conn); |
---|
| 268 | + local->prod_flags = peer->cons.prod_flags; |
---|
| 269 | + local->conn_state_flags = peer->cons.conn_state_flags; |
---|
256 | 270 | } |
---|
257 | 271 | |
---|
258 | 272 | static inline void smc_cdc_msg_to_host(struct smc_host_cdc_msg *local, |
---|
.. | .. |
---|
260 | 274 | struct smc_connection *conn) |
---|
261 | 275 | { |
---|
262 | 276 | if (conn->lgr->is_smcd) |
---|
263 | | - smcd_cdc_msg_to_host(local, (struct smcd_cdc_msg *)peer); |
---|
| 277 | + smcd_cdc_msg_to_host(local, (struct smcd_cdc_msg *)peer, conn); |
---|
264 | 278 | else |
---|
265 | 279 | smcr_cdc_msg_to_host(local, peer, conn); |
---|
266 | 280 | } |
---|
267 | 281 | |
---|
268 | | -struct smc_cdc_tx_pend; |
---|
| 282 | +struct smc_cdc_tx_pend { |
---|
| 283 | + struct smc_connection *conn; /* socket connection */ |
---|
| 284 | + union smc_host_cursor cursor; /* tx sndbuf cursor sent */ |
---|
| 285 | + union smc_host_cursor p_cursor; /* rx RMBE cursor produced */ |
---|
| 286 | + u16 ctrl_seq; /* conn. tx sequence # */ |
---|
| 287 | +}; |
---|
269 | 288 | |
---|
270 | 289 | int smc_cdc_get_free_slot(struct smc_connection *conn, |
---|
| 290 | + struct smc_link *link, |
---|
271 | 291 | struct smc_wr_buf **wr_buf, |
---|
| 292 | + struct smc_rdma_wr **wr_rdma_buf, |
---|
272 | 293 | struct smc_cdc_tx_pend **pend); |
---|
273 | | -void smc_cdc_tx_dismiss_slots(struct smc_connection *conn); |
---|
| 294 | +void smc_cdc_wait_pend_tx_wr(struct smc_connection *conn); |
---|
274 | 295 | int smc_cdc_msg_send(struct smc_connection *conn, struct smc_wr_buf *wr_buf, |
---|
275 | 296 | struct smc_cdc_tx_pend *pend); |
---|
276 | 297 | int smc_cdc_get_slot_and_msg_send(struct smc_connection *conn); |
---|
277 | 298 | int smcd_cdc_msg_send(struct smc_connection *conn); |
---|
| 299 | +int smcr_cdc_msg_send_validation(struct smc_connection *conn, |
---|
| 300 | + struct smc_cdc_tx_pend *pend, |
---|
| 301 | + struct smc_wr_buf *wr_buf); |
---|
278 | 302 | int smc_cdc_init(void) __init; |
---|
279 | 303 | void smcd_cdc_rx_init(struct smc_connection *conn); |
---|
280 | 304 | |
---|