net/smc: fix sender_free computation
authorUrsula Braun <ubraun@linux.ibm.com>
Mon, 4 Feb 2019 12:44:45 +0000 (13:44 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 4 Feb 2019 17:11:19 +0000 (09:11 -0800)
commitb8649efad879c69c7ab1f19ce8814fcabef1f72b
treec5f16db7dbde8bb5da8db0b74f538a2a58c78036
parentad6f317f720f4a3121756c23831a43dda9b095e5
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: e82f2e31f559 ("net/smc: optimize consumer cursor updates")
Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/smc/smc_cdc.c
net/smc/smc_cdc.h
net/smc/smc_tx.c