Ciclo de energia de disco PCIe NVMe

6

Eu quero testar um SSD NVMe que está conectado a um slot PCIe da minha placa-mãe. O procedimento de teste é um algoritmo específico que grava cargas de trabalho no SSD, enquanto o SSD é exposto a radiações (por exemplo, nêutrons)

Estou executando o Fedora 22, com o kernel 4.4.6.

Meu software atual funciona com sucesso com o SSD SATA. Como o SSD pode se tornar irresponsivo devido às radiações, às vezes é obrigatório fazer o ciclo de energia para retomar as operações. Isso é possível com uma fonte de alimentação controlada externamente.

Agora, gostaria de portar meu software para testar o NVMe SSD PCIe. Eu modifiquei um extensor PCIe para aplicar tensão externamente ao SSD; as linhas de energia derivadas (+ 12V e 3.3V) são isoladas das linhas de energia do conector PCIe. Com esta configuração, o SSD é bem reconhecido - e funciona - ao inicializar com a fonte de alimentação externa.

Remover o dispositivo e redigitalizar o barramento PCI funciona enquanto o SSD NVMe estiver ligado, a saber:

echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/remove

seguido por:

echo 1 > /sys/bus/pci/rescan

funciona. No entanto, se eu desligar e depois ligar o dispositivo após removê-lo, o barramento PCI rescan não funcionará (e nenhuma mensagem será exibida em dmesg )

Se eu "brutalmente" desligar o SSD (com minha fonte de alimentação controlada) sem remover o SSD em sysfs , eu obteria o seguinte:

[  192.688934] nvme 0000:01:00.0: Failed status: ffffffff, reset controller
[  192.689274] Trying to free nonexistent resource <000000000000e000-000000000000e0ff>
[  192.699900] nvme 0000:01:00.0: Refused to change power state, currently in D3
[  192.699946] Trying to free nonexistent resource <000000000000e000-000000000000e0ff>
[  192.699953] nvme 0000:01:00.0: Device failed to resume

E, obviamente, digitalizar novamente o barramento PCI não faz nada.

Pergunta: o que seria necessário para alcançar o ciclo de potência do SSD sem reiniciar a estação de teste? A partir de tópicos semelhantes, eu entendo que esse problema não é trivial, então eu ficaria satisfeito com uma ampla gama de soluções - ou dicas -, incluindo:

  • Adicionando parâmetros de inicialização do kernel
  • Uso de comandos setpci (dicas?)
  • Uso de lógica extra, por exemplo fazer modificações no extensor PCIe para "enganar" o barramento PCIe
  • Modificações nas fontes do kernel (dicas?)
por mamahuhu 14.04.2016 / 14:52

1 resposta

0

É improvável que o dispositivo funcione novamente, mas pode fazer com que o dispositivo responda o suficiente para responder à remoção. Enquanto o dispositivo estiver ok, salve todos os registradores de configuração pci e, após o ciclo de energia, os restaure. Você pode obter algum caminho para isso, encontrando o slot do controlador

$ lspci | grep SATA
00:1f.2 SATA controller: Intel Corporation 7 Series Chipset Family 6-port SATA Controller [AHCI mode] (rev 04)

listando os nomes dos registradores e passando cada um para setpci (você não precisa ser root):

$ setpci --dumpregs |
awk -v slot='00:1f.2' 'NR>1 && !/ E?CAP/{
  reg = tolower($NF)
  printf "%s=",reg
  system("setpci -s " slot " " reg)
}'

Isso gera linhas como

vendor_id=8086
device_id=1e03
command=0407
status=02b0
base_address_0=0000f0b1
base_address_1=0000f0a1
base_address_2=0000f091
base_address_3=0000f081
base_address_4=0000f061
base_address_5=f7c06000

Obviamente, alguns desses registradores são somente leitura, ou possuem somente leitura de bits. A idéia é chamar sudo setpci -s "$slot" com cada uma dessas linhas, ignorando esse aspecto.

O acima apenas lida com os registradores básicos de configuração pci. No entanto, você precisará salvar e restaurar alguns registros de capacidade também. Isso vai exigir mais esforço, dependendo do registro. Você também precisa ser root para lê-los. Por exemplo,

sudo setpci -s 00:1f.2   CAP_MSI+0.l CAP_MSI+4.l CAP_MSI+8.l

imprimirá os registros de recursos MSI:

00017005
fee0200c
000041b1

Compare isso com os valores mostrados por

sudo lspci -s "$slot" -vvv
    ...
    Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
            Address: fee0200c  Data: 41b1
    
por 14.04.2016 / 16:21