2023-05-15

Linux Mint で r8168-dkms ドライバーを試してみた

PC をサスペンドから復帰させた直後、インターネットにアクセスできない状態が 1分ほど発生したので、なんとかならないものかと調べてみました。

この PC の NIC は Realtek の RTL8118AS というチップらしいです。GIGABYTE のマザーボードにオンボードで搭載されているものです。

これまでも使用中に数十秒ほどインターネットが不通になる時があり、対処として DNS サーバーをプロバイダーの自動設定のものから Google や Cloudflare の Pubric DNS に固定することで回避できるようになった気がしていました。(IPv4、IPv6 とも固定して効果が出た気がした)

ところが、「最近だいぶ調子が良くなったなぁ」と思った矢先に PC をサスペンドから解除したタイミングで再び数十秒ほどのインターネット不通が再発してしまったのです。

 

サスペンドを解除したタイミングで必ず発生するわけではないので、何も問題がなかった時と再発した時のシステムログを journalctl コマンドで比べてみました。

すると、以下のようなメッセージが再発時にのみ出力されていました。

NetworkManager[940]:   [1683972858.7330] dhcp6 (eno1): activation: beginning transaction (timeout in 45 seconds)

これを手がかりに障害情報を探ってみると、どうも Linux Mint というか Ubuntu のインストーラーが NIC のドライバーとして r8169 を選択してしまうことで多少の問題が発生しているようでした。

これを回避するために r8168-dkms というパッケージをインストールしている方がボチボチ散見される状況でした。

 

手順は簡単で、以下の通りです。

apt install r8168-dkms
sudo su
echo "blacklist r8169"  > /etc/modprobe.d/blacklist-r8169.conf

その後は PC を再起動します。

 

(追記)
r8168-dkms をインストールすることで /etc/modprobe.d/r8168-dkms.conf が自動的に作成されていたので、blacklilst.-r8169.conf を自分で作成する必要はありませんでした。

以下、r8168-dkms.conf の内容です。

# settings for r8168-dkms

# map the specific PCI IDs instead of blacklisting the whole r8169 module
alias	pci:v00001186d00004300sv00001186sd00004B10bc*sc*i*	r8168
alias	pci:v000010ECd00008168sv*sd*bc*sc*i*			r8168

# if the aliases above do not work, uncomment the following line
# to blacklist the whole r8169 module
#blacklist r8169

 

こちらは r8169 ドライバー(インストール時に自動で選定されたもの)で PC を起動した時のシステムログです。

kernel: r8169 0000:03:00.0 eth0: RTL8168h/8111h, e0:d5:5e:d9:f7:40, XID 541, IRQ 42
kernel: r8169 0000:03:00.0 eth0: jumbo features [frames: 9194 bytes, tx checksumming: ko]
kernel: r8169 0000:03:00.0 eno1: renamed from eth0
kernel: Generic FE-GE Realtek PHY r8169-0-300:00: attached PHY driver (mii_bus:phy_addr=r8169-0-300:00, irq=MAC)
kernel: r8169 0000:03:00.0 eno1: Link is Down
kernel: r8169 0000:03:00.0 eno1: Link is Up - 1Gbps/Full - flow control rx/tx
kernel: r8169 0000:03:00.0 eno1: Link is Down
kernel: r8169 0000:03:00.0 eno1: Link is Up - 1Gbps/Full - flow control off

 

こちらは r8168-dkms ドライバー(手動で差し替えたもの)で PC を起動した時のシステムログです。

kernel: r8168: loading out-of-tree module taints kernel.
kernel: r8168: module verification failed: signature and/or required key missing - tainting kernel
kernel: r8168 Gigabit Ethernet driver 8.049.02-NAPI loaded
kernel: r8168: This product is covered by one or more of the following patents: US6,570,884, US6,115,776, and US6,327,625.
kernel: r8168  Copyright (C) 2021 Realtek NIC software team  
kernel: r8168 0000:03:00.0 eno1: renamed from eth0
kernel: r8168: eno1: link up
kernel: r8168: eno1: link up

 

なんか全然別物に見えますね。 r8168-dkms は Realtek の中の人が作っているんでしょうか?


ちょっとまだドライバーを差し替えたばかりでサスペンド解除時の動作は回数がこなせていないですが、しばらくこの状態で様子を見てみたいと思います。

 

