scsi_remove_target: debug softlockup From: Dan Williams dump more info in the case where we get stuck trying to remove a device. --- drivers/scsi/scsi_sysfs.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 093d4f6..011f8ee 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1032,8 +1032,11 @@ void scsi_remove_target(struct device *dev) { struct Scsi_Host *shost = dev_to_shost(dev->parent); struct scsi_target *starget, *found; + struct scsi_target *found_log[3]; unsigned long flags; + memset(found_log, 0, sizeof(found_log)); + restart: found = NULL; spin_lock_irqsave(shost->host_lock, flags); @@ -1041,8 +1044,24 @@ void scsi_remove_target(struct device *dev) if (starget->state == STARGET_DEL) continue; if (starget->dev.parent == dev || &starget->dev == dev) { + int i; + found = starget; found->reap_ref++; + for (i = 0; i < ARRAY_SIZE(found_log); i++) + if (!found_log[i]) { + found_log[i] = found; + break; + } else if (found_log[i] == found) { + struct scsi_device *sdev = NULL; + + if (!list_empty(&found->devices)) + sdev = list_entry(found->devices.next, typeof(*sdev), same_target_siblings); + pr_err_once("%s[%d]: reap %d:%d state: %d reap: %d dev_del: %d\n", + __func__, i, found->channel, found->id, + found->state, found->reap_ref, + sdev ? work_busy(&sdev->ew.work) ? 2 : 1 : 0); + } break; } }