net/smc: fix sender_free computation
In some scenarios a separate consumer cursor update is necessary.
The decision is made in smc_tx_consumer_cursor_update(). The
sender_free computation could be wrong:
The rx confirmed cursor is always smaller than or equal to the
rx producer cursor. The parameters in the smc_curs_diff() call
have to be exchanged, otherwise sender_free might even be negative.
And if more data arrives local_rx_ctrl.prod might be updated, enabling
a cursor difference between local_rx_ctrl.prod and rx confirmed cursor
larger than the RMB size. This case is not covered by smc_curs_diff().
Thus function smc_curs_diff_large() is introduced here.
If a recvmsg() is processed in parallel, local_tx_ctrl.cons might
change during smc_cdc_msg_send. Make sure rx_curs_confirmed is updated
with the actually sent local_tx_ctrl.cons value.
Fixes: e82f2e31f5
("net/smc: optimize consumer cursor updates")
Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
ad6f317f72
commit
b8649efad8
@@ -595,7 +595,8 @@ void smc_tx_consumer_update(struct smc_connection *conn, bool force)
|
||||
if (to_confirm > conn->rmbe_update_limit) {
|
||||
smc_curs_copy(&prod, &conn->local_rx_ctrl.prod, conn);
|
||||
sender_free = conn->rmb_desc->len -
|
||||
smc_curs_diff(conn->rmb_desc->len, &prod, &cfed);
|
||||
smc_curs_diff_large(conn->rmb_desc->len,
|
||||
&cfed, &prod);
|
||||
}
|
||||
|
||||
if (conn->local_rx_ctrl.prod_flags.cons_curs_upd_req ||
|
||||
|
Reference in New Issue
Block a user