(追記)
r8168-dkms ドライバーの場合、サスペンドに入る度に 5秒ほど余計に時間がかかるようになってしまいました。r8169 ドライバーだとサスペンドは瞬時に終わるのですが。むむむ・・・。

結局は元の r8169 ドライバーに戻してしまいました。
・r8168-dkms の場合、毎日に 2回のサスペンドを行うと 5秒待ち x 2回 x 30日 = 300秒待ち
・r8169 の場合、45秒待ち x 1回 x 1日 = 45秒待ち

サスペンド突入時の 5秒待ちは 100% で発生するのですが、サスペンドからの復帰時の待ちは月に 1回程度とすると、トータルでは r8169 の方が待ち時間が少ないと判断したからです。

やっぱりサスペンドはスッと終了してくれた方がストレスがないです。

(さらに追記)
サスペンドから復帰して、直後は Firefox でインターネットにアクセスできたのですが、数分後にインターネットにアクセスできなくなってしまいました。ネットワーク接続を手動で切断した後に再度接続して復旧させました。(自動回復をじっと待ってるよりも速く回復できるらしいですが、数十秒はかかった気がします)

再びシステムログを確認してみると以下のようなメッセージが出力されていたことに気づきました。

$ systemctl status networking.service
● networking.service - Raise network interfaces
     Loaded: loaded (/lib/systemd/system/networking.service; enabled; vendor preset: enabled)
     Active: active (exited) since Tue 2023-05-16 13:22:08 JST; 2 days ago
       Docs: man:interfaces(5)
   Main PID: 975 (code=exited, status=0/SUCCESS)
        CPU: 18ms

 5月 16 13:22:08 systemd[1]: Starting Raise network interfaces...
 5月 16 13:22:08 ifup[1091]: /etc/network/if-up.d/resolved: 12: mystatedir: not found
 5月 16 13:22:08 systemd[1]: Finished Raise network interfaces.

この mystatedir というキーワードで調べてみると、どうやら ifupdown というパッケージのバグで、Ubuntu 22.10 向けには ifupdown  0.8.36+nmu1ubuntu4 というバージョンで修正されているようなんですが、22.04 向けにはまだリリースされていないようです。

wrong var declaration in if-up.d/resolved (nm-dispatcher[54417]: /etc/network/if-up.d/resolved: 12: mystatedir: not found)

このバグがワタシの事象の原因なのかはハッキリしませんが、スクリプトを手動で修正すればよいようなので、修正してみました。

$ cat /etc/network/if-up.d/resolved | nl
     1	#!/bin/sh
     2	#
     3	# Script fragment to make ifupdown supply DNS infromation to resolved
     4	#
       
     5	case "$ADDRFAM" in
     6	    inet|inet6) : ;;
     7	    *) exit 0 ;;
     8	esac            
       
     9	if systemctl is-enabled systemd-resolved > /dev/null 2>&1; then
    10	    mystatedir statedir ifindex interface
       
    11	    interface=$IFACE
    12	    if [ ! "$interface" ]; then
    13	        return
    14	    fi

これは修正前の状態ですが、10行目の行頭に # を挿入してコメントアウト状態にしてしまいます。11行目に「interface=$IFACE」というように 10行目に登場している変数に値をセットしているので、10行目は何のため?という状況です。同じように mystatedir などの変数もその後に変数に値がセットされていたため、10行目はコメントアウトで良さそうです。

$ sudo systemctl restart networking.service

$ systemctl status networking.service
● networking.service - Raise network interfaces
     Loaded: loaded (/lib/systemd/system/networking.service; enabled; vendor preset: enabled)
     Active: active (exited) since Thu 2023-05-18 20:07:29 JST; 9s ago
       Docs: man:interfaces(5)
    Process: 96259 ExecStart=/sbin/ifup -a --read-environment (code=exited, status=0/SUCCESS)
   Main PID: 96259 (code=exited, status=0/SUCCESS)
        CPU: 20ms

 5月 18 20:07:29 systemd[1]: Starting Raise network interfaces...
 5月 18 20:07:29 systemd[1]: Finished Raise network interfaces.

スクリプトの編集が終わったら、networking.service を再起動させました。その後に systemctl status で状況を確認してみると、以前は出力されていた「not found」というエラーメッセージは消えていました。

この状態でまたサスペンドからの復帰後の様子を見てみようと思います。