Frigate + Hailo-8 na Raspberry Pi 5: instalace, patch ovladače a stabilní provoz

Frigate + Hailo-8 na Raspberry Pi 5: instalace, patch ovladače a stabilní provoz

Raspberry Pi 5 je konečně dost výkonné na seriózní video analytiku.
V kombinaci s Frigate NVR a akcelerátorem Hailo-8 dostaneš AI detekci v reálném čase s minimálním zatížením CPU.

Na novém kernelu (6.x) ale Hailo PCIe driver v defaultu narazí na několik low-level problémů:

  • HW limit DMA descriptor page size (Hailo max 4096) vs RPi kernel page size (často 16k)
  • kernel WARN kvůli find_vma() bez mmap locku
  • nestabilní userspace alokace DMA bufferů na RPi (lepší je driver-alokace)

Tady je kompletní postup, jak to rozchodit stabilně.


🧱 Použité prostředí

  • Raspberry Pi 5 (8 GB)
  • Debian 12 (Bookworm)
  • Kernel: 6.12.47+rpt-rpi-2712
  • Hailo-8 PCIe
  • Frigate v Dockeru


1) Instalace závislostí

sudo apt update
sudo apt install -y git build-essential linux-headers-$(uname -r) docker.io
sudo usermod -aG docker petka
newgrp docker

2) Stažení zdrojáků Hailo PCIe driveru přes git

V tomhle návodu používám zdrojáky hailort-drivers (PCIE driver je v linux/pcie).

cd ~
git clone https://github.com/hailo-ai/hailort-drivers.git
cd hailort-drivers

3) Patche pro kernel 6.12 + RPi5

Níže je popis změn + na konci celý git diff.


🔧 Patch A: default max_desc_page_size → 4096 (HW limit)

Soubor:

linux/pcie/src/pcie.c

Změna:

  • Původně driver používá PAGE_SIZE (na RPi to může být 16384)
  • Hailo HW ale má limit 4096, takže inference padá s chybou typu:
    max_desc_page_size given 16384 is bigger than hw max desc page size 4096

Fix:

const u32 defualt_page_size = min((u32)PAGE_SIZE, 4096u);

🔧 Patch B: vynucení driver-alokace vdma bufferů (RPi workaround)

Soubor:

linux/vdma/memory.c

Kernel WARN:

WARNING: ... find_vma+0x6c/0x80
lr: hailo_vdma_buffer_map ...

Fix je obalit find_vma():

mmap_read_lock(current->mm);
vma = find_vma(current->mm, addr_or_fd);
mmap_read_unlock(current->mm);

doplnit include:

#include <linux/mm.h>

4) Kompilace a instalace driveru

cd ~/hailort-drivers/linux/pcie
make clean
make all
sudo make install
sudo depmod -a
sudo modprobe hailo_pci

Kontrola zařízení:

ls -l /dev/hailo0
dmesg -T | grep -i hailo | tail -n 50

5) HailoRT userspace knihovny (4.21.0)

Použil jsem balíček z Frigate HailoRT release (Debian12 arm64).

cd ~
ARCH=arm64
VER=4.21.0
wget -O hailort.tar.gz "https://github.com/frigate-nvr/hailort/releases/download/v${VER}/hailort-debian12-${ARCH}.tar.gz"
sudo tar -C / -xzf hailort.tar.gz
sudo ldconfig

Kontrola knihovny:

ldconfig -p | grep -i hailo | head

Kontrola zařízení z userspace:

hailortcli scan

6) Udev práva pro /dev/hailo0 (aby to šlo bez root)

echo 'KERNEL=="hailo0", MODE="0660", GROUP="plugdev"' | sudo tee /etc/udev/rules.d/99-hailo.rules
sudo udevadm control --reload-rules
sudo udevadm trigger
sudo usermod -aG plugdev petka

7) Frigate v Dockeru (výřez docker-compose)

services:
  frigate:
    image: ghcr.io/blakeblackshear/frigate:latest
    privileged: true
    shm_size: "2gb"
    devices:
      - /dev/hailo0:/dev/hailo0
      - /dev/dri:/dev/dri
    volumes:
      - /mnt/nvr:/media/frigate
      - /mnt/nvr/frigate-config:/config
    ports:
      - "5000:5000"
      - "8554:8554"
      - "8555:8555/tcp"
      - "8555:8555/udp"

Start:

cd ~/docker
docker-compose up -d
docker-compose logs -f frigate

✅ 8) Ověření, že je to stabilní

Kontrola, že nepadá find_vma:

dmesg -T | grep -i find_vma

Kontrola, že je aktivní workaround:

dmesg -T | grep -i "Forcing driver allocated vdma buffers" | tail -n 5

Kontrola, že driver používá 4096:

cat /sys/module/hailo_pci/parameters/force_desc_page_size 2>/dev/null || true

📌 Kompletní git diff (patche)

diff --git a/linux/pcie/src/pcie.c b/linux/pcie/src/pcie.c
index c7b881f..142bcc2 100644
--- a/linux/pcie/src/pcie.c
+++ b/linux/pcie/src/pcie.c
@@ -89,7 +89,7 @@ static int hailo_get_desc_page_size(struct pci_dev *pdev, u32 *out_page_size)
     int err = 0;
     // The default page size must be smaller/equal to 32K (due to PLDA registers limit).
     const u32 max_page_size = 32u * 1024u;
-    const u32 defualt_page_size = min((u32)PAGE_SIZE, max_page_size);
+    const u32 defualt_page_size = min((u32)PAGE_SIZE, 4096u);

     if (force_desc_page_size != 0) {
         // The user given desc_page_size as a module parameter
@@ -1130,6 +1130,10 @@ static bool is_kmalloc_dma_capable(struct device *dev)

 static int hailo_get_allocation_mode(struct pci_dev *pdev, enum hailo_allocation_mode *allocation_mode)
 {
+    *allocation_mode = HAILO_ALLOCATION_MODE_DRIVER;
+    pci_notice(pdev, "Probing: Forcing driver allocated vdma buffers (RPi kernel workaround)\n");
+    return 0;
+
     // Check if module paramater was given to override driver choice
     if (HAILO_NO_FORCE_BUFFER != force_allocation_from_driver) {
         if (HAILO_FORCE_BUFFER_FROM_USERSPACE == force_allocation_from_driver) {
diff --git a/linux/vdma/memory.c b/linux/vdma/memory.c
index 7ad4a68..7e05067 100644
--- a/linux/vdma/memory.c
+++ b/linux/vdma/memory.c
@@ -4,6 +4,7 @@
  **/

 #define pr_fmt(fmt) "hailo: " fmt
+#include <linux/mm.h>

 #include "memory.h"
 #include "utils.h"
@@ -167,7 +168,9 @@ struct hailo_vdma_buffer *hailo_vdma_buffer_map(struct device *dev,
     }

     if (HAILO_DMA_DMABUF_BUFFER != buffer_type) {
+        mmap_read_lock(current->mm);
         vma = find_vma(current->mm, addr_or_fd);
+        mmap_read_unlock(current->mm);
         if (IS_ENABLED(HAILO_SUPPORT_MMIO_DMA_MAPPING)) {
             if (NULL == vma) {
                 dev_err(dev, "no vma for virt_addr/size = 0x%08lx/0x%08zx\n", addr_or_fd, size);

🎯 Závěr

Po těchto úpravách:

✔ Frigate běží stabilně
✔ HailoRT nepadají na internal failure
✔ kernel je bez WARNů
✔ inference jede naplno a CPU je v klidu