diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-04 19:31:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-04 19:31:54 -0500 |
commit | ba77df570c6710c9c19b31e0e48e4bcdf31cefe8 (patch) | |
tree | 997c210135b5578982df256dd5a0140e04d972d1 /drivers/infiniband/core | |
parent | 602d4a7e2f4b843d1a67375d4d7104073495b758 (diff) | |
parent | d09e32764176b61c4afee9fd5e7fe04713bfa56f (diff) |
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
Diffstat (limited to 'drivers/infiniband/core')
-rw-r--r-- | drivers/infiniband/core/agent.c | 3 | ||||
-rw-r--r-- | drivers/infiniband/core/cm.c | 6 | ||||
-rw-r--r-- | drivers/infiniband/core/device.c | 10 | ||||
-rw-r--r-- | drivers/infiniband/core/mad.c | 31 | ||||
-rw-r--r-- | drivers/infiniband/core/sysfs.c | 6 | ||||
-rw-r--r-- | drivers/infiniband/core/ucm.c | 9 | ||||
-rw-r--r-- | drivers/infiniband/core/user_mad.c | 80 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 1 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 13 |
10 files changed, 91 insertions, 69 deletions
diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c index 0c3c6952faae..7545775d38ef 100644 --- a/drivers/infiniband/core/agent.c +++ b/drivers/infiniband/core/agent.c | |||
@@ -155,13 +155,12 @@ int ib_agent_port_open(struct ib_device *device, int port_num) | |||
155 | int ret; | 155 | int ret; |
156 | 156 | ||
157 | /* Create new device info */ | 157 | /* Create new device info */ |
158 | port_priv = kmalloc(sizeof *port_priv, GFP_KERNEL); | 158 | port_priv = kzalloc(sizeof *port_priv, GFP_KERNEL); |
159 | if (!port_priv) { | 159 | if (!port_priv) { |
160 | printk(KERN_ERR SPFX "No memory for ib_agent_port_private\n"); | 160 | printk(KERN_ERR SPFX "No memory for ib_agent_port_private\n"); |
161 | ret = -ENOMEM; | 161 | ret = -ENOMEM; |
162 | goto error1; | 162 | goto error1; |
163 | } | 163 | } |
164 | memset(port_priv, 0, sizeof *port_priv); | ||
165 | 164 | ||
166 | /* Obtain send only MAD agent for SMI QP */ | 165 | /* Obtain send only MAD agent for SMI QP */ |
167 | port_priv->agent[0] = ib_register_mad_agent(device, port_num, | 166 | port_priv->agent[0] = ib_register_mad_agent(device, port_num, |
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 580c3a2bb102..02110e00d145 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
@@ -544,11 +544,10 @@ struct ib_cm_id *ib_create_cm_id(struct ib_device *device, | |||
544 | struct cm_id_private *cm_id_priv; | 544 | struct cm_id_private *cm_id_priv; |
545 | int ret; | 545 | int ret; |
546 | 546 | ||
547 | cm_id_priv = kmalloc(sizeof *cm_id_priv, GFP_KERNEL); | 547 | cm_id_priv = kzalloc(sizeof *cm_id_priv, GFP_KERNEL); |
548 | if (!cm_id_priv) | 548 | if (!cm_id_priv) |
549 | return ERR_PTR(-ENOMEM); | 549 | return ERR_PTR(-ENOMEM); |
550 | 550 | ||
551 | memset(cm_id_priv, 0, sizeof *cm_id_priv); | ||
552 | cm_id_priv->id.state = IB_CM_IDLE; | 551 | cm_id_priv->id.state = IB_CM_IDLE; |
553 | cm_id_priv->id.device = device; | 552 | cm_id_priv->id.device = device; |
554 | cm_id_priv->id.cm_handler = cm_handler; | 553 | cm_id_priv->id.cm_handler = cm_handler; |
@@ -621,10 +620,9 @@ static struct cm_timewait_info * cm_create_timewait_info(__be32 local_id) | |||
621 | { | 620 | { |
622 | struct cm_timewait_info *timewait_info; | 621 | struct cm_timewait_info *timewait_info; |
623 | 622 | ||
624 | timewait_info = kmalloc(sizeof *timewait_info, GFP_KERNEL); | 623 | timewait_info = kzalloc(sizeof *timewait_info, GFP_KERNEL); |
625 | if (!timewait_info) | 624 | if (!timewait_info) |
626 | return ERR_PTR(-ENOMEM); | 625 | return ERR_PTR(-ENOMEM); |
627 | memset(timewait_info, 0, sizeof *timewait_info); | ||
628 | 626 | ||
629 | timewait_info->work.local_id = local_id; | 627 | timewait_info->work.local_id = local_id; |
630 | INIT_WORK(&timewait_info->work.work, cm_work_handler, | 628 | INIT_WORK(&timewait_info->work.work, cm_work_handler, |
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 5a6e44976405..e169e798354b 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c | |||
@@ -161,17 +161,9 @@ static int alloc_name(char *name) | |||
161 | */ | 161 | */ |
162 | struct ib_device *ib_alloc_device(size_t size) | 162 | struct ib_device *ib_alloc_device(size_t size) |
163 | { | 163 | { |
164 | void *dev; | ||
165 | |||
166 | BUG_ON(size < sizeof (struct ib_device)); | 164 | BUG_ON(size < sizeof (struct ib_device)); |
167 | 165 | ||
168 | dev = kmalloc(size, GFP_KERNEL); | 166 | return kzalloc(size, GFP_KERNEL); |
169 | if (!dev) | ||
170 | return NULL; | ||
171 | |||
172 | memset(dev, 0, size); | ||
173 | |||
174 | return dev; | ||
175 | } | 167 | } |
176 | EXPORT_SYMBOL(ib_alloc_device); | 168 | EXPORT_SYMBOL(ib_alloc_device); |
177 | 169 | ||
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 88f9f8c9eacc..3d8175e5f054 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
@@ -255,12 +255,11 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, | |||
255 | } | 255 | } |
256 | 256 | ||
257 | /* Allocate structures */ | 257 | /* Allocate structures */ |
258 | mad_agent_priv = kmalloc(sizeof *mad_agent_priv, GFP_KERNEL); | 258 | mad_agent_priv = kzalloc(sizeof *mad_agent_priv, GFP_KERNEL); |
259 | if (!mad_agent_priv) { | 259 | if (!mad_agent_priv) { |
260 | ret = ERR_PTR(-ENOMEM); | 260 | ret = ERR_PTR(-ENOMEM); |
261 | goto error1; | 261 | goto error1; |
262 | } | 262 | } |
263 | memset(mad_agent_priv, 0, sizeof *mad_agent_priv); | ||
264 | 263 | ||
265 | mad_agent_priv->agent.mr = ib_get_dma_mr(port_priv->qp_info[qpn].qp->pd, | 264 | mad_agent_priv->agent.mr = ib_get_dma_mr(port_priv->qp_info[qpn].qp->pd, |
266 | IB_ACCESS_LOCAL_WRITE); | 265 | IB_ACCESS_LOCAL_WRITE); |
@@ -448,14 +447,13 @@ struct ib_mad_agent *ib_register_mad_snoop(struct ib_device *device, | |||
448 | goto error1; | 447 | goto error1; |
449 | } | 448 | } |
450 | /* Allocate structures */ | 449 | /* Allocate structures */ |
451 | mad_snoop_priv = kmalloc(sizeof *mad_snoop_priv, GFP_KERNEL); | 450 | mad_snoop_priv = kzalloc(sizeof *mad_snoop_priv, GFP_KERNEL); |
452 | if (!mad_snoop_priv) { | 451 | if (!mad_snoop_priv) { |
453 | ret = ERR_PTR(-ENOMEM); | 452 | ret = ERR_PTR(-ENOMEM); |
454 | goto error1; | 453 | goto error1; |
455 | } | 454 | } |
456 | 455 | ||
457 | /* Now, fill in the various structures */ | 456 | /* Now, fill in the various structures */ |
458 | memset(mad_snoop_priv, 0, sizeof *mad_snoop_priv); | ||
459 | mad_snoop_priv->qp_info = &port_priv->qp_info[qpn]; | 457 | mad_snoop_priv->qp_info = &port_priv->qp_info[qpn]; |
460 | mad_snoop_priv->agent.device = device; | 458 | mad_snoop_priv->agent.device = device; |
461 | mad_snoop_priv->agent.recv_handler = recv_handler; | 459 | mad_snoop_priv->agent.recv_handler = recv_handler; |
@@ -794,10 +792,9 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent, | |||
794 | (!rmpp_active && buf_size > sizeof(struct ib_mad))) | 792 | (!rmpp_active && buf_size > sizeof(struct ib_mad))) |
795 | return ERR_PTR(-EINVAL); | 793 | return ERR_PTR(-EINVAL); |
796 | 794 | ||
797 | buf = kmalloc(sizeof *mad_send_wr + buf_size, gfp_mask); | 795 | buf = kzalloc(sizeof *mad_send_wr + buf_size, gfp_mask); |
798 | if (!buf) | 796 | if (!buf) |
799 | return ERR_PTR(-ENOMEM); | 797 | return ERR_PTR(-ENOMEM); |
800 | memset(buf, 0, sizeof *mad_send_wr + buf_size); | ||
801 | 798 | ||
802 | mad_send_wr = buf + buf_size; | 799 | mad_send_wr = buf + buf_size; |
803 | mad_send_wr->send_buf.mad = buf; | 800 | mad_send_wr->send_buf.mad = buf; |
@@ -1039,14 +1036,12 @@ static int method_in_use(struct ib_mad_mgmt_method_table **method, | |||
1039 | static int allocate_method_table(struct ib_mad_mgmt_method_table **method) | 1036 | static int allocate_method_table(struct ib_mad_mgmt_method_table **method) |
1040 | { | 1037 | { |
1041 | /* Allocate management method table */ | 1038 | /* Allocate management method table */ |
1042 | *method = kmalloc(sizeof **method, GFP_ATOMIC); | 1039 | *method = kzalloc(sizeof **method, GFP_ATOMIC); |
1043 | if (!*method) { | 1040 | if (!*method) { |
1044 | printk(KERN_ERR PFX "No memory for " | 1041 | printk(KERN_ERR PFX "No memory for " |
1045 | "ib_mad_mgmt_method_table\n"); | 1042 | "ib_mad_mgmt_method_table\n"); |
1046 | return -ENOMEM; | 1043 | return -ENOMEM; |
1047 | } | 1044 | } |
1048 | /* Clear management method table */ | ||
1049 | memset(*method, 0, sizeof **method); | ||
1050 | 1045 | ||
1051 | return 0; | 1046 | return 0; |
1052 | } | 1047 | } |
@@ -1137,15 +1132,14 @@ static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req, | |||
1137 | class = &port_priv->version[mad_reg_req->mgmt_class_version].class; | 1132 | class = &port_priv->version[mad_reg_req->mgmt_class_version].class; |
1138 | if (!*class) { | 1133 | if (!*class) { |
1139 | /* Allocate management class table for "new" class version */ | 1134 | /* Allocate management class table for "new" class version */ |
1140 | *class = kmalloc(sizeof **class, GFP_ATOMIC); | 1135 | *class = kzalloc(sizeof **class, GFP_ATOMIC); |
1141 | if (!*class) { | 1136 | if (!*class) { |
1142 | printk(KERN_ERR PFX "No memory for " | 1137 | printk(KERN_ERR PFX "No memory for " |
1143 | "ib_mad_mgmt_class_table\n"); | 1138 | "ib_mad_mgmt_class_table\n"); |
1144 | ret = -ENOMEM; | 1139 | ret = -ENOMEM; |
1145 | goto error1; | 1140 | goto error1; |
1146 | } | 1141 | } |
1147 | /* Clear management class table */ | 1142 | |
1148 | memset(*class, 0, sizeof(**class)); | ||
1149 | /* Allocate method table for this management class */ | 1143 | /* Allocate method table for this management class */ |
1150 | method = &(*class)->method_table[mgmt_class]; | 1144 | method = &(*class)->method_table[mgmt_class]; |
1151 | if ((ret = allocate_method_table(method))) | 1145 | if ((ret = allocate_method_table(method))) |
@@ -1209,25 +1203,24 @@ static int add_oui_reg_req(struct ib_mad_reg_req *mad_reg_req, | |||
1209 | mad_reg_req->mgmt_class_version].vendor; | 1203 | mad_reg_req->mgmt_class_version].vendor; |
1210 | if (!*vendor_table) { | 1204 | if (!*vendor_table) { |
1211 | /* Allocate mgmt vendor class table for "new" class version */ | 1205 | /* Allocate mgmt vendor class table for "new" class version */ |
1212 | vendor = kmalloc(sizeof *vendor, GFP_ATOMIC); | 1206 | vendor = kzalloc(sizeof *vendor, GFP_ATOMIC); |
1213 | if (!vendor) { | 1207 | if (!vendor) { |
1214 | printk(KERN_ERR PFX "No memory for " | 1208 | printk(KERN_ERR PFX "No memory for " |
1215 | "ib_mad_mgmt_vendor_class_table\n"); | 1209 | "ib_mad_mgmt_vendor_class_table\n"); |
1216 | goto error1; | 1210 | goto error1; |
1217 | } | 1211 | } |
1218 | /* Clear management vendor class table */ | 1212 | |
1219 | memset(vendor, 0, sizeof(*vendor)); | ||
1220 | *vendor_table = vendor; | 1213 | *vendor_table = vendor; |
1221 | } | 1214 | } |
1222 | if (!(*vendor_table)->vendor_class[vclass]) { | 1215 | if (!(*vendor_table)->vendor_class[vclass]) { |
1223 | /* Allocate table for this management vendor class */ | 1216 | /* Allocate table for this management vendor class */ |
1224 | vendor_class = kmalloc(sizeof *vendor_class, GFP_ATOMIC); | 1217 | vendor_class = kzalloc(sizeof *vendor_class, GFP_ATOMIC); |
1225 | if (!vendor_class) { | 1218 | if (!vendor_class) { |
1226 | printk(KERN_ERR PFX "No memory for " | 1219 | printk(KERN_ERR PFX "No memory for " |
1227 | "ib_mad_mgmt_vendor_class\n"); | 1220 | "ib_mad_mgmt_vendor_class\n"); |
1228 | goto error2; | 1221 | goto error2; |
1229 | } | 1222 | } |
1230 | memset(vendor_class, 0, sizeof(*vendor_class)); | 1223 | |
1231 | (*vendor_table)->vendor_class[vclass] = vendor_class; | 1224 | (*vendor_table)->vendor_class[vclass] = vendor_class; |
1232 | } | 1225 | } |
1233 | for (i = 0; i < MAX_MGMT_OUI; i++) { | 1226 | for (i = 0; i < MAX_MGMT_OUI; i++) { |
@@ -2524,12 +2517,12 @@ static int ib_mad_port_open(struct ib_device *device, | |||
2524 | char name[sizeof "ib_mad123"]; | 2517 | char name[sizeof "ib_mad123"]; |
2525 | 2518 | ||
2526 | /* Create new device info */ | 2519 | /* Create new device info */ |
2527 | port_priv = kmalloc(sizeof *port_priv, GFP_KERNEL); | 2520 | port_priv = kzalloc(sizeof *port_priv, GFP_KERNEL); |
2528 | if (!port_priv) { | 2521 | if (!port_priv) { |
2529 | printk(KERN_ERR PFX "No memory for ib_mad_port_private\n"); | 2522 | printk(KERN_ERR PFX "No memory for ib_mad_port_private\n"); |
2530 | return -ENOMEM; | 2523 | return -ENOMEM; |
2531 | } | 2524 | } |
2532 | memset(port_priv, 0, sizeof *port_priv); | 2525 | |
2533 | port_priv->device = device; | 2526 | port_priv->device = device; |
2534 | port_priv->port_num = port_num; | 2527 | port_priv->port_num = port_num; |
2535 | spin_lock_init(&port_priv->reg_lock); | 2528 | spin_lock_init(&port_priv->reg_lock); |
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 7ce7a6c782fa..b8120650e711 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c | |||
@@ -307,14 +307,13 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr, | |||
307 | if (!p->ibdev->process_mad) | 307 | if (!p->ibdev->process_mad) |
308 | return sprintf(buf, "N/A (no PMA)\n"); | 308 | return sprintf(buf, "N/A (no PMA)\n"); |
309 | 309 | ||
310 | in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); | 310 | in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); |
311 | out_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); | 311 | out_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); |
312 | if (!in_mad || !out_mad) { | 312 | if (!in_mad || !out_mad) { |
313 | ret = -ENOMEM; | 313 | ret = -ENOMEM; |
314 | goto out; | 314 | goto out; |
315 | } | 315 | } |
316 | 316 | ||
317 | memset(in_mad, 0, sizeof *in_mad); | ||
318 | in_mad->mad_hdr.base_version = 1; | 317 | in_mad->mad_hdr.base_version = 1; |
319 | in_mad->mad_hdr.mgmt_class = IB_MGMT_CLASS_PERF_MGMT; | 318 | in_mad->mad_hdr.mgmt_class = IB_MGMT_CLASS_PERF_MGMT; |
320 | in_mad->mad_hdr.class_version = 1; | 319 | in_mad->mad_hdr.class_version = 1; |
@@ -508,10 +507,9 @@ static int add_port(struct ib_device *device, int port_num) | |||
508 | if (ret) | 507 | if (ret) |
509 | return ret; | 508 | return ret; |
510 | 509 | ||
511 | p = kmalloc(sizeof *p, GFP_KERNEL); | 510 | p = kzalloc(sizeof *p, GFP_KERNEL); |
512 | if (!p) | 511 | if (!p) |
513 | return -ENOMEM; | 512 | return -ENOMEM; |
514 | memset(p, 0, sizeof *p); | ||
515 | 513 | ||
516 | p->ibdev = device; | 514 | p->ibdev = device; |
517 | p->port_num = port_num; | 515 | p->port_num = port_num; |
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index 28477565ecba..6e15787d1de1 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c | |||
@@ -172,11 +172,10 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file) | |||
172 | struct ib_ucm_context *ctx; | 172 | struct ib_ucm_context *ctx; |
173 | int result; | 173 | int result; |
174 | 174 | ||
175 | ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); | 175 | ctx = kzalloc(sizeof *ctx, GFP_KERNEL); |
176 | if (!ctx) | 176 | if (!ctx) |
177 | return NULL; | 177 | return NULL; |
178 | 178 | ||
179 | memset(ctx, 0, sizeof *ctx); | ||
180 | atomic_set(&ctx->ref, 1); | 179 | atomic_set(&ctx->ref, 1); |
181 | init_waitqueue_head(&ctx->wait); | 180 | init_waitqueue_head(&ctx->wait); |
182 | ctx->file = file; | 181 | ctx->file = file; |
@@ -386,11 +385,10 @@ static int ib_ucm_event_handler(struct ib_cm_id *cm_id, | |||
386 | 385 | ||
387 | ctx = cm_id->context; | 386 | ctx = cm_id->context; |
388 | 387 | ||
389 | uevent = kmalloc(sizeof(*uevent), GFP_KERNEL); | 388 | uevent = kzalloc(sizeof *uevent, GFP_KERNEL); |
390 | if (!uevent) | 389 | if (!uevent) |
391 | goto err1; | 390 | goto err1; |
392 | 391 | ||
393 | memset(uevent, 0, sizeof(*uevent)); | ||
394 | uevent->ctx = ctx; | 392 | uevent->ctx = ctx; |
395 | uevent->cm_id = cm_id; | 393 | uevent->cm_id = cm_id; |
396 | uevent->resp.uid = ctx->uid; | 394 | uevent->resp.uid = ctx->uid; |
@@ -1345,11 +1343,10 @@ static void ib_ucm_add_one(struct ib_device *device) | |||
1345 | if (!device->alloc_ucontext) | 1343 | if (!device->alloc_ucontext) |
1346 | return; | 1344 | return; |
1347 | 1345 | ||
1348 | ucm_dev = kmalloc(sizeof *ucm_dev, GFP_KERNEL); | 1346 | ucm_dev = kzalloc(sizeof *ucm_dev, GFP_KERNEL); |
1349 | if (!ucm_dev) | 1347 | if (!ucm_dev) |
1350 | return; | 1348 | return; |
1351 | 1349 | ||
1352 | memset(ucm_dev, 0, sizeof *ucm_dev); | ||
1353 | ucm_dev->ib_dev = device; | 1350 | ucm_dev->ib_dev = device; |
1354 | 1351 | ||
1355 | ucm_dev->devnum = find_first_zero_bit(dev_map, IB_UCM_MAX_DEVICES); | 1352 | ucm_dev->devnum = find_first_zero_bit(dev_map, IB_UCM_MAX_DEVICES); |
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 97128e25f78b..aed5ca23fb22 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c | |||
@@ -94,6 +94,9 @@ struct ib_umad_port { | |||
94 | struct class_device *sm_class_dev; | 94 | struct class_device *sm_class_dev; |
95 | struct semaphore sm_sem; | 95 | struct semaphore sm_sem; |
96 | 96 | ||
97 | struct rw_semaphore mutex; | ||
98 | struct list_head file_list; | ||
99 | |||
97 | struct ib_device *ib_dev; | 100 | struct ib_device *ib_dev; |
98 | struct ib_umad_device *umad_dev; | 101 | struct ib_umad_device *umad_dev; |
99 | int dev_num; | 102 | int dev_num; |
@@ -108,10 +111,10 @@ struct ib_umad_device { | |||
108 | 111 | ||
109 | struct ib_umad_file { | 112 | struct ib_umad_file { |
110 | struct ib_umad_port *port; | 113 | struct ib_umad_port *port; |
111 | spinlock_t recv_lock; | ||
112 | struct list_head recv_list; | 114 | struct list_head recv_list; |
115 | struct list_head port_list; | ||
116 | spinlock_t recv_lock; | ||
113 | wait_queue_head_t recv_wait; | 117 | wait_queue_head_t recv_wait; |
114 | struct rw_semaphore agent_mutex; | ||
115 | struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS]; | 118 | struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS]; |
116 | struct ib_mr *mr[IB_UMAD_MAX_AGENTS]; | 119 | struct ib_mr *mr[IB_UMAD_MAX_AGENTS]; |
117 | }; | 120 | }; |
@@ -148,7 +151,7 @@ static int queue_packet(struct ib_umad_file *file, | |||
148 | { | 151 | { |
149 | int ret = 1; | 152 | int ret = 1; |
150 | 153 | ||
151 | down_read(&file->agent_mutex); | 154 | down_read(&file->port->mutex); |
152 | for (packet->mad.hdr.id = 0; | 155 | for (packet->mad.hdr.id = 0; |
153 | packet->mad.hdr.id < IB_UMAD_MAX_AGENTS; | 156 | packet->mad.hdr.id < IB_UMAD_MAX_AGENTS; |
154 | packet->mad.hdr.id++) | 157 | packet->mad.hdr.id++) |
@@ -161,7 +164,7 @@ static int queue_packet(struct ib_umad_file *file, | |||
161 | break; | 164 | break; |
162 | } | 165 | } |
163 | 166 | ||
164 | up_read(&file->agent_mutex); | 167 | up_read(&file->port->mutex); |
165 | 168 | ||
166 | return ret; | 169 | return ret; |
167 | } | 170 | } |
@@ -322,7 +325,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
322 | goto err; | 325 | goto err; |
323 | } | 326 | } |
324 | 327 | ||
325 | down_read(&file->agent_mutex); | 328 | down_read(&file->port->mutex); |
326 | 329 | ||
327 | agent = file->agent[packet->mad.hdr.id]; | 330 | agent = file->agent[packet->mad.hdr.id]; |
328 | if (!agent) { | 331 | if (!agent) { |
@@ -419,7 +422,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
419 | if (ret) | 422 | if (ret) |
420 | goto err_msg; | 423 | goto err_msg; |
421 | 424 | ||
422 | up_read(&file->agent_mutex); | 425 | up_read(&file->port->mutex); |
423 | 426 | ||
424 | return count; | 427 | return count; |
425 | 428 | ||
@@ -430,7 +433,7 @@ err_ah: | |||
430 | ib_destroy_ah(ah); | 433 | ib_destroy_ah(ah); |
431 | 434 | ||
432 | err_up: | 435 | err_up: |
433 | up_read(&file->agent_mutex); | 436 | up_read(&file->port->mutex); |
434 | 437 | ||
435 | err: | 438 | err: |
436 | kfree(packet); | 439 | kfree(packet); |
@@ -460,7 +463,12 @@ static int ib_umad_reg_agent(struct ib_umad_file *file, unsigned long arg) | |||
460 | int agent_id; | 463 | int agent_id; |
461 | int ret; | 464 | int ret; |
462 | 465 | ||
463 | down_write(&file->agent_mutex); | 466 | down_write(&file->port->mutex); |
467 | |||
468 | if (!file->port->ib_dev) { | ||
469 | ret = -EPIPE; | ||
470 | goto out; | ||
471 | } | ||
464 | 472 | ||
465 | if (copy_from_user(&ureq, (void __user *) arg, sizeof ureq)) { | 473 | if (copy_from_user(&ureq, (void __user *) arg, sizeof ureq)) { |
466 | ret = -EFAULT; | 474 | ret = -EFAULT; |
@@ -522,7 +530,7 @@ err: | |||
522 | ib_unregister_mad_agent(agent); | 530 | ib_unregister_mad_agent(agent); |
523 | 531 | ||
524 | out: | 532 | out: |
525 | up_write(&file->agent_mutex); | 533 | up_write(&file->port->mutex); |
526 | return ret; | 534 | return ret; |
527 | } | 535 | } |
528 | 536 | ||
@@ -531,7 +539,7 @@ static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg) | |||
531 | u32 id; | 539 | u32 id; |
532 | int ret = 0; | 540 | int ret = 0; |
533 | 541 | ||
534 | down_write(&file->agent_mutex); | 542 | down_write(&file->port->mutex); |
535 | 543 | ||
536 | if (get_user(id, (u32 __user *) arg)) { | 544 | if (get_user(id, (u32 __user *) arg)) { |
537 | ret = -EFAULT; | 545 | ret = -EFAULT; |
@@ -548,7 +556,7 @@ static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg) | |||
548 | file->agent[id] = NULL; | 556 | file->agent[id] = NULL; |
549 | 557 | ||
550 | out: | 558 | out: |
551 | up_write(&file->agent_mutex); | 559 | up_write(&file->port->mutex); |
552 | return ret; | 560 | return ret; |
553 | } | 561 | } |
554 | 562 | ||
@@ -569,6 +577,7 @@ static int ib_umad_open(struct inode *inode, struct file *filp) | |||
569 | { | 577 | { |
570 | struct ib_umad_port *port; | 578 | struct ib_umad_port *port; |
571 | struct ib_umad_file *file; | 579 | struct ib_umad_file *file; |
580 | int ret = 0; | ||
572 | 581 | ||
573 | spin_lock(&port_lock); | 582 | spin_lock(&port_lock); |
574 | port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE]; | 583 | port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE]; |
@@ -579,21 +588,32 @@ static int ib_umad_open(struct inode *inode, struct file *filp) | |||
579 | if (!port) | 588 | if (!port) |
580 | return -ENXIO; | 589 | return -ENXIO; |
581 | 590 | ||
591 | down_write(&port->mutex); | ||
592 | |||
593 | if (!port->ib_dev) { | ||
594 | ret = -ENXIO; | ||
595 | goto out; | ||
596 | } | ||
597 | |||
582 | file = kzalloc(sizeof *file, GFP_KERNEL); | 598 | file = kzalloc(sizeof *file, GFP_KERNEL); |
583 | if (!file) { | 599 | if (!file) { |
584 | kref_put(&port->umad_dev->ref, ib_umad_release_dev); | 600 | kref_put(&port->umad_dev->ref, ib_umad_release_dev); |
585 | return -ENOMEM; | 601 | ret = -ENOMEM; |
602 | goto out; | ||
586 | } | 603 | } |
587 | 604 | ||
588 | spin_lock_init(&file->recv_lock); | 605 | spin_lock_init(&file->recv_lock); |
589 | init_rwsem(&file->agent_mutex); | ||
590 | INIT_LIST_HEAD(&file->recv_list); | 606 | INIT_LIST_HEAD(&file->recv_list); |
591 | init_waitqueue_head(&file->recv_wait); | 607 | init_waitqueue_head(&file->recv_wait); |
592 | 608 | ||
593 | file->port = port; | 609 | file->port = port; |
594 | filp->private_data = file; | 610 | filp->private_data = file; |
595 | 611 | ||
596 | return 0; | 612 | list_add_tail(&file->port_list, &port->file_list); |
613 | |||
614 | out: | ||
615 | up_write(&port->mutex); | ||
616 | return ret; | ||
597 | } | 617 | } |
598 | 618 | ||
599 | static int ib_umad_close(struct inode *inode, struct file *filp) | 619 | static int ib_umad_close(struct inode *inode, struct file *filp) |
@@ -603,6 +623,7 @@ static int ib_umad_close(struct inode *inode, struct file *filp) | |||
603 | struct ib_umad_packet *packet, *tmp; | 623 | struct ib_umad_packet *packet, *tmp; |
604 | int i; | 624 | int i; |
605 | 625 | ||
626 | down_write(&file->port->mutex); | ||
606 | for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i) | 627 | for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i) |
607 | if (file->agent[i]) { | 628 | if (file->agent[i]) { |
608 | ib_dereg_mr(file->mr[i]); | 629 | ib_dereg_mr(file->mr[i]); |
@@ -612,6 +633,9 @@ static int ib_umad_close(struct inode *inode, struct file *filp) | |||
612 | list_for_each_entry_safe(packet, tmp, &file->recv_list, list) | 633 | list_for_each_entry_safe(packet, tmp, &file->recv_list, list) |
613 | kfree(packet); | 634 | kfree(packet); |
614 | 635 | ||
636 | list_del(&file->port_list); | ||
637 | up_write(&file->port->mutex); | ||
638 | |||
615 | kfree(file); | 639 | kfree(file); |
616 | 640 | ||
617 | kref_put(&dev->ref, ib_umad_release_dev); | 641 | kref_put(&dev->ref, ib_umad_release_dev); |
@@ -680,9 +704,13 @@ static int ib_umad_sm_close(struct inode *inode, struct file *filp) | |||
680 | struct ib_port_modify props = { | 704 | struct ib_port_modify props = { |
681 | .clr_port_cap_mask = IB_PORT_SM | 705 | .clr_port_cap_mask = IB_PORT_SM |
682 | }; | 706 | }; |
683 | int ret; | 707 | int ret = 0; |
708 | |||
709 | down_write(&port->mutex); | ||
710 | if (port->ib_dev) | ||
711 | ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props); | ||
712 | up_write(&port->mutex); | ||
684 | 713 | ||
685 | ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props); | ||
686 | up(&port->sm_sem); | 714 | up(&port->sm_sem); |
687 | 715 | ||
688 | kref_put(&port->umad_dev->ref, ib_umad_release_dev); | 716 | kref_put(&port->umad_dev->ref, ib_umad_release_dev); |
@@ -745,6 +773,8 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, | |||
745 | port->ib_dev = device; | 773 | port->ib_dev = device; |
746 | port->port_num = port_num; | 774 | port->port_num = port_num; |
747 | init_MUTEX(&port->sm_sem); | 775 | init_MUTEX(&port->sm_sem); |
776 | init_rwsem(&port->mutex); | ||
777 | INIT_LIST_HEAD(&port->file_list); | ||
748 | 778 | ||
749 | port->dev = cdev_alloc(); | 779 | port->dev = cdev_alloc(); |
750 | if (!port->dev) | 780 | if (!port->dev) |
@@ -813,6 +843,9 @@ err_cdev: | |||
813 | 843 | ||
814 | static void ib_umad_kill_port(struct ib_umad_port *port) | 844 | static void ib_umad_kill_port(struct ib_umad_port *port) |
815 | { | 845 | { |
846 | struct ib_umad_file *file; | ||
847 | int id; | ||
848 | |||
816 | class_set_devdata(port->class_dev, NULL); | 849 | class_set_devdata(port->class_dev, NULL); |
817 | class_set_devdata(port->sm_class_dev, NULL); | 850 | class_set_devdata(port->sm_class_dev, NULL); |
818 | 851 | ||
@@ -826,6 +859,21 @@ static void ib_umad_kill_port(struct ib_umad_port *port) | |||
826 | umad_port[port->dev_num] = NULL; | 859 | umad_port[port->dev_num] = NULL; |
827 | spin_unlock(&port_lock); | 860 | spin_unlock(&port_lock); |
828 | 861 | ||
862 | down_write(&port->mutex); | ||
863 | |||
864 | port->ib_dev = NULL; | ||
865 | |||
866 | list_for_each_entry(file, &port->file_list, port_list) | ||
867 | for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id) { | ||
868 | if (!file->agent[id]) | ||
869 | continue; | ||
870 | ib_dereg_mr(file->mr[id]); | ||
871 | ib_unregister_mad_agent(file->agent[id]); | ||
872 | file->agent[id] = NULL; | ||
873 | } | ||
874 | |||
875 | up_write(&port->mutex); | ||
876 | |||
829 | clear_bit(port->dev_num, dev_map); | 877 | clear_bit(port->dev_num, dev_map); |
830 | } | 878 | } |
831 | 879 | ||
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 031cdf3c066d..ecb830127865 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
@@ -113,6 +113,7 @@ struct ib_uevent_object { | |||
113 | 113 | ||
114 | struct ib_ucq_object { | 114 | struct ib_ucq_object { |
115 | struct ib_uobject uobject; | 115 | struct ib_uobject uobject; |
116 | struct ib_uverbs_file *uverbs_file; | ||
116 | struct list_head comp_list; | 117 | struct list_head comp_list; |
117 | struct list_head async_list; | 118 | struct list_head async_list; |
118 | u32 comp_events_reported; | 119 | u32 comp_events_reported; |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 8c89abc8c764..63a74151c60b 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -602,6 +602,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, | |||
602 | 602 | ||
603 | uobj->uobject.user_handle = cmd.user_handle; | 603 | uobj->uobject.user_handle = cmd.user_handle; |
604 | uobj->uobject.context = file->ucontext; | 604 | uobj->uobject.context = file->ucontext; |
605 | uobj->uverbs_file = file; | ||
605 | uobj->comp_events_reported = 0; | 606 | uobj->comp_events_reported = 0; |
606 | uobj->async_events_reported = 0; | 607 | uobj->async_events_reported = 0; |
607 | INIT_LIST_HEAD(&uobj->comp_list); | 608 | INIT_LIST_HEAD(&uobj->comp_list); |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 0eb38f479b39..de6581d7cb8d 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -442,13 +442,10 @@ static void ib_uverbs_async_handler(struct ib_uverbs_file *file, | |||
442 | 442 | ||
443 | void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr) | 443 | void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr) |
444 | { | 444 | { |
445 | struct ib_uverbs_event_file *ev_file = context_ptr; | 445 | struct ib_ucq_object *uobj = container_of(event->element.cq->uobject, |
446 | struct ib_ucq_object *uobj; | 446 | struct ib_ucq_object, uobject); |
447 | 447 | ||
448 | uobj = container_of(event->element.cq->uobject, | 448 | ib_uverbs_async_handler(uobj->uverbs_file, uobj->uobject.user_handle, |
449 | struct ib_ucq_object, uobject); | ||
450 | |||
451 | ib_uverbs_async_handler(ev_file->uverbs_file, uobj->uobject.user_handle, | ||
452 | event->event, &uobj->async_list, | 449 | event->event, &uobj->async_list, |
453 | &uobj->async_events_reported); | 450 | &uobj->async_events_reported); |
454 | 451 | ||
@@ -728,12 +725,10 @@ static void ib_uverbs_add_one(struct ib_device *device) | |||
728 | if (!device->alloc_ucontext) | 725 | if (!device->alloc_ucontext) |
729 | return; | 726 | return; |
730 | 727 | ||
731 | uverbs_dev = kmalloc(sizeof *uverbs_dev, GFP_KERNEL); | 728 | uverbs_dev = kzalloc(sizeof *uverbs_dev, GFP_KERNEL); |
732 | if (!uverbs_dev) | 729 | if (!uverbs_dev) |
733 | return; | 730 | return; |
734 | 731 | ||
735 | memset(uverbs_dev, 0, sizeof *uverbs_dev); | ||
736 | |||
737 | kref_init(&uverbs_dev->ref); | 732 | kref_init(&uverbs_dev->ref); |
738 | 733 | ||
739 | spin_lock(&map_lock); | 734 | spin_lock(&map_lock); |