|
@@ -130,6 +130,7 @@ static void srp_send_completion(struct ib_cq *cq, void *target_ptr);
|
|
|
static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event);
|
|
|
|
|
|
static struct scsi_transport_template *ib_srp_transport_template;
|
|
|
+static struct workqueue_struct *srp_remove_wq;
|
|
|
|
|
|
static struct ib_client srp_client = {
|
|
|
.name = "srp",
|
|
@@ -731,7 +732,7 @@ static bool srp_queue_remove_work(struct srp_target_port *target)
|
|
|
spin_unlock_irq(&target->lock);
|
|
|
|
|
|
if (changed)
|
|
|
- queue_work(system_long_wq, &target->remove_work);
|
|
|
+ queue_work(srp_remove_wq, &target->remove_work);
|
|
|
|
|
|
return changed;
|
|
|
}
|
|
@@ -3261,9 +3262,10 @@ static void srp_remove_one(struct ib_device *device)
|
|
|
spin_unlock(&host->target_lock);
|
|
|
|
|
|
/*
|
|
|
- * Wait for target port removal tasks.
|
|
|
+ * Wait for tl_err and target port removal tasks.
|
|
|
*/
|
|
|
flush_workqueue(system_long_wq);
|
|
|
+ flush_workqueue(srp_remove_wq);
|
|
|
|
|
|
kfree(host);
|
|
|
}
|
|
@@ -3313,16 +3315,22 @@ static int __init srp_init_module(void)
|
|
|
indirect_sg_entries = cmd_sg_entries;
|
|
|
}
|
|
|
|
|
|
+ srp_remove_wq = create_workqueue("srp_remove");
|
|
|
+ if (IS_ERR(srp_remove_wq)) {
|
|
|
+ ret = PTR_ERR(srp_remove_wq);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = -ENOMEM;
|
|
|
ib_srp_transport_template =
|
|
|
srp_attach_transport(&ib_srp_transport_functions);
|
|
|
if (!ib_srp_transport_template)
|
|
|
- return -ENOMEM;
|
|
|
+ goto destroy_wq;
|
|
|
|
|
|
ret = class_register(&srp_class);
|
|
|
if (ret) {
|
|
|
pr_err("couldn't register class infiniband_srp\n");
|
|
|
- srp_release_transport(ib_srp_transport_template);
|
|
|
- return ret;
|
|
|
+ goto release_tr;
|
|
|
}
|
|
|
|
|
|
ib_sa_register_client(&srp_sa_client);
|
|
@@ -3330,13 +3338,22 @@ static int __init srp_init_module(void)
|
|
|
ret = ib_register_client(&srp_client);
|
|
|
if (ret) {
|
|
|
pr_err("couldn't register IB client\n");
|
|
|
- srp_release_transport(ib_srp_transport_template);
|
|
|
- ib_sa_unregister_client(&srp_sa_client);
|
|
|
- class_unregister(&srp_class);
|
|
|
- return ret;
|
|
|
+ goto unreg_sa;
|
|
|
}
|
|
|
|
|
|
- return 0;
|
|
|
+out:
|
|
|
+ return ret;
|
|
|
+
|
|
|
+unreg_sa:
|
|
|
+ ib_sa_unregister_client(&srp_sa_client);
|
|
|
+ class_unregister(&srp_class);
|
|
|
+
|
|
|
+release_tr:
|
|
|
+ srp_release_transport(ib_srp_transport_template);
|
|
|
+
|
|
|
+destroy_wq:
|
|
|
+ destroy_workqueue(srp_remove_wq);
|
|
|
+ goto out;
|
|
|
}
|
|
|
|
|
|
static void __exit srp_cleanup_module(void)
|
|
@@ -3345,6 +3362,7 @@ static void __exit srp_cleanup_module(void)
|
|
|
ib_sa_unregister_client(&srp_sa_client);
|
|
|
class_unregister(&srp_class);
|
|
|
srp_release_transport(ib_srp_transport_template);
|
|
|
+ destroy_workqueue(srp_remove_wq);
|
|
|
}
|
|
|
|
|
|
module_init(srp_init_module);
|