RDMA/core: Add CM to restrack after successful attachment to a device
The device attach triggers addition of CM_ID to the restrack DB.
However, when error occurs, we releasing this device, but defer CM_ID
release. This causes to the situation where restrack sees CM_ID that
is not valid anymore.
As a solution, add the CM_ID to the resource tracking DB only after the
attachment is finished.
Found by syzcaller:
infiniband syz0: added syz_tun
rdma_rxe: ignoring netdev event = 10 for syz_tun
infiniband syz0: set down
infiniband syz0: ib_query_port failed (-19)
restrack: ------------[ cut here ]------------
infiniband syz0: BUG: RESTRACK detected leak of resources
restrack: User CM_ID object allocated by syz-executor716 is not freed
restrack: ------------[ cut here ]------------
Fixes: b09c4d7012
("RDMA/restrack: Improve readability in task name management")
Link: https://lore.kernel.org/r/ab93e56ba831eac65c322b3256796fa1589ec0bb.1618753862.git.leonro@nvidia.com
Signed-off-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
4d51c3d9de
commit
cb5cd0ea4e
|
@ -454,7 +454,6 @@ static void _cma_attach_to_dev(struct rdma_id_private *id_priv,
|
|||
id_priv->id.route.addr.dev_addr.transport =
|
||||
rdma_node_get_transport(cma_dev->device->node_type);
|
||||
list_add_tail(&id_priv->list, &cma_dev->id_list);
|
||||
rdma_restrack_add(&id_priv->res);
|
||||
|
||||
trace_cm_id_attach(id_priv, cma_dev->device);
|
||||
}
|
||||
|
@ -691,6 +690,7 @@ static int cma_ib_acquire_dev(struct rdma_id_private *id_priv,
|
|||
mutex_lock(&lock);
|
||||
cma_attach_to_dev(id_priv, listen_id_priv->cma_dev);
|
||||
mutex_unlock(&lock);
|
||||
rdma_restrack_add(&id_priv->res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -745,8 +745,10 @@ static int cma_iw_acquire_dev(struct rdma_id_private *id_priv,
|
|||
}
|
||||
|
||||
out:
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
cma_attach_to_dev(id_priv, cma_dev);
|
||||
rdma_restrack_add(&id_priv->res);
|
||||
}
|
||||
|
||||
mutex_unlock(&lock);
|
||||
return ret;
|
||||
|
@ -807,6 +809,7 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv)
|
|||
|
||||
found:
|
||||
cma_attach_to_dev(id_priv, cma_dev);
|
||||
rdma_restrack_add(&id_priv->res);
|
||||
mutex_unlock(&lock);
|
||||
addr = (struct sockaddr_ib *)cma_src_addr(id_priv);
|
||||
memcpy(&addr->sib_addr, &sgid, sizeof(sgid));
|
||||
|
@ -2526,6 +2529,7 @@ static int cma_listen_on_dev(struct rdma_id_private *id_priv,
|
|||
rdma_addr_size(cma_src_addr(id_priv)));
|
||||
|
||||
_cma_attach_to_dev(dev_id_priv, cma_dev);
|
||||
rdma_restrack_add(&dev_id_priv->res);
|
||||
cma_id_get(id_priv);
|
||||
dev_id_priv->internal_id = 1;
|
||||
dev_id_priv->afonly = id_priv->afonly;
|
||||
|
@ -3203,6 +3207,7 @@ port_found:
|
|||
ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey);
|
||||
id_priv->id.port_num = p;
|
||||
cma_attach_to_dev(id_priv, cma_dev);
|
||||
rdma_restrack_add(&id_priv->res);
|
||||
cma_set_loopback(cma_src_addr(id_priv));
|
||||
out:
|
||||
mutex_unlock(&lock);
|
||||
|
@ -3235,6 +3240,7 @@ static void addr_handler(int status, struct sockaddr *src_addr,
|
|||
if (status)
|
||||
pr_debug_ratelimited("RDMA CM: ADDR_ERROR: failed to acquire device. status %d\n",
|
||||
status);
|
||||
rdma_restrack_add(&id_priv->res);
|
||||
} else if (status) {
|
||||
pr_debug_ratelimited("RDMA CM: ADDR_ERROR: failed to resolve IP. status %d\n", status);
|
||||
}
|
||||
|
@ -3846,6 +3852,8 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
|
|||
if (ret)
|
||||
goto err2;
|
||||
|
||||
if (!cma_any_addr(addr))
|
||||
rdma_restrack_add(&id_priv->res);
|
||||
return 0;
|
||||
err2:
|
||||
if (id_priv->cma_dev)
|
||||
|
|
Loading…
Reference in New Issue