* [PATCH net-next v3] net/smc: avoid atomic_set and smp_wmb in the tx path when possible
@ 2023-11-17 11:16 Li RongQing
2023-11-17 12:27 ` Alexandra Winter
0 siblings, 1 reply; 7+ messages in thread
From: Li RongQing @ 2023-11-17 11:16 UTC (permalink / raw)
To: kgraul, wenjia, jaka, alibuda, tonylu, guwen, davem, edumazet,
kuba, pabeni, linux-s390, netdev, dust.li
There is rare possibility that conn->tx_pushing is not 1, since
tx_pushing is just checked with 1, so move the setting tx_pushing
to 1 after atomic_dec_and_test() return false, to avoid atomic_set
and smp_wmb in tx path
Reviewed-by: Dust Li <dust.li@linux.alibaba.com>
Signed-off-by: Li RongQing <lirongqing@baidu.com>
---
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_tx.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/smc/smc_tx.c b/net/smc/smc_tx.c
index 3b0ff3b..2c2933f 100644
--- a/net/smc/smc_tx.c
+++ b/net/smc/smc_tx.c
@@ -667,8 +667,6 @@ int smc_tx_sndbuf_nonempty(struct smc_connection *conn)
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
@@ -677,8 +675,11 @@ int smc_tx_sndbuf_nonempty(struct smc_connection *conn)
* 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)))
+ if (unlikely(!atomic_dec_and_test(&conn->tx_pushing))) {
+ atomic_set(&conn->tx_pushing, 1);
+ smp_wmb(); /* Make sure tx_pushing is 1 before send again */
goto again;
+ }
return rc;
}
--
2.9.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH net-next v3] net/smc: avoid atomic_set and smp_wmb in the tx path when possible
2023-11-17 11:16 [PATCH net-next v3] net/smc: avoid atomic_set and smp_wmb in the tx path when possible Li RongQing
@ 2023-11-17 12:27 ` Alexandra Winter
2023-11-20 3:20 ` Dust Li
0 siblings, 1 reply; 7+ messages in thread
From: Alexandra Winter @ 2023-11-17 12:27 UTC (permalink / raw)
To: Li RongQing, kgraul, wenjia, jaka, alibuda, tonylu, guwen, davem,
edumazet, kuba, pabeni, linux-s390, netdev, dust.li
On 17.11.23 12:16, Li RongQing wrote:
> There is rare possibility that conn->tx_pushing is not 1, since
> tx_pushing is just checked with 1, so move the setting tx_pushing
> to 1 after atomic_dec_and_test() return false, to avoid atomic_set
> and smp_wmb in tx path
>
> Reviewed-by: Dust Li <dust.li@linux.alibaba.com>
> Signed-off-by: Li RongQing <lirongqing@baidu.com>
> ---
> 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_tx.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/net/smc/smc_tx.c b/net/smc/smc_tx.c
> index 3b0ff3b..2c2933f 100644
> --- a/net/smc/smc_tx.c
> +++ b/net/smc/smc_tx.c
> @@ -667,8 +667,6 @@ int smc_tx_sndbuf_nonempty(struct smc_connection *conn)
> 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
> @@ -677,8 +675,11 @@ int smc_tx_sndbuf_nonempty(struct smc_connection *conn)
> * 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)))
> + if (unlikely(!atomic_dec_and_test(&conn->tx_pushing))) {
> + atomic_set(&conn->tx_pushing, 1);
> + smp_wmb(); /* Make sure tx_pushing is 1 before send again */
> goto again;
> + }
>
> return rc;
> }
It seems to me that the purpose of conn->tx_pushing is
a) Serve as a mutex, so only one thread per conn will call __smc_tx_sndbuf_nonempty().
b) Repeat, in case some other thread has added data to sndbuf concurrently.
I agree that this patch does not change the behaviour of this function and removes an
atomic_set() in the likely path.
I wonder however: All callers of smc_tx_sndbuf_nonempty() must hold the socket lock.
So how can we ever run in a concurrency situation?
Is this handling of conn->tx_pushing necessary at all?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net-next v3] net/smc: avoid atomic_set and smp_wmb in the tx path when possible
2023-11-17 12:27 ` Alexandra Winter
@ 2023-11-20 3:20 ` Dust Li
2023-11-20 9:11 ` Alexandra Winter
0 siblings, 1 reply; 7+ messages in thread
From: Dust Li @ 2023-11-20 3:20 UTC (permalink / raw)
To: Alexandra Winter, Li RongQing, kgraul, wenjia, jaka, alibuda,
tonylu, guwen, davem, edumazet, kuba, pabeni, linux-s390, netdev
On Fri, Nov 17, 2023 at 01:27:57PM +0100, Alexandra Winter wrote:
>
>
>On 17.11.23 12:16, Li RongQing wrote:
>> There is rare possibility that conn->tx_pushing is not 1, since
>> tx_pushing is just checked with 1, so move the setting tx_pushing
>> to 1 after atomic_dec_and_test() return false, to avoid atomic_set
>> and smp_wmb in tx path
>>
>> Reviewed-by: Dust Li <dust.li@linux.alibaba.com>
>> Signed-off-by: Li RongQing <lirongqing@baidu.com>
>> ---
>> 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_tx.c | 7 ++++---
>> 1 file changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/net/smc/smc_tx.c b/net/smc/smc_tx.c
>> index 3b0ff3b..2c2933f 100644
>> --- a/net/smc/smc_tx.c
>> +++ b/net/smc/smc_tx.c
>> @@ -667,8 +667,6 @@ int smc_tx_sndbuf_nonempty(struct smc_connection *conn)
>> 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
>> @@ -677,8 +675,11 @@ int smc_tx_sndbuf_nonempty(struct smc_connection *conn)
>> * 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)))
>> + if (unlikely(!atomic_dec_and_test(&conn->tx_pushing))) {
>> + atomic_set(&conn->tx_pushing, 1);
>> + smp_wmb(); /* Make sure tx_pushing is 1 before send again */
>> goto again;
>> + }
>>
>> return rc;
>> }
>
>It seems to me that the purpose of conn->tx_pushing is
>a) Serve as a mutex, so only one thread per conn will call __smc_tx_sndbuf_nonempty().
>b) Repeat, in case some other thread has added data to sndbuf concurrently.
>
>I agree that this patch does not change the behaviour of this function and removes an
>atomic_set() in the likely path.
>
>I wonder however: All callers of smc_tx_sndbuf_nonempty() must hold the socket lock.
>So how can we ever run in a concurrency situation?
>Is this handling of conn->tx_pushing necessary at all?
Hi Sandy,
Overall, I think you are right. But there is something we need to take care.
Before commit 6b88af839d20 ("net/smc: don't send in the BH context if
sock_owned_by_user"), we used to call smc_tx_pending() in the soft IRQ,
without checking sock_owned_by_user(), which would caused a race condition
because bh_lock_sock() did not honor sock_lock(). To address this issue,
I have added the tx_pushing mechanism. However, with commit 6b88af839d20,
we now defer the transmission if sock_lock() is held by the user.
Therefore, there should no longer be a race condition. Nevertheless, if
we remove the tx_pending mechanism, we must always remember not to call
smc_tx_sndbuf_nonempty() in the soft IRQ when the user holds the sock lock.
Thanks
Dust
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net-next v3] net/smc: avoid atomic_set and smp_wmb in the tx path when possible
2023-11-20 3:20 ` Dust Li
@ 2023-11-20 9:11 ` Alexandra Winter
2023-11-20 9:17 ` Alexandra Winter
2023-11-22 9:53 ` Dust Li
0 siblings, 2 replies; 7+ messages in thread
From: Alexandra Winter @ 2023-11-20 9:11 UTC (permalink / raw)
To: dust.li, Li RongQing, kgraul, wenjia, jaka, alibuda, tonylu,
guwen, davem, edumazet, kuba, pabeni, linux-s390, netdev
On 20.11.23 04:20, Dust Li wrote:
>> It seems to me that the purpose of conn->tx_pushing is
>> a) Serve as a mutex, so only one thread per conn will call __smc_tx_sndbuf_nonempty().
>> b) Repeat, in case some other thread has added data to sndbuf concurrently.
>>
>> I agree that this patch does not change the behaviour of this function and removes an
>> atomic_set() in the likely path.
>>
>> I wonder however: All callers of smc_tx_sndbuf_nonempty() must hold the socket lock.
>> So how can we ever run in a concurrency situation?
>> Is this handling of conn->tx_pushing necessary at all?
> Hi Sandy,
>
> Overall, I think you are right. But there is something we need to take care.
>
> Before commit 6b88af839d20 ("net/smc: don't send in the BH context if
> sock_owned_by_user"), we used to call smc_tx_pending() in the soft IRQ,
> without checking sock_owned_by_user(), which would caused a race condition
> because bh_lock_sock() did not honor sock_lock(). To address this issue,
> I have added the tx_pushing mechanism. However, with commit 6b88af839d20,
> we now defer the transmission if sock_lock() is held by the user.
> Therefore, there should no longer be a race condition. Nevertheless, if
> we remove the tx_pending mechanism, we must always remember not to call
> smc_tx_sndbuf_nonempty() in the soft IRQ when the user holds the sock lock.
>
> Thanks
> Dust
ok, I understand.
So whoever is willing to give it a try and simplify smc_tx_sndbuf_nonempty(),
should remember to document that requirement/precondition.
Maybe in a Function context section of a kernel-doc function decription?
(as described in https://docs.kernel.org/doc-guide/kernel-doc.html)
Although smc_tx_sndbuf_nonempty() is not exported, this format is helpful.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net-next v3] net/smc: avoid atomic_set and smp_wmb in the tx path when possible
2023-11-20 9:11 ` Alexandra Winter
@ 2023-11-20 9:17 ` Alexandra Winter
2023-11-20 9:49 ` Tony Lu
2023-11-22 9:53 ` Dust Li
1 sibling, 1 reply; 7+ messages in thread
From: Alexandra Winter @ 2023-11-20 9:17 UTC (permalink / raw)
To: dust.li, Li RongQing, kgraul, wenjia, jaka, alibuda, Tony Lu,
guwen, davem, edumazet, kuba, pabeni, linux-s390, netdev
On 20.11.23 10:11, Alexandra Winter wrote:
>
>
> On 20.11.23 04:20, Dust Li wrote:
>>> It seems to me that the purpose of conn->tx_pushing is
>>> a) Serve as a mutex, so only one thread per conn will call __smc_tx_sndbuf_nonempty().
>>> b) Repeat, in case some other thread has added data to sndbuf concurrently.
>>>
>>> I agree that this patch does not change the behaviour of this function and removes an
>>> atomic_set() in the likely path.
>>>
>>> I wonder however: All callers of smc_tx_sndbuf_nonempty() must hold the socket lock.
>>> So how can we ever run in a concurrency situation?
>>> Is this handling of conn->tx_pushing necessary at all?
>> Hi Sandy,
>>
>> Overall, I think you are right. But there is something we need to take care.
>>
>> Before commit 6b88af839d20 ("net/smc: don't send in the BH context if
>> sock_owned_by_user"), we used to call smc_tx_pending() in the soft IRQ,
>> without checking sock_owned_by_user(), which would caused a race condition
>> because bh_lock_sock() did not honor sock_lock(). To address this issue,
>> I have added the tx_pushing mechanism. However, with commit 6b88af839d20,
>> we now defer the transmission if sock_lock() is held by the user.
>> Therefore, there should no longer be a race condition. Nevertheless, if
>> we remove the tx_pending mechanism, we must always remember not to call
>> smc_tx_sndbuf_nonempty() in the soft IRQ when the user holds the sock lock.
>>
>> Thanks
>> Dust
>
>
> ok, I understand.
> So whoever is willing to give it a try and simplify smc_tx_sndbuf_nonempty(),
> should remember to document that requirement/precondition.
> Maybe in a Function context section of a kernel-doc function decription?
> (as described in https://docs.kernel.org/doc-guide/kernel-doc.html)
> Although smc_tx_sndbuf_nonempty() is not exported, this format is helpful.
>
Tony Lu <tonylu@linux.alibaba.com> ' mail address has been corrupted in this whole thread.
Please reply to this message (corrected address) or take care, if replying to
other messages in this thread.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net-next v3] net/smc: avoid atomic_set and smp_wmb in the tx path when possible
2023-11-20 9:17 ` Alexandra Winter
@ 2023-11-20 9:49 ` Tony Lu
0 siblings, 0 replies; 7+ messages in thread
From: Tony Lu @ 2023-11-20 9:49 UTC (permalink / raw)
To: Li RongQing
Cc: dust.li, Alexandra Winter, kgraul, wenjia, jaka, alibuda, guwen,
davem, edumazet, kuba, pabeni, linux-s390, netdev
On Mon, Nov 20, 2023 at 10:17:15AM +0100, Alexandra Winter wrote:
>
>
> On 20.11.23 10:11, Alexandra Winter wrote:
> >
> >
> > On 20.11.23 04:20, Dust Li wrote:
> >>> It seems to me that the purpose of conn->tx_pushing is
> >>> a) Serve as a mutex, so only one thread per conn will call __smc_tx_sndbuf_nonempty().
> >>> b) Repeat, in case some other thread has added data to sndbuf concurrently.
> >>>
> >>> I agree that this patch does not change the behaviour of this function and removes an
> >>> atomic_set() in the likely path.
> >>>
> >>> I wonder however: All callers of smc_tx_sndbuf_nonempty() must hold the socket lock.
> >>> So how can we ever run in a concurrency situation?
> >>> Is this handling of conn->tx_pushing necessary at all?
> >> Hi Sandy,
> >>
> >> Overall, I think you are right. But there is something we need to take care.
> >>
> >> Before commit 6b88af839d20 ("net/smc: don't send in the BH context if
> >> sock_owned_by_user"), we used to call smc_tx_pending() in the soft IRQ,
> >> without checking sock_owned_by_user(), which would caused a race condition
> >> because bh_lock_sock() did not honor sock_lock(). To address this issue,
> >> I have added the tx_pushing mechanism. However, with commit 6b88af839d20,
> >> we now defer the transmission if sock_lock() is held by the user.
> >> Therefore, there should no longer be a race condition. Nevertheless, if
> >> we remove the tx_pending mechanism, we must always remember not to call
> >> smc_tx_sndbuf_nonempty() in the soft IRQ when the user holds the sock lock.
> >>
> >> Thanks
> >> Dust
> >
> >
> > ok, I understand.
> > So whoever is willing to give it a try and simplify smc_tx_sndbuf_nonempty(),
> > should remember to document that requirement/precondition.
> > Maybe in a Function context section of a kernel-doc function decription?
> > (as described in https://docs.kernel.org/doc-guide/kernel-doc.html)
> > Although smc_tx_sndbuf_nonempty() is not exported, this format is helpful.
> >
>
>
> Tony Lu <tonylu@linux.alibaba.com> ' mail address has been corrupted in this whole thread.
> Please reply to this message (corrected address) or take care, if replying to
> other messages in this thread.
Yes, that's true. Thanks Alexandra.
Please use my correct address, RongQing: Tony Lu <tonylu@linux.alibaba.com>.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net-next v3] net/smc: avoid atomic_set and smp_wmb in the tx path when possible
2023-11-20 9:11 ` Alexandra Winter
2023-11-20 9:17 ` Alexandra Winter
@ 2023-11-22 9:53 ` Dust Li
1 sibling, 0 replies; 7+ messages in thread
From: Dust Li @ 2023-11-22 9:53 UTC (permalink / raw)
To: Alexandra Winter, Li RongQing, kgraul, wenjia, jaka, alibuda,
tonylu, guwen, davem, edumazet, kuba, pabeni, linux-s390, netdev
On Mon, Nov 20, 2023 at 10:11:17AM +0100, Alexandra Winter wrote:
>
>
>On 20.11.23 04:20, Dust Li wrote:
>>> It seems to me that the purpose of conn->tx_pushing is
>>> a) Serve as a mutex, so only one thread per conn will call __smc_tx_sndbuf_nonempty().
>>> b) Repeat, in case some other thread has added data to sndbuf concurrently.
>>>
>>> I agree that this patch does not change the behaviour of this function and removes an
>>> atomic_set() in the likely path.
>>>
>>> I wonder however: All callers of smc_tx_sndbuf_nonempty() must hold the socket lock.
>>> So how can we ever run in a concurrency situation?
>>> Is this handling of conn->tx_pushing necessary at all?
>> Hi Sandy,
>>
>> Overall, I think you are right. But there is something we need to take care.
>>
>> Before commit 6b88af839d20 ("net/smc: don't send in the BH context if
>> sock_owned_by_user"), we used to call smc_tx_pending() in the soft IRQ,
>> without checking sock_owned_by_user(), which would caused a race condition
>> because bh_lock_sock() did not honor sock_lock(). To address this issue,
>> I have added the tx_pushing mechanism. However, with commit 6b88af839d20,
>> we now defer the transmission if sock_lock() is held by the user.
>> Therefore, there should no longer be a race condition. Nevertheless, if
>> we remove the tx_pending mechanism, we must always remember not to call
>> smc_tx_sndbuf_nonempty() in the soft IRQ when the user holds the sock lock.
>>
>> Thanks
>> Dust
>
>
>ok, I understand.
>So whoever is willing to give it a try and simplify smc_tx_sndbuf_nonempty(),
>should remember to document that requirement/precondition.
>Maybe in a Function context section of a kernel-doc function decription?
>(as described in https://docs.kernel.org/doc-guide/kernel-doc.html)
>Although smc_tx_sndbuf_nonempty() is not exported, this format is helpful.
I double checked this and realized that I may have missed something
previously. The original goal of introducing tx_push was to maximize the
amount of data that could be corked in order to achieve the best
performance.
__smc_tx_sndbuf_nonempty() is thread and context safe, meaning that
it can be called simultaneously in both user context and softirq without
causing any bugs, just some CPU waste. Although I think we should remove
all the atomics & locks in the data path and only use sock_lock in the
long-term.
I will collaborate with Li RongQing on a new version that eliminates the
tx_pushing.
Best regards,
Dust
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2023-11-22 9:53 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-17 11:16 [PATCH net-next v3] net/smc: avoid atomic_set and smp_wmb in the tx path when possible Li RongQing
2023-11-17 12:27 ` Alexandra Winter
2023-11-20 3:20 ` Dust Li
2023-11-20 9:11 ` Alexandra Winter
2023-11-20 9:17 ` Alexandra Winter
2023-11-20 9:49 ` Tony Lu
2023-11-22 9:53 ` Dust Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).