Skip to contentSkip to conversation

aic94xx: cleanup after a discovery error

PATCH In review Alexis Bruemmer 2 participants 5 messages Nov 9, 2006 – Nov 12, 2006

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 3/4 aic94xx: cleanup after a discovery error

Domain device is freed but the port dev list is not adjusted on some discovery errors. Module unload will Oops if this happens.

---

drivers/scsi/libsas/sas_discover.c +15 -2
index 23461dc..dcd0461 100644
@@ -585,7 +598,7 @@ int sas_discover_end_dev(struct domain_d
 
 	res = sas_notify_lldd_dev_found(dev);
 	if (res)
-		return res;
+		goto out_err2;
 
 	res = sas_rphy_add(dev->rphy);
 	if (res)
@@ -594,12 +607,21 @@ int sas_discover_end_dev(struct domain_d
 	/* do this to get the end device port attributes which will have
 	 * been scanned in sas_rphy_add */
 	sas_notify_lldd_dev_gone(dev);
-	sas_notify_lldd_dev_found(dev);
+	res = sas_notify_lldd_dev_found(dev);
+	if (res)
+		goto out_err3;
 
 	return 0;
 
 out_err:
 	sas_notify_lldd_dev_gone(dev);
+out_err2:
+	sas_rphy_free(dev->rphy);
+	dev->rphy = NULL;
+	return res;
+out_err3:
+	sas_rphy_delete(dev->rphy);
+	dev->rphy = NULL;
 	return res;
 }
 
@@ -689,6 +711,10 @@ static void sas_discover_domain(void *da
 	}
 
 	if (error) {
+		spin_lock(&port->dev_list_lock);
+		list_del_init(&port->port_dev->dev_list_node);
+		spin_unlock(&port->dev_list_lock);
+
 		kfree(port->port_dev); /* not kobject_register-ed yet */
 		port->port_dev = NULL;
 	}
drivers/scsi/libsas/sas_expander.c +16 -3
index 4cc7457..a79e89c 100644
@@ -1474,14 +1474,27 @@ int sas_discover_root_expander(struct do
 	int res;
 	struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy);
 
-	sas_rphy_add(dev->rphy);
+	res = sas_rphy_add(dev->rphy);
+	if (res)
+		goto out_err;
 
 	ex->level = dev->port->disc.max_level; /* 0 */
 	res = sas_discover_expander(dev);
-	if (!res)
-		sas_ex_bfs_disc(dev->port);
+	if (res)
+		goto out_err2;
+
+	sas_ex_bfs_disc(dev->port);
 
 	return res;
+
+out_err2:
+	sas_rphy_delete(dev->rphy);
+	dev->rphy = NULL;
+	return res;
+out_err:
+	sas_rphy_free(dev->rphy);
+	dev->rphy = NULL;
+	return res;
 }
 
 /* ---------- Domain revalidation ---------- */

---

One question that remains with this patch is whether or not sas_get_port_device should be moved into sas_discover_{sas,expander} to ensure that the rphy struct is allocated and freed-in-error in the same function

#1 lore raw
Quoted 4 lines · Alexis Bruemmer

One question that remains with this patch is whether or not sas_get_port_device should be moved into sas_discover_{sas,expander} to ensure that the rphy struct is allocated and freed-in-error in the same function

It looks as though we could move the parts of sas_get_port_device() that deal with rphy allocation/initialization into the sas_discover_{sata,sas,expander} functions? I don't know for sure; I could be missing some subtlety that requires the sas_rphy creation to be in sas_get_port_device.

--D

#2 lore raw
In reply to Alexis Bruemmer
Quoted 2 lines · Alexis Bruemmer

Domain device is freed but the port dev list is not adjusted on some discovery errors. Module unload will Oops if this happens.

It'll still oops; sas_ex_discover_end_dev needs to be updated to know that it needn't call sas_rphy_free if the device-specific discovery functions fail. This patch should fix that case too.

--

drivers/scsi/libsas/sas_expander.c +0 -1
index 4cc7457..a38d05b 100644
@@ -711,7 +711,6 @@ static struct domain_device *sas_ex_disc
 
  out_list_del:
 	list_del(&child->dev_list_node);
-	sas_rphy_free(rphy);
  out_free:
 	sas_port_delete(phy->port);
  out_err:
#3 lore raw
Quoted 3 lines · Darrick J. Wong

It'll still oops; sas_ex_discover_end_dev needs to be updated to know that it needn't call sas_rphy_free if the device-specific discovery functions fail. This patch should fix that case too.

Erm... this patch is only necessary if one has jejb's "better error handling in sas_ex_discover_end_dev()" patch applied.

http://www.kernel.org/git/?p=linux/kernel/git/jejb/aic94xx-sas-2.6.git;a=commitdiff;h=82f6bc0849b6fce9a965dde11dd6f685adc7285e

(My queue of pending patches is getting a bit too long, methinks.)

--D

#4 lore raw
In reply to Alexis Bruemmer

This patch applies the same cleanups to sas_discover_sata. Note that this is against aic94xx-sas, not scsi-misc.

--

drivers/scsi/libsas/sas_discover.c +18 -5
index 23461dc..dcd0461 100644
@@ -552,7 +552,7 @@ int sas_discover_sata(struct domain_devi
 
 	res = sas_notify_lldd_dev_found(dev);
 	if (res)
-		return res;
+		goto out_err2;
 
 	switch (dev->dev_type) {
 	case SATA_DEV:
@@ -564,12 +564,25 @@ int sas_discover_sata(struct domain_devi
 	default:
 		break;
 	}
+	if (res)
+		goto out_err;
 
 	sas_notify_lldd_dev_gone(dev);
-	if (!res) {
-		sas_notify_lldd_dev_found(dev);
-		res = sas_rphy_add(dev->rphy);
-	}
+	res = sas_notify_lldd_dev_found(dev);
+	if (res)
+		goto out_err2;
+
+	res = sas_rphy_add(dev->rphy);
+	if (res)
+		goto out_err;
+
+	return res;
+
+out_err:
+	sas_notify_lldd_dev_gone(dev);
+out_err2:
+	sas_rphy_free(dev->rphy);
+	dev->rphy = NULL;
 	return res;
 }