Index: sys/ofed/drivers/infiniband/core/ib_cm.c =================================================================== --- sys/ofed/drivers/infiniband/core/ib_cm.c +++ sys/ofed/drivers/infiniband/core/ib_cm.c @@ -70,7 +70,8 @@ static struct ib_client cm_client = { .name = "cm", .add = cm_add_one, - .remove = cm_remove_one + .remove = cm_remove_one, + .detach_order = IB_DETACH_FOURTH, }; static struct ib_cm { Index: sys/ofed/drivers/infiniband/core/ib_cma.c =================================================================== --- sys/ofed/drivers/infiniband/core/ib_cma.c +++ sys/ofed/drivers/infiniband/core/ib_cma.c @@ -115,7 +115,8 @@ static struct ib_client cma_client = { .name = "cma", .add = cma_add_one, - .remove = cma_remove_one + .remove = cma_remove_one, + .detach_order = IB_DETACH_SECOND, }; static struct ib_sa_client sa_client; Index: sys/ofed/drivers/infiniband/core/ib_device.c =================================================================== --- sys/ofed/drivers/infiniband/core/ib_device.c +++ sys/ofed/drivers/infiniband/core/ib_device.c @@ -455,6 +455,7 @@ */ int ib_register_client(struct ib_client *client) { + struct ib_client *parent; struct ib_device *device; mutex_lock(&device_mutex); @@ -464,7 +465,14 @@ client->add(device); down_write(&lists_rwsem); + list_for_each_entry(parent, &client_list, list) { + if (parent->detach_order > client->detach_order) { + list_add_tail(&client->list, &parent->list); + goto skip_list_add; + } + } list_add_tail(&client->list, &client_list); +skip_list_add: up_write(&lists_rwsem); mutex_unlock(&device_mutex); Index: sys/ofed/drivers/infiniband/core/ib_mad.c =================================================================== --- sys/ofed/drivers/infiniband/core/ib_mad.c +++ sys/ofed/drivers/infiniband/core/ib_mad.c @@ -3316,7 +3316,8 @@ static struct ib_client mad_client = { .name = "mad", .add = ib_mad_init_device, - .remove = ib_mad_remove_device + .remove = ib_mad_remove_device, + .detach_order = IB_DETACH_FOURTH, }; int ib_mad_init(void) Index: sys/ofed/drivers/infiniband/core/ib_multicast.c =================================================================== --- sys/ofed/drivers/infiniband/core/ib_multicast.c +++ sys/ofed/drivers/infiniband/core/ib_multicast.c @@ -55,7 +55,8 @@ static struct ib_client mcast_client = { .name = "ib_multicast", .add = mcast_add_one, - .remove = mcast_remove_one + .remove = mcast_remove_one, + .detach_order = IB_DETACH_SECOND, }; static struct ib_sa_client sa_client; Index: sys/ofed/drivers/infiniband/core/ib_sa_query.c =================================================================== --- sys/ofed/drivers/infiniband/core/ib_sa_query.c +++ sys/ofed/drivers/infiniband/core/ib_sa_query.c @@ -141,7 +141,8 @@ static struct ib_client sa_client = { .name = "sa", .add = ib_sa_add_one, - .remove = ib_sa_remove_one + .remove = ib_sa_remove_one, + .detach_order = IB_DETACH_THIRD, }; static DEFINE_SPINLOCK(idr_lock); Index: sys/ofed/drivers/infiniband/core/ib_ucm.c =================================================================== --- sys/ofed/drivers/infiniband/core/ib_ucm.c +++ sys/ofed/drivers/infiniband/core/ib_ucm.c @@ -118,7 +118,8 @@ static struct ib_client ucm_client = { .name = "ucm", .add = ib_ucm_add_one, - .remove = ib_ucm_remove_one + .remove = ib_ucm_remove_one, + .detach_order = IB_DETACH_FOURTH, }; static DEFINE_MUTEX(ctx_id_mutex); Index: sys/ofed/drivers/infiniband/core/ib_user_mad.c =================================================================== --- sys/ofed/drivers/infiniband/core/ib_user_mad.c +++ sys/ofed/drivers/infiniband/core/ib_user_mad.c @@ -1104,7 +1104,8 @@ static struct ib_client umad_client = { .name = "umad", .add = ib_umad_add_one, - .remove = ib_umad_remove_one + .remove = ib_umad_remove_one, + .detach_order = IB_DETACH_FOURTH, }; static ssize_t show_ibdev(struct device *dev, struct device_attribute *attr, Index: sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c =================================================================== --- sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -171,6 +171,7 @@ .add = ipoib_add_one, .remove = ipoib_remove_one, .get_net_dev_by_params = ipoib_get_net_dev_by_params, + .detach_order = IB_DETACH_FIRST, }; int Index: sys/ofed/include/rdma/ib_verbs.h =================================================================== --- sys/ofed/include/rdma/ib_verbs.h +++ sys/ofed/include/rdma/ib_verbs.h @@ -2147,6 +2147,12 @@ const struct sockaddr *addr, void *client_data); struct list_head list; + + u8 detach_order; +#define IB_DETACH_FIRST 0 +#define IB_DETACH_SECOND 1 +#define IB_DETACH_THIRD 2 +#define IB_DETACH_FOURTH 3 }; struct ib_device *ib_alloc_device(size_t size);