diff options
author | Faisal Latif <faisal.latif@intel.com> | 2016-02-26 10:18:05 -0500 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2016-03-16 13:48:32 -0400 |
commit | dafb5587178afe8abf85f3ae91bbc88de9e54782 (patch) | |
tree | dc4d80e87a0c3a9a3ab70bf485fe79776bd3c7d2 | |
parent | c1340e8aa628d65bcb5c5b7e332bde8a17851ebf (diff) |
iwpm: crash fix for large connections test
During large connection test, there is a crash at wake_up() in the callback as waitq is
not yet initialized. Callback can happen before iwpm_wait_complete_req() is called to
initialize waitq.
To resolve, using signaling semaphore instead of waitq.
Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
Reviewed-by: Tatyana E Nikolova <tatyana.e.nikolova@intel.com>
Signed-off-by: Faisal Latif <faisal.latif@intel.com>
Reviewed-by: Steve Wise <swise@opengridcomputing.com>
Tested-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r-- | drivers/infiniband/core/iwpm_msg.c | 10 | ||||
-rw-r--r-- | drivers/infiniband/core/iwpm_util.c | 14 | ||||
-rw-r--r-- | drivers/infiniband/core/iwpm_util.h | 2 |
3 files changed, 13 insertions, 13 deletions
diff --git a/drivers/infiniband/core/iwpm_msg.c b/drivers/infiniband/core/iwpm_msg.c index c2b4ce67fd4a..43e3fa27102b 100644 --- a/drivers/infiniband/core/iwpm_msg.c +++ b/drivers/infiniband/core/iwpm_msg.c | |||
@@ -89,7 +89,7 @@ int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client) | |||
89 | if (ret) | 89 | if (ret) |
90 | goto pid_query_error; | 90 | goto pid_query_error; |
91 | ret = ibnl_put_attr(skb, nlh, IFNAMSIZ, | 91 | ret = ibnl_put_attr(skb, nlh, IFNAMSIZ, |
92 | pm_msg->if_name, IWPM_NLA_REG_IF_NAME); | 92 | pm_msg->if_name, IWPM_NLA_REG_IF_NAME); |
93 | if (ret) | 93 | if (ret) |
94 | goto pid_query_error; | 94 | goto pid_query_error; |
95 | ret = ibnl_put_attr(skb, nlh, IWPM_DEVNAME_SIZE, | 95 | ret = ibnl_put_attr(skb, nlh, IWPM_DEVNAME_SIZE, |
@@ -394,7 +394,7 @@ register_pid_response_exit: | |||
394 | /* always for found nlmsg_request */ | 394 | /* always for found nlmsg_request */ |
395 | kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); | 395 | kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); |
396 | barrier(); | 396 | barrier(); |
397 | wake_up(&nlmsg_request->waitq); | 397 | up(&nlmsg_request->sem); |
398 | return 0; | 398 | return 0; |
399 | } | 399 | } |
400 | EXPORT_SYMBOL(iwpm_register_pid_cb); | 400 | EXPORT_SYMBOL(iwpm_register_pid_cb); |
@@ -463,7 +463,7 @@ add_mapping_response_exit: | |||
463 | /* always for found request */ | 463 | /* always for found request */ |
464 | kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); | 464 | kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); |
465 | barrier(); | 465 | barrier(); |
466 | wake_up(&nlmsg_request->waitq); | 466 | up(&nlmsg_request->sem); |
467 | return 0; | 467 | return 0; |
468 | } | 468 | } |
469 | EXPORT_SYMBOL(iwpm_add_mapping_cb); | 469 | EXPORT_SYMBOL(iwpm_add_mapping_cb); |
@@ -555,7 +555,7 @@ query_mapping_response_exit: | |||
555 | /* always for found request */ | 555 | /* always for found request */ |
556 | kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); | 556 | kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); |
557 | barrier(); | 557 | barrier(); |
558 | wake_up(&nlmsg_request->waitq); | 558 | up(&nlmsg_request->sem); |
559 | return 0; | 559 | return 0; |
560 | } | 560 | } |
561 | EXPORT_SYMBOL(iwpm_add_and_query_mapping_cb); | 561 | EXPORT_SYMBOL(iwpm_add_and_query_mapping_cb); |
@@ -749,7 +749,7 @@ int iwpm_mapping_error_cb(struct sk_buff *skb, struct netlink_callback *cb) | |||
749 | /* always for found request */ | 749 | /* always for found request */ |
750 | kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); | 750 | kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); |
751 | barrier(); | 751 | barrier(); |
752 | wake_up(&nlmsg_request->waitq); | 752 | up(&nlmsg_request->sem); |
753 | return 0; | 753 | return 0; |
754 | } | 754 | } |
755 | EXPORT_SYMBOL(iwpm_mapping_error_cb); | 755 | EXPORT_SYMBOL(iwpm_mapping_error_cb); |
diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c index 5fb089e91353..9b2bf2fb2b00 100644 --- a/drivers/infiniband/core/iwpm_util.c +++ b/drivers/infiniband/core/iwpm_util.c | |||
@@ -254,9 +254,9 @@ void iwpm_add_remote_info(struct iwpm_remote_info *rem_info) | |||
254 | } | 254 | } |
255 | 255 | ||
256 | int iwpm_get_remote_info(struct sockaddr_storage *mapped_loc_addr, | 256 | int iwpm_get_remote_info(struct sockaddr_storage *mapped_loc_addr, |
257 | struct sockaddr_storage *mapped_rem_addr, | 257 | struct sockaddr_storage *mapped_rem_addr, |
258 | struct sockaddr_storage *remote_addr, | 258 | struct sockaddr_storage *remote_addr, |
259 | u8 nl_client) | 259 | u8 nl_client) |
260 | { | 260 | { |
261 | struct hlist_node *tmp_hlist_node; | 261 | struct hlist_node *tmp_hlist_node; |
262 | struct hlist_head *hash_bucket_head; | 262 | struct hlist_head *hash_bucket_head; |
@@ -322,6 +322,8 @@ struct iwpm_nlmsg_request *iwpm_get_nlmsg_request(__u32 nlmsg_seq, | |||
322 | nlmsg_request->nl_client = nl_client; | 322 | nlmsg_request->nl_client = nl_client; |
323 | nlmsg_request->request_done = 0; | 323 | nlmsg_request->request_done = 0; |
324 | nlmsg_request->err_code = 0; | 324 | nlmsg_request->err_code = 0; |
325 | sema_init(&nlmsg_request->sem, 1); | ||
326 | down(&nlmsg_request->sem); | ||
325 | return nlmsg_request; | 327 | return nlmsg_request; |
326 | } | 328 | } |
327 | 329 | ||
@@ -364,11 +366,9 @@ struct iwpm_nlmsg_request *iwpm_find_nlmsg_request(__u32 echo_seq) | |||
364 | int iwpm_wait_complete_req(struct iwpm_nlmsg_request *nlmsg_request) | 366 | int iwpm_wait_complete_req(struct iwpm_nlmsg_request *nlmsg_request) |
365 | { | 367 | { |
366 | int ret; | 368 | int ret; |
367 | init_waitqueue_head(&nlmsg_request->waitq); | ||
368 | 369 | ||
369 | ret = wait_event_timeout(nlmsg_request->waitq, | 370 | ret = down_timeout(&nlmsg_request->sem, IWPM_NL_TIMEOUT); |
370 | (nlmsg_request->request_done != 0), IWPM_NL_TIMEOUT); | 371 | if (ret) { |
371 | if (!ret) { | ||
372 | ret = -EINVAL; | 372 | ret = -EINVAL; |
373 | pr_info("%s: Timeout %d sec for netlink request (seq = %u)\n", | 373 | pr_info("%s: Timeout %d sec for netlink request (seq = %u)\n", |
374 | __func__, (IWPM_NL_TIMEOUT/HZ), nlmsg_request->nlmsg_seq); | 374 | __func__, (IWPM_NL_TIMEOUT/HZ), nlmsg_request->nlmsg_seq); |
diff --git a/drivers/infiniband/core/iwpm_util.h b/drivers/infiniband/core/iwpm_util.h index b7b9e194ce81..af1fc14a0d3d 100644 --- a/drivers/infiniband/core/iwpm_util.h +++ b/drivers/infiniband/core/iwpm_util.h | |||
@@ -69,7 +69,7 @@ struct iwpm_nlmsg_request { | |||
69 | u8 nl_client; | 69 | u8 nl_client; |
70 | u8 request_done; | 70 | u8 request_done; |
71 | u16 err_code; | 71 | u16 err_code; |
72 | wait_queue_head_t waitq; | 72 | struct semaphore sem; |
73 | struct kref kref; | 73 | struct kref kref; |
74 | }; | 74 | }; |
75 | 75 | ||