ib_modify_qp() is an expensive operation on some HCAs running
virtualized. This series removes two ib_modify_qp() calls from RDS.
I am sending this as a v3, even though it is the first sent to
net. This because the IB Core commit has reach v3.
Håkon Bugge (2):
IB/cma: Introduce rdma_set_min_rnr_timer()
rds: ib: Remove two ib_modify_qp() calls
drivers/infiniband/core/cma.c | 41 ++++++++++++++++++++++++++++++++++++++
drivers/infiniband/core/cma_priv.h | 2 ++
include/rdma/rdma_cm.h | 2 ++
net/rds/ib_cm.c | 35 +-------------------------------
net/rds/rdma_transport.c | 1 +
5 files changed, 47 insertions(+), 34 deletions(-)
--
1.8.3.1
Introduce the ability for kernel ULPs to adjust the minimum RNR Retry
timer. The INIT -> RTR transition executed by RDMA CM will be used for
this adjustment. This avoids an additional ib_modify_qp() call.
rdma_set_min_rnr_timer() must be called before the call to
rdma_connect() on the active side and before the call to rdma_accept()
on the passive side.
The default value of RNR Retry timer is zero, which translates to 655
ms. When the receiver is not ready to accept a send messages, it
encodes the RNR Retry timer value in the NAK. The requestor will then
wait at least the specified time value before retrying the send.
The 5-bit value to be supplied to the rdma_set_min_rnr_timer() is
documented in IBTA Table 45: "Encoding for RNR NAK Timer Field".
Signed-off-by: Håkon Bugge <redacted>
Acked-by: Jason Gunthorpe <jgg@nvidia.com>
---
drivers/infiniband/core/cma.c | 41 ++++++++++++++++++++++++++++++++++++++
drivers/infiniband/core/cma_priv.h | 2 ++
include/rdma/rdma_cm.h | 2 ++
3 files changed, 45 insertions(+)
@@ -2615,6 +2619,43 @@ int rdma_set_ack_timeout(struct rdma_cm_id *id, u8 timeout)}EXPORT_SYMBOL(rdma_set_ack_timeout);+/**+*rdma_set_min_rnr_timer()-SettheminimumRNRRetrytimerofthe+*QPassociatedwithaconnectionidentifier.+*@id:Communicationidentifiertoassociatedwithservicetype.+*@min_rnr_timer:5-bitvalueencodedasTable45:"Encoding for RNR NAK+*TimerField" in the IBTA specification.+*+*Thisfunctionshouldbecalledbeforerdma_connect()onactive+*side,andonpassivesidebeforerdma_accept().Thetimervalue+*willbeassociatedwiththelocalQP.Whenitreceivesasenditis+*notreadtohandle,typicallyifthereceivequeueisempty,anRNR+*RetryNAKisreturnedtotherequesterwiththemin_rnr_timer+*encoded.Therequesterwillthenwaitatleastthetimespecified+*intheNAKbeforeretrying.Thedefaultiszero,whichtranslates+*toaminimumRNRTimervalueof655ms.+*+*Return:0forsuccess+*/+intrdma_set_min_rnr_timer(structrdma_cm_id*id,u8min_rnr_timer)+{+structrdma_id_private*id_priv;++/* It is a five-bit value */+if(min_rnr_timer&0xe0)+return-EINVAL;++if(id->qp_type!=IB_QPT_RC&&id->qp_type!=IB_QPT_XRC_TGT)+return-EINVAL;++id_priv=container_of(id,structrdma_id_private,id);+id_priv->min_rnr_timer=min_rnr_timer;+id_priv->min_rnr_timer_set=true;++return0;+}+EXPORT_SYMBOL(rdma_set_min_rnr_timer);+staticvoidcma_query_handler(intstatus,structsa_path_rec*path_rec,void*context){
For some HCAs, ib_modify_qp() is an expensive operation running
virtualized.
For both the active and passive side, the QP returned by the CM has
the state set to RTS, so no need for this excess RTS -> RTS
transition. With IB Core's ability to set the RNR Retry timer, we use
this interface to shave off another ib_modify_qp().
Fixes: ec16227e1414 ("RDS/IB: Infiniband transport")
Signed-off-by: Håkon Bugge <redacted>
---
net/rds/ib_cm.c | 35 +----------------------------------
net/rds/rdma_transport.c | 1 +
2 files changed, 2 insertions(+), 34 deletions(-)
@@ -87,6 +87,7 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,caseRDMA_CM_EVENT_ADDR_RESOLVED:rdma_set_service_type(cm_id,conn->c_tos);+rdma_set_min_rnr_timer(cm_id,IB_RNR_TIMER_000_32);/* XXX do we need to clean up if this fails? */ret=rdma_resolve_route(cm_id,RDS_RDMA_RESOLVE_TIMEOUT_MS);
From: Leon Romanovsky <leon@kernel.org> Date: 2021-04-01 10:56:08
On Wed, Mar 31, 2021 at 08:43:13PM +0200, Håkon Bugge wrote:
quoted hunk
Introduce the ability for kernel ULPs to adjust the minimum RNR Retry
timer. The INIT -> RTR transition executed by RDMA CM will be used for
this adjustment. This avoids an additional ib_modify_qp() call.
rdma_set_min_rnr_timer() must be called before the call to
rdma_connect() on the active side and before the call to rdma_accept()
on the passive side.
The default value of RNR Retry timer is zero, which translates to 655
ms. When the receiver is not ready to accept a send messages, it
encodes the RNR Retry timer value in the NAK. The requestor will then
wait at least the specified time value before retrying the send.
The 5-bit value to be supplied to the rdma_set_min_rnr_timer() is
documented in IBTA Table 45: "Encoding for RNR NAK Timer Field".
Signed-off-by: Håkon Bugge <redacted>
Acked-by: Jason Gunthorpe <jgg@nvidia.com>
---
drivers/infiniband/core/cma.c | 41 ++++++++++++++++++++++++++++++++++++++
drivers/infiniband/core/cma_priv.h | 2 ++
include/rdma/rdma_cm.h | 2 ++
3 files changed, 45 insertions(+)
@@ -2615,6 +2619,43 @@ int rdma_set_ack_timeout(struct rdma_cm_id *id, u8 timeout)}EXPORT_SYMBOL(rdma_set_ack_timeout);+/**+*rdma_set_min_rnr_timer()-SettheminimumRNRRetrytimerofthe+*QPassociatedwithaconnectionidentifier.+*@id:Communicationidentifiertoassociatedwithservicetype.+*@min_rnr_timer:5-bitvalueencodedasTable45:"Encoding for RNR NAK+*TimerField" in the IBTA specification.+*+*Thisfunctionshouldbecalledbeforerdma_connect()onactive+*side,andonpassivesidebeforerdma_accept().Thetimervalue+*willbeassociatedwiththelocalQP.Whenitreceivesasenditis+*notreadtohandle,typicallyifthereceivequeueisempty,anRNR+*RetryNAKisreturnedtotherequesterwiththemin_rnr_timer+*encoded.Therequesterwillthenwaitatleastthetimespecified+*intheNAKbeforeretrying.Thedefaultiszero,whichtranslates+*toaminimumRNRTimervalueof655ms.+*+*Return:0forsuccess+*/+intrdma_set_min_rnr_timer(structrdma_cm_id*id,u8min_rnr_timer)+{+structrdma_id_private*id_priv;++/* It is a five-bit value */+if(min_rnr_timer&0xe0)+return-EINVAL;++if(id->qp_type!=IB_QPT_RC&&id->qp_type!=IB_QPT_XRC_TGT)+return-EINVAL;
This is in-kernel API and safe to use WARN_ON() instead of returning
error which RDS is not checking anyway.
Thanks
From: Jason Gunthorpe <jgg@nvidia.com> Date: 2021-04-12 22:58:56
On Wed, Mar 31, 2021 at 08:43:12PM +0200, Håkon Bugge wrote:
ib_modify_qp() is an expensive operation on some HCAs running
virtualized. This series removes two ib_modify_qp() calls from RDS.
I am sending this as a v3, even though it is the first sent to
net. This because the IB Core commit has reach v3.
Håkon Bugge (2):
IB/cma: Introduce rdma_set_min_rnr_timer()
rds: ib: Remove two ib_modify_qp() calls
From: Leon Romanovsky <leon@kernel.org> Date: 2021-04-13 06:29:47
On Mon, Apr 12, 2021 at 07:58:47PM -0300, Jason Gunthorpe wrote:
On Wed, Mar 31, 2021 at 08:43:12PM +0200, Håkon Bugge wrote:
quoted
ib_modify_qp() is an expensive operation on some HCAs running
virtualized. This series removes two ib_modify_qp() calls from RDS.
I am sending this as a v3, even though it is the first sent to
net. This because the IB Core commit has reach v3.
Håkon Bugge (2):
IB/cma: Introduce rdma_set_min_rnr_timer()
rds: ib: Remove two ib_modify_qp() calls
Applied to rdma for-next, thanks
Jason,
It should be
+ WARN_ON(id->qp_type != IB_QPT_RC && id->qp_type != IB_QPT_XRC_TGT);
and not
+ if (WARN_ON(id->qp_type != IB_QPT_RC && id->qp_type != IB_QPT_XRC_TGT))
+ return -EINVAL;
Thanks
On 13 Apr 2021, at 08:29, Leon Romanovsky [off-list ref] wrote:
On Mon, Apr 12, 2021 at 07:58:47PM -0300, Jason Gunthorpe wrote:
quoted
On Wed, Mar 31, 2021 at 08:43:12PM +0200, Håkon Bugge wrote:
quoted
ib_modify_qp() is an expensive operation on some HCAs running
virtualized. This series removes two ib_modify_qp() calls from RDS.
I am sending this as a v3, even though it is the first sent to
net. This because the IB Core commit has reach v3.
Håkon Bugge (2):
IB/cma: Introduce rdma_set_min_rnr_timer()
rds: ib: Remove two ib_modify_qp() calls
Applied to rdma for-next, thanks
Jason,
It should be
+ WARN_ON(id->qp_type != IB_QPT_RC && id->qp_type != IB_QPT_XRC_TGT);
With no return you will arm the setting of the timer and subsequently get an error from the modify_qp later.
Håkon
and not
+ if (WARN_ON(id->qp_type != IB_QPT_RC && id->qp_type != IB_QPT_XRC_TGT))
+ return -EINVAL;
Thanks
From: Leon Romanovsky <leon@kernel.org> Date: 2021-04-13 11:37:49
On Tue, Apr 13, 2021 at 11:13:38AM +0000, Haakon Bugge wrote:
quoted
On 13 Apr 2021, at 08:29, Leon Romanovsky [off-list ref] wrote:
On Mon, Apr 12, 2021 at 07:58:47PM -0300, Jason Gunthorpe wrote:
quoted
On Wed, Mar 31, 2021 at 08:43:12PM +0200, Håkon Bugge wrote:
quoted
ib_modify_qp() is an expensive operation on some HCAs running
virtualized. This series removes two ib_modify_qp() calls from RDS.
I am sending this as a v3, even though it is the first sent to
net. This because the IB Core commit has reach v3.
Håkon Bugge (2):
IB/cma: Introduce rdma_set_min_rnr_timer()
rds: ib: Remove two ib_modify_qp() calls
Applied to rdma for-next, thanks
Jason,
It should be
+ WARN_ON(id->qp_type != IB_QPT_RC && id->qp_type != IB_QPT_XRC_TGT);
With no return you will arm the setting of the timer and subsequently get an error from the modify_qp later.
The addition of WARN_ON() means that this is programmer error to get
such input. Historically, in-kernel API doesn't need to have protection
from other kernel developers.
Thanks
Håkon
quoted
and not
+ if (WARN_ON(id->qp_type != IB_QPT_RC && id->qp_type != IB_QPT_XRC_TGT))
+ return -EINVAL;
Thanks
From: Jason Gunthorpe <jgg@nvidia.com> Date: 2021-04-13 13:51:29
On Tue, Apr 13, 2021 at 09:29:41AM +0300, Leon Romanovsky wrote:
On Mon, Apr 12, 2021 at 07:58:47PM -0300, Jason Gunthorpe wrote:
quoted
On Wed, Mar 31, 2021 at 08:43:12PM +0200, Håkon Bugge wrote:
quoted
ib_modify_qp() is an expensive operation on some HCAs running
virtualized. This series removes two ib_modify_qp() calls from RDS.
I am sending this as a v3, even though it is the first sent to
net. This because the IB Core commit has reach v3.
Håkon Bugge (2):
IB/cma: Introduce rdma_set_min_rnr_timer()
rds: ib: Remove two ib_modify_qp() calls
Applied to rdma for-next, thanks
Jason,
It should be
+ WARN_ON(id->qp_type != IB_QPT_RC && id->qp_type != IB_QPT_XRC_TGT);
and not
+ if (WARN_ON(id->qp_type != IB_QPT_RC && id->qp_type != IB_QPT_XRC_TGT))
+ return -EINVAL;
Unless we can completely remove the return code the if statement is a
reasonable way to use the WARN_ON here
Jason