Author: np
Date: Tue Jun 14 20:58:05 2016
New Revision: 301896
URL: https://svnweb.freebsd.org/changeset/base/301896

Log:
  Fix bug in iwcm that caused a panic in iw_cm_wq when krping is run
  repeatedly in a tight loop.
  
  Approved by:  re (gjb@)
  Obtained from:        hselasky@ (part of larger changes in D5791)

Modified:
  head/sys/ofed/drivers/infiniband/core/iwcm.c

Modified: head/sys/ofed/drivers/infiniband/core/iwcm.c
==============================================================================
--- head/sys/ofed/drivers/infiniband/core/iwcm.c        Tue Jun 14 18:41:18 
2016        (r301895)
+++ head/sys/ofed/drivers/infiniband/core/iwcm.c        Tue Jun 14 20:58:05 
2016        (r301896)
@@ -266,9 +266,16 @@ static void add_ref(struct iw_cm_id *cm_
 static void rem_ref(struct iw_cm_id *cm_id)
 {
        struct iwcm_id_private *cm_id_priv;
+       int cb_destroy;
+
        cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
-       if (iwcm_deref_id(cm_id_priv) &&
-           test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags)) {
+
+       /*
+        * Test bit before deref in case the cm_id gets freed on another
+        * thread.
+        */
+       cb_destroy = test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
+       if (iwcm_deref_id(cm_id_priv) && cb_destroy) {
                BUG_ON(!list_empty(&cm_id_priv->work_list));
                free_cm_id(cm_id_priv);
        }
@@ -1157,6 +1164,8 @@ static void cm_work_handler(struct work_
                        }
                        return;
                }
+               if (empty)
+                       return;
                spin_lock_irqsave(&cm_id_priv->lock, flags);
        }
        spin_unlock_irqrestore(&cm_id_priv->lock, flags);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to