From: Jason Gunthorpe <jgg@nvidia.com>
To: Patrisious Haddad <phaddad@nvidia.com>
Cc: Leon Romanovsky <leon@kernel.org>,
linux-rdma@vger.kernel.org, Maor Gottlieb <maorg@nvidia.com>,
Wei Chen <harperchen1110@gmail.com>
Subject: Re: [PATCH rdma-next] RDMA/core: Fix resolve_prepare_src error cleanup
Date: Mon, 12 Dec 2022 16:15:46 -0400 [thread overview]
Message-ID: <Y5eL8h2HCwaOU2xR@nvidia.com> (raw)
In-Reply-To: <486d8fe0-96ff-a670-7bf5-be04cafbaedf@nvidia.com>
On Mon, Dec 12, 2022 at 04:06:03PM +0200, Patrisious Haddad wrote:
> Btw there is the easy ugly fix obviously, which would be this patch +
> locking this function with the tree spin-lock(to avoid any race).
>
> I'll check however if there is hope for a better possible design for this
> function.
The usual way I've fixed this is to avoid touching, in this case,
cma_dst_addr() in the call chain. eg we already pass in the correct
dst_addr
What you've done is made it so that in RDMA_CM_ROUTE_QUERY and beyond
the CM id's dst cannot change. The trick with this nasty code is that
it is trying to trigger auto-bind, and it has to do it blind because
of bad code structure
So, try something like this:
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 13e0ab785baa24..1d1f9cd01dd38f 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -3547,7 +3547,7 @@ static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
struct sockaddr_storage zero_sock = {};
if (src_addr && src_addr->sa_family)
- return rdma_bind_addr(id, src_addr);
+ return rdma_bind_addr_dst(id, src_addr, dst_addr);
/*
* When the src_addr is not specified, automatically supply an any addr
@@ -3567,7 +3567,7 @@ static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
((struct sockaddr_ib *)&zero_sock)->sib_pkey =
((struct sockaddr_ib *)dst_addr)->sib_pkey;
}
- return rdma_bind_addr(id, (struct sockaddr *)&zero_sock);
+ return rdma_bind_addr_dst(id, (struct sockaddr *)&zero_sock, dst_addr);
}
/*
@@ -3582,17 +3582,14 @@ static int resolve_prepare_src(struct rdma_id_private *id_priv,
{
int ret;
- memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));
if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) {
/* For a well behaved ULP state will be RDMA_CM_IDLE */
ret = cma_bind_addr(&id_priv->id, src_addr, dst_addr);
if (ret)
- goto err_dst;
+ return ret;
if (WARN_ON(!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND,
- RDMA_CM_ADDR_QUERY))) {
- ret = -EINVAL;
- goto err_dst;
- }
+ RDMA_CM_ADDR_QUERY)))
+ return -EINVAL;
}
if (cma_family(id_priv) != dst_addr->sa_family) {
@@ -3603,8 +3600,6 @@ static int resolve_prepare_src(struct rdma_id_private *id_priv,
err_state:
cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND);
-err_dst:
- memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr));
return ret;
}
@@ -4058,27 +4053,25 @@ int rdma_listen(struct rdma_cm_id *id, int backlog)
}
EXPORT_SYMBOL(rdma_listen);
-int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
+static int rdma_bind_addr_dst(struct rdma_id_private *id_priv,
+ struct sockaddr *addr, struct sockaddr *daddr)
{
- struct rdma_id_private *id_priv;
int ret;
- struct sockaddr *daddr;
if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6 &&
addr->sa_family != AF_IB)
return -EAFNOSUPPORT;
- id_priv = container_of(id, struct rdma_id_private, id);
if (!cma_comp_exch(id_priv, RDMA_CM_IDLE, RDMA_CM_ADDR_BOUND))
return -EINVAL;
- ret = cma_check_linklocal(&id->route.addr.dev_addr, addr);
+ ret = cma_check_linklocal(&id_priv->id.route.addr.dev_addr, addr);
if (ret)
goto err1;
memcpy(cma_src_addr(id_priv), addr, rdma_addr_size(addr));
if (!cma_any_addr(addr)) {
- ret = cma_translate_addr(addr, &id->route.addr.dev_addr);
+ ret = cma_translate_addr(addr, &id_priv->id.route.addr.dev_addr);
if (ret)
goto err1;
@@ -4098,8 +4091,14 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
}
#endif
}
- daddr = cma_dst_addr(id_priv);
+
+ /*
+ * FIXME: This seems wrong, we can't just blidnly replace the sa_family
+ * unless we know the daddr is zero. It will corrupt it.
+ */
daddr->sa_family = addr->sa_family;
+ if (daddr != cma_dst_addr(id_priv))
+ memcpy(cma_dst_addr(id_priv), daddr, rdma_addr_size(addr));
ret = cma_get_port(id_priv);
if (ret)
@@ -4115,6 +4114,14 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_IDLE);
return ret;
}
+
+int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
+{
+ struct rdma_id_private *id_priv =
+ container_of(id, struct rdma_id_private, id);
+
+ return rdma_bind_addr_dst(id_priv, addr, cma_dst_addr(id_priv));
+}
EXPORT_SYMBOL(rdma_bind_addr);
static int cma_format_hdr(void *hdr, struct rdma_id_private *id_priv)
prev parent reply other threads:[~2022-12-12 20:16 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-11 9:08 [PATCH rdma-next] RDMA/core: Fix resolve_prepare_src error cleanup Leon Romanovsky
2022-12-12 13:27 ` Jason Gunthorpe
2022-12-12 13:42 ` Patrisious Haddad
2022-12-12 13:43 ` Jason Gunthorpe
2022-12-12 13:55 ` Patrisious Haddad
2022-12-12 14:00 ` Jason Gunthorpe
2022-12-12 14:06 ` Patrisious Haddad
2022-12-12 20:15 ` Jason Gunthorpe [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Y5eL8h2HCwaOU2xR@nvidia.com \
--to=jgg@nvidia.com \
--cc=harperchen1110@gmail.com \
--cc=leon@kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=maorg@nvidia.com \
--cc=phaddad@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).