diff options
| -rw-r--r-- | drivers/infiniband/core/addr.c | 28 | ||||
| -rw-r--r-- | drivers/infiniband/core/cma.c | 8 | ||||
| -rw-r--r-- | include/rdma/ib_addr.h | 20 |
3 files changed, 52 insertions, 4 deletions
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 60d3fbdd216c..e11187ecc931 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c | |||
| @@ -47,6 +47,7 @@ struct addr_req { | |||
| 47 | struct sockaddr src_addr; | 47 | struct sockaddr src_addr; |
| 48 | struct sockaddr dst_addr; | 48 | struct sockaddr dst_addr; |
| 49 | struct rdma_dev_addr *addr; | 49 | struct rdma_dev_addr *addr; |
| 50 | struct rdma_addr_client *client; | ||
| 50 | void *context; | 51 | void *context; |
| 51 | void (*callback)(int status, struct sockaddr *src_addr, | 52 | void (*callback)(int status, struct sockaddr *src_addr, |
| 52 | struct rdma_dev_addr *addr, void *context); | 53 | struct rdma_dev_addr *addr, void *context); |
| @@ -61,6 +62,26 @@ static LIST_HEAD(req_list); | |||
| 61 | static DECLARE_WORK(work, process_req, NULL); | 62 | static DECLARE_WORK(work, process_req, NULL); |
| 62 | static struct workqueue_struct *addr_wq; | 63 | static struct workqueue_struct *addr_wq; |
| 63 | 64 | ||
| 65 | void rdma_addr_register_client(struct rdma_addr_client *client) | ||
| 66 | { | ||
| 67 | atomic_set(&client->refcount, 1); | ||
| 68 | init_completion(&client->comp); | ||
| 69 | } | ||
| 70 | EXPORT_SYMBOL(rdma_addr_register_client); | ||
| 71 | |||
| 72 | static inline void put_client(struct rdma_addr_client *client) | ||
| 73 | { | ||
| 74 | if (atomic_dec_and_test(&client->refcount)) | ||
| 75 | complete(&client->comp); | ||
| 76 | } | ||
| 77 | |||
| 78 | void rdma_addr_unregister_client(struct rdma_addr_client *client) | ||
| 79 | { | ||
| 80 | put_client(client); | ||
| 81 | wait_for_completion(&client->comp); | ||
| 82 | } | ||
| 83 | EXPORT_SYMBOL(rdma_addr_unregister_client); | ||
| 84 | |||
| 64 | int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev, | 85 | int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev, |
| 65 | const unsigned char *dst_dev_addr) | 86 | const unsigned char *dst_dev_addr) |
| 66 | { | 87 | { |
| @@ -229,6 +250,7 @@ static void process_req(void *data) | |||
| 229 | list_del(&req->list); | 250 | list_del(&req->list); |
| 230 | req->callback(req->status, &req->src_addr, req->addr, | 251 | req->callback(req->status, &req->src_addr, req->addr, |
| 231 | req->context); | 252 | req->context); |
| 253 | put_client(req->client); | ||
| 232 | kfree(req); | 254 | kfree(req); |
| 233 | } | 255 | } |
| 234 | } | 256 | } |
| @@ -264,7 +286,8 @@ static int addr_resolve_local(struct sockaddr_in *src_in, | |||
| 264 | return ret; | 286 | return ret; |
| 265 | } | 287 | } |
| 266 | 288 | ||
| 267 | int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, | 289 | int rdma_resolve_ip(struct rdma_addr_client *client, |
| 290 | struct sockaddr *src_addr, struct sockaddr *dst_addr, | ||
| 268 | struct rdma_dev_addr *addr, int timeout_ms, | 291 | struct rdma_dev_addr *addr, int timeout_ms, |
| 269 | void (*callback)(int status, struct sockaddr *src_addr, | 292 | void (*callback)(int status, struct sockaddr *src_addr, |
| 270 | struct rdma_dev_addr *addr, void *context), | 293 | struct rdma_dev_addr *addr, void *context), |
| @@ -285,6 +308,8 @@ int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, | |||
| 285 | req->addr = addr; | 308 | req->addr = addr; |
| 286 | req->callback = callback; | 309 | req->callback = callback; |
| 287 | req->context = context; | 310 | req->context = context; |
| 311 | req->client = client; | ||
| 312 | atomic_inc(&client->refcount); | ||
| 288 | 313 | ||
| 289 | src_in = (struct sockaddr_in *) &req->src_addr; | 314 | src_in = (struct sockaddr_in *) &req->src_addr; |
| 290 | dst_in = (struct sockaddr_in *) &req->dst_addr; | 315 | dst_in = (struct sockaddr_in *) &req->dst_addr; |
| @@ -305,6 +330,7 @@ int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, | |||
| 305 | break; | 330 | break; |
| 306 | default: | 331 | default: |
| 307 | ret = req->status; | 332 | ret = req->status; |
| 333 | atomic_dec(&client->refcount); | ||
| 308 | kfree(req); | 334 | kfree(req); |
| 309 | break; | 335 | break; |
| 310 | } | 336 | } |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index d8ca3c1368b5..845090b0859c 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
| @@ -63,6 +63,7 @@ static struct ib_client cma_client = { | |||
| 63 | }; | 63 | }; |
| 64 | 64 | ||
| 65 | static struct ib_sa_client sa_client; | 65 | static struct ib_sa_client sa_client; |
| 66 | static struct rdma_addr_client addr_client; | ||
| 66 | static LIST_HEAD(dev_list); | 67 | static LIST_HEAD(dev_list); |
| 67 | static LIST_HEAD(listen_any_list); | 68 | static LIST_HEAD(listen_any_list); |
| 68 | static DEFINE_MUTEX(lock); | 69 | static DEFINE_MUTEX(lock); |
| @@ -1625,8 +1626,8 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, | |||
| 1625 | if (cma_any_addr(dst_addr)) | 1626 | if (cma_any_addr(dst_addr)) |
| 1626 | ret = cma_resolve_loopback(id_priv); | 1627 | ret = cma_resolve_loopback(id_priv); |
| 1627 | else | 1628 | else |
| 1628 | ret = rdma_resolve_ip(&id->route.addr.src_addr, dst_addr, | 1629 | ret = rdma_resolve_ip(&addr_client, &id->route.addr.src_addr, |
| 1629 | &id->route.addr.dev_addr, | 1630 | dst_addr, &id->route.addr.dev_addr, |
| 1630 | timeout_ms, addr_handler, id_priv); | 1631 | timeout_ms, addr_handler, id_priv); |
| 1631 | if (ret) | 1632 | if (ret) |
| 1632 | goto err; | 1633 | goto err; |
| @@ -2217,6 +2218,7 @@ static int cma_init(void) | |||
| 2217 | return -ENOMEM; | 2218 | return -ENOMEM; |
| 2218 | 2219 | ||
| 2219 | ib_sa_register_client(&sa_client); | 2220 | ib_sa_register_client(&sa_client); |
| 2221 | rdma_addr_register_client(&addr_client); | ||
| 2220 | 2222 | ||
| 2221 | ret = ib_register_client(&cma_client); | 2223 | ret = ib_register_client(&cma_client); |
| 2222 | if (ret) | 2224 | if (ret) |
| @@ -2224,6 +2226,7 @@ static int cma_init(void) | |||
| 2224 | return 0; | 2226 | return 0; |
| 2225 | 2227 | ||
| 2226 | err: | 2228 | err: |
| 2229 | rdma_addr_unregister_client(&addr_client); | ||
| 2227 | ib_sa_unregister_client(&sa_client); | 2230 | ib_sa_unregister_client(&sa_client); |
| 2228 | destroy_workqueue(cma_wq); | 2231 | destroy_workqueue(cma_wq); |
| 2229 | return ret; | 2232 | return ret; |
| @@ -2232,6 +2235,7 @@ err: | |||
| 2232 | static void cma_cleanup(void) | 2235 | static void cma_cleanup(void) |
| 2233 | { | 2236 | { |
| 2234 | ib_unregister_client(&cma_client); | 2237 | ib_unregister_client(&cma_client); |
| 2238 | rdma_addr_unregister_client(&addr_client); | ||
| 2235 | ib_sa_unregister_client(&sa_client); | 2239 | ib_sa_unregister_client(&sa_client); |
| 2236 | destroy_workqueue(cma_wq); | 2240 | destroy_workqueue(cma_wq); |
| 2237 | idr_destroy(&sdp_ps); | 2241 | idr_destroy(&sdp_ps); |
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index 81b62307621d..c094e5012862 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h | |||
| @@ -36,6 +36,22 @@ | |||
| 36 | #include <linux/socket.h> | 36 | #include <linux/socket.h> |
| 37 | #include <rdma/ib_verbs.h> | 37 | #include <rdma/ib_verbs.h> |
| 38 | 38 | ||
| 39 | struct rdma_addr_client { | ||
| 40 | atomic_t refcount; | ||
| 41 | struct completion comp; | ||
| 42 | }; | ||
| 43 | |||
| 44 | /** | ||
| 45 | * rdma_addr_register_client - Register an address client. | ||
| 46 | */ | ||
| 47 | void rdma_addr_register_client(struct rdma_addr_client *client); | ||
| 48 | |||
| 49 | /** | ||
| 50 | * rdma_addr_unregister_client - Deregister an address client. | ||
| 51 | * @client: Client object to deregister. | ||
| 52 | */ | ||
| 53 | void rdma_addr_unregister_client(struct rdma_addr_client *client); | ||
| 54 | |||
| 39 | struct rdma_dev_addr { | 55 | struct rdma_dev_addr { |
| 40 | unsigned char src_dev_addr[MAX_ADDR_LEN]; | 56 | unsigned char src_dev_addr[MAX_ADDR_LEN]; |
| 41 | unsigned char dst_dev_addr[MAX_ADDR_LEN]; | 57 | unsigned char dst_dev_addr[MAX_ADDR_LEN]; |
| @@ -52,6 +68,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr); | |||
| 52 | /** | 68 | /** |
| 53 | * rdma_resolve_ip - Resolve source and destination IP addresses to | 69 | * rdma_resolve_ip - Resolve source and destination IP addresses to |
| 54 | * RDMA hardware addresses. | 70 | * RDMA hardware addresses. |
| 71 | * @client: Address client associated with request. | ||
| 55 | * @src_addr: An optional source address to use in the resolution. If a | 72 | * @src_addr: An optional source address to use in the resolution. If a |
| 56 | * source address is not provided, a usable address will be returned via | 73 | * source address is not provided, a usable address will be returned via |
| 57 | * the callback. | 74 | * the callback. |
| @@ -64,7 +81,8 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr); | |||
| 64 | * or been canceled. A status of 0 indicates success. | 81 | * or been canceled. A status of 0 indicates success. |
| 65 | * @context: User-specified context associated with the call. | 82 | * @context: User-specified context associated with the call. |
| 66 | */ | 83 | */ |
| 67 | int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, | 84 | int rdma_resolve_ip(struct rdma_addr_client *client, |
| 85 | struct sockaddr *src_addr, struct sockaddr *dst_addr, | ||
| 68 | struct rdma_dev_addr *addr, int timeout_ms, | 86 | struct rdma_dev_addr *addr, int timeout_ms, |
| 69 | void (*callback)(int status, struct sockaddr *src_addr, | 87 | void (*callback)(int status, struct sockaddr *src_addr, |
| 70 | struct rdma_dev_addr *addr, void *context), | 88 | struct rdma_dev_addr *addr, void *context), |
