Commit e7bed88e authored by Li RongQing's avatar Li RongQing Committed by David S. Miller

net/smc: remove unneeded atomic operations in smc_tx_sndbuf_nonempty

The commit dcd2cf5f ("net/smc: add autocorking support") adds an
atomic variable tx_pushing in smc_connection to make sure only one can
send to let it cork more and save CDC slot. since smc_tx_pending can be
called in the soft IRQ without checking sock_owned_by_user() at that
time, which would cause a race condition because bh_lock_sock() did
not honor sock_lock()

After commit 6b88af83 ("net/smc: don't send in the BH context if
sock_owned_by_user"), the transmission is deferred to when sock_lock()
is held by the user. Therefore, we no longer need tx_pending to hold
message.

So remove atomic variable tx_pushing and its operation, and
smc_tx_sndbuf_nonempty becomes a wrapper of __smc_tx_sndbuf_nonempty,
so rename __smc_tx_sndbuf_nonempty back to smc_tx_sndbuf_nonempty
Suggested-by: default avatarAlexandra Winter <wintera@linux.ibm.com>
Co-developed-by: default avatarDust Li <dust.li@linux.alibaba.com>
Signed-off-by: default avatarDust Li <dust.li@linux.alibaba.com>
Signed-off-by: default avatarLi RongQing <lirongqing@baidu.com>
Reviewed-by: default avatarAlexandra Winter <wintera@linux.ibm.com>

diff v4: remove atomic variable tx_pushing
diff v3: improvements in the commit body and comments
diff v2: fix a typo in commit body and add net-next subject-prefix

 net/smc/smc.h    |  1 -
 net/smc/smc_tx.c | 30 +-----------------------------
 2 files changed, 1 insertion(+), 30 deletions(-)
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8e370797
......@@ -196,7 +196,6 @@ struct smc_connection {
* - dec on polled tx cqe
*/
wait_queue_head_t cdc_pend_tx_wq; /* wakeup on no cdc_pend_tx_wr*/
atomic_t tx_pushing; /* nr_threads trying tx push */
struct delayed_work tx_work; /* retry of smc_cdc_msg_send */
u32 tx_off; /* base offset in peer rmb */
......
......@@ -621,7 +621,7 @@ static int smcd_tx_sndbuf_nonempty(struct smc_connection *conn)
return rc;
}
static int __smc_tx_sndbuf_nonempty(struct smc_connection *conn)
int smc_tx_sndbuf_nonempty(struct smc_connection *conn)
{
struct smc_sock *smc = container_of(conn, struct smc_sock, conn);
int rc = 0;
......@@ -655,34 +655,6 @@ static int __smc_tx_sndbuf_nonempty(struct smc_connection *conn)
return rc;
}
int smc_tx_sndbuf_nonempty(struct smc_connection *conn)
{
int rc;
/* This make sure only one can send simultaneously to prevent wasting
* of CPU and CDC slot.
* Record whether someone has tried to push while we are pushing.
*/
if (atomic_inc_return(&conn->tx_pushing) > 1)
return 0;
again:
atomic_set(&conn->tx_pushing, 1);
smp_wmb(); /* Make sure tx_pushing is 1 before real send */
rc = __smc_tx_sndbuf_nonempty(conn);
/* We need to check whether someone else have added some data into
* the send queue and tried to push but failed after the atomic_set()
* when we are pushing.
* If so, we need to push again to prevent those data hang in the send
* queue.
*/
if (unlikely(!atomic_dec_and_test(&conn->tx_pushing)))
goto again;
return rc;
}
/* Wakeup sndbuf consumers from process context
* since there is more data to transmit. The caller
* must hold sock lock.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment