0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Linux 6.17でPLEX録画の音飛びを修正する(smsdvbドライバのsysfs_emit_at警告対応)

0
Posted at

title: Linux 6.17でPLEX録画の音飛びを修正する(smsdvbドライバのsysfs_emit_at警告対応)
tags:

  • Linux
  • Ubuntu
  • 録画
  • カーネルモジュール
  • NHK

はじめに

Ubuntu 24.04 + Linux kernel 6.17 環境でdocker-mirakurun-epgstationを使って録画していたところ、録画ファイルに断続的な音飛びが発生するようになりました。

調査の結果、Linux 6.17で追加されたsysfs_emit_at()の厳格な検証チェックが、USBチューナードライバ(smsdvb)で誤発火し、USBの割り込み処理に遅延が生じてTSパケットがドロップしていたことが原因でした。

本記事では原因の特定から修正・適用までの手順を解説します。


環境

項目 内容
OS Ubuntu 24.04 LTS
カーネル Linux 6.17.0-20-generic (HWE)
チューナー PLEX PX-S1UD(Sianoチップ搭載 USBチューナー)
録画ソフト docker-mirakurun-epgstation
チューナーコマンド dvbv5-zap + arib-b25-stream-test

症状

  • 録画した.tsファイルを再生すると、数分おきに音声が一瞬途切れる
  • 映像は乱れないが音だけ飛ぶ
  • リアルタイム視聴でも同様の現象が発生

原因調査

dmesgを確認したところ、録画中に以下のWARNINGが繰り返し出力されていました。

[2304623.686375] invalid sysfs_emit_at: buf:000000001fec78bb at:0
[2304623.686384] WARNING: CPU: 0 PID: 0 at fs/sysfs/file.c:795 sysfs_emit_at+0x63/0xd0
...
[2304623.686675]  smsdvb_print_isdb_stats_ex+0x42e/0x650 [smsdvb]
[2304623.686682]  smsdvb_update_isdbt_stats_ex+0x31/0x6e0 [smsdvb]
[2304623.686694]  smsdvb_onresponse+0x2bc/0x660 [smsdvb]

根本原因

sysfs_emit_at()はLinux 6.17でsysfsページバッファ以外から呼ばれた場合にWARN_ONを発火する検証ロジックが追加されました。

drivers/media/common/siano/smsdvb-debugfs.cでは、構造体内のchar stats_data[PAGE_SIZE]バッファ(syfsページではない)に対してsysfs_emit_at()を使って統計情報を書き込んでいます。そのため、チューナーからレスポンスが届くたびにWARN_ONが発火。

WARN_ONはカーネルのスタックトレース出力を伴うため、USB割り込みコンテキストで数msの遅延が生じ、TSパケットのドロップ → 音飛びにつながっていました。


修正方法

sysfs_emit_at(buf, n, fmt, ...)snprintf(buf + n, PAGE_SIZE - n, fmt, ...) に置き換えます。

対象ファイル:drivers/media/common/siano/smsdvb-debugfs.c(104箇所)

手順

1. カーネルソースを取得

mkdir -p ~/kernel-build && cd ~/kernel-build
apt-get source linux-hwe-6.17

deb-srcが有効になっている必要があります。確認方法:

grep "deb-src" /etc/apt/sources.list /etc/apt/sources.list.d/*.sources 2>/dev/null | grep -v "^#"

2. 対象ファイルを確認

find ~/kernel-build/linux-hwe-6.17-6.17.0 -name "smsdvb-debugfs.c"
# → ~/kernel-build/linux-hwe-6.17-6.17.0/drivers/media/common/siano/smsdvb-debugfs.c

3. sysfs_emit_at → snprintf に一括置換

sed -i 's/sysfs_emit_at(buf, n, /snprintf(buf + n, PAGE_SIZE - n, /g' \
    ~/kernel-build/linux-hwe-6.17-6.17.0/drivers/media/common/siano/smsdvb-debugfs.c

置換件数の確認:

grep -c "snprintf" ~/kernel-build/linux-hwe-6.17-6.17.0/drivers/media/common/siano/smsdvb-debugfs.c
# → 104
grep -c "sysfs_emit_at" ~/kernel-build/linux-hwe-6.17-6.17.0/drivers/media/common/siano/smsdvb-debugfs.c
# → 0

4. カーネルヘッダーの確認

dpkg -l linux-headers-$(uname -r)
# ii  linux-headers-6.17.0-20-generic ...

インストールされていない場合:

sudo apt install linux-headers-$(uname -r)

5. モジュールのビルド

cd ~/kernel-build/linux-hwe-6.17-6.17.0
make -C /lib/modules/$(uname -r)/build M=$(pwd)/drivers/media/common/siano modules

成功するとsmsdvb.koが生成されます:

  CC [M]  smsdvb-debugfs.o
  LD [M]  smsdvb.o
  LD [M]  smsdvb.ko

6. 既存モジュールをバックアップして差し替え

現在のモジュールはzstd圧縮(.ko.zst)されているので、圧縮してから配置します。

# バックアップ
sudo cp /lib/modules/$(uname -r)/kernel/drivers/media/common/siano/smsdvb.ko.zst \
        /lib/modules/$(uname -r)/kernel/drivers/media/common/siano/smsdvb.ko.zst.bak

# 新モジュールを圧縮
zstd -19 ~/kernel-build/linux-hwe-6.17-6.17.0/drivers/media/common/siano/smsdvb.ko \
     -o /tmp/smsdvb.ko.zst

# zstdファイルの検証
zstd -t /tmp/smsdvb.ko.zst

# 配置
sudo cp /tmp/smsdvb.ko.zst \
        /lib/modules/$(uname -r)/kernel/drivers/media/common/siano/smsdvb.ko.zst

7. モジュールの再読み込み

sudo depmod -a
sudo modprobe -r smsdvb
sudo modprobe smsdvb

8. 確認

sudo dmesg | grep -E "smsdvb|sysfs_emit|WARNING" | tail -20

修正前:

[xxxxxx] invalid sysfs_emit_at: buf:000000001fec78bb at:0
[xxxxxx] WARNING: CPU: 0 PID: 0 at fs/sysfs/file.c:795 sysfs_emit_at+0x63/0xd0

修正後(新モジュールロード後にWARNINGが出なくなる):

[xxxxxx] smsdvb: loading out-of-tree module taints kernel.
[xxxxxx] smsdvb: module verification failed: signature and/or required key missing - tainting kernel
[xxxxxx] smsdvb:smsdvb_hotplug: DVB interface registered.
[xxxxxx] smsdvb:smsdvb_hotplug: DVB interface registered.
[xxxxxx] smsdvb:smsdvb_hotplug: DVB interface registered.
[xxxxxx] smsdvb:smsdvb_hotplug: DVB interface registered.

WARNINGが消え、DVBインターフェースが正常に登録されました。


注意事項

カーネルが"tainted"になる

自前ビルドのモジュールは署名がないため、module verification failedと表示されカーネルがtainted状態になります。動作に支障はありません。

カーネルアップデート時に元に戻る

apt upgradeでカーネルが更新されると、このモジュールは上書きされます。その場合は再度ビルドが必要ですが、ソースは~/kernel-build/に残っているので手順5以降を繰り返すだけで済みます。


まとめ

項目 内容
原因 Linux 6.17のsysfs_emit_at()にsysfsページ検証が追加され、smsdvbドライバで誤発火
影響 USB割り込み遅延 → TSパケットドロップ → 音飛び
修正 sysfs_emit_at(buf, n, ...)snprintf(buf + n, PAGE_SIZE - n, ...) に置換(104箇所)
対象ファイル drivers/media/common/siano/smsdvb-debugfs.c

同じ環境(PLEX PX-S1UD/PX-Q1UD/VASTDTV VT20など Sianoチップ搭載USBチューナー + Linux 6.17)で録画の音飛びに悩んでいる方の参考になれば幸いです。


参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?