Skip to content

Commit 6b5771a

Browse files
Ursula Braundavem330
authored andcommitted
smc: no consumer update in tasklet context
The SMC protocol requires to send a separate consumer cursor update, if it cannot be piggybacked to updates of the producer cursor. When receiving a blocked signal from the sender, this update is sent already in tasklet context. In addition consumer cursor updates are sent after data receival. Sending of cursor updates is controlled by sequence numbers. Assuming receiving stray messages the receiver drops updates with older sequence numbers than an already received cursor update with a higher sequence number. Sending consumer cursor updates in tasklet context may result in wrong order sends and its corresponding drops at the receiver. Since it is sufficient to send consumer cursor updates once the data is received, this patch gets rid of the consumer cursor update in tasklet context to guarantee in-sequence arrival of cursor updates. Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 71c125c commit 6b5771a

File tree

2 files changed

+5
-16
lines changed

2 files changed

+5
-16
lines changed

net/smc/smc_cdc.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ static void smc_cdc_msg_recv_action(struct smc_sock *smc,
213213
/* guarantee 0 <= bytes_to_rcv <= rmbe_size */
214214
smp_mb__after_atomic();
215215
smc->sk.sk_data_ready(&smc->sk);
216+
} else if ((conn->local_rx_ctrl.prod_flags.write_blocked) ||
217+
(conn->local_rx_ctrl.prod_flags.cons_curs_upd_req)) {
218+
smc->sk.sk_data_ready(&smc->sk);
216219
}
217220

218221
if (conn->local_rx_ctrl.conn_state_flags.peer_conn_abort) {
@@ -234,15 +237,6 @@ static void smc_cdc_msg_recv_action(struct smc_sock *smc,
234237
/* trigger socket release if connection closed */
235238
smc_close_wake_tx_prepared(smc);
236239
}
237-
238-
/* socket connected but not accepted */
239-
if (!smc->sk.sk_socket)
240-
return;
241-
242-
/* data available */
243-
if ((conn->local_rx_ctrl.prod_flags.write_blocked) ||
244-
(conn->local_rx_ctrl.prod_flags.cons_curs_upd_req))
245-
smc_tx_consumer_update(conn);
246240
}
247241

248242
/* called under tasklet context */

net/smc/smc_tx.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -448,9 +448,7 @@ static void smc_tx_work(struct work_struct *work)
448448
void smc_tx_consumer_update(struct smc_connection *conn)
449449
{
450450
union smc_host_cursor cfed, cons;
451-
struct smc_cdc_tx_pend *pend;
452-
struct smc_wr_buf *wr_buf;
453-
int to_confirm, rc;
451+
int to_confirm;
454452

455453
smc_curs_write(&cons,
456454
smc_curs_read(&conn->local_tx_ctrl.cons, conn),
@@ -464,10 +462,7 @@ void smc_tx_consumer_update(struct smc_connection *conn)
464462
((to_confirm > conn->rmbe_update_limit) &&
465463
((to_confirm > (conn->rmbe_size / 2)) ||
466464
conn->local_rx_ctrl.prod_flags.write_blocked))) {
467-
rc = smc_cdc_get_free_slot(conn, &wr_buf, &pend);
468-
if (!rc)
469-
rc = smc_cdc_msg_send(conn, wr_buf, pend);
470-
if (rc < 0) {
465+
if (smc_cdc_get_slot_and_msg_send(conn) < 0) {
471466
schedule_delayed_work(&conn->tx_work,
472467
SMC_TX_WORK_DELAY);
473468
return;

0 commit comments

Comments
 (0)