| Summary: | net/realtek-re-kmod: kernel panic when generating MAC address | ||
|---|---|---|---|
| Product: | Ports & Packages | Reporter: | Evgeni Golov <evgeni> |
| Component: | Individual Port(s) | Assignee: | Alex Dupre <ale> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | CC: | grahamperrin, kib, pi, s199p.wa1k9r |
| Priority: | --- | Keywords: | crash, needs-qa |
| Version: | Latest | Flags: | bugzilla:
maintainer-feedback?
(ale) grahamperrin: maintainer-feedback? (kib) |
| Hardware: | Any | ||
| OS: | Any | ||
@kib, any idea about the cause of the failure? This is due to ether_gen_addr() using if_name(), most likely.
Try this:
diff --git a/if_re.c b/if_re.c
index 541af57..95da310 100644
--- a/if_re.c
+++ b/if_re.c
@@ -4978,6 +4978,24 @@ static int re_attach(device_t dev)
re_reset(sc);
RE_UNLOCK(sc);
+#if OS_VER < VERSION(6,0)
+ ifp = &sc->arpcom.ac_if;
+#else
+ ifp = sc->re_ifp = if_alloc(IFT_ETHER);
+ if (ifp == NULL) {
+ device_printf(dev, "can not if_alloc()\n");
+ error = ENOSPC;
+ goto fail;
+ }
+#endif
+ ifp->if_softc = sc;
+#if OS_VER < VERSION(5,3)
+ ifp->if_unit = unit;
+ ifp->if_name = "re";
+#else
+ if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+#endif
+
/* Get station address. */
RE_LOCK(sc);
re_get_hw_mac_address(sc, eaddr);
@@ -5076,23 +5094,6 @@ static int re_attach(device_t dev)
sc->re_tx_cstag =1;
sc->re_rx_cstag =1;
-#if OS_VER < VERSION(6,0)
- ifp = &sc->arpcom.ac_if;
-#else
- ifp = sc->re_ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL) {
- device_printf(dev, "can not if_alloc()\n");
- error = ENOSPC;
- goto fail;
- }
-#endif
- ifp->if_softc = sc;
-#if OS_VER < VERSION(5,3)
- ifp->if_unit = unit;
- ifp->if_name = "re";
-#else
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
-#endif
ifp->if_mtu = ETHERMTU;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = re_ioctl;
Perhaps this variant is less intrusive
diff --git a/if_re.c b/if_re.c
index 541af57..0e99dfd 100644
--- a/if_re.c
+++ b/if_re.c
@@ -4978,25 +4978,8 @@ static int re_attach(device_t dev)
re_reset(sc);
RE_UNLOCK(sc);
- /* Get station address. */
- RE_LOCK(sc);
- re_get_hw_mac_address(sc, eaddr);
- RE_UNLOCK(sc);
-
- /*
- * A RealTek chip was detected. Inform the world.
- */
- device_printf(dev,"version:%s\n", RE_VERSION);
- device_printf(dev,"Ethernet address: %6D\n", eaddr, ":");
- printf("\nThis product is covered by one or more of the following patents: \
- \nUS6,570,884, US6,115,776, and US6,327,625.\n");
-
sc->re_unit = unit;
-#if OS_VER < VERSION(6,0)
- bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
-#endif
-
if (sc->re_type == MACFG_3) { /* Change PCI Latency time*/
pci_write_config(dev, RE_PCI_LATENCY_TIMER, 0x40, 1);
}
@@ -5119,6 +5102,23 @@ static int re_attach(device_t dev)
ifp->if_capenable = ifp->if_capabilities;
ifp->if_capenable &= ~(IFCAP_WOL_UCAST | IFCAP_WOL_MCAST);
+ /* Get station address. */
+ RE_LOCK(sc);
+ re_get_hw_mac_address(sc, eaddr);
+ RE_UNLOCK(sc);
+
+ /*
+ * A RealTek chip was detected. Inform the world.
+ */
+ device_printf(dev,"version:%s\n", RE_VERSION);
+ device_printf(dev,"Ethernet address: %6D\n", eaddr, ":");
+ printf("\nThis product is covered by one or more of the following patents: \
+ \nUS6,570,884, US6,115,776, and US6,327,625.\n");
+
+#if OS_VER < VERSION(6,0)
+ bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
+#endif
+
RE_LOCK(sc);
re_phy_power_up(dev);
re_hw_phy_config(sc);
In the meantime, I got the in-kernel driver working as needed (see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=262406 and https://reviews.freebsd.org/D34485), so I'm not currently using the kmod and facing this issue. Konstantin, do you want me to test your patch on my HW to verify it solves the issue? Yes, if you can test the patch it'd be quite useful, so I can update the port. The port version is 198.04_2. When calling the random_ether_addr(eaddr) function, the kernel still crashes. Is there a patch for the current diver version. I'm in to run tests Oh, sorry ether_gen_addr(sc->re_ifp, (struct ether_addr *)eaddr); Updated patch here: https://github.com/alexdupre/rtl_bsd_drv/commit/422aad16b625bb4f4036749452164f4a4fba4108 Let me know if it fixes the issue. root@NanoPC-T6:~ # ifconfig re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=201b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,WOL_MAGIC> ether 58:9c:fc:10:81:7a inet 192.168.1.180 netmask 0xffffff00 broadcast 192.168.1.255 media: Ethernet autoselect (1000baseT <full-duplex>) status: active re1: flags=8803<UP,BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=201b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,WOL_MAGIC> ether 58:9c:fc:10:d2:a1 inet 192.168.0.180 netmask 0xffffff00 broadcast 192.168.0.255 media: Ethernet autoselect status: no carrier -- Thank you. Now it works reliably. Tested on aarch64 SoC Rockchip RK3588 Speed test using iperf3 showed about 1.3Gbps. Is it possible to achieve high speeds on AMD64? (In reply to s199p.wa1k9r from comment #10) Do you have any evidence that it's not achieving high speed on AMD64? Reaching 1.3Gbps on a 1000baseT link seems too good :-) A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/ports/commit/?id=7845799f666b35881b8387bd1ae5aba68d666b61 commit 7845799f666b35881b8387bd1ae5aba68d666b61 Author: Alex Dupre <ale@FreeBSD.org> AuthorDate: 2023-07-17 15:50:18 +0000 Commit: Alex Dupre <ale@FreeBSD.org> CommitDate: 2023-07-17 15:50:18 +0000 net/realtek-re-kmod: fix kernel panic when generating MAC address. PR: 262407 Reported by: Evgeni Golov <evgeni@debian.org> Submitted by: kib net/realtek-re-kmod/Makefile | 4 ++-- net/realtek-re-kmod/distinfo | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (In reply to Alex Dupre from comment #11) I tested at home with my hack. There is a 2.5Gbps switch I tested your patch in the office. There is no 2.5Gbps here. It's all fair, don't worry |
Ohai, there exists hardware (like [1]) that has no ethernet address burned into the EEPROM. Realteks driver (contrary to the one in the FreeBSD kernel, see #262406) tries to accommodate for that by generating a random mac address: 3890- if (!is_valid_ether_addr(eaddr)) { 3891- device_printf(dev,"Invalid ether addr: %6D\n", eaddr, ":"); 3892: random_ether_addr(eaddr); 3893- device_printf(dev,"Random ether addr: %6D\n", eaddr, ":"); 3894- } However, the net/realtek-re-kmod port patches (in files/patch-if__re.c) the `random_ether_addr` call to be ether_gen_addr(sc->re_ifp, (struct ether_addr *)eaddr); instead. This leads to a crash on my HW, with the following trace: KDB: stack backtrace: #0 0xffff00000050d058 at kdb_backtrace+0x60 #1 0xffff0000004b7228 at vpanic+0x184 #2 0xffff0000004b70a0 at panic+0x44 #3 0xffff000000824d2c at data_abort+0x1d8 #4 0xffff000000805078 at handle_el1h_sync+0x78 #5 0xffff00000051434c at kvprintf+0xbb4 #6 0xffff00000051434c at kvprintf+0xbb4 #7 0xffff000000515100 at vsnprintf+0x3c #8 0xffff0000005c70c8 at vasprintf+0x4c #9 0xffff0000005c7190 at asprintf+0x40 #10 0xffff0000005eb284 at ether_gen_addr+0x74 #11 0xffff000001222294 at re_attach+0x1b90 #12 0xffff0000004f9254 at device_attach+0x400 #13 0xffff0000004fa770 at bus_generic_attach+0x4c #14 0xffff000000236e08 at pci_attach+0xe0 #15 0xffff0000004f9254 at device_attach+0x400 #16 0xffff0000004fa770 at bus_generic_attach+0x4c #17 0xffff0000004f9254 at device_attach+0x400 I am not exactly sure *what* triggers this. At first I thought it'd be the cast of eaddr, but that *should* work. ether_gen_addr *does* call asprintf, so it might be that? Reverting to the original random code from Realtek works. Thanks! [1] https://www.dfrobot.com/product-2242.html