Merge tag 'r8169-20060920-00' of git://electric-eye.fr.zoreil.com/home/romieu/linux...
[pandora-kernel.git] / drivers / infiniband / core / uverbs_main.c
index e57d3c5..4e16314 100644 (file)
@@ -122,7 +122,7 @@ static void ib_uverbs_release_dev(struct kref *ref)
        struct ib_uverbs_device *dev =
                container_of(ref, struct ib_uverbs_device, ref);
 
-       kfree(dev);
+       complete(&dev->comp);
 }
 
 void ib_uverbs_release_ucq(struct ib_uverbs_file *file,
@@ -188,7 +188,6 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
 
                idr_remove_uobj(&ib_uverbs_ah_idr, uobj);
                ib_destroy_ah(ah);
-               list_del(&uobj->list);
                kfree(uobj);
        }
 
@@ -200,7 +199,6 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
                idr_remove_uobj(&ib_uverbs_qp_idr, uobj);
                ib_uverbs_detach_umcast(qp, uqp);
                ib_destroy_qp(qp);
-               list_del(&uobj->list);
                ib_uverbs_release_uevent(file, &uqp->uevent);
                kfree(uqp);
        }
@@ -213,7 +211,6 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
 
                idr_remove_uobj(&ib_uverbs_cq_idr, uobj);
                ib_destroy_cq(cq);
-               list_del(&uobj->list);
                ib_uverbs_release_ucq(file, ev_file, ucq);
                kfree(ucq);
        }
@@ -225,7 +222,6 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
 
                idr_remove_uobj(&ib_uverbs_srq_idr, uobj);
                ib_destroy_srq(srq);
-               list_del(&uobj->list);
                ib_uverbs_release_uevent(file, uevent);
                kfree(uevent);
        }
@@ -243,7 +239,6 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
                memobj = container_of(uobj, struct ib_umem_object, uobject);
                ib_umem_release_on_close(mrdev, &memobj->umem);
 
-               list_del(&uobj->list);
                kfree(memobj);
        }
 
@@ -252,7 +247,6 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
 
                idr_remove_uobj(&ib_uverbs_pd_idr, uobj);
                ib_dealloc_pd(pd);
-               list_del(&uobj->list);
                kfree(uobj);
        }
 
@@ -746,6 +740,7 @@ static void ib_uverbs_add_one(struct ib_device *device)
                return;
 
        kref_init(&uverbs_dev->ref);
+       init_completion(&uverbs_dev->comp);
 
        spin_lock(&map_lock);
        uverbs_dev->devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES);
@@ -799,6 +794,8 @@ err_cdev:
 
 err:
        kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);
+       wait_for_completion(&uverbs_dev->comp);
+       kfree(uverbs_dev);
        return;
 }
 
@@ -818,7 +815,10 @@ static void ib_uverbs_remove_one(struct ib_device *device)
        spin_unlock(&map_lock);
 
        clear_bit(uverbs_dev->devnum, dev_map);
+
        kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);
+       wait_for_completion(&uverbs_dev->comp);
+       kfree(uverbs_dev);
 }
 
 static int uverbs_event_get_sb(struct file_system_type *fs_type, int flags,