forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-09 244b2c5ca8b14627e4a17755e5922221e121c771
kernel/drivers/infiniband/core/user_mad.c
....@@ -55,6 +55,7 @@
5555
5656 #include <rdma/ib_mad.h>
5757 #include <rdma/ib_user_mad.h>
58
+#include <rdma/rdma_netlink.h>
5859
5960 #include "core_priv.h"
6061
....@@ -89,10 +90,9 @@
8990
9091 struct ib_umad_port {
9192 struct cdev cdev;
92
- struct device *dev;
93
-
93
+ struct device dev;
9494 struct cdev sm_cdev;
95
- struct device *sm_dev;
95
+ struct device sm_dev;
9696 struct semaphore sm_sem;
9797
9898 struct mutex file_mutex;
....@@ -105,8 +105,8 @@
105105 };
106106
107107 struct ib_umad_device {
108
- struct kobject kobj;
109
- struct ib_umad_port port[0];
108
+ struct kref kref;
109
+ struct ib_umad_port ports[];
110110 };
111111
112112 struct ib_umad_file {
....@@ -131,7 +131,13 @@
131131 struct ib_user_mad mad;
132132 };
133133
134
-static struct class *umad_class;
134
+struct ib_rmpp_mad_hdr {
135
+ struct ib_mad_hdr mad_hdr;
136
+ struct ib_rmpp_hdr rmpp_hdr;
137
+} __packed;
138
+
139
+#define CREATE_TRACE_POINTS
140
+#include <trace/events/ib_umad.h>
135141
136142 static const dev_t base_umad_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE);
137143 static const dev_t base_issm_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE) +
....@@ -139,22 +145,28 @@
139145 static dev_t dynamic_umad_dev;
140146 static dev_t dynamic_issm_dev;
141147
142
-static DECLARE_BITMAP(dev_map, IB_UMAD_MAX_PORTS);
148
+static DEFINE_IDA(umad_ida);
143149
144
-static void ib_umad_add_one(struct ib_device *device);
150
+static int ib_umad_add_one(struct ib_device *device);
145151 static void ib_umad_remove_one(struct ib_device *device, void *client_data);
146152
147
-static void ib_umad_release_dev(struct kobject *kobj)
153
+static void ib_umad_dev_free(struct kref *kref)
148154 {
149155 struct ib_umad_device *dev =
150
- container_of(kobj, struct ib_umad_device, kobj);
156
+ container_of(kref, struct ib_umad_device, kref);
151157
152158 kfree(dev);
153159 }
154160
155
-static struct kobj_type ib_umad_dev_ktype = {
156
- .release = ib_umad_release_dev,
157
-};
161
+static void ib_umad_dev_get(struct ib_umad_device *dev)
162
+{
163
+ kref_get(&dev->kref);
164
+}
165
+
166
+static void ib_umad_dev_put(struct ib_umad_device *dev)
167
+{
168
+ kref_put(&dev->kref, ib_umad_dev_free);
169
+}
158170
159171 static int hdr_size(struct ib_umad_file *file)
160172 {
....@@ -206,7 +218,7 @@
206218 struct ib_umad_packet *packet = send_wc->send_buf->context[0];
207219
208220 dequeue_send(file, packet);
209
- rdma_destroy_ah(packet->msg->ah);
221
+ rdma_destroy_ah(packet->msg->ah, RDMA_DESTROY_AH_SLEEPABLE);
210222 ib_free_send_mad(packet->msg);
211223
212224 if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) {
....@@ -332,6 +344,9 @@
332344 return -EFAULT;
333345 }
334346 }
347
+
348
+ trace_ib_umad_read_recv(file, &packet->mad.hdr, &recv_buf->mad->mad_hdr);
349
+
335350 return hdr_size(file) + packet->length;
336351 }
337352
....@@ -350,6 +365,9 @@
350365
351366 if (copy_to_user(buf, packet->mad.data, packet->length))
352367 return -EFAULT;
368
+
369
+ trace_ib_umad_read_send(file, &packet->mad.hdr,
370
+ (struct ib_mad_hdr *)&packet->mad.data);
353371
354372 return size;
355373 }
....@@ -481,11 +499,11 @@
481499 size_t count, loff_t *pos)
482500 {
483501 struct ib_umad_file *file = filp->private_data;
502
+ struct ib_rmpp_mad_hdr *rmpp_mad_hdr;
484503 struct ib_umad_packet *packet;
485504 struct ib_mad_agent *agent;
486505 struct rdma_ah_attr ah_attr;
487506 struct ib_ah *ah;
488
- struct ib_rmpp_mad *rmpp_mad;
489507 __be64 *tid;
490508 int ret, data_len, hdr_len, copy_offset, rmpp_active;
491509 u8 base_version;
....@@ -493,7 +511,7 @@
493511 if (count < hdr_size(file) + IB_MGMT_RMPP_HDR)
494512 return -EINVAL;
495513
496
- packet = kzalloc(sizeof *packet + IB_MGMT_RMPP_HDR, GFP_KERNEL);
514
+ packet = kzalloc(sizeof(*packet) + IB_MGMT_RMPP_HDR, GFP_KERNEL);
497515 if (!packet)
498516 return -ENOMEM;
499517
....@@ -515,6 +533,9 @@
515533 }
516534
517535 mutex_lock(&file->mutex);
536
+
537
+ trace_ib_umad_write(file, &packet->mad.hdr,
538
+ (struct ib_mad_hdr *)&packet->mad.data);
518539
519540 agent = __get_agent(file, packet->mad.hdr.id);
520541 if (!agent) {
....@@ -544,13 +565,13 @@
544565 goto err_up;
545566 }
546567
547
- rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data;
548
- hdr_len = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class);
568
+ rmpp_mad_hdr = (struct ib_rmpp_mad_hdr *)packet->mad.data;
569
+ hdr_len = ib_get_mad_data_offset(rmpp_mad_hdr->mad_hdr.mgmt_class);
549570
550
- if (ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)
571
+ if (ib_is_mad_class_rmpp(rmpp_mad_hdr->mad_hdr.mgmt_class)
551572 && ib_mad_kernel_rmpp_agent(agent)) {
552573 copy_offset = IB_MGMT_RMPP_HDR;
553
- rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
574
+ rmpp_active = ib_get_rmpp_flags(&rmpp_mad_hdr->rmpp_hdr) &
554575 IB_MGMT_RMPP_FLAG_ACTIVE;
555576 } else {
556577 copy_offset = IB_MGMT_MAD_HDR;
....@@ -599,12 +620,12 @@
599620 tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid;
600621 *tid = cpu_to_be64(((u64) agent->hi_tid) << 32 |
601622 (be64_to_cpup(tid) & 0xffffffff));
602
- rmpp_mad->mad_hdr.tid = *tid;
623
+ rmpp_mad_hdr->mad_hdr.tid = *tid;
603624 }
604625
605626 if (!ib_mad_kernel_rmpp_agent(agent)
606
- && ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)
607
- && (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) {
627
+ && ib_is_mad_class_rmpp(rmpp_mad_hdr->mad_hdr.mgmt_class)
628
+ && (ib_get_rmpp_flags(&rmpp_mad_hdr->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) {
608629 spin_lock_irq(&file->send_lock);
609630 list_add_tail(&packet->list, &file->send_list);
610631 spin_unlock_irq(&file->send_lock);
....@@ -632,7 +653,7 @@
632653 err_msg:
633654 ib_free_send_mad(packet->msg);
634655 err_ah:
635
- rdma_destroy_ah(ah);
656
+ rdma_destroy_ah(ah, RDMA_DESTROY_AH_SLEEPABLE);
636657 err_up:
637658 mutex_unlock(&file->mutex);
638659 err:
....@@ -672,7 +693,7 @@
672693 mutex_lock(&file->mutex);
673694
674695 if (!file->port->ib_dev) {
675
- dev_notice(file->port->dev,
696
+ dev_notice(&file->port->dev,
676697 "ib_umad_reg_agent: invalid device\n");
677698 ret = -EPIPE;
678699 goto out;
....@@ -684,7 +705,7 @@
684705 }
685706
686707 if (ureq.qpn != 0 && ureq.qpn != 1) {
687
- dev_notice(file->port->dev,
708
+ dev_notice(&file->port->dev,
688709 "ib_umad_reg_agent: invalid QPN %d specified\n",
689710 ureq.qpn);
690711 ret = -EINVAL;
....@@ -695,7 +716,7 @@
695716 if (!__get_agent(file, agent_id))
696717 goto found;
697718
698
- dev_notice(file->port->dev,
719
+ dev_notice(&file->port->dev,
699720 "ib_umad_reg_agent: Max Agents (%u) reached\n",
700721 IB_UMAD_MAX_AGENTS);
701722 ret = -ENOMEM;
....@@ -740,11 +761,11 @@
740761 if (!file->already_used) {
741762 file->already_used = 1;
742763 if (!file->use_pkey_index) {
743
- dev_warn(file->port->dev,
764
+ dev_warn(&file->port->dev,
744765 "process %s did not enable P_Key index support.\n",
745766 current->comm);
746
- dev_warn(file->port->dev,
747
- " Documentation/infiniband/user_mad.txt has info on the new ABI.\n");
767
+ dev_warn(&file->port->dev,
768
+ " Documentation/infiniband/user_mad.rst has info on the new ABI.\n");
748769 }
749770 }
750771
....@@ -774,7 +795,7 @@
774795 mutex_lock(&file->mutex);
775796
776797 if (!file->port->ib_dev) {
777
- dev_notice(file->port->dev,
798
+ dev_notice(&file->port->dev,
778799 "ib_umad_reg_agent2: invalid device\n");
779800 ret = -EPIPE;
780801 goto out;
....@@ -786,7 +807,7 @@
786807 }
787808
788809 if (ureq.qpn != 0 && ureq.qpn != 1) {
789
- dev_notice(file->port->dev,
810
+ dev_notice(&file->port->dev,
790811 "ib_umad_reg_agent2: invalid QPN %d specified\n",
791812 ureq.qpn);
792813 ret = -EINVAL;
....@@ -794,7 +815,7 @@
794815 }
795816
796817 if (ureq.flags & ~IB_USER_MAD_REG_FLAGS_CAP) {
797
- dev_notice(file->port->dev,
818
+ dev_notice(&file->port->dev,
798819 "ib_umad_reg_agent2 failed: invalid registration flags specified 0x%x; supported 0x%x\n",
799820 ureq.flags, IB_USER_MAD_REG_FLAGS_CAP);
800821 ret = -EINVAL;
....@@ -811,7 +832,7 @@
811832 if (!__get_agent(file, agent_id))
812833 goto found;
813834
814
- dev_notice(file->port->dev,
835
+ dev_notice(&file->port->dev,
815836 "ib_umad_reg_agent2: Max Agents (%u) reached\n",
816837 IB_UMAD_MAX_AGENTS);
817838 ret = -ENOMEM;
....@@ -823,7 +844,7 @@
823844 req.mgmt_class = ureq.mgmt_class;
824845 req.mgmt_class_version = ureq.mgmt_class_version;
825846 if (ureq.oui & 0xff000000) {
826
- dev_notice(file->port->dev,
847
+ dev_notice(&file->port->dev,
827848 "ib_umad_reg_agent2 failed: oui invalid 0x%08x\n",
828849 ureq.oui);
829850 ret = -EINVAL;
....@@ -972,19 +993,27 @@
972993 {
973994 struct ib_umad_port *port;
974995 struct ib_umad_file *file;
975
- int ret = -ENXIO;
996
+ int ret = 0;
976997
977998 port = container_of(inode->i_cdev, struct ib_umad_port, cdev);
978999
9791000 mutex_lock(&port->file_mutex);
9801001
981
- if (!port->ib_dev)
1002
+ if (!port->ib_dev) {
1003
+ ret = -ENXIO;
9821004 goto out;
1005
+ }
9831006
984
- ret = -ENOMEM;
985
- file = kzalloc(sizeof *file, GFP_KERNEL);
986
- if (!file)
1007
+ if (!rdma_dev_access_netns(port->ib_dev, current->nsproxy->net_ns)) {
1008
+ ret = -EPERM;
9871009 goto out;
1010
+ }
1011
+
1012
+ file = kzalloc(sizeof(*file), GFP_KERNEL);
1013
+ if (!file) {
1014
+ ret = -ENOMEM;
1015
+ goto out;
1016
+ }
9881017
9891018 mutex_init(&file->mutex);
9901019 spin_lock_init(&file->send_lock);
....@@ -997,15 +1026,7 @@
9971026
9981027 list_add_tail(&file->port_list, &port->file_list);
9991028
1000
- ret = nonseekable_open(inode, filp);
1001
- if (ret) {
1002
- list_del(&file->port_list);
1003
- kfree(file);
1004
- goto out;
1005
- }
1006
-
1007
- kobject_get(&port->umad_dev->kobj);
1008
-
1029
+ stream_open(inode, filp);
10091030 out:
10101031 mutex_unlock(&port->file_mutex);
10111032 return ret;
....@@ -1014,7 +1035,6 @@
10141035 static int ib_umad_close(struct inode *inode, struct file *filp)
10151036 {
10161037 struct ib_umad_file *file = filp->private_data;
1017
- struct ib_umad_device *dev = file->port->umad_dev;
10181038 struct ib_umad_packet *packet, *tmp;
10191039 int already_dead;
10201040 int i;
....@@ -1041,10 +1061,8 @@
10411061 ib_unregister_mad_agent(file->agent[i]);
10421062
10431063 mutex_unlock(&file->port->file_mutex);
1044
-
1064
+ mutex_destroy(&file->mutex);
10451065 kfree(file);
1046
- kobject_put(&dev->kobj);
1047
-
10481066 return 0;
10491067 }
10501068
....@@ -1084,23 +1102,19 @@
10841102 }
10851103 }
10861104
1105
+ if (!rdma_dev_access_netns(port->ib_dev, current->nsproxy->net_ns)) {
1106
+ ret = -EPERM;
1107
+ goto err_up_sem;
1108
+ }
1109
+
10871110 ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props);
10881111 if (ret)
10891112 goto err_up_sem;
10901113
10911114 filp->private_data = port;
10921115
1093
- ret = nonseekable_open(inode, filp);
1094
- if (ret)
1095
- goto err_clr_sm_cap;
1096
-
1097
- kobject_get(&port->umad_dev->kobj);
1098
-
1116
+ nonseekable_open(inode, filp);
10991117 return 0;
1100
-
1101
-err_clr_sm_cap:
1102
- swap(props.set_port_cap_mask, props.clr_port_cap_mask);
1103
- ib_modify_port(port->ib_dev, port->port_num, 0, &props);
11041118
11051119 err_up_sem:
11061120 up(&port->sm_sem);
....@@ -1124,8 +1138,6 @@
11241138
11251139 up(&port->sm_sem);
11261140
1127
- kobject_put(&port->umad_dev->kobj);
1128
-
11291141 return ret;
11301142 }
11311143
....@@ -1136,13 +1148,61 @@
11361148 .llseek = no_llseek,
11371149 };
11381150
1151
+static struct ib_umad_port *get_port(struct ib_device *ibdev,
1152
+ struct ib_umad_device *umad_dev,
1153
+ unsigned int port)
1154
+{
1155
+ if (!umad_dev)
1156
+ return ERR_PTR(-EOPNOTSUPP);
1157
+ if (!rdma_is_port_valid(ibdev, port))
1158
+ return ERR_PTR(-EINVAL);
1159
+ if (!rdma_cap_ib_mad(ibdev, port))
1160
+ return ERR_PTR(-EOPNOTSUPP);
1161
+
1162
+ return &umad_dev->ports[port - rdma_start_port(ibdev)];
1163
+}
1164
+
1165
+static int ib_umad_get_nl_info(struct ib_device *ibdev, void *client_data,
1166
+ struct ib_client_nl_info *res)
1167
+{
1168
+ struct ib_umad_port *port = get_port(ibdev, client_data, res->port);
1169
+
1170
+ if (IS_ERR(port))
1171
+ return PTR_ERR(port);
1172
+
1173
+ res->abi = IB_USER_MAD_ABI_VERSION;
1174
+ res->cdev = &port->dev;
1175
+ return 0;
1176
+}
1177
+
11391178 static struct ib_client umad_client = {
11401179 .name = "umad",
11411180 .add = ib_umad_add_one,
1142
- .remove = ib_umad_remove_one
1181
+ .remove = ib_umad_remove_one,
1182
+ .get_nl_info = ib_umad_get_nl_info,
11431183 };
1184
+MODULE_ALIAS_RDMA_CLIENT("umad");
11441185
1145
-static ssize_t show_ibdev(struct device *dev, struct device_attribute *attr,
1186
+static int ib_issm_get_nl_info(struct ib_device *ibdev, void *client_data,
1187
+ struct ib_client_nl_info *res)
1188
+{
1189
+ struct ib_umad_port *port = get_port(ibdev, client_data, res->port);
1190
+
1191
+ if (IS_ERR(port))
1192
+ return PTR_ERR(port);
1193
+
1194
+ res->abi = IB_USER_MAD_ABI_VERSION;
1195
+ res->cdev = &port->sm_dev;
1196
+ return 0;
1197
+}
1198
+
1199
+static struct ib_client issm_client = {
1200
+ .name = "issm",
1201
+ .get_nl_info = ib_issm_get_nl_info,
1202
+};
1203
+MODULE_ALIAS_RDMA_CLIENT("issm");
1204
+
1205
+static ssize_t ibdev_show(struct device *dev, struct device_attribute *attr,
11461206 char *buf)
11471207 {
11481208 struct ib_umad_port *port = dev_get_drvdata(dev);
....@@ -1150,11 +1210,11 @@
11501210 if (!port)
11511211 return -ENODEV;
11521212
1153
- return sprintf(buf, "%s\n", port->ib_dev->name);
1213
+ return sprintf(buf, "%s\n", dev_name(&port->ib_dev->dev));
11541214 }
1155
-static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
1215
+static DEVICE_ATTR_RO(ibdev);
11561216
1157
-static ssize_t show_port(struct device *dev, struct device_attribute *attr,
1217
+static ssize_t port_show(struct device *dev, struct device_attribute *attr,
11581218 char *buf)
11591219 {
11601220 struct ib_umad_port *port = dev_get_drvdata(dev);
....@@ -1164,10 +1224,59 @@
11641224
11651225 return sprintf(buf, "%d\n", port->port_num);
11661226 }
1167
-static DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
1227
+static DEVICE_ATTR_RO(port);
11681228
1169
-static CLASS_ATTR_STRING(abi_version, S_IRUGO,
1170
- __stringify(IB_USER_MAD_ABI_VERSION));
1229
+static struct attribute *umad_class_dev_attrs[] = {
1230
+ &dev_attr_ibdev.attr,
1231
+ &dev_attr_port.attr,
1232
+ NULL,
1233
+};
1234
+ATTRIBUTE_GROUPS(umad_class_dev);
1235
+
1236
+static char *umad_devnode(struct device *dev, umode_t *mode)
1237
+{
1238
+ return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev));
1239
+}
1240
+
1241
+static ssize_t abi_version_show(struct class *class,
1242
+ struct class_attribute *attr, char *buf)
1243
+{
1244
+ return sprintf(buf, "%d\n", IB_USER_MAD_ABI_VERSION);
1245
+}
1246
+static CLASS_ATTR_RO(abi_version);
1247
+
1248
+static struct attribute *umad_class_attrs[] = {
1249
+ &class_attr_abi_version.attr,
1250
+ NULL,
1251
+};
1252
+ATTRIBUTE_GROUPS(umad_class);
1253
+
1254
+static struct class umad_class = {
1255
+ .name = "infiniband_mad",
1256
+ .devnode = umad_devnode,
1257
+ .class_groups = umad_class_groups,
1258
+ .dev_groups = umad_class_dev_groups,
1259
+};
1260
+
1261
+static void ib_umad_release_port(struct device *device)
1262
+{
1263
+ struct ib_umad_port *port = dev_get_drvdata(device);
1264
+ struct ib_umad_device *umad_dev = port->umad_dev;
1265
+
1266
+ ib_umad_dev_put(umad_dev);
1267
+}
1268
+
1269
+static void ib_umad_init_port_dev(struct device *dev,
1270
+ struct ib_umad_port *port,
1271
+ const struct ib_device *device)
1272
+{
1273
+ device_initialize(dev);
1274
+ ib_umad_dev_get(port->umad_dev);
1275
+ dev->class = &umad_class;
1276
+ dev->parent = device->dev.parent;
1277
+ dev_set_drvdata(dev, port);
1278
+ dev->release = ib_umad_release_port;
1279
+}
11711280
11721281 static int ib_umad_init_port(struct ib_device *device, int port_num,
11731282 struct ib_umad_device *umad_dev,
....@@ -1176,12 +1285,12 @@
11761285 int devnum;
11771286 dev_t base_umad;
11781287 dev_t base_issm;
1288
+ int ret;
11791289
1180
- devnum = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS);
1181
- if (devnum >= IB_UMAD_MAX_PORTS)
1290
+ devnum = ida_alloc_max(&umad_ida, IB_UMAD_MAX_PORTS - 1, GFP_KERNEL);
1291
+ if (devnum < 0)
11821292 return -1;
11831293 port->dev_num = devnum;
1184
- set_bit(devnum, dev_map);
11851294 if (devnum >= IB_UMAD_NUM_FIXED_MINOR) {
11861295 base_umad = dynamic_umad_dev + devnum - IB_UMAD_NUM_FIXED_MINOR;
11871296 base_issm = dynamic_issm_dev + devnum - IB_UMAD_NUM_FIXED_MINOR;
....@@ -1191,63 +1300,41 @@
11911300 }
11921301
11931302 port->ib_dev = device;
1303
+ port->umad_dev = umad_dev;
11941304 port->port_num = port_num;
11951305 sema_init(&port->sm_sem, 1);
11961306 mutex_init(&port->file_mutex);
11971307 INIT_LIST_HEAD(&port->file_list);
11981308
1309
+ ib_umad_init_port_dev(&port->dev, port, device);
1310
+ port->dev.devt = base_umad;
1311
+ dev_set_name(&port->dev, "umad%d", port->dev_num);
11991312 cdev_init(&port->cdev, &umad_fops);
12001313 port->cdev.owner = THIS_MODULE;
1201
- cdev_set_parent(&port->cdev, &umad_dev->kobj);
1202
- kobject_set_name(&port->cdev.kobj, "umad%d", port->dev_num);
1203
- if (cdev_add(&port->cdev, base_umad, 1))
1314
+
1315
+ ret = cdev_device_add(&port->cdev, &port->dev);
1316
+ if (ret)
12041317 goto err_cdev;
12051318
1206
- port->dev = device_create(umad_class, device->dev.parent,
1207
- port->cdev.dev, port,
1208
- "umad%d", port->dev_num);
1209
- if (IS_ERR(port->dev))
1210
- goto err_cdev;
1211
-
1212
- if (device_create_file(port->dev, &dev_attr_ibdev))
1213
- goto err_dev;
1214
- if (device_create_file(port->dev, &dev_attr_port))
1215
- goto err_dev;
1216
-
1319
+ ib_umad_init_port_dev(&port->sm_dev, port, device);
1320
+ port->sm_dev.devt = base_issm;
1321
+ dev_set_name(&port->sm_dev, "issm%d", port->dev_num);
12171322 cdev_init(&port->sm_cdev, &umad_sm_fops);
12181323 port->sm_cdev.owner = THIS_MODULE;
1219
- cdev_set_parent(&port->sm_cdev, &umad_dev->kobj);
1220
- kobject_set_name(&port->sm_cdev.kobj, "issm%d", port->dev_num);
1221
- if (cdev_add(&port->sm_cdev, base_issm, 1))
1222
- goto err_sm_cdev;
12231324
1224
- port->sm_dev = device_create(umad_class, device->dev.parent,
1225
- port->sm_cdev.dev, port,
1226
- "issm%d", port->dev_num);
1227
- if (IS_ERR(port->sm_dev))
1228
- goto err_sm_cdev;
1229
-
1230
- if (device_create_file(port->sm_dev, &dev_attr_ibdev))
1231
- goto err_sm_dev;
1232
- if (device_create_file(port->sm_dev, &dev_attr_port))
1233
- goto err_sm_dev;
1325
+ ret = cdev_device_add(&port->sm_cdev, &port->sm_dev);
1326
+ if (ret)
1327
+ goto err_dev;
12341328
12351329 return 0;
12361330
1237
-err_sm_dev:
1238
- device_destroy(umad_class, port->sm_cdev.dev);
1239
-
1240
-err_sm_cdev:
1241
- cdev_del(&port->sm_cdev);
1242
-
12431331 err_dev:
1244
- device_destroy(umad_class, port->cdev.dev);
1245
-
1332
+ put_device(&port->sm_dev);
1333
+ cdev_device_del(&port->cdev, &port->dev);
12461334 err_cdev:
1247
- cdev_del(&port->cdev);
1248
- clear_bit(devnum, dev_map);
1249
-
1250
- return -1;
1335
+ put_device(&port->dev);
1336
+ ida_free(&umad_ida, devnum);
1337
+ return ret;
12511338 }
12521339
12531340 static void ib_umad_kill_port(struct ib_umad_port *port)
....@@ -1255,17 +1342,14 @@
12551342 struct ib_umad_file *file;
12561343 int id;
12571344
1258
- dev_set_drvdata(port->dev, NULL);
1259
- dev_set_drvdata(port->sm_dev, NULL);
1260
-
1261
- device_destroy(umad_class, port->cdev.dev);
1262
- device_destroy(umad_class, port->sm_cdev.dev);
1263
-
1264
- cdev_del(&port->cdev);
1265
- cdev_del(&port->sm_cdev);
1345
+ cdev_device_del(&port->sm_cdev, &port->sm_dev);
1346
+ cdev_device_del(&port->cdev, &port->dev);
12661347
12671348 mutex_lock(&port->file_mutex);
12681349
1350
+ /* Mark ib_dev NULL and block ioctl or other file ops to progress
1351
+ * further.
1352
+ */
12691353 port->ib_dev = NULL;
12701354
12711355 list_for_each_entry(file, &port->file_list, port_list) {
....@@ -1280,76 +1364,75 @@
12801364 }
12811365
12821366 mutex_unlock(&port->file_mutex);
1283
- clear_bit(port->dev_num, dev_map);
1367
+
1368
+ ida_free(&umad_ida, port->dev_num);
1369
+
1370
+ /* balances device_initialize() */
1371
+ put_device(&port->sm_dev);
1372
+ put_device(&port->dev);
12841373 }
12851374
1286
-static void ib_umad_add_one(struct ib_device *device)
1375
+static int ib_umad_add_one(struct ib_device *device)
12871376 {
12881377 struct ib_umad_device *umad_dev;
12891378 int s, e, i;
12901379 int count = 0;
1380
+ int ret;
12911381
12921382 s = rdma_start_port(device);
12931383 e = rdma_end_port(device);
12941384
1295
- umad_dev = kzalloc(sizeof *umad_dev +
1296
- (e - s + 1) * sizeof (struct ib_umad_port),
1297
- GFP_KERNEL);
1385
+ umad_dev = kzalloc(struct_size(umad_dev, ports, e - s + 1), GFP_KERNEL);
12981386 if (!umad_dev)
1299
- return;
1387
+ return -ENOMEM;
13001388
1301
- kobject_init(&umad_dev->kobj, &ib_umad_dev_ktype);
1302
-
1389
+ kref_init(&umad_dev->kref);
13031390 for (i = s; i <= e; ++i) {
13041391 if (!rdma_cap_ib_mad(device, i))
13051392 continue;
13061393
1307
- umad_dev->port[i - s].umad_dev = umad_dev;
1308
-
1309
- if (ib_umad_init_port(device, i, umad_dev,
1310
- &umad_dev->port[i - s]))
1394
+ ret = ib_umad_init_port(device, i, umad_dev,
1395
+ &umad_dev->ports[i - s]);
1396
+ if (ret)
13111397 goto err;
13121398
13131399 count++;
13141400 }
13151401
1316
- if (!count)
1402
+ if (!count) {
1403
+ ret = -EOPNOTSUPP;
13171404 goto free;
1405
+ }
13181406
13191407 ib_set_client_data(device, &umad_client, umad_dev);
13201408
1321
- return;
1409
+ return 0;
13221410
13231411 err:
13241412 while (--i >= s) {
13251413 if (!rdma_cap_ib_mad(device, i))
13261414 continue;
13271415
1328
- ib_umad_kill_port(&umad_dev->port[i - s]);
1416
+ ib_umad_kill_port(&umad_dev->ports[i - s]);
13291417 }
13301418 free:
1331
- kobject_put(&umad_dev->kobj);
1419
+ /* balances kref_init */
1420
+ ib_umad_dev_put(umad_dev);
1421
+ return ret;
13321422 }
13331423
13341424 static void ib_umad_remove_one(struct ib_device *device, void *client_data)
13351425 {
13361426 struct ib_umad_device *umad_dev = client_data;
1337
- int i;
1427
+ unsigned int i;
13381428
1339
- if (!umad_dev)
1340
- return;
1341
-
1342
- for (i = 0; i <= rdma_end_port(device) - rdma_start_port(device); ++i) {
1343
- if (rdma_cap_ib_mad(device, i + rdma_start_port(device)))
1344
- ib_umad_kill_port(&umad_dev->port[i]);
1429
+ rdma_for_each_port (device, i) {
1430
+ if (rdma_cap_ib_mad(device, i))
1431
+ ib_umad_kill_port(
1432
+ &umad_dev->ports[i - rdma_start_port(device)]);
13451433 }
1346
-
1347
- kobject_put(&umad_dev->kobj);
1348
-}
1349
-
1350
-static char *umad_devnode(struct device *dev, umode_t *mode)
1351
-{
1352
- return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev));
1434
+ /* balances kref_init() */
1435
+ ib_umad_dev_put(umad_dev);
13531436 }
13541437
13551438 static int __init ib_umad_init(void)
....@@ -1358,7 +1441,7 @@
13581441
13591442 ret = register_chrdev_region(base_umad_dev,
13601443 IB_UMAD_NUM_FIXED_MINOR * 2,
1361
- "infiniband_mad");
1444
+ umad_class.name);
13621445 if (ret) {
13631446 pr_err("couldn't register device number\n");
13641447 goto out;
....@@ -1366,38 +1449,33 @@
13661449
13671450 ret = alloc_chrdev_region(&dynamic_umad_dev, 0,
13681451 IB_UMAD_NUM_DYNAMIC_MINOR * 2,
1369
- "infiniband_mad");
1452
+ umad_class.name);
13701453 if (ret) {
13711454 pr_err("couldn't register dynamic device number\n");
13721455 goto out_alloc;
13731456 }
13741457 dynamic_issm_dev = dynamic_umad_dev + IB_UMAD_NUM_DYNAMIC_MINOR;
13751458
1376
- umad_class = class_create(THIS_MODULE, "infiniband_mad");
1377
- if (IS_ERR(umad_class)) {
1378
- ret = PTR_ERR(umad_class);
1459
+ ret = class_register(&umad_class);
1460
+ if (ret) {
13791461 pr_err("couldn't create class infiniband_mad\n");
13801462 goto out_chrdev;
13811463 }
13821464
1383
- umad_class->devnode = umad_devnode;
1384
-
1385
- ret = class_create_file(umad_class, &class_attr_abi_version.attr);
1386
- if (ret) {
1387
- pr_err("couldn't create abi_version attribute\n");
1388
- goto out_class;
1389
- }
1390
-
13911465 ret = ib_register_client(&umad_client);
1392
- if (ret) {
1393
- pr_err("couldn't register ib_umad client\n");
1466
+ if (ret)
13941467 goto out_class;
1395
- }
1468
+
1469
+ ret = ib_register_client(&issm_client);
1470
+ if (ret)
1471
+ goto out_client;
13961472
13971473 return 0;
13981474
1475
+out_client:
1476
+ ib_unregister_client(&umad_client);
13991477 out_class:
1400
- class_destroy(umad_class);
1478
+ class_unregister(&umad_class);
14011479
14021480 out_chrdev:
14031481 unregister_chrdev_region(dynamic_umad_dev,
....@@ -1413,8 +1491,9 @@
14131491
14141492 static void __exit ib_umad_cleanup(void)
14151493 {
1494
+ ib_unregister_client(&issm_client);
14161495 ib_unregister_client(&umad_client);
1417
- class_destroy(umad_class);
1496
+ class_unregister(&umad_class);
14181497 unregister_chrdev_region(base_umad_dev,
14191498 IB_UMAD_NUM_FIXED_MINOR * 2);
14201499 unregister_chrdev_region(dynamic_umad_dev,