Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net/smc: remove unneeded atomic operations in smc_tx_sndbuf_nonempty

The commit dcd2cf5f2fc0 ("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 6b88af839d20 ("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: Alexandra Winter <wintera@linux.ibm.com>
Co-developed-by: Dust Li <dust.li@linux.alibaba.com>
Signed-off-by: Dust Li <dust.li@linux.alibaba.com>
Signed-off-by: Li RongQing <lirongqing@baidu.com>
Reviewed-by: Alexandra 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: David S. Miller <davem@davemloft.net>

authored by

Li RongQing and committed by
David S. Miller
e7bed88e 8e370797

+1 -30
-1
net/smc/smc.h
··· 196 196 * - dec on polled tx cqe 197 197 */ 198 198 wait_queue_head_t cdc_pend_tx_wq; /* wakeup on no cdc_pend_tx_wr*/ 199 - atomic_t tx_pushing; /* nr_threads trying tx push */ 200 199 struct delayed_work tx_work; /* retry of smc_cdc_msg_send */ 201 200 u32 tx_off; /* base offset in peer rmb */ 202 201
+1 -29
net/smc/smc_tx.c
··· 621 621 return rc; 622 622 } 623 623 624 - static int __smc_tx_sndbuf_nonempty(struct smc_connection *conn) 624 + int smc_tx_sndbuf_nonempty(struct smc_connection *conn) 625 625 { 626 626 struct smc_sock *smc = container_of(conn, struct smc_sock, conn); 627 627 int rc = 0; ··· 652 652 } 653 653 654 654 out: 655 - return rc; 656 - } 657 - 658 - int smc_tx_sndbuf_nonempty(struct smc_connection *conn) 659 - { 660 - int rc; 661 - 662 - /* This make sure only one can send simultaneously to prevent wasting 663 - * of CPU and CDC slot. 664 - * Record whether someone has tried to push while we are pushing. 665 - */ 666 - if (atomic_inc_return(&conn->tx_pushing) > 1) 667 - return 0; 668 - 669 - again: 670 - atomic_set(&conn->tx_pushing, 1); 671 - smp_wmb(); /* Make sure tx_pushing is 1 before real send */ 672 - rc = __smc_tx_sndbuf_nonempty(conn); 673 - 674 - /* We need to check whether someone else have added some data into 675 - * the send queue and tried to push but failed after the atomic_set() 676 - * when we are pushing. 677 - * If so, we need to push again to prevent those data hang in the send 678 - * queue. 679 - */ 680 - if (unlikely(!atomic_dec_and_test(&conn->tx_pushing))) 681 - goto again; 682 - 683 655 return rc; 684 656 } 685 657