]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/infiniband/core/cma.c
WorkStruct: make allyesconfig
[net-next-2.6.git] / drivers / infiniband / core / cma.c
index f383a4f50ab01289069365f89dfdfcfbbfb56a20..189f73f3f721f4744f2b78abc2d5f698ce3adc4d 100644 (file)
@@ -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);
@@ -874,23 +875,25 @@ static struct rdma_id_private *cma_new_id(struct rdma_cm_id *listen_id,
        __u16 port;
        u8 ip_ver;
 
+       if (cma_get_net_info(ib_event->private_data, listen_id->ps,
+                            &ip_ver, &port, &src, &dst))
+               goto err;
+
        id = rdma_create_id(listen_id->event_handler, listen_id->context,
                            listen_id->ps);
        if (IS_ERR(id))
-               return NULL;
+               goto err;
+
+       cma_save_net_info(&id->route.addr, &listen_id->route.addr,
+                         ip_ver, port, src, dst);
 
        rt = &id->route;
        rt->num_paths = ib_event->param.req_rcvd.alternate_path ? 2 : 1;
-       rt->path_rec = kmalloc(sizeof *rt->path_rec * rt->num_paths, GFP_KERNEL);
+       rt->path_rec = kmalloc(sizeof *rt->path_rec * rt->num_paths,
+                              GFP_KERNEL);
        if (!rt->path_rec)
-               goto err;
+               goto destroy_id;
 
-       if (cma_get_net_info(ib_event->private_data, listen_id->ps,
-                            &ip_ver, &port, &src, &dst))
-               goto err;
-
-       cma_save_net_info(&id->route.addr, &listen_id->route.addr,
-                         ip_ver, port, src, dst);
        rt->path_rec[0] = *ib_event->param.req_rcvd.primary_path;
        if (rt->num_paths == 2)
                rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path;
@@ -903,8 +906,10 @@ static struct rdma_id_private *cma_new_id(struct rdma_cm_id *listen_id,
        id_priv = container_of(id, struct rdma_id_private, id);
        id_priv->state = CMA_CONNECT;
        return id_priv;
-err:
+
+destroy_id:
        rdma_destroy_id(id);
+err:
        return NULL;
 }
 
@@ -1308,6 +1313,7 @@ static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec,
                work->old_state = CMA_ROUTE_QUERY;
                work->new_state = CMA_ADDR_RESOLVED;
                work->event.event = RDMA_CM_EVENT_ROUTE_ERROR;
+               work->event.status = status;
        }
 
        queue_work(cma_wq, &work->work);
@@ -1335,9 +1341,9 @@ static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms,
        return (id_priv->query_id < 0) ? id_priv->query_id : 0;
 }
 
-static void cma_work_handler(void *data)
+static void cma_work_handler(struct work_struct *_work)
 {
-       struct cma_work *work = data;
+       struct cma_work *work = container_of(_work, struct cma_work, work);
        struct rdma_id_private *id_priv = work->id;
        int destroy = 0;
 
@@ -1368,7 +1374,7 @@ static int cma_resolve_ib_route(struct rdma_id_private *id_priv, int timeout_ms)
                return -ENOMEM;
 
        work->id = id_priv;
-       INIT_WORK(&work->work, cma_work_handler, work);
+       INIT_WORK(&work->work, cma_work_handler);
        work->old_state = CMA_ROUTE_QUERY;
        work->new_state = CMA_ROUTE_RESOLVED;
        work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED;
@@ -1425,7 +1431,7 @@ static int cma_resolve_iw_route(struct rdma_id_private *id_priv, int timeout_ms)
                return -ENOMEM;
 
        work->id = id_priv;
-       INIT_WORK(&work->work, cma_work_handler, work);
+       INIT_WORK(&work->work, cma_work_handler);
        work->old_state = CMA_ROUTE_QUERY;
        work->new_state = CMA_ROUTE_RESOLVED;
        work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED;
@@ -1579,7 +1585,7 @@ static int cma_resolve_loopback(struct rdma_id_private *id_priv)
        }
 
        work->id = id_priv;
-       INIT_WORK(&work->work, cma_work_handler, work);
+       INIT_WORK(&work->work, cma_work_handler);
        work->old_state = CMA_ADDR_QUERY;
        work->new_state = CMA_ADDR_RESOLVED;
        work->event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
@@ -1620,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;
@@ -1757,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;
 }
@@ -2150,12 +2163,9 @@ static int cma_remove_id_dev(struct rdma_id_private *id_priv)
 
 static void cma_process_remove(struct cma_device *cma_dev)
 {
-       struct list_head remove_list;
        struct rdma_id_private *id_priv;
        int ret;
 
-       INIT_LIST_HEAD(&remove_list);
-
        mutex_lock(&lock);
        while (!list_empty(&cma_dev->id_list)) {
                id_priv = list_entry(cma_dev->id_list.next,
@@ -2166,8 +2176,7 @@ static void cma_process_remove(struct cma_device *cma_dev)
                        continue;
                }
 
-               list_del(&id_priv->list);
-               list_add_tail(&id_priv->list, &remove_list);
+               list_del_init(&id_priv->list);
                atomic_inc(&id_priv->refcount);
                mutex_unlock(&lock);
 
@@ -2209,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)
@@ -2216,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;
@@ -2224,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);