aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/uverbs_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/core/uverbs_main.c')
-rw-r--r--drivers/infiniband/core/uverbs_main.c91
1 files changed, 43 insertions, 48 deletions
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 823beca448e1..16e5f714ca53 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -169,20 +169,16 @@ int uverbs_dealloc_mw(struct ib_mw *mw)
169 return ret; 169 return ret;
170} 170}
171 171
172static void ib_uverbs_release_dev(struct kobject *kobj) 172static void ib_uverbs_release_dev(struct device *device)
173{ 173{
174 struct ib_uverbs_device *dev = 174 struct ib_uverbs_device *dev =
175 container_of(kobj, struct ib_uverbs_device, kobj); 175 container_of(device, struct ib_uverbs_device, dev);
176 176
177 uverbs_destroy_api(dev->uapi); 177 uverbs_destroy_api(dev->uapi);
178 cleanup_srcu_struct(&dev->disassociate_srcu); 178 cleanup_srcu_struct(&dev->disassociate_srcu);
179 kfree(dev); 179 kfree(dev);
180} 180}
181 181
182static struct kobj_type ib_uverbs_dev_ktype = {
183 .release = ib_uverbs_release_dev,
184};
185
186static void ib_uverbs_release_async_event_file(struct kref *ref) 182static void ib_uverbs_release_async_event_file(struct kref *ref)
187{ 183{
188 struct ib_uverbs_async_event_file *file = 184 struct ib_uverbs_async_event_file *file =
@@ -265,7 +261,7 @@ void ib_uverbs_release_file(struct kref *ref)
265 if (atomic_dec_and_test(&file->device->refcount)) 261 if (atomic_dec_and_test(&file->device->refcount))
266 ib_uverbs_comp_dev(file->device); 262 ib_uverbs_comp_dev(file->device);
267 263
268 kobject_put(&file->device->kobj); 264 put_device(&file->device->dev);
269 kfree(file); 265 kfree(file);
270} 266}
271 267
@@ -838,6 +834,7 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp)
838 if (!atomic_inc_not_zero(&dev->refcount)) 834 if (!atomic_inc_not_zero(&dev->refcount))
839 return -ENXIO; 835 return -ENXIO;
840 836
837 get_device(&dev->dev);
841 srcu_key = srcu_read_lock(&dev->disassociate_srcu); 838 srcu_key = srcu_read_lock(&dev->disassociate_srcu);
842 mutex_lock(&dev->lists_mutex); 839 mutex_lock(&dev->lists_mutex);
843 ib_dev = srcu_dereference(dev->ib_dev, 840 ib_dev = srcu_dereference(dev->ib_dev,
@@ -877,7 +874,6 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp)
877 init_rwsem(&file->hw_destroy_rwsem); 874 init_rwsem(&file->hw_destroy_rwsem);
878 875
879 filp->private_data = file; 876 filp->private_data = file;
880 kobject_get(&dev->kobj);
881 list_add_tail(&file->list, &dev->uverbs_file_list); 877 list_add_tail(&file->list, &dev->uverbs_file_list);
882 mutex_unlock(&dev->lists_mutex); 878 mutex_unlock(&dev->lists_mutex);
883 srcu_read_unlock(&dev->disassociate_srcu, srcu_key); 879 srcu_read_unlock(&dev->disassociate_srcu, srcu_key);
@@ -898,6 +894,7 @@ err:
898 if (atomic_dec_and_test(&dev->refcount)) 894 if (atomic_dec_and_test(&dev->refcount))
899 ib_uverbs_comp_dev(dev); 895 ib_uverbs_comp_dev(dev);
900 896
897 put_device(&dev->dev);
901 return ret; 898 return ret;
902} 899}
903 900
@@ -950,17 +947,15 @@ static struct ib_client uverbs_client = {
950 .remove = ib_uverbs_remove_one 947 .remove = ib_uverbs_remove_one
951}; 948};
952 949
953static ssize_t show_ibdev(struct device *device, struct device_attribute *attr, 950static ssize_t ibdev_show(struct device *device, struct device_attribute *attr,
954 char *buf) 951 char *buf)
955{ 952{
953 struct ib_uverbs_device *dev =
954 container_of(device, struct ib_uverbs_device, dev);
956 int ret = -ENODEV; 955 int ret = -ENODEV;
957 int srcu_key; 956 int srcu_key;
958 struct ib_uverbs_device *dev = dev_get_drvdata(device);
959 struct ib_device *ib_dev; 957 struct ib_device *ib_dev;
960 958
961 if (!dev)
962 return -ENODEV;
963
964 srcu_key = srcu_read_lock(&dev->disassociate_srcu); 959 srcu_key = srcu_read_lock(&dev->disassociate_srcu);
965 ib_dev = srcu_dereference(dev->ib_dev, &dev->disassociate_srcu); 960 ib_dev = srcu_dereference(dev->ib_dev, &dev->disassociate_srcu);
966 if (ib_dev) 961 if (ib_dev)
@@ -969,18 +964,17 @@ static ssize_t show_ibdev(struct device *device, struct device_attribute *attr,
969 964
970 return ret; 965 return ret;
971} 966}
972static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); 967static DEVICE_ATTR_RO(ibdev);
973 968
974static ssize_t show_dev_abi_version(struct device *device, 969static ssize_t abi_version_show(struct device *device,
975 struct device_attribute *attr, char *buf) 970 struct device_attribute *attr, char *buf)
976{ 971{
977 struct ib_uverbs_device *dev = dev_get_drvdata(device); 972 struct ib_uverbs_device *dev =
973 container_of(device, struct ib_uverbs_device, dev);
978 int ret = -ENODEV; 974 int ret = -ENODEV;
979 int srcu_key; 975 int srcu_key;
980 struct ib_device *ib_dev; 976 struct ib_device *ib_dev;
981 977
982 if (!dev)
983 return -ENODEV;
984 srcu_key = srcu_read_lock(&dev->disassociate_srcu); 978 srcu_key = srcu_read_lock(&dev->disassociate_srcu);
985 ib_dev = srcu_dereference(dev->ib_dev, &dev->disassociate_srcu); 979 ib_dev = srcu_dereference(dev->ib_dev, &dev->disassociate_srcu);
986 if (ib_dev) 980 if (ib_dev)
@@ -989,7 +983,17 @@ static ssize_t show_dev_abi_version(struct device *device,
989 983
990 return ret; 984 return ret;
991} 985}
992static DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL); 986static DEVICE_ATTR_RO(abi_version);
987
988static struct attribute *ib_dev_attrs[] = {
989 &dev_attr_abi_version.attr,
990 &dev_attr_ibdev.attr,
991 NULL,
992};
993
994static const struct attribute_group dev_attr_group = {
995 .attrs = ib_dev_attrs,
996};
993 997
994static CLASS_ATTR_STRING(abi_version, S_IRUGO, 998static CLASS_ATTR_STRING(abi_version, S_IRUGO,
995 __stringify(IB_USER_VERBS_ABI_VERSION)); 999 __stringify(IB_USER_VERBS_ABI_VERSION));
@@ -1031,7 +1035,6 @@ static void ib_uverbs_add_one(struct ib_device *device)
1031 init_completion(&uverbs_dev->comp); 1035 init_completion(&uverbs_dev->comp);
1032 uverbs_dev->xrcd_tree = RB_ROOT; 1036 uverbs_dev->xrcd_tree = RB_ROOT;
1033 mutex_init(&uverbs_dev->xrcd_tree_mutex); 1037 mutex_init(&uverbs_dev->xrcd_tree_mutex);
1034 kobject_init(&uverbs_dev->kobj, &ib_uverbs_dev_ktype);
1035 mutex_init(&uverbs_dev->lists_mutex); 1038 mutex_init(&uverbs_dev->lists_mutex);
1036 INIT_LIST_HEAD(&uverbs_dev->uverbs_file_list); 1039 INIT_LIST_HEAD(&uverbs_dev->uverbs_file_list);
1037 INIT_LIST_HEAD(&uverbs_dev->uverbs_events_file_list); 1040 INIT_LIST_HEAD(&uverbs_dev->uverbs_events_file_list);
@@ -1050,43 +1053,37 @@ static void ib_uverbs_add_one(struct ib_device *device)
1050 uverbs_dev->num_comp_vectors = device->num_comp_vectors; 1053 uverbs_dev->num_comp_vectors = device->num_comp_vectors;
1051 1054
1052 if (ib_uverbs_create_uapi(device, uverbs_dev)) 1055 if (ib_uverbs_create_uapi(device, uverbs_dev))
1053 goto err; 1056 goto err_uapi;
1054 1057
1055 cdev_init(&uverbs_dev->cdev, NULL); 1058 device_initialize(&uverbs_dev->dev);
1059 uverbs_dev->dev.class = uverbs_class;
1060 uverbs_dev->dev.parent = device->dev.parent;
1061 uverbs_dev->dev.devt = base;
1062 uverbs_dev->dev.release = ib_uverbs_release_dev;
1063 uverbs_dev->groups[0] = &dev_attr_group;
1064 uverbs_dev->dev.groups = uverbs_dev->groups;
1065 dev_set_name(&uverbs_dev->dev, "uverbs%d", uverbs_dev->devnum);
1066
1067 cdev_init(&uverbs_dev->cdev,
1068 device->mmap ? &uverbs_mmap_fops : &uverbs_fops);
1056 uverbs_dev->cdev.owner = THIS_MODULE; 1069 uverbs_dev->cdev.owner = THIS_MODULE;
1057 uverbs_dev->cdev.ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops;
1058 cdev_set_parent(&uverbs_dev->cdev, &uverbs_dev->kobj);
1059 kobject_set_name(&uverbs_dev->cdev.kobj, "uverbs%d", uverbs_dev->devnum);
1060 if (cdev_add(&uverbs_dev->cdev, base, 1))
1061 goto err_cdev;
1062 1070
1063 uverbs_dev->dev = device_create(uverbs_class, device->dev.parent, 1071 ret = cdev_device_add(&uverbs_dev->cdev, &uverbs_dev->dev);
1064 uverbs_dev->cdev.dev, uverbs_dev, 1072 if (ret)
1065 "uverbs%d", uverbs_dev->devnum);
1066 if (IS_ERR(uverbs_dev->dev))
1067 goto err_cdev; 1073 goto err_cdev;
1068 1074
1069 if (device_create_file(uverbs_dev->dev, &dev_attr_ibdev))
1070 goto err_class;
1071 if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version))
1072 goto err_class;
1073
1074 ib_set_client_data(device, &uverbs_client, uverbs_dev); 1075 ib_set_client_data(device, &uverbs_client, uverbs_dev);
1075
1076 return; 1076 return;
1077 1077
1078err_class:
1079 device_destroy(uverbs_class, uverbs_dev->cdev.dev);
1080
1081err_cdev: 1078err_cdev:
1082 cdev_del(&uverbs_dev->cdev); 1079 cdev_del(&uverbs_dev->cdev);
1080 put_device(&uverbs_dev->dev);
1081err_uapi:
1083 clear_bit(devnum, dev_map); 1082 clear_bit(devnum, dev_map);
1084
1085err: 1083err:
1086 if (atomic_dec_and_test(&uverbs_dev->refcount)) 1084 if (atomic_dec_and_test(&uverbs_dev->refcount))
1087 ib_uverbs_comp_dev(uverbs_dev); 1085 ib_uverbs_comp_dev(uverbs_dev);
1088 wait_for_completion(&uverbs_dev->comp); 1086 wait_for_completion(&uverbs_dev->comp);
1089 kobject_put(&uverbs_dev->kobj);
1090 return; 1087 return;
1091} 1088}
1092 1089
@@ -1156,9 +1153,7 @@ static void ib_uverbs_remove_one(struct ib_device *device, void *client_data)
1156 if (!uverbs_dev) 1153 if (!uverbs_dev)
1157 return; 1154 return;
1158 1155
1159 dev_set_drvdata(uverbs_dev->dev, NULL); 1156 cdev_device_del(&uverbs_dev->cdev, &uverbs_dev->dev);
1160 device_destroy(uverbs_class, uverbs_dev->cdev.dev);
1161 cdev_del(&uverbs_dev->cdev);
1162 clear_bit(uverbs_dev->devnum, dev_map); 1157 clear_bit(uverbs_dev->devnum, dev_map);
1163 1158
1164 if (device->disassociate_ucontext) { 1159 if (device->disassociate_ucontext) {
@@ -1182,7 +1177,7 @@ static void ib_uverbs_remove_one(struct ib_device *device, void *client_data)
1182 if (wait_clients) 1177 if (wait_clients)
1183 wait_for_completion(&uverbs_dev->comp); 1178 wait_for_completion(&uverbs_dev->comp);
1184 1179
1185 kobject_put(&uverbs_dev->kobj); 1180 put_device(&uverbs_dev->dev);
1186} 1181}
1187 1182
1188static char *uverbs_devnode(struct device *dev, umode_t *mode) 1183static char *uverbs_devnode(struct device *dev, umode_t *mode)