@@ -1561,7 +1561,16 @@ void scsi_remove_target(struct device *dev)
starget->state == STARGET_CREATED_REMOVE)
continue;
if (starget->dev.parent == dev || &starget->dev == dev) {
- kref_get(&starget->reap_ref);
+ /*
+ * If the reference count is already zero, skip
+ * this target. Calling kref_get_unless_zero() if
+ * the reference count is zero is safe because
+ * scsi_target_destroy() will wait until the host
+ * lock has been released before freeing starget.
+ */
+ if (!kref_get_unless_zero(&starget->reap_ref))
+ continue;
+
if (starget->state == STARGET_CREATED)
starget->state = STARGET_CREATED_REMOVE;
else