|
@@ -47,6 +47,7 @@ struct addr_req {
|
|
struct sockaddr src_addr;
|
|
struct sockaddr src_addr;
|
|
struct sockaddr dst_addr;
|
|
struct sockaddr dst_addr;
|
|
struct rdma_dev_addr *addr;
|
|
struct rdma_dev_addr *addr;
|
|
|
|
+ struct rdma_addr_client *client;
|
|
void *context;
|
|
void *context;
|
|
void (*callback)(int status, struct sockaddr *src_addr,
|
|
void (*callback)(int status, struct sockaddr *src_addr,
|
|
struct rdma_dev_addr *addr, void *context);
|
|
struct rdma_dev_addr *addr, void *context);
|
|
@@ -61,6 +62,26 @@ static LIST_HEAD(req_list);
|
|
static DECLARE_WORK(work, process_req, NULL);
|
|
static DECLARE_WORK(work, process_req, NULL);
|
|
static struct workqueue_struct *addr_wq;
|
|
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,
|
|
int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
|
|
const unsigned char *dst_dev_addr)
|
|
const unsigned char *dst_dev_addr)
|
|
{
|
|
{
|
|
@@ -229,6 +250,7 @@ static void process_req(void *data)
|
|
list_del(&req->list);
|
|
list_del(&req->list);
|
|
req->callback(req->status, &req->src_addr, req->addr,
|
|
req->callback(req->status, &req->src_addr, req->addr,
|
|
req->context);
|
|
req->context);
|
|
|
|
+ put_client(req->client);
|
|
kfree(req);
|
|
kfree(req);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -264,7 +286,8 @@ static int addr_resolve_local(struct sockaddr_in *src_in,
|
|
return ret;
|
|
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,
|
|
struct rdma_dev_addr *addr, int timeout_ms,
|
|
void (*callback)(int status, struct sockaddr *src_addr,
|
|
void (*callback)(int status, struct sockaddr *src_addr,
|
|
struct rdma_dev_addr *addr, void *context),
|
|
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->addr = addr;
|
|
req->callback = callback;
|
|
req->callback = callback;
|
|
req->context = context;
|
|
req->context = context;
|
|
|
|
+ req->client = client;
|
|
|
|
+ atomic_inc(&client->refcount);
|
|
|
|
|
|
src_in = (struct sockaddr_in *) &req->src_addr;
|
|
src_in = (struct sockaddr_in *) &req->src_addr;
|
|
dst_in = (struct sockaddr_in *) &req->dst_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;
|
|
break;
|
|
default:
|
|
default:
|
|
ret = req->status;
|
|
ret = req->status;
|
|
|
|
+ atomic_dec(&client->refcount);
|
|
kfree(req);
|
|
kfree(req);
|
|
break;
|
|
break;
|
|
}
|
|
}
|