diff options
author | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-11-22 12:06:44 -0600 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-11-22 12:06:44 -0600 |
commit | 0bd2af46839ad6262d25714a6ec0365db9d6b98f (patch) | |
tree | dcced72d230d69fd0c5816ac6dd03ab84799a93e /drivers/infiniband/core | |
parent | e138a5d2356729b8752e88520cc1525fae9794ac (diff) | |
parent | f26b90440cd74c78fe10c9bd5160809704a9627c (diff) |
Merge ../scsi-rc-fixes-2.6
Diffstat (limited to 'drivers/infiniband/core')
-rw-r--r-- | drivers/infiniband/core/addr.c | 28 | ||||
-rw-r--r-- | drivers/infiniband/core/cma.c | 31 | ||||
-rw-r--r-- | drivers/infiniband/core/mad.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 2 |
4 files changed, 50 insertions, 13 deletions
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 60d3fbdd216..e11187ecc93 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -47,6 +47,7 @@ struct addr_req { struct sockaddr src_addr; struct sockaddr dst_addr; struct rdma_dev_addr *addr; + struct rdma_addr_client *client; void *context; void (*callback)(int status, struct sockaddr *src_addr, struct rdma_dev_addr *addr, void *context); @@ -61,6 +62,26 @@ static LIST_HEAD(req_list); static DECLARE_WORK(work, process_req, NULL); static struct workqueue_struct *addr_wq; +void rdma_addr_register_client(struct rdma_addr_client *client) +{ + atomic_set(&client->refcount, 1); + init_completion(&client->comp); +} +EXPORT_SYMBOL(rdma_addr_register_client); + +static inline void put_client(struct rdma_addr_client *client) +{ + if (atomic_dec_and_test(&client->refcount)) + complete(&client->comp); +} + +void rdma_addr_unregister_client(struct rdma_addr_client *client) +{ + put_client(client); + wait_for_completion(&client->comp); +} +EXPORT_SYMBOL(rdma_addr_unregister_client); + int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev, const unsigned char *dst_dev_addr) { @@ -229,6 +250,7 @@ static void process_req(void *data) list_del(&req->list); req->callback(req->status, &req->src_addr, req->addr, req->context); + put_client(req->client); kfree(req); } } @@ -264,7 +286,8 @@ static int addr_resolve_local(struct sockaddr_in *src_in, return ret; } -int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, +int rdma_resolve_ip(struct rdma_addr_client *client, + struct sockaddr *src_addr, struct sockaddr *dst_addr, struct rdma_dev_addr *addr, int timeout_ms, void (*callback)(int status, struct sockaddr *src_addr, struct rdma_dev_addr *addr, void *context), @@ -285,6 +308,8 @@ int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, req->addr = addr; req->callback = callback; req->context = context; + req->client = client; + atomic_inc(&client->refcount); src_in = (struct sockaddr_in *) &req->src_addr; dst_in = (struct sockaddr_in *) &req->dst_addr; @@ -305,6 +330,7 @@ int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, break; default: ret = req->status; + atomic_dec(&client->refcount); kfree(req); break; } diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 9ae4f3a67c7..845090b0859 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -63,6 +63,7 @@ static struct ib_client cma_client = { }; static struct ib_sa_client sa_client; +static struct rdma_addr_client addr_client; static LIST_HEAD(dev_list); static LIST_HEAD(listen_any_list); static DEFINE_MUTEX(lock); @@ -1625,8 +1626,8 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, if (cma_any_addr(dst_addr)) ret = cma_resolve_loopback(id_priv); else - ret = rdma_resolve_ip(&id->route.addr.src_addr, dst_addr, - &id->route.addr.dev_addr, + ret = rdma_resolve_ip(&addr_client, &id->route.addr.src_addr, + dst_addr, &id->route.addr.dev_addr, timeout_ms, addr_handler, id_priv); if (ret) goto err; @@ -1762,22 +1763,29 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) if (!cma_any_addr(addr)) { ret = rdma_translate_ip(addr, &id->route.addr.dev_addr); - if (!ret) { - mutex_lock(&lock); - ret = cma_acquire_dev(id_priv); - mutex_unlock(&lock); - } if (ret) - goto err; + goto err1; + + mutex_lock(&lock); + ret = cma_acquire_dev(id_priv); + mutex_unlock(&lock); + if (ret) + goto err1; } memcpy(&id->route.addr.src_addr, addr, ip_addr_size(addr)); ret = cma_get_port(id_priv); if (ret) - goto err; + goto err2; return 0; -err: +err2: + if (!cma_any_addr(addr)) { + mutex_lock(&lock); + cma_detach_from_dev(id_priv); + mutex_unlock(&lock); + } +err1: cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_IDLE); return ret; } @@ -2210,6 +2218,7 @@ static int cma_init(void) return -ENOMEM; ib_sa_register_client(&sa_client); + rdma_addr_register_client(&addr_client); ret = ib_register_client(&cma_client); if (ret) @@ -2217,6 +2226,7 @@ static int cma_init(void) return 0; err: + rdma_addr_unregister_client(&addr_client); ib_sa_unregister_client(&sa_client); destroy_workqueue(cma_wq); return ret; @@ -2225,6 +2235,7 @@ err: static void cma_cleanup(void) { ib_unregister_client(&cma_client); + rdma_addr_unregister_client(&addr_client); ib_sa_unregister_client(&sa_client); destroy_workqueue(cma_wq); idr_destroy(&sdp_ps); diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 493f4c65c7a..a72bcea46ff 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -1750,7 +1750,7 @@ ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, */ (is_direct(wc->recv_buf.mad->mad_hdr.mgmt_class) || rcv_has_same_gid(mad_agent_priv, wr, wc))) - return wr; + return (wr->status == IB_WC_SUCCESS) ? wr : NULL; } /* diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index b72c7f69ca9..743247ec065 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -1214,7 +1214,7 @@ ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file, resp.qp_access_flags = attr->qp_access_flags; resp.pkey_index = attr->pkey_index; resp.alt_pkey_index = attr->alt_pkey_index; - resp.en_sqd_async_notify = attr->en_sqd_async_notify; + resp.sq_draining = attr->sq_draining; resp.max_rd_atomic = attr->max_rd_atomic; resp.max_dest_rd_atomic = attr->max_dest_rd_atomic; resp.min_rnr_timer = attr->min_rnr_timer; |