Como redefinir / desligar a energia de um dispositivo PCIe?

20

Eu tenho um dispositivo PCIe que só funciona corretamente quando o computador está totalmente desligado e ligado novamente. A emissão de um comando rebootou simples reboot -pnão parece ligar e desligar a placa PCIe, o que faz com que ela não funcione após a reinicialização.

Existe uma maneira de, no sistema operacional, ligar e desligar o dispositivo em um slot PCIe? Posso encontrá-lo /sys/bus/pci/devices/0000*/, mas não consigo descobrir como redefinir adequadamente o quadro. Alternar o poder parece ser o único caminho.

Exceto isso, posso alterar uma configuração em algum lugar que cause um ciclo de energia total em um rebootcomando?

Estou executando o Ubuntu 12.10 por sinal.

zachd1_618
fonte
Você tentou reboot -f? É semelhante a pressionar o botão liga / desliga da CPU.
Ktc #
11
Há dois anos, o OP apontou que um soft rebootnão funcionou. Você reboot -fainda é uma reinicialização suave.
roaima

Respostas:

16

Método Potencial # 1

Eu acho que você pode fazê-lo com estes comandos:

desabilitar

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

habilitar

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

Onde $NUMBERestá o número do slot PCI.

lspci -vvpode ajudar a identificar o dispositivo. Isso não está muito bem documentado ...

Método potencial # 2

Me deparei com este tópico no U&L , problema semelhante: existem algumas respostas para essa pergunta que dizem que você pode redefinir com este comando:

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

No entanto, eu leria as respostas lá! Existem condições para fazê-lo desta maneira! Especificamente, eu iria ler esta resposta !

Método potencial # 3

Existe um comando Unix,, setpcique pode fornecer um método para redefinir um dispositivo no barramento PCI.

Como não vi nenhum exemplo específico com esse comando, você terá que procurar no Google por exemplos e consultar a página de manual . Eu pisaria levianamente com este comando até que você esteja confiante em seu uso. Pelo que li sobre isso, ele está manipulando o hardware diretamente e, portanto, sempre há riscos em fazê-lo você mesmo, em comparação com o uso de uma ferramenta que está expondo esse tipo de funcionalidade!

slm
fonte
11
Nada aparece nos slots, mesmo que eu tenha várias placas conectadas. Eu tenho um diretório de energia /sys/bus/pci/devices/$NUMBER/. Mas nada parece configuração mandado de 0 ou 1
zachd1_618
11
Me deparei com este tópico no U&L , problema semelhante: existem algumas respostas para esse Q que dizem que você pode redefinir com isso: echo "1"> / sys / bus / pci / devices / $ NUMBER / reset. Leia que Q, no entanto, existem condições para fazê-lo dessa maneira!
Slm
Obrigado pelo link. Eu tentei isso no entanto e parece não fazer nada. Especificamente, o dispositivo não liga e o sistema ainda sabe que está lá. (Quando a placa está ligada e conectada, existem dispositivos em / dev que eu posso assistir). Eles não desaparecem quando eu echo "1" > ....
precisa saber é o seguinte
11
Você está descarregando os módulos do kernel para essa placa antes do ciclo de energia? Eu acho que você tem que fazer isso também.
slm
11
Acho que vou verificar o código fonte do kernel para ver se a alternância powerrealmente o coloca no D3.
forest
7

removee rescanpermitirá que o kernel ligue e ligue o dispositivo PCI sem reboot:

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

where DDDD.BB.DD.F = Domínio: Barramento: Device.Function

cibernético
fonte
echo "1"> / sys / bus / pci / rescan é trabalhado para mim no slot pci lenovo g560 mini. Liguei a placa USB 3.0 minipci. Sistema é Ubuntu 16.04 x64
kodmanyagha
Não funciona para todos os dispositivos. Eu tenho um adaptador de rede Cavium que não é desligado por esse método, pois ainda posso acessar o seu u-boot ao usar uma linha serial.
Eric
7

As redefinições no PCI Express são um pouco complexas. Existem dois tipos principais de redefinições - redefinição convencional e redefinição no nível da função. Existem também dois tipos de redefinições convencionais, redefinições fundamentais e redefinições não fundamentais. Veja a especificação PCI Express para todos os detalhes.

Uma 'redefinição a frio' é uma redefinição fundamental que ocorre após a energia ser aplicada a um dispositivo PCIe. Parece não haver uma maneira padrão de ativar uma reinicialização a frio, exceto para desligar e ligar o sistema novamente. Nas minhas máquinas, o /sys/bus/pci/slotsdiretório está vazio.

Uma 'reinicialização a quente' é uma reinicialização fundamental que é acionada sem desconectar a energia do dispositivo. Parece não haver uma maneira padrão de acionar uma redefinição a quente.

Uma 'redefinição a quente' é uma redefinição convencional que é disparada através de um link PCI Express. Uma reinicialização a quente é acionada quando um link é forçado a inatividade elétrica ou enviando conjuntos ordenados TS1 e TS2 com o bit de reinicialização a quente definido. O software pode iniciar uma redefinição a quente definindo e limpando o bit de redefinição do barramento secundário no registro de controle da ponte no espaço de configuração PCI da porta da ponte a montante do dispositivo.

Uma 'redefinição no nível da função' (FLR) é uma redefinição que afeta apenas uma única função de um dispositivo PCI Express. Não deve redefinir todo o dispositivo PCIe. A implementação de redefinições no nível da função não é exigida pela especificação PCIe. Uma redefinição no nível da função é iniciada definindo o bit de redefinição no nível da função no registro de controle do dispositivo da função na estrutura de capacidade do PCI Express no espaço de configuração do PCI.

O Linux expõe a funcionalidade de redefinição no nível da função na forma de /sys/bus/pci/devices/$dev/reset. Escrever 1 neste arquivo iniciará uma redefinição no nível da função na função correspondente. Observe que isso afeta apenas a função específica do dispositivo, não o dispositivo inteiro, e os dispositivos não são necessários para implementar redefinições no nível da função, conforme a especificação PCIe.

Não conheço nenhum método 'bom' para acionar uma redefinição a quente (não há entrada sysfs para isso). No entanto, é possível usar o setpci para fazer isso:

#!/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"

Verifique se todos os drivers conectados estão descarregados antes de executar este script. Este script tentará remover o dispositivo PCIe, depois comandará a porta do switch upstream para emitir uma redefinição a quente e, em seguida, tentará verificar novamente o barramento PCIe. Esse script também foi testado apenas em dispositivos com uma única função; portanto, pode ser necessário retrabalhar para dispositivos com várias funções.

alex.forencich
fonte
Este script funcionou para o meu AMD RX480. Contexto: passagem do PCI para um convidado do Win10 e, em seguida, encerra ou reinicia o convidado. Iniciar o convidado novamente (sem usar esse script) seria interrompido se a GPU ainda estivesse conectada. A execução deste script entre corrigiu o problema
小太郎