i40e: Fix client interaction
authorCarolyn Wyborny <carolyn.wyborny@intel.com>
Wed, 14 Sep 2016 23:24:31 +0000 (16:24 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Sat, 29 Oct 2016 06:28:39 +0000 (23:28 -0700)
This patch fixes a problem in the client interface that
was causing random stack traces in RDMA driver load and
unload tests.  This patch fixes the problem by checking
for an existing client before trying to open it.  Without
this patch, there is a timing related null pointer deref.

Change-ID: Ib73d30671a27f6f9770dd53b3e5292b88d6b62da
Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_client.c

index 250db0b244b7677107ca1c56df23c23789e80fee..6ffac03d5015a00e1d061193d5bcde0c996c762a 100644 (file)
@@ -565,7 +565,7 @@ void i40e_client_subtask(struct i40e_pf *pf)
                        if (test_bit(__I40E_DOWN, &pf->vsi[pf->lan_vsi]->state))
                                continue;
                } else {
-                       dev_warn(&pf->pdev->dev, "This client %s is being instanciated at probe\n",
+                       dev_warn(&pf->pdev->dev, "This client %s is being instantiated at probe\n",
                                 client->name);
                }
 
@@ -582,24 +582,21 @@ void i40e_client_subtask(struct i40e_pf *pf)
                        dev_info(&pf->pdev->dev, "Added instance of Client %s to PF%d bus=0x%02x func=0x%02x\n",
                                 client->name, pf->hw.pf_id,
                                 pf->hw.bus.device, pf->hw.bus.func);
-               }
-
-               mutex_lock(&i40e_client_instance_mutex);
-               /* Send an Open request to the client */
-               atomic_inc(&cdev->ref_cnt);
-               if (client->ops && client->ops->open)
-                       ret = client->ops->open(&cdev->lan_info, client);
-               atomic_dec(&cdev->ref_cnt);
-               if (!ret) {
+                       mutex_lock(&i40e_client_instance_mutex);
+                       atomic_inc(&cdev->ref_cnt);
+                       if (client->ops && client->ops->open)
+                               ret = client->ops->open(&cdev->lan_info,
+                                                       client);
+                       atomic_dec(&cdev->ref_cnt);
+                       if (ret < 0) {
+                               mutex_unlock(&i40e_client_instance_mutex);
+                               i40e_client_del_instance(pf, client);
+                               atomic_dec(&client->ref_cnt);
+                               continue;
+                       }
                        set_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state);
-               } else {
-                       /* remove client instance */
                        mutex_unlock(&i40e_client_instance_mutex);
-                       i40e_client_del_instance(pf, client);
-                       atomic_dec(&client->ref_cnt);
-                       continue;
                }
-               mutex_unlock(&i40e_client_instance_mutex);
        }
        mutex_unlock(&i40e_client_mutex);
 }