Blob Blame History Raw
From: Stefan Raspl <raspl@linux.ibm.com>
Subject: net/smc: optimize consumer cursor updates
Patch-mainline: v4.19-rc1
Git-commit: e82f2e31f5597a3de44bd27b7427f577f637c552
References: FATE#325698, LTC#167867, bsc#1113481

Summary:     net/smc: Add support for SMC-D
Description: Add support for SMC-D to the existing AF_SMC address family.
             Also includes the ISM device driver as required by SMC-D.

Upstream-Description:

             net/smc: optimize consumer cursor updates

             The SMC protocol requires to send a separate consumer cursor update,
             if it cannot be piggybacked to updates of the producer cursor.
             Currently the decision to send a separate consumer cursor update
             just considers the amount of data already received by the socket
             program. It does not consider the amount of data already arrived, but
             not yet consumed by the receiver. Basing the decision on the
             difference between already confirmed and already arrived data
             (instead of difference between already confirmed and already consumed
             data), may lead to a somewhat earlier consumer cursor update send in
             fast unidirectional traffic scenarios, and thus to better throughput.

             Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
             Suggested-by: Thomas Richter <tmricht@linux.ibm.com>
             Signed-off-by: David S. Miller <davem@davemloft.net>

Signed-off-by: Stefan Raspl <raspl@linux.ibm.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 net/smc/smc_tx.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

--- a/net/smc/smc_tx.c
+++ b/net/smc/smc_tx.c
@@ -494,7 +494,8 @@ out:
 
 void smc_tx_consumer_update(struct smc_connection *conn, bool force)
 {
-	union smc_host_cursor cfed, cons;
+	union smc_host_cursor cfed, cons, prod;
+	int sender_free = conn->rmb_desc->len;
 	int to_confirm;
 
 	smc_curs_write(&cons,
@@ -504,11 +505,18 @@ void smc_tx_consumer_update(struct smc_c
 		       smc_curs_read(&conn->rx_curs_confirmed, conn),
 		       conn);
 	to_confirm = smc_curs_diff(conn->rmb_desc->len, &cfed, &cons);
+	if (to_confirm > conn->rmbe_update_limit) {
+		smc_curs_write(&prod,
+			       smc_curs_read(&conn->local_rx_ctrl.prod, conn),
+			       conn);
+		sender_free = conn->rmb_desc->len -
+			      smc_curs_diff(conn->rmb_desc->len, &prod, &cfed);
+	}
 
 	if (conn->local_rx_ctrl.prod_flags.cons_curs_upd_req ||
 	    force ||
 	    ((to_confirm > conn->rmbe_update_limit) &&
-	     ((to_confirm > (conn->rmb_desc->len / 2)) ||
+	     ((sender_free <= (conn->rmb_desc->len / 2)) ||
 	      conn->local_rx_ctrl.prod_flags.write_blocked))) {
 		if ((smc_cdc_get_slot_and_msg_send(conn) < 0) &&
 		    conn->alert_token_local) { /* connection healthy */