Qemu TRIM e descartar em um dispositivo SSD físico

1

Estou executando o Windows 7 em um Qemu / KVM com uma GPU passada, usada em materiais relacionados ao trabalho. Eu recentemente me aborreci com sua lentidão sem precedentes devido a uma unidade mecânica, então adicionei um SSD à minha caixa para 'dar' ao meu Windows-KVM. Estou usando as seguintes opções de linha de comando do qemu para o disco 'passado por': -drive file=/dev/disk/by-id/wwn-0x5002538d4002d61f,if=none,id=drive-scsi0-0-0-0,format=raw,discard=on" \ -device virtio-scsi-pci,id=scsi0" \ -device scsi-hd,bus=scsi0.0,drive=drive-scsi0-0-0-0"

Eu esperava que os comandos TRIM guest-OS fossem realmente passados para a unidade física no host, mas esse parece não ser o caso.

O "discard = on" afeta somente as unidades suportadas por arquivos de imagem, e não por SSDs físicos reais? Em caso afirmativo, como eu seria capaz de realizar comandos TRIM para o dispositivo no sistema operacional convidado a ser passado para o dispositivo físico no host? Está usando um arquivo de imagem no host a única solução? Eu estou esperando por algo melhor, já que ter um sistema de arquivos naquele disco só criaria sobrecarga, e eu não preciso disso para mais nada.

    
por nohupper 09.02.2018 / 05:17

2 respostas

2

Pesquisa

O Qemu trata discard=unmap e discard=on da mesma forma:

block.c (linha 773): } else if (!strcmp(mode, "on") || !strcmp(mode, "unmap")) {

Ele também parece suportar vários dos ioctls do Linux, conforme descrito aqui para escrever ou descartar zeros no nível do bloco:

bloco / arquivo-posix.c (linha 581): if (ioctl(s->fd, BLKDISCARDZEROES, &arg) == 0 && arg) {

bloco / arquivo-posix.c (linha 1374): if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {

bloco / arquivo-posix.c (linha 1509): if (ioctl(aiocb->aio_fildes, BLKDISCARD, range) == 0) {

Portanto, com base nisso, bloqueie a passagem com emulação SCSI usando as opções discard=unmap,detect-zeroes=unmap , a menos que você esteja usando um tipo de máquina Qemu antigo ou uma versão com bugs do Qemu, ambos devem funcionar.

Exemplo

Encontrou uma excelente apresentação aqui .

Lições aprendidas da apresentação:

  1. Você deve estar executando o Qemu / KVM como root ou um usuário com permissão CAP_SYS_RAWIO para descartar para não ser ignorado pelo Linux.
  2. Se o seu dispositivo de passagem for realmente um disco SCSI, ele deve prestar atenção aos comandos reais SCSI UNMAP e WRITE SAME, e você pode usar scsi-block para repasse.
  3. Se não, você terá que emular um disco SCSI com scsi-hd, que enviará os comandos de descarte pelo Qemu para a camada de bloco do Linux

Para mim, embora o uso de scsi-block para passagem permitisse acesso a estatísticas e informações SMART para o dispositivo real e o IO normal funcionasse bem, o comando de descarte não era suportado.

Como meu dispositivo de apoio é realmente SATA, portanto, IDE, não SCSI LUN, acredito que esse seja o motivo de não haver suporte a descarte dessa maneira.

Mudando de scsi-block para scsi-hd, você perderá estatísticas e informações SMART, mas ganhe o descarte ... então, um trade off.

Pessoalmente, não tive nenhuma queda de desempenho notável, passando de "true passthrough" para "emulado com passagem" para minhas necessidades.

Aqui está um exemplo de VirtSI SCSI com SCSI emulado e um dispositivo de bloco de apoio:

    -device virtio-scsi-pci,id=scsi \
    -blockdev driver=raw,node-name=disk.0,cache.direct=on,discard=unmap,file.driver=host_device,file.aio=native,file.filename=/dev/disk/by-id/ata-Samsung_SSD_840_PRO_Series_S12PNEAD233247L \
    -device scsi-hd,drive=disk.0,bus=scsi.0

A parte que você não encontrará na documentação do Qemu é a seção file.driver=host_device . é necessário que o scsi-block funcione, e parece não ferir o scsi-hd também, quando estamos usando um dispositivo de bloco real, não é um arquivo no sistema de arquivos do host.

Teste

A ferramenta blktrace que eu usei para testar as chamadas de função de nível de bloco do Linux está documentada aqui .

Você pode executar os programas blktrace e blkparse juntos para interceptar chamadas de descarte:

blktrace -a discard -d /dev/disk/by-id/ata-Samsung_SSD_840_PRO_Series_S12PNEAD233247L -o - | blkparse -i -

Agora, quando você executar defrag /L c: ou fstrim -v / em sua VM, verá muitos descartes sendo impressos no host. Exemplo de snippet da saída:

    8,0    1      493     0.641661863  3118  Q  DS 45458024 + 728 [qemu-system-x86]
    8,0    1      494     0.641664662  3118  G  DS 45458024 + 728 [qemu-system-x86]
    8,0    1      495     0.641665920  3118  I  DS 45458024 + 728 [qemu-system-x86]
    8,0    1      496     0.641669312  3118  D  DS 45458024 + 728 [qemu-system-x86]

Então, isso é prova suficiente para mim de que o descarte está funcionando.

    
por 15.06.2018 / 11:15
-1

Não sei se discard=on deve funcionar. Eu tenho discard=unmap em todas as minhas linhas de comando do qemu. E é isso que tudo o que posso encontrar na Internet diz para usar.

    
por 09.02.2018 / 17:42