Linux crashes every time its VFIO guest shuts down

I have a computer that I have dubbed as my IntelMediaRig because Intel QuickSync is awesome. It’s running an Intel Core i3 12100 with an Intel Arc A380. I use VFIO to pass the Arc GPU to a Windows guest so that I can use AV1 encode and decode because I have been unable to get it to work on Linux yet. I would prefer to use the AV1 encode/decode functionality of the dGPU on Linux, but tbh Handbrake on Linux is also unfortunately inferior to the Windows version. This somewhat leads me to believe that it might be, at least in part, a Handbrake issue; but I have also seen other reports of the lack of AV1 functionality in the Arc Linux “drivers”.

Shutting down my guest OS causes the host to crash. Considering the guest’s propensity to reboot randomly for updates, this is getting fairly annoying. At first I thought it was an Arc issue, but after some surface digging online, I believe it may be an incorrect setup with my VFIO configuration.

P.S. It may be helpful to know that I have tried this setup on Arch Linux, Fedora, and finally Debian. I was hoping that different kernels and philosophies might allow this setup without without crashing. After Debian also kept crashing upon VFIO guest reboot, I gave up.

P.P.S. Also the workflow for this machine is that I use the Linux side of things to interface with my homelab via SSH and NFS. On the Linux side, I use MakeMKV to rip the blu-rays (or the occasional DVD). It stores them in a directory exported as a Samba share to my LAN. Windows has a bridged ethernet connection rather than a virsh NAT. Then, I use Handbrake on Windows to encode the video and place it elsewhere within the networked filesystem. Finally, I use Linux to copy or move the file onto the mounted NFS share from the homelab. The homelab also uses bind mounts to provide ro access to a Jellyfin container.

Can you capture the hosts crash log?

For Arc cards, do not passthrough the HDMI Audio device. Linux trying to reset this device on restart/shutdown is what causing the host crash.

I have two systems with Arc passthrough, one i7-13700K with A750 (for VFIO gaming) and EPYC 7551P with A380 (for encoding). I’ve only seen this issue happen with the i7-13700K/A750 one, which I used to mentioned solution to fix.

For encoding with Arc on Linux, AV1 should work just fine on a more recent kernel (IIRC, 6.3+) and ffmpeg 6.0. The encoder is “av1_qsv” under ffmpeg (I’ve been using it with the forementioned A380 system). You can verify if AV1 is available by running ffmpeg -codecs |grep _qsv. (The upcoming Handbrake 1.7.0 will use ffmpeg 6.)

4 Likes

So I put Arch Linux back on this machine. It’s using kernel 6.5. I ran the FFMPEG command you provided, and AV1 shows up. After installing the intel-media-driver with pacman and Handbrake-full from the AUR, I still do not see Intel QSV AV1 options within Handbrake. Could it be that it’s using the iGPU?

Can you try handbrake-git from AUR and see if it shows up there?

Alternatively, perhaps try using ffmpeg directly. This is the script I’m using with my Jellyfin for reencoding a TV recording:

#!/bin/sh

NICE=${NICE:-nice}
NICE_LEVEL=${NICE_LEVEL:-20}
FFMPEG=${FFMPEG:-/usr/bin/ffmpeg}
OUTPUT_EXT=${OUTPUT_EXT:-mkv}

QSV_AV1_LAD=40
QSV_AV1_BITRATE=3072 # kbit

reencode() {
    src=$1
    dst=$2

    # https://github.com/intel/media-delivery/blob/master/doc/quality.rst
    ${NICE} -n ${NICE_LEVEL} ${FFMPEG} \
        -y \
        -nostdin \
        -hide_banner \
        -extra_hw_frames "$QSV_AV1_LAD" \
        -i "$src" \
        -map 0:v \
        -map 0:a \
        -ignore_unknown \
        -g 256 \
        -vf yadif=0:-1:0 \
        -c:v av1_qsv \
        -b:v "${QSV_AV1_BITRATE}K" \
        -maxrate "$((QSV_AV1_BITRATE * 2))K" \
        -bufsize "$((QSV_AV1_BITRATE * 4))K" \
        -rc_init_occupancy "$((QSV_AV1_BITRATE * 2))K" \
        -tile_cols 2 \
        -tile_rows 2 \
        -profile:v 1 \
        -preset veryslow \
        -extbrc 1 \
        -look_ahead_depth "$QSV_AV1_LAD" \
        -b_strategy 1 \
        -bf "$((QSV_AV1_LAD - 1))" \
        -adaptive_i 1 \
        -adaptive_b 1 \
        -strict 1 \
        -c:a libopus \
        -b:a 128k \
        -ac 2 \
        "$dst"
}

usage() {
    echo >&2 "Usage: $(basename "$0") SRC"
    exit 2
}

error() {
    echo >&2 "Error: $*"
    exit 1
}

main() {
    src=$1

    [ -n "$src" ] || usage
    [ -f "$src" ] || error "Error: src is not a file" 

    srcdir=$(dirname "$src")
    srcfile=$(basename "$src")
    dstname=${srcfile%.*}_encoded.${OUTPUT_EXT}

    reencode "$src" "$srcdir/$dstname"
}

main "$@"

Set QSV_AV1_LAD to 8 for performance mode (40 is quality mode). For tone mapping and such, try adapting this StackOverflow answer:

Late reply but as someone who has only did some stuff to get decoding working and not encoding and has seen some stuff come up, you should be able to make things work with Handbrake. There were issues in Arch Linux documented here where the main issues seem to be if you had the GUC firmware working and if you installed onevpl-intel-gpu from here if using the flatpak. You may also need to use a ffmpeg compiled with oneVPL but it doesn’t seem to be necessary.

2 Likes