summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Hefty2007-05-07 20:49:27 +0200
committerRoland Dreier2007-05-14 23:10:32 +0200
commit6c719f5c6c823901fac2d46b83db5a69ba7e9152 (patch)
treeb85bcb8ee9d6064fbde7bd34294e8a91d76a6bc7
parentRDMA/cma: Fix synchronization with device removal in cma_iw_handler (diff)
downloadkernel-qcow2-linux-6c719f5c6c823901fac2d46b83db5a69ba7e9152.tar.gz
kernel-qcow2-linux-6c719f5c6c823901fac2d46b83db5a69ba7e9152.tar.xz
kernel-qcow2-linux-6c719f5c6c823901fac2d46b83db5a69ba7e9152.zip
RDMA/cma: Add check to validate that cm_id is bound to a device
Several checks in the rdma_cm check against the state of the cm_id, but only to validate that the cm_id is bound to an underlying transport specific CM and an RDMA device. Make the check explicit in what we're trying to check for, since we're not synchronizing against the cm_id state. This will allow a user to disconnect a cm_id or reject a connection after receiving a device removal event. Signed-off-by: Sean Hefty <sean.hefty@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/core/cma.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index cfd57b4abd03..2eb52b7a71da 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -368,6 +368,11 @@ static void cma_enable_remove(struct rdma_id_private *id_priv)
wake_up(&id_priv->wait_remove);
}
+static int cma_has_cm_dev(struct rdma_id_private *id_priv)
+{
+ return (id_priv->id.device && id_priv->cm_id.ib);
+}
+
struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler,
void *context, enum rdma_port_space ps)
{
@@ -2422,7 +2427,7 @@ int rdma_notify(struct rdma_cm_id *id, enum ib_event_type event)
int ret;
id_priv = container_of(id, struct rdma_id_private, id);
- if (!cma_comp(id_priv, CMA_CONNECT))
+ if (!cma_has_cm_dev(id_priv))
return -EINVAL;
switch (id->device->node_type) {
@@ -2444,7 +2449,7 @@ int rdma_reject(struct rdma_cm_id *id, const void *private_data,
int ret;
id_priv = container_of(id, struct rdma_id_private, id);
- if (!cma_comp(id_priv, CMA_CONNECT))
+ if (!cma_has_cm_dev(id_priv))
return -EINVAL;
switch (rdma_node_get_transport(id->device->node_type)) {
@@ -2475,8 +2480,7 @@ int rdma_disconnect(struct rdma_cm_id *id)
int ret;
id_priv = container_of(id, struct rdma_id_private, id);
- if (!cma_comp(id_priv, CMA_CONNECT) &&
- !cma_comp(id_priv, CMA_DISCONNECT))
+ if (!cma_has_cm_dev(id_priv))
return -EINVAL;
switch (rdma_node_get_transport(id->device->node_type)) {