Skip to content

Commit

Permalink
RDMA/core/sa_query: Retry SA queries
Browse files Browse the repository at this point in the history
A MAD packet is sent as an unreliable datagram (UD). SA requests are sent
as MAD packets. As such, SA requests or responses may be silently dropped.

IB Core's MAD layer has a timeout and retry mechanism, which amongst
other, is used by RDMA CM. But it is not used by SA queries. The lack of
retries of SA queries leads to long specified timeout, and error being
returned in case of packet loss. The ULP or user-land process has to
perform the retry.

Fix this by taking advantage of the MAD layer's retry mechanism.

First, a check against a zero timeout is added in rdma_resolve_route(). In
send_mad(), we set the MAD layer timeout to one tenth of the specified
timeout and the number of retries to 10. The special case when timeout is
less than 10 is handled.

With this fix:

 # ucmatose -c 1000 -S 1024 -C 1

runs stable on an Infiniband fabric. Without this fix, we see an
intermittent behavior and it errors out with:

cmatose: event: RDMA_CM_EVENT_ROUTE_ERROR, error: -110

(110 is ETIMEDOUT)

Link: https://lore.kernel.org/r/1628784755-28316-1-git-send-email-haakon.bugge@oracle.com
Signed-off-by: Håkon Bugge <haakon.bugge@oracle.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
  • Loading branch information
Håkon Bugge authored and Jason Gunthorpe committed Aug 25, 2021
1 parent f0a6419 commit 5f5a650
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 1 deletion.
3 changes: 3 additions & 0 deletions drivers/infiniband/core/cma.c
Original file line number Diff line number Diff line change
Expand Up @@ -3117,6 +3117,9 @@ int rdma_resolve_route(struct rdma_cm_id *id, unsigned long timeout_ms)
struct rdma_id_private *id_priv;
int ret;

if (!timeout_ms)
return -EINVAL;

id_priv = container_of(id, struct rdma_id_private, id);
if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_RESOLVED, RDMA_CM_ROUTE_QUERY))
return -EINVAL;
Expand Down
9 changes: 8 additions & 1 deletion drivers/infiniband/core/sa_query.c
Original file line number Diff line number Diff line change
Expand Up @@ -1304,14 +1304,21 @@ static int send_mad(struct ib_sa_query *query, unsigned long timeout_ms,
{
unsigned long flags;
int ret, id;
const int nmbr_sa_query_retries = 10;

xa_lock_irqsave(&queries, flags);
ret = __xa_alloc(&queries, &id, query, xa_limit_32b, gfp_mask);
xa_unlock_irqrestore(&queries, flags);
if (ret < 0)
return ret;

query->mad_buf->timeout_ms = timeout_ms;
query->mad_buf->timeout_ms = timeout_ms / nmbr_sa_query_retries;
query->mad_buf->retries = nmbr_sa_query_retries;
if (!query->mad_buf->timeout_ms) {
/* Special case, very small timeout_ms */
query->mad_buf->timeout_ms = 1;
query->mad_buf->retries = timeout_ms;
}
query->mad_buf->context[0] = query;
query->id = id;

Expand Down

0 comments on commit 5f5a650

Please sign in to comment.