Come ripristinare / spegnere e riaccendere un dispositivo PCIe?


20

Ho un dispositivo PCIe che funziona correttamente solo quando il computer è completamente spento e poi riacceso. Emettere un semplice rebooto un reboot -pcomando non sembra spegnere e riaccendere la scheda PCIe, il che fa sì che non funzioni dopo il riavvio.

Esiste un modo per, dal sistema operativo, spegnere e riaccendere un dispositivo in uno slot PCIe? Posso trovarlo /sys/bus/pci/devices/0000*/, ma non riesco a capire come ripristinare correttamente la scheda. Il potere di aggancio sembra essere l'unico modo.

A parte questo, posso cambiare un'impostazione da qualche parte che causerà un ciclo di accensione completo su un rebootcomando?

A proposito, eseguo Ubuntu 12.10.


Ci hai provato reboot -f? Questo è simile alla pressione del pulsante di accensione della CPU.
ktan il

1
Due anni fa l'OP ha sottolineato che un software rebootnon funzionava. Il tuo reboot -fè ancora un riavvio graduale.
roaima,

Risposte:


16

Metodo potenziale n. 1

Penso che tu possa farlo con questi comandi:

disattivare

echo 0 > /sys/bus/pci/slots/$NUMBER/power

abilitare

echo 1 > /sys/bus/pci/slots/$NUMBER/power

Dov'è $NUMBERil numero dello slot PCI.

lspci -vvpuò aiutare a identificare il dispositivo. Questo non è ben documentato ...

Metodo potenziale n. 2

Mi sono imbattuto in questo thread su U&L , problema simile: ci sono alcune risposte a quella domanda che dicono che puoi resettare con questo comando:

echo "1" > /sys/bus/pci/devices/$NUMBER/reset

Tuttavia, vorrei leggere le risposte lì! Ci sono delle condizioni per farlo in questo modo! In particolare vorrei leggere questa risposta !

Metodo potenziale n. 3

Esiste un comando Unix setpci, che può fornire un metodo per ripristinare un dispositivo nel bus PCI.

Non ho visto alcun esempio specifico con questo comando, quindi dovrai cercare Google e cercare nella pagina man . Vorrei seguire leggermente questo comando fino a quando non sei sicuro del suo utilizzo. Da quello che ho letto a proposito, sta manipolando direttamente l'hardware e quindi ci sono sempre rischi nel farlo da soli rispetto all'uso di uno strumento che espone questo tipo di funzionalità!


1
Non viene visualizzato nulla negli slot, anche se sono collegate più schede. Ho una directory di alimentazione /sys/bus/pci/devices/$NUMBER/. Ma nulla sembra giustificare l'impostazione 0 o 1
zachd1_618

1
Mi sono imbattuto in questo thread su U&L , problema simile: ci sono alcune risposte a quella Q che dicono che puoi resettare con questo: echo "1"> / sys / bus / pci / devices / $ NUMBER / reset. Leggi però Q, ci sono delle condizioni per farlo in quel modo!
slm

Grazie per il link Ci ho provato comunque e non sembra fare nulla. In particolare, il dispositivo non si spegne e il sistema sa ancora che è lì. (Quando la scheda è accesa e collegata, ci sono dispositivi in ​​/ dev che posso guardare). Non scompaiono quando io echo "1" > ....
zachd1_618

1
Stai scaricando i moduli del kernel per quella scheda prima del ciclo di accensione? Penso che anche tu debba farlo.
slm

1
Penso che controllerò il codice sorgente del kernel per vedere se la commutazione powerlo mette effettivamente in D3.
foresta

7

removee rescanconsentirà al kernel di alimentare il dispositivo PCI in modo ciclatore senza reboot:

echo "1" > /sys/bus/pci/devices/DDDD\:BB\:DD.F//remove
sleep 1
echo "1" > /sys/bus/pci/rescan

dove DDDD.BB.DD.F = Dominio: Bus: Device.Function


echo "1"> / sys / bus / pci / rescan funziona per me nello slot mini pci lenovo g560. Ho collegato la scheda minipci USB 3.0. Il sistema è Ubuntu 16.04 x64
kodmanyagha

Non funziona per tutti i dispositivi. Ho un adattatore di rete Cavium che non si spegne con quel metodo in quanto posso ancora accedere al suo u-boot quando utilizzo una linea seriale.
Eric

7

I ripristini in PCI express sono un po 'complessi. Esistono due tipi principali di ripristini: il ripristino convenzionale e il ripristino a livello di funzione. Esistono anche due tipi di ripristini convenzionali, ripristini fondamentali e ripristini non fondamentali. Vedi le specifiche PCI Express per tutti i dettagli.

Un "ripristino a freddo" è un ripristino fondamentale che ha luogo dopo che l'alimentazione è stata applicata a un dispositivo PCIe. Sembra che non ci sia un modo standard di innescare un ripristino a freddo, tranne per spegnere e riaccendere il sistema. Sul mio computer, la /sys/bus/pci/slotsdirectory è vuota.

Un "ripristino a caldo" è un ripristino fondamentale che viene attivato senza scollegare l'alimentazione dal dispositivo. Sembra che non ci sia un modo standard di innescare un ripristino a caldo.

Un "hot reset" è un reset convenzionale che viene attivato attraverso un collegamento PCI Express. Un ripristino a caldo viene attivato quando un collegamento viene forzato in inattivo elettrico o inviando i set ordinati TS1 e TS2 con il bit di ripristino a caldo impostato. Il software può avviare un ripristino a caldo impostando e quindi cancellando il bit di ripristino del bus secondario nel registro di controllo del ponte nello spazio di configurazione PCI della porta del ponte a monte del dispositivo.

Un "reset a livello di funzione" (FLR) è un reset che interessa solo una singola funzione di un dispositivo PCI Express. Non deve ripristinare l'intero dispositivo PCIe. L'implementazione dei ripristini a livello di funzione non è richiesta dalla specifica PCIe. Un ripristino a livello di funzione viene avviato impostando il bit di ripristino di avvio a livello di funzione nel registro di controllo del dispositivo della funzione nella struttura di capacità PCI Express nello spazio di configurazione PCI.

Linux espone la funzionalità di ripristino a livello di funzione sotto forma di /sys/bus/pci/devices/$dev/reset. La scrittura di un 1 in questo file avvierà un ripristino a livello di funzione sulla funzione corrispondente. Si noti che ciò influisce solo su quella specifica funzione del dispositivo, non dell'intero dispositivo, e i dispositivi non sono tenuti ad implementare ripristini a livello di funzione secondo le specifiche PCIe.

Non sono a conoscenza di alcun metodo "carino" per innescare un ripristino a caldo (non esiste una voce sysfs per quello). Tuttavia, è possibile utilizzare setpci per farlo:

#!/bin/bash

dev=$1

if [ -z "$dev" ]; then
    echo "Error: no device specified"
    exit 1
fi

if [ ! -e "/sys/bus/pci/devices/$dev" ]; then
    dev="0000:$dev"
fi

if [ ! -e "/sys/bus/pci/devices/$dev" ]; then
    echo "Error: device $dev not found"
    exit 1
fi

port=$(basename $(dirname $(readlink "/sys/bus/pci/devices/$dev")))

if [ ! -e "/sys/bus/pci/devices/$port" ]; then
    echo "Error: device $port not found"
    exit 1
fi

echo "Removing $dev..."

echo 1 > "/sys/bus/pci/devices/$dev/remove"

echo "Performing hot reset of port $port..."

bc=$(setpci -s $port BRIDGE_CONTROL)

echo "Bridge control:" $bc

setpci -s $port BRIDGE_CONTROL=$(printf "%04x" $(("0x$bc" | 0x40)))
sleep 0.01
setpci -s $port BRIDGE_CONTROL=$bc
sleep 0.5

echo "Rescanning bus..."

echo 1 > "/sys/bus/pci/devices/$port/rescan"

Assicurarsi che tutti i driver collegati siano scaricati prima di eseguire questo script. Questo script tenterà di rimuovere il dispositivo PCIe, quindi comanda alla porta dello switch upstream di eseguire un ripristino a caldo, quindi tenta di ripetere la scansione del bus PCIe. Questo script è stato testato solo su dispositivi con una singola funzione, quindi potrebbe essere necessario rielaborarli per dispositivi con più funzioni.


Questo script ha funzionato per il mio AMD RX480. Contesto: passthrough PCI a un guest Win10, quindi chiusura o riavvio del guest. Il riavvio del guest (senza utilizzare questo script) si bloccherebbe se la GPU fosse ancora collegata. L'esecuzione di questo script tra i due ha risolto il problema
太郎 太郎
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.