NVMe PCIe 디스크 전원 사이클링

NVMe PCIe 디스크 전원 사이클링

마더보드의 PCIe 슬롯에 연결된 NVMe SSD를 테스트하고 싶습니다. 테스트 프로세스는 SSD가 방사선(예: 중성자)에 노출되는 동안 SSD에 작업 부하를 기록하는 특정 알고리즘입니다.

저는 커널 4.4.6과 함께 Fedora 22를 실행하고 있습니다.

현재 소프트웨어가 SATA SSD에서 성공적으로 작동합니다. 방사선으로 인해 SSD가 응답하지 않을 수 있으므로 작동을 재개하려면 SSD를 다시 시작해야 하는 경우가 있습니다. 이는 외부 제어 전원 공급 장치를 통해 달성할 수 있습니다.

이제 NVMe SSD PCIe를 테스트하기 위해 소프트웨어를 포팅하고 싶습니다. SSD에 외부적으로 전압을 적용하기 위해 PCIe 확장기를 수정했습니다. 파생 전원 라인(+12V 및 3.3V)은 PCIe 커넥터 전원 라인과 격리되어 있습니다. 이렇게 설정하면 외부 전원을 켠 상태에서 부팅 시 SSD가 잘 인식되어 제대로 작동하게 됩니다.

NVMe SSD의 전원이 켜져 있는 동안 장치를 제거하고 PCI 버스를 다시 검색하십시오. 즉, 다음과 같습니다.

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

다음은:

echo 1 > /sys/bus/pci/rescan

일하다. 그러나 장치를 제거한 후 전원을 껐다가 다시 켜면 PCI 버스가 rescan작동하지 않습니다(그리고 메시지도 나타나지 않습니다 dmesg).

아래에 있는 SSD를 제거하지 않고 SSD의 전원을 "잔인하게" 끄면(내가 제어하는 ​​전원 공급 장치 사용) sysfs다음과 같은 결과가 나타납니다.

[  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

분명히 PCI 버스를 다시 검색해도 효과가 없습니다.

질문: 테스트 스테이션을 다시 시작하지 않고 SSD의 전원을 껐다 켜려면 무엇이 필요합니까? 유사한 스레드를 통해 이 문제가 사소한 것이 아니라는 것을 이해하므로 다음을 포함한 다양한 솔루션(또는 팁)에 만족하겠습니다.

  • 커널 부팅 매개변수 추가
  • 명령 사용법 setpci(팁?)
  • PCIe 확장기의 라인을 수정하여 PCIe 버스를 "스푸핑"하는 등의 추가 논리를 사용하십시오.
  • 커널 소스 코드 수정(힌트?)

답변1

이렇게 하면 장치가 다시 작동하는 데 성공할 가능성이 낮지만 장치가 제거에 응답할 만큼 충분히 반응하게 만들 수 있습니다. 장치가 정상일 때 모든 PCI 구성 레지스터를 저장하고 전원을 껐다 켠 후 복원하십시오. 컨트롤러 슬롯을 찾아서 이 작업을 수행할 수 있습니다.

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

그런 다음 레지스터 이름을 나열하고 각 레지스터 이름을 setpci에 전달합니다(루트일 필요는 없음).

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

그러면 선이 다음과 같이 보일 것입니다.

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

분명히 이러한 레지스터 중 일부는 읽기 전용이거나 읽기 전용 비트를 가지고 있습니다. 아이디어는 sudo setpci -s "$slot"이 측면을 무시하고 각 행을 호출하는 것입니다.

위의 내용은 기본 pci 구성 레지스터만 다룹니다. 그러나 일부 기능 레지스터도 저장하고 복원해야 합니다. 이를 위해서는 레지스터에 따라 더 많은 노력이 필요합니다. 또한 해당 내용을 읽으려면 루트 권한이 있어야 합니다. 예를 들어,

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

MSI 기능 레지스터를 인쇄합니다.

00017005
fee0200c
000041b1

이 값을 표시된 값과 비교하십시오.

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

관련 정보