diff options
| -rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index e3c2c5b4297f..767000811cf9 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
| @@ -130,6 +130,7 @@ static void srp_send_completion(struct ib_cq *cq, void *target_ptr); | |||
| 130 | static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event); | 130 | static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event); |
| 131 | 131 | ||
| 132 | static struct scsi_transport_template *ib_srp_transport_template; | 132 | static struct scsi_transport_template *ib_srp_transport_template; |
| 133 | static struct workqueue_struct *srp_remove_wq; | ||
| 133 | 134 | ||
| 134 | static struct ib_client srp_client = { | 135 | static struct ib_client srp_client = { |
| 135 | .name = "srp", | 136 | .name = "srp", |
| @@ -731,7 +732,7 @@ static bool srp_queue_remove_work(struct srp_target_port *target) | |||
| 731 | spin_unlock_irq(&target->lock); | 732 | spin_unlock_irq(&target->lock); |
| 732 | 733 | ||
| 733 | if (changed) | 734 | if (changed) |
| 734 | queue_work(system_long_wq, &target->remove_work); | 735 | queue_work(srp_remove_wq, &target->remove_work); |
| 735 | 736 | ||
| 736 | return changed; | 737 | return changed; |
| 737 | } | 738 | } |
| @@ -3261,9 +3262,10 @@ static void srp_remove_one(struct ib_device *device) | |||
| 3261 | spin_unlock(&host->target_lock); | 3262 | spin_unlock(&host->target_lock); |
| 3262 | 3263 | ||
| 3263 | /* | 3264 | /* |
| 3264 | * Wait for target port removal tasks. | 3265 | * Wait for tl_err and target port removal tasks. |
| 3265 | */ | 3266 | */ |
| 3266 | flush_workqueue(system_long_wq); | 3267 | flush_workqueue(system_long_wq); |
| 3268 | flush_workqueue(srp_remove_wq); | ||
| 3267 | 3269 | ||
| 3268 | kfree(host); | 3270 | kfree(host); |
| 3269 | } | 3271 | } |
| @@ -3313,16 +3315,22 @@ static int __init srp_init_module(void) | |||
| 3313 | indirect_sg_entries = cmd_sg_entries; | 3315 | indirect_sg_entries = cmd_sg_entries; |
| 3314 | } | 3316 | } |
| 3315 | 3317 | ||
| 3318 | srp_remove_wq = create_workqueue("srp_remove"); | ||
| 3319 | if (IS_ERR(srp_remove_wq)) { | ||
| 3320 | ret = PTR_ERR(srp_remove_wq); | ||
| 3321 | goto out; | ||
| 3322 | } | ||
| 3323 | |||
| 3324 | ret = -ENOMEM; | ||
| 3316 | ib_srp_transport_template = | 3325 | ib_srp_transport_template = |
| 3317 | srp_attach_transport(&ib_srp_transport_functions); | 3326 | srp_attach_transport(&ib_srp_transport_functions); |
| 3318 | if (!ib_srp_transport_template) | 3327 | if (!ib_srp_transport_template) |
| 3319 | return -ENOMEM; | 3328 | goto destroy_wq; |
| 3320 | 3329 | ||
| 3321 | ret = class_register(&srp_class); | 3330 | ret = class_register(&srp_class); |
| 3322 | if (ret) { | 3331 | if (ret) { |
| 3323 | pr_err("couldn't register class infiniband_srp\n"); | 3332 | pr_err("couldn't register class infiniband_srp\n"); |
| 3324 | srp_release_transport(ib_srp_transport_template); | 3333 | goto release_tr; |
| 3325 | return ret; | ||
| 3326 | } | 3334 | } |
| 3327 | 3335 | ||
| 3328 | ib_sa_register_client(&srp_sa_client); | 3336 | ib_sa_register_client(&srp_sa_client); |
| @@ -3330,13 +3338,22 @@ static int __init srp_init_module(void) | |||
| 3330 | ret = ib_register_client(&srp_client); | 3338 | ret = ib_register_client(&srp_client); |
| 3331 | if (ret) { | 3339 | if (ret) { |
| 3332 | pr_err("couldn't register IB client\n"); | 3340 | pr_err("couldn't register IB client\n"); |
| 3333 | srp_release_transport(ib_srp_transport_template); | 3341 | goto unreg_sa; |
| 3334 | ib_sa_unregister_client(&srp_sa_client); | ||
| 3335 | class_unregister(&srp_class); | ||
| 3336 | return ret; | ||
| 3337 | } | 3342 | } |
| 3338 | 3343 | ||
| 3339 | return 0; | 3344 | out: |
| 3345 | return ret; | ||
| 3346 | |||
| 3347 | unreg_sa: | ||
| 3348 | ib_sa_unregister_client(&srp_sa_client); | ||
| 3349 | class_unregister(&srp_class); | ||
| 3350 | |||
| 3351 | release_tr: | ||
| 3352 | srp_release_transport(ib_srp_transport_template); | ||
| 3353 | |||
| 3354 | destroy_wq: | ||
| 3355 | destroy_workqueue(srp_remove_wq); | ||
| 3356 | goto out; | ||
| 3340 | } | 3357 | } |
| 3341 | 3358 | ||
| 3342 | static void __exit srp_cleanup_module(void) | 3359 | static void __exit srp_cleanup_module(void) |
| @@ -3345,6 +3362,7 @@ static void __exit srp_cleanup_module(void) | |||
| 3345 | ib_sa_unregister_client(&srp_sa_client); | 3362 | ib_sa_unregister_client(&srp_sa_client); |
| 3346 | class_unregister(&srp_class); | 3363 | class_unregister(&srp_class); |
| 3347 | srp_release_transport(ib_srp_transport_template); | 3364 | srp_release_transport(ib_srp_transport_template); |
| 3365 | destroy_workqueue(srp_remove_wq); | ||
| 3348 | } | 3366 | } |
| 3349 | 3367 | ||
| 3350 | module_init(srp_init_module); | 3368 | module_init(srp_init_module); |
