iwpm: crash fix for large connections test
authorFaisal Latif <faisal.latif@intel.com>
Fri, 26 Feb 2016 15:18:05 +0000 (09:18 -0600)
committerDoug Ledford <dledford@redhat.com>
Wed, 16 Mar 2016 17:48:32 +0000 (13:48 -0400)
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>
drivers/infiniband/core/iwpm_msg.c
drivers/infiniband/core/iwpm_util.c
drivers/infiniband/core/iwpm_util.h

index c2b4ce6..43e3fa2 100644 (file)
@@ -89,7 +89,7 @@ int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client)
        if (ret)
                goto pid_query_error;
        ret = ibnl_put_attr(skb, nlh, IFNAMSIZ,
-                               pm_msg->if_name, IWPM_NLA_REG_IF_NAME);
+                           pm_msg->if_name, IWPM_NLA_REG_IF_NAME);
        if (ret)
                goto pid_query_error;
        ret = ibnl_put_attr(skb, nlh, IWPM_DEVNAME_SIZE,
@@ -394,7 +394,7 @@ register_pid_response_exit:
        /* always for found nlmsg_request */
        kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
        barrier();
-       wake_up(&nlmsg_request->waitq);
+       up(&nlmsg_request->sem);
        return 0;
 }
 EXPORT_SYMBOL(iwpm_register_pid_cb);
@@ -463,7 +463,7 @@ add_mapping_response_exit:
        /* always for found request */
        kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
        barrier();
-       wake_up(&nlmsg_request->waitq);
+       up(&nlmsg_request->sem);
        return 0;
 }
 EXPORT_SYMBOL(iwpm_add_mapping_cb);
@@ -555,7 +555,7 @@ query_mapping_response_exit:
        /* always for found request */
        kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
        barrier();
-       wake_up(&nlmsg_request->waitq);
+       up(&nlmsg_request->sem);
        return 0;
 }
 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)
        /* always for found request */
        kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
        barrier();
-       wake_up(&nlmsg_request->waitq);
+       up(&nlmsg_request->sem);
        return 0;
 }
 EXPORT_SYMBOL(iwpm_mapping_error_cb);
index 5fb089e..9b2bf2f 100644 (file)
@@ -254,9 +254,9 @@ void iwpm_add_remote_info(struct iwpm_remote_info *rem_info)
 }
 
 int iwpm_get_remote_info(struct sockaddr_storage *mapped_loc_addr,
-                               struct sockaddr_storage *mapped_rem_addr,
-                               struct sockaddr_storage *remote_addr,
-                               u8 nl_client)
+                        struct sockaddr_storage *mapped_rem_addr,
+                        struct sockaddr_storage *remote_addr,
+                        u8 nl_client)
 {
        struct hlist_node *tmp_hlist_node;
        struct hlist_head *hash_bucket_head;
@@ -322,6 +322,8 @@ struct iwpm_nlmsg_request *iwpm_get_nlmsg_request(__u32 nlmsg_seq,
        nlmsg_request->nl_client = nl_client;
        nlmsg_request->request_done = 0;
        nlmsg_request->err_code = 0;
+       sema_init(&nlmsg_request->sem, 1);
+       down(&nlmsg_request->sem);
        return nlmsg_request;
 }
 
@@ -364,11 +366,9 @@ struct iwpm_nlmsg_request *iwpm_find_nlmsg_request(__u32 echo_seq)
 int iwpm_wait_complete_req(struct iwpm_nlmsg_request *nlmsg_request)
 {
        int ret;
-       init_waitqueue_head(&nlmsg_request->waitq);
 
-       ret = wait_event_timeout(nlmsg_request->waitq,
-                       (nlmsg_request->request_done != 0), IWPM_NL_TIMEOUT);
-       if (!ret) {
+       ret = down_timeout(&nlmsg_request->sem, IWPM_NL_TIMEOUT);
+       if (ret) {
                ret = -EINVAL;
                pr_info("%s: Timeout %d sec for netlink request (seq = %u)\n",
                        __func__, (IWPM_NL_TIMEOUT/HZ), nlmsg_request->nlmsg_seq);
index b7b9e19..af1fc14 100644 (file)
@@ -69,7 +69,7 @@ struct iwpm_nlmsg_request {
        u8                  nl_client;
        u8                  request_done;
        u16                 err_code;
-       wait_queue_head_t   waitq;
+       struct semaphore    sem;
        struct kref         kref;
 };