RDMA/{cma, core}: Avoid callback on rdma_addr_cancel()

Currently rdma_addr_cancel() is an async operation, which notifies that
cancel is done by executing the callback function given during
rdma_resolve_ip(). If resolve_ip request is already completed than
callback is not executed.

Instead, now rdma_resolve_addr() and rdma_addr_cancel() simplified in
following ways.
1. rdma_addr_cancel() now a synchronous method. If request was
pending, after it is cancelled, no callback is notified.
2. rdma_resolve_addr() and respective addr_handler() callback doesn't
need to hold reference to cm_id.

Signed-off-by: Parav Pandit <parav@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
Parav Pandit 2018-08-28 14:45:32 +03:00 committed by Jason Gunthorpe
parent f9d08f1e19
commit 722c7b2bfe
2 changed files with 7 additions and 9 deletions

View File

@ -660,6 +660,13 @@ int rdma_resolve_ip_route(struct sockaddr *src_addr,
return addr_resolve(src_in, dst_addr, addr, false, 0); return addr_resolve(src_in, dst_addr, addr, false, 0);
} }
/**
* rdma_addr_cancel - Cancel resolve ip request
* @addr: Pointer to address structure given previously
* during rdma_resolve_ip().
* rdma_addr_cancel() is synchronous function which cancels any pending
* request if there is any.
*/
void rdma_addr_cancel(struct rdma_dev_addr *addr) void rdma_addr_cancel(struct rdma_dev_addr *addr)
{ {
struct addr_req *req, *temp_req; struct addr_req *req, *temp_req;
@ -687,11 +694,6 @@ void rdma_addr_cancel(struct rdma_dev_addr *addr)
* guarentees no work is running and none will be started. * guarentees no work is running and none will be started.
*/ */
cancel_delayed_work_sync(&found->work); cancel_delayed_work_sync(&found->work);
if (found->callback)
found->callback(-ECANCELED, (struct sockaddr *)&found->src_addr,
found->addr, found->context);
kfree(found); kfree(found);
} }
EXPORT_SYMBOL(rdma_addr_cancel); EXPORT_SYMBOL(rdma_addr_cancel);

View File

@ -2880,13 +2880,11 @@ static void addr_handler(int status, struct sockaddr *src_addr,
if (id_priv->id.event_handler(&id_priv->id, &event)) { if (id_priv->id.event_handler(&id_priv->id, &event)) {
cma_exch(id_priv, RDMA_CM_DESTROYING); cma_exch(id_priv, RDMA_CM_DESTROYING);
mutex_unlock(&id_priv->handler_mutex); mutex_unlock(&id_priv->handler_mutex);
cma_deref_id(id_priv);
rdma_destroy_id(&id_priv->id); rdma_destroy_id(&id_priv->id);
return; return;
} }
out: out:
mutex_unlock(&id_priv->handler_mutex); mutex_unlock(&id_priv->handler_mutex);
cma_deref_id(id_priv);
} }
static int cma_resolve_loopback(struct rdma_id_private *id_priv) static int cma_resolve_loopback(struct rdma_id_private *id_priv)
@ -2983,7 +2981,6 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
return -EINVAL; return -EINVAL;
memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr)); memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));
atomic_inc(&id_priv->refcount);
if (cma_any_addr(dst_addr)) { if (cma_any_addr(dst_addr)) {
ret = cma_resolve_loopback(id_priv); ret = cma_resolve_loopback(id_priv);
} else { } else {
@ -3001,7 +2998,6 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
return 0; return 0;
err: err:
cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND); cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND);
cma_deref_id(id_priv);
return ret; return ret;
} }
EXPORT_SYMBOL(rdma_resolve_addr); EXPORT_SYMBOL(rdma_resolve_addr);