Hi Dave,
here is a collection of small smc-patches built for net-next improving
the smc code in different areas.
Thanks,
Ursula
Hans Wippel (2):
net/smc: add missing dev_put
net/smc: add receive timeout check
Ursula Braun (8):
net/smc: take RCU read lock for routing cache lookup
net/smc: adjust net_device refcount
net/smc: adapt send request completion notification
net/smc: longer delay for client link group removal
net/smc: terminate link group if out-of-sync is received
net/smc: introduce a delay
net/smc: parameter cleanup in smc_cdc_get_free_slot()
net/smc: no close wait in case of process shut down
net/smc/af_smc.c | 16 +++++++++-------
net/smc/smc.h | 2 +-
net/smc/smc_cdc.c | 7 ++++---
net/smc/smc_cdc.h | 3 ++-
net/smc/smc_clc.c | 10 +++++-----
net/smc/smc_clc.h | 3 +--
net/smc/smc_close.c | 27 +++++++++++++++------------
net/smc/smc_core.c | 16 ++++++++++++----
net/smc/smc_ib.c | 1 +
net/smc/smc_pnet.c | 4 +++-
net/smc/smc_rx.c | 2 ++
net/smc/smc_tx.c | 18 ++++++++++--------
net/smc/smc_wr.c | 2 +-
13 files changed, 66 insertions(+), 45 deletions(-)
--
2.13.5
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Hans Wippel <redacted>
In the infiniband part, SMC currently uses get_netdev which calls
dev_hold on the returned net device. However, the SMC code never calls
dev_put on that net device resulting in a wrong reference count.
This patch adds a dev_put after the usage of the net device to fix the
issue.
Signed-off-by: Hans Wippel <redacted>
Signed-off-by: Ursula Braun <redacted>
---
net/smc/smc_ib.c | 1 +
1 file changed, 1 insertion(+)
From: Hans Wippel <redacted>
The SMC receive function currently lacks a timeout check under the
condition that no data were received and no data are available. This
patch adds such a check.
Signed-off-by: Hans Wippel <redacted>
Signed-off-by: Ursula Braun <redacted>
---
net/smc/smc_rx.c | 2 ++
1 file changed, 2 insertions(+)
smc_pnet_fill_entry() uses dev_get_by_name() adding a refcount to ndev.
The following smc_pnet_enter() has to reduce the refcount if the entry
to be added exists already in the pnet table.
Signed-off-by: Ursula Braun <redacted>
---
net/smc/smc_pnet.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
Client link group creation always follows the server linkgroup creation.
If peer creates a new server link group, client has to create a new
client link group. If peer reuses a server link group for a new
connection, client has to reuse its client link group as well. This
patch introduces a longer delay for client link group removal to make
sure this link group still exists, once the peer decides to reuse a
server link group. This avoids out-of-sync conditions for link groups.
If already scheduled, modify the delay.
Signed-off-by: Ursula Braun <redacted>
---
net/smc/smc_core.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
@@ -25,8 +25,9 @@#include"smc_cdc.h"#include"smc_close.h"-#define SMC_LGR_NUM_INCR 256-#define SMC_LGR_FREE_DELAY (600 * HZ)+#define SMC_LGR_NUM_INCR 256+#define SMC_LGR_FREE_DELAY_SERV (600 * HZ)+#define SMC_LGR_FREE_DELAY_CLNT (SMC_LGR_FREE_DELAY_SERV + 10)staticu32smc_lgr_num;/* unique link group number */
@@ -107,8 +108,15 @@ static void smc_lgr_unregister_conn(struct smc_connection *conn)__smc_lgr_unregister_conn(conn);}write_unlock_bh(&lgr->conns_lock);-if(reduced&&!lgr->conns_num)-schedule_delayed_work(&lgr->free_work,SMC_LGR_FREE_DELAY);+if(!reduced||lgr->conns_num)+return;+/* client link group creation always follows the server link group+*creation.Forclientuseasomewhathigherremovaldelaytime,+*otherwisethereisariskofout-of-synclinkgroups.+*/+mod_delayed_work(system_wq,&lgr->free_work,+lgr->role==SMC_CLNT?SMC_LGR_FREE_DELAY_CLNT:+SMC_LGR_FREE_DELAY_SERV);}staticvoidsmc_lgr_free_work(structwork_struct*work)
An out-of-sync condition can just be detected by the client.
If the server receives a CLC DECLINE message indicating an out-of-sync
condition for the link groups, the server must clean up the out-of-sync
link group.
There is no need for an extra third parameter in smc_clc_send_decline().
Signed-off-by: Ursula Braun <redacted>
---
net/smc/af_smc.c | 6 ++----
net/smc/smc_clc.c | 10 +++++-----
net/smc/smc_clc.h | 3 +--
3 files changed, 8 insertions(+), 11 deletions(-)
The solicited flag is meaningful for the receive completion queue.
Ask for next work completion of any type on the send queue.
Signed-off-by: Ursula Braun <redacted>
---
net/smc/smc_wr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
The number of outstanding work requests is limited. If all work
requests are in use, tx processing is postponed to another scheduling
of the tx worker. Switch to a delayed worker to have a gap for tx
completion queue events before the next retry.
Signed-off-by: Ursula Braun <redacted>
---
net/smc/smc.h | 2 +-
net/smc/smc_close.c | 12 +++++++-----
net/smc/smc_tx.c | 12 ++++++++----
3 files changed, 16 insertions(+), 10 deletions(-)
@@ -208,7 +208,7 @@ int smc_close_active(struct smc_sock *smc)caseSMC_ACTIVE:smc_close_stream_wait(smc,timeout);release_sock(sk);-cancel_work_sync(&conn->tx_work);+cancel_delayed_work_sync(&conn->tx_work);lock_sock(sk);if(sk->sk_state==SMC_ACTIVE){/* send close request */
@@ -234,7 +234,7 @@ int smc_close_active(struct smc_sock *smc)if(!smc_cdc_rxed_any_close(conn))smc_close_stream_wait(smc,timeout);release_sock(sk);-cancel_work_sync(&conn->tx_work);+cancel_delayed_work_sync(&conn->tx_work);lock_sock(sk);if(sk->sk_err!=ECONNABORTED){/* confirm close from peer */
@@ -263,7 +263,9 @@ int smc_close_active(struct smc_sock *smc)/* peer sending PeerConnectionClosed will cause transition */break;caseSMC_PROCESSABORT:-cancel_work_sync(&conn->tx_work);+release_sock(sk);+cancel_delayed_work_sync(&conn->tx_work);+lock_sock(sk);smc_close_abort(conn);sk->sk_state=SMC_CLOSED;smc_close_wait_tx_pends(smc);
@@ -425,7 +427,7 @@ int smc_close_shutdown_write(struct smc_sock *smc)caseSMC_ACTIVE:smc_close_stream_wait(smc,timeout);release_sock(sk);-cancel_work_sync(&conn->tx_work);+cancel_delayed_work_sync(&conn->tx_work);lock_sock(sk);/* send close wr request */rc=smc_close_wr(conn);
@@ -439,7 +441,7 @@ int smc_close_shutdown_write(struct smc_sock *smc)if(!smc_cdc_rxed_any_close(conn))smc_close_stream_wait(smc,timeout);release_sock(sk);-cancel_work_sync(&conn->tx_work);+cancel_delayed_work_sync(&conn->tx_work);lock_sock(sk);/* confirm close from peer */rc=smc_close_wr(conn);
Use the smc_connection as first parameter with smc_cdc_get_free_slot().
This is just a small code cleanup, no functional change.
Signed-off-by: Ursula Braun <redacted>
---
net/smc/smc_cdc.c | 7 ++++---
net/smc/smc_cdc.h | 3 ++-
net/smc/smc_tx.c | 6 ++----
3 files changed, 8 insertions(+), 8 deletions(-)
Usually socket closing is delayed if there is still data available in
the send buffer to be transmitted. If a process is killed, the delay
should be avoided.
Signed-off-by: Ursula Braun <redacted>
---
net/smc/smc_close.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
From: Leon Romanovsky <leon@kernel.org> Date: 2017-09-20 14:03:19
On Wed, Sep 20, 2017 at 01:58:11PM +0200, Ursula Braun wrote:
The number of outstanding work requests is limited. If all work
requests are in use, tx processing is postponed to another scheduling
of the tx worker. Switch to a delayed worker to have a gap for tx
completion queue events before the next retry.
How will delay prevent and protect the resource exhausting?
Thanks
On Wed, Sep 20, 2017 at 01:58:11PM +0200, Ursula Braun wrote:
quoted
The number of outstanding work requests is limited. If all work
requests are in use, tx processing is postponed to another scheduling
of the tx worker. Switch to a delayed worker to have a gap for tx
completion queue events before the next retry.
How will delay prevent and protect the resource exhausting?
Thanks
SMC runs with a fixed number of in-flight work requests per QP (constant
SMC_WR_BUF_CNT) to prevent resource exhausting. If all work requests are
currently in use, sending of another work request has to wait till some
outstanding work request is confirmed via send completion queue. If sending
is done in a context which is not allowed to wait, the tx_worker is
scheduled instead.
With this patch a small delay is added to avoid too many unsuccessful send
retries due to a still ongoing "all work requests in use" condition.
-----Original Message-----
From: linux-rdma-owner@vger.kernel.org [mailto:linux-rdma-
owner@vger.kernel.org] On Behalf Of Ursula Braun
Sent: Wednesday, September 20, 2017 6:58 AM
To: davem@davemloft.net
Cc: netdev@vger.kernel.org; linux-rdma@vger.kernel.org; linux-
s390@vger.kernel.org; jwi@linux.vnet.ibm.com; schwidefsky@de.ibm.com;
heiko.carstens@de.ibm.com; raspl@linux.vnet.ibm.com;
ubraun@linux.vnet.ibm.com
Subject: [PATCH net-next 01/10] net/smc: add missing dev_put
From: Hans Wippel <redacted>
In the infiniband part, SMC currently uses get_netdev which calls dev_hold on
the returned net device. However, the SMC code never calls dev_put on that net
device resulting in a wrong reference count.
This patch adds a dev_put after the usage of the net device to fix the issue.
Signed-off-by: Hans Wippel <redacted>
Signed-off-by: Ursula Braun <redacted>
---
net/smc/smc_ib.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c index
547e0e113b17..0b5852299158 100644
--- a/net/smc/smc_ib.c+++ b/net/smc/smc_ib.c
@@ -380,6 +380,7 @@ static int smc_ib_fill_gid_and_mac(struct smc_ib_device
I am sorry for providing late comments. smc_ib_fill_gid_and_mac() is not coded correctly.
Few fixes are needed.
1. ULP such as SMC should not open code/deference any function pointer like get_netdev() of the IB device.
2. Replace ib_query_gid(..., NULL)
With
ib_query_gid(..., gid_attr);
Use gid_attr.ndev to get the MAC address.
Do dev_put(gid_attr.ndev);
Code should look like below,
struct ib_gid_attr gid_attr;
rc = ib_query_gid(..., &gid_attr);
if (rc || !gid_addr.ndev)
return -ENODEV;
else
memcpy(smcibdev->mac, ndev->dev_addr, ETH_ALEN);
dev_put(gid_addr.ndev);
-----Original Message-----
From: linux-rdma-owner@vger.kernel.org [mailto:linux-rdma-
owner@vger.kernel.org] On Behalf Of Parav Pandit
Sent: Monday, October 02, 2017 3:36 PM
To: Ursula Braun <redacted>; davem@davemloft.net
Cc: netdev@vger.kernel.org; linux-rdma@vger.kernel.org; linux-
s390@vger.kernel.org; jwi@linux.vnet.ibm.com; schwidefsky@de.ibm.com;
heiko.carstens@de.ibm.com; raspl@linux.vnet.ibm.com
Subject: RE: [PATCH net-next 01/10] net/smc: add missing dev_put
Hi Ursula, Dave, Hans,
quoted
-----Original Message-----
From: linux-rdma-owner@vger.kernel.org [mailto:linux-rdma-
owner@vger.kernel.org] On Behalf Of Ursula Braun
Sent: Wednesday, September 20, 2017 6:58 AM
To: davem@davemloft.net
Cc: netdev@vger.kernel.org; linux-rdma@vger.kernel.org; linux-
s390@vger.kernel.org; jwi@linux.vnet.ibm.com; schwidefsky@de.ibm.com;
heiko.carstens@de.ibm.com; raspl@linux.vnet.ibm.com;
ubraun@linux.vnet.ibm.com
Subject: [PATCH net-next 01/10] net/smc: add missing dev_put
From: Hans Wippel <redacted>
In the infiniband part, SMC currently uses get_netdev which calls
dev_hold on the returned net device. However, the SMC code never calls
dev_put on that net device resulting in a wrong reference count.
This patch adds a dev_put after the usage of the net device to fix the issue.
Signed-off-by: Hans Wippel <redacted>
Signed-off-by: Ursula Braun <redacted>
---
net/smc/smc_ib.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c index
547e0e113b17..0b5852299158 100644
--- a/net/smc/smc_ib.c+++ b/net/smc/smc_ib.c
@@ -380,6 +380,7 @@ static int smc_ib_fill_gid_and_mac(struct
I am sorry for providing late comments. smc_ib_fill_gid_and_mac() is not coded
correctly.
Few fixes are needed.
1. ULP such as SMC should not open code/deference any function pointer like
get_netdev() of the IB device.
2. Replace ib_query_gid(..., NULL)
With
ib_query_gid(..., gid_attr);
Use gid_attr.ndev to get the MAC address.
Do dev_put(gid_attr.ndev);
Code should look like below,
struct ib_gid_attr gid_attr;
rc = ib_query_gid(..., &gid_attr);
if (rc || !gid_addr.ndev)
return -ENODEV;
else
memcpy(smcibdev->mac, ndev->dev_addr, ETH_ALEN);
dev_put(gid_addr.ndev);
--
Also,
smc_link_determine_gid() doesn't do dev_put(gattr.ndev) in for loop.
Please fix it as well.
-----Original Message-----
From: linux-rdma-owner@vger.kernel.org [mailto:linux-rdma-
owner@vger.kernel.org] On Behalf Of Ursula Braun
Sent: Wednesday, September 20, 2017 6:58 AM
To: davem@davemloft.net
Cc: netdev@vger.kernel.org; linux-rdma@vger.kernel.org; linux-
s390@vger.kernel.org; jwi@linux.vnet.ibm.com; schwidefsky@de.ibm.com;
heiko.carstens@de.ibm.com; raspl@linux.vnet.ibm.com;
ubraun@linux.vnet.ibm.com
Subject: [PATCH net-next 01/10] net/smc: add missing dev_put
From: Hans Wippel <redacted>
In the infiniband part, SMC currently uses get_netdev which calls dev_hold on
the returned net device. However, the SMC code never calls dev_put on that net
device resulting in a wrong reference count.
This patch adds a dev_put after the usage of the net device to fix the issue.
Signed-off-by: Hans Wippel <redacted>
Signed-off-by: Ursula Braun <redacted>
---
net/smc/smc_ib.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c index
547e0e113b17..0b5852299158 100644
--- a/net/smc/smc_ib.c+++ b/net/smc/smc_ib.c
@@ -380,6 +380,7 @@ static int smc_ib_fill_gid_and_mac(struct smc_ib_device
I am sorry for providing late comments. smc_ib_fill_gid_and_mac() is not coded correctly.
Few fixes are needed.
1. ULP such as SMC should not open code/deference any function pointer like get_netdev() of the IB device.
2. Replace ib_query_gid(..., NULL)
With
ib_query_gid(..., gid_attr);
Use gid_attr.ndev to get the MAC address.
Do dev_put(gid_attr.ndev);
Code should look like below,
struct ib_gid_attr gid_attr;
rc = ib_query_gid(..., &gid_attr);
if (rc || !gid_addr.ndev)
return -ENODEV;
else
memcpy(smcibdev->mac, ndev->dev_addr, ETH_ALEN);
dev_put(gid_addr.ndev);
Thanks, Parav!
Following your fix ideas I plan to change the function into this one:
static int smc_ib_fill_gid_and_mac(struct smc_ib_device *smcibdev, u8 ibport)
{
struct ib_gid_attr gattr;
int rc;
rc = ib_query_gid(smcibdev->ibdev, ibport, 0,
&smcibdev->gid[ibport - 1], &gattr);
/* the SMC protocol requires specification of the roce MAC address;
* if net_device cannot be determined, it can be derived from gid 0
*/
if (rc)
return rc;
if (gattr.ndev) {
memcpy(&smcibdev->mac, gattr.ndev->dev_addr, ETH_ALEN);
dev_put(gattr.ndev);
} else {
memcpy(&smcibdev->mac[ibport - 1][0],
&smcibdev->gid[ibport - 1].raw[8], 3);
memcpy(&smcibdev->mac[ibport - 1][3],
&smcibdev->gid[ibport - 1].raw[13], 3);
smcibdev->mac[ibport - 1][0] &= ~0x02;
}
return 0;
}
If you agree, I will submit the corresponding patch including a
Suggested-by: Parav Pandit [off-list ref]
Regards, Ursula
-----Original Message-----
From: linux-rdma-owner@vger.kernel.org [mailto:linux-rdma-
owner@vger.kernel.org] On Behalf Of Ursula Braun
Sent: Wednesday, September 20, 2017 6:58 AM
To: davem@davemloft.net
Cc: netdev@vger.kernel.org; linux-rdma@vger.kernel.org; linux-
s390@vger.kernel.org; jwi@linux.vnet.ibm.com; schwidefsky@de.ibm.com;
heiko.carstens@de.ibm.com; raspl@linux.vnet.ibm.com;
ubraun@linux.vnet.ibm.com
Subject: [PATCH net-next 01/10] net/smc: add missing dev_put
From: Hans Wippel <redacted>
In the infiniband part, SMC currently uses get_netdev which calls
dev_hold on the returned net device. However, the SMC code never
calls dev_put on that net device resulting in a wrong reference count.
This patch adds a dev_put after the usage of the net device to fix the issue.
Signed-off-by: Hans Wippel <redacted>
Signed-off-by: Ursula Braun <redacted>
---
net/smc/smc_ib.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c index
547e0e113b17..0b5852299158 100644
--- a/net/smc/smc_ib.c+++ b/net/smc/smc_ib.c
@@ -380,6 +380,7 @@ static int smc_ib_fill_gid_and_mac(struct
I am sorry for providing late comments. smc_ib_fill_gid_and_mac() is not
coded correctly.
quoted
Few fixes are needed.
1. ULP such as SMC should not open code/deference any function pointer like
get_netdev() of the IB device.
quoted
2. Replace ib_query_gid(..., NULL)
With
ib_query_gid(..., gid_attr);
Use gid_attr.ndev to get the MAC address.
Do dev_put(gid_attr.ndev);
Code should look like below,
struct ib_gid_attr gid_attr;
rc = ib_query_gid(..., &gid_attr);
if (rc || !gid_addr.ndev)
return -ENODEV;
else
memcpy(smcibdev->mac, ndev->dev_addr, ETH_ALEN);
dev_put(gid_addr.ndev);
Thanks, Parav!
Following your fix ideas I plan to change the function into this one:
static int smc_ib_fill_gid_and_mac(struct smc_ib_device *smcibdev, u8 ibport) {
struct ib_gid_attr gattr;
int rc;
rc = ib_query_gid(smcibdev->ibdev, ibport, 0,
&smcibdev->gid[ibport - 1], &gattr);
/* the SMC protocol requires specification of the roce MAC address;
* if net_device cannot be determined, it can be derived from gid 0
*/
if (rc)
return rc;
if (gattr.ndev) {
memcpy(&smcibdev->mac, gattr.ndev->dev_addr, ETH_ALEN);
dev_put(gattr.ndev);
} else {
memcpy(&smcibdev->mac[ibport - 1][0],
&smcibdev->gid[ibport - 1].raw[8], 3);
memcpy(&smcibdev->mac[ibport - 1][3],
&smcibdev->gid[ibport - 1].raw[13], 3);
smcibdev->mac[ibport - 1][0] &= ~0x02;
This else part is not needed. You can fail the call as suggested above, inline below too.
if (rc || !gid_addr.ndev)
return -ENODEV;
There must be valid netdev for RoCE gid.
Rest code looks fine.