staticbool eeh_edev_actionable(struct eeh_dev *edev)
{ if (!edev->pdev) returnfalse; if (edev->pdev->error_state == pci_channel_io_perm_failure) returnfalse; if (eeh_dev_removed(edev)) returnfalse; if (eeh_pe_passed(edev->pe)) returnfalse;
eeh_for_each_pe(root, pe) { if (include_passed || !eeh_pe_passed(pe)) { for (i = 0; i < 3; i++) if (!eeh_unfreeze_pe(pe)) break; if (i >= 3) return -EIO;
}
}
eeh_pe_state_clear(root, EEH_PE_ISOLATED, include_passed); return0;
}
int eeh_pe_reset_and_recover(struct eeh_pe *pe)
{ int ret;
/* Bail if the PE is being recovered */ if (pe->state & EEH_PE_RECOVERING) return0;
/* Put the PE into recovery mode */
eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
/* Save states */
eeh_pe_dev_traverse(pe, eeh_dev_save_state, NULL);
/* Issue reset */
ret = eeh_pe_reset_full(pe, true); if (ret) {
eeh_pe_state_clear(pe, EEH_PE_RECOVERING, true); return ret;
}
/* Unfreeze the PE */
ret = eeh_clear_pe_frozen_state(pe, true); if (ret) {
eeh_pe_state_clear(pe, EEH_PE_RECOVERING, true); return ret;
}
/* Restore device state */
eeh_pe_dev_traverse(pe, eeh_dev_restore_state, NULL);
/* Restore PE */
eeh_ops->configure_bridge(pe);
eeh_pe_restore_bars(pe);
/* Clear frozen state */
rc = eeh_clear_pe_frozen_state(pe, false); if (rc) { return rc;
}
/* Give the system 5 seconds to finish running the user-space *hotplugshutdownscripts,e.g.ifdownforethernet.Yes, *thisisahack,butifwedon'tdothis,andtrytobring *thedeviceupbeforethescriptshavetakenitdown, *potentiallyweirdthingshappen.
*/ if (!driver_eeh_aware || rmv_data->removed_dev_count) {
pr_info("EEH: Sleep 5s ahead of %s hotplug\n",
(driver_eeh_aware ? "partial" : "complete"));
ssleep(5);
/* The longest amount of time to wait for a pci device *tocomebackonline,inseconds.
*/ #define MAX_WAIT_FOR_RECOVERY 300
/* Walks the PE tree after processing an event to remove any stale PEs. * *NB:ThisneedstoberecursivetoensuretheleafPEsgetremoved *beforetheirparentsdo.Althoughthisispossibletodorecursively *wedon'tsincethisiseasiertoreadandweneedtogarantee *theleafnodeswillbehandledfirst.
*/ staticvoid eeh_pe_cleanup(struct eeh_pe *pe)
{ struct eeh_pe *child_pe, *tmp;
bus = eeh_pe_bus_get(pe); if (!bus) {
pr_err("%s: Cannot find PCI bus for PHB#%x-PE#%x\n",
__func__, pe->phb->global_number, pe->addr);
pci_unlock_rescan_remove(); return;
}
/* FIXME: Use the same format as dump_stack() */
pr_err("EEH: Call Trace:\n"); for (i = 0; i < pe->trace_entries; i++)
pr_err("EEH: [%p] %pS\n", ptrs[i], ptrs[i]);
eeh_pe_update_time_stamp(pe);
pe->freeze_count++; if (pe->freeze_count > eeh_max_freezes) {
pr_err("EEH: PHB#%x-PE#%x has failed %d times in the last hour and has been permanently disabled.\n",
pe->phb->global_number, pe->addr,
pe->freeze_count);
goto recover_failed;
}
/* Walk the various device drivers attached to this slot through *aresetsequence,givingeachanopportunitytodowhatitneeds *toaccomplishthereset.Eachchildgetsareportofthe *status...ifanychildcan'thandlethereset,thentheentire *slotisdlparremovedandadded. * *WhenthePHBisfenced,wehavetoissuearesettorecoverfrom *theerror.Overridetheresultifnecessarytohavepartially *hotplugforthiscase.
*/
pr_warn("EEH: This PCI device has failed %d times in the last hour and will be permanently disabled after %d failures.\n",
pe->freeze_count, eeh_max_freezes);
pr_info("EEH: Notify device drivers to shutdown\n");
eeh_set_channel_state(pe, pci_channel_io_frozen);
eeh_set_irq_state(pe, false);
eeh_pe_report("error_detected(IO frozen)", pe,
eeh_report_error, &result); if (result == PCI_ERS_RESULT_DISCONNECT) goto recover_failed;
/* *ErrorloggedonaPHBarealwaysfenceswhichneedafull *PHBresettoclearsoforcethattohappen.
*/ if ((pe->type & EEH_PE_PHB) && result != PCI_ERS_RESULT_NONE)
result = PCI_ERS_RESULT_NEED_RESET;
/* Get the current PCI slot state. This can take a long time, *sometimesover300secondsforcertainsystems.
*/
rc = eeh_wait_state(pe, MAX_WAIT_FOR_RECOVERY * 1000); if (rc < 0 || rc == EEH_STATE_NOT_SUPPORT) {
pr_warn("EEH: Permanent failure\n"); goto recover_failed;
}
/* Since rtas may enable MMIO when posting the error log, *don'tposttheerrorloguntilafteralldevdrivers *havebeeninformed.
*/
pr_info("EEH: Collect temporary log\n");
eeh_slot_error_detail(pe, EEH_LOG_TEMP);
/* If all device drivers were EEH-unaware, then shut *downallofthedevicedrivers,andhopethey *godownwillingly,withoutpanicingthesystem.
*/ if (result == PCI_ERS_RESULT_NONE) {
pr_info("EEH: Reset with hotplug activity\n");
rc = eeh_reset_device(pe, bus, NULL, false); if (rc) {
pr_warn("%s: Unable to reset, err=%d\n", __func__, rc); goto recover_failed;
}
}
/* If all devices reported they can proceed, then re-enable MMIO */ if (result == PCI_ERS_RESULT_CAN_RECOVER) {
pr_info("EEH: Enable I/O for affected devices\n");
rc = eeh_pci_enable(pe, EEH_OPT_THAW_MMIO); if (rc < 0) goto recover_failed;
if (rc) {
result = PCI_ERS_RESULT_NEED_RESET;
} else {
pr_info("EEH: Notify device drivers to resume I/O\n");
eeh_pe_report("mmio_enabled", pe,
eeh_report_mmio_enabled, &result);
}
} if (result == PCI_ERS_RESULT_CAN_RECOVER) {
pr_info("EEH: Enabled DMA for affected devices\n");
rc = eeh_pci_enable(pe, EEH_OPT_THAW_DMA); if (rc < 0) goto recover_failed;
if (rc) {
result = PCI_ERS_RESULT_NEED_RESET;
} else { /* *Wedidn'tdoPEresetforthecase.ThePE *isstillinfrozenstate.Clearitbefore *resumingthePE.
*/
eeh_pe_state_clear(pe, EEH_PE_ISOLATED, true);
result = PCI_ERS_RESULT_RECOVERED;
}
}
/* If any device called out for a reset, then reset the slot */ if (result == PCI_ERS_RESULT_NEED_RESET) {
pr_info("EEH: Reset without hotplug activity\n");
rc = eeh_reset_device(pe, bus, &rmv_data, true); if (rc) {
pr_warn("%s: Cannot reset, err=%d\n", __func__, rc); goto recover_failed;
}
recover_failed: /* *About90%ofallreal-lifeEEHfailuresinthefield *areduetopoorlyseatedPCIcards.Only10%orsoare *duetoactual,failedcards.
*/
pr_err("EEH: Unable to recover from failure from PHB#%x-PE#%x.\n" "Please try reseating or replacing it\n",
pe->phb->global_number, pe->addr);
eeh_slot_error_detail(pe, EEH_LOG_PERM);
/* Notify all devices that they're about to go down. */
eeh_set_irq_state(pe, false);
eeh_pe_report("error_detected(permanent failure)", pe,
eeh_report_failure, NULL);
eeh_set_channel_state(pe, pci_channel_io_perm_failure);
/* Mark the PE to be removed permanently */
eeh_pe_state_mark(pe, EEH_PE_REMOVED);
bus = eeh_pe_bus_get(pe); if (bus)
pci_hp_remove_devices(bus); else
pr_err("%s: PCI bus for PHB#%x-PE#%x disappeared\n",
__func__, pe->phb->global_number, pe->addr);
/* The passed PE should no longer be used */
pci_unlock_rescan_remove(); return;
}
/* clear the slot attention LED for all recovered devices */
eeh_for_each_pe(pe, tmp_pe)
eeh_pe_for_each_dev(tmp_pe, edev, tmp)
eeh_clear_slot_attention(edev->pdev);
switch (rc) { case EEH_NEXT_ERR_DEAD_IOC: /* Mark all PHBs in dead state */
eeh_serialize_lock(&flags);
/* Purge all events */
eeh_remove_event(NULL, true);
list_for_each_entry(hose, &hose_list, list_node) {
phb_pe = eeh_phb_pe_get(hose); if (!phb_pe) continue;
eeh_pe_mark_isolated(phb_pe);
}
eeh_serialize_unlock(flags);
break; case EEH_NEXT_ERR_FROZEN_PE: case EEH_NEXT_ERR_FENCED_PHB: case EEH_NEXT_ERR_DEAD_PHB: /* Mark the PE in fenced state */
eeh_serialize_lock(&flags);
/* Purge all events of the PHB */
eeh_remove_event(pe, true);
if (rc != EEH_NEXT_ERR_DEAD_PHB)
eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
eeh_pe_mark_isolated(pe);
eeh_serialize_unlock(flags);
break; case EEH_NEXT_ERR_NONE:
pci_unlock_rescan_remove(); return; default:
pr_warn("%s: Invalid value %d from next_error()\n",
__func__, rc);
pci_unlock_rescan_remove(); return;
}
/* Notify all devices to be down */
eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true);
eeh_pe_report( "error_detected(permanent failure)", pe,
eeh_report_failure, NULL);
eeh_set_channel_state(pe, pci_channel_io_perm_failure);
bus = eeh_pe_bus_get(phb_pe); if (!bus) {
pr_err("%s: Cannot find PCI bus for " "PHB#%x-PE#%x\n",
__func__,
pe->phb->global_number,
pe->addr); break;
}
pci_hp_remove_devices(bus);
}
}
/* *IfwehavedetecteddeadIOC,weneedn'tproceed *anymoresinceallPHBswouldhavebeenremoved
*/ if (rc == EEH_NEXT_ERR_DEAD_IOC) break;
} while (rc != EEH_NEXT_ERR_NONE);
pci_unlock_rescan_remove();
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.22Bemerkung:
(vorverarbeitet am 2026-09-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.