⬢ DragonFlyBSD Kernel Audit
DF-4235 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/rl/if_rl.c
+++ b/sys/dev/netif/rl/if_rl.c
@@ -1025,10 +1025,22 @@
 		if ((uint16_t)(rxstat >> 16) == RL_RXSTAT_UNFINISHED)
 			break;
 
+		/*
+		 * Ordinary per-frame receive errors (CRC, runt, alignment,
+		 * giant, bad symbol) are remotely generatable at line rate
+		 * and must not each cost a full adapter re-init from
+		 * interrupt context under the ifnet serializer (DF-4235).
+		 * The status word's length field is still valid for error
+		 * frames, so skip the descriptor and keep receiving.
+		 * Reset-class conditions are already handled through
+		 * RL_ISR_SYSTEM_ERR in rl_intr().
+		 */
 		if ((rxstat & RL_RXSTAT_RXOK) == 0) {
 			IFNET_STAT_INC(ifp, ierrors, 1);
-			rl_init(sc);
-			return;
+			cur_rx += sizeof(uint32_t) + (rxstat >> 16);
+			cur_rx = (cur_rx + 3) & ~3;
+			CSR_WRITE_2(sc, RL_CURRXADDR, cur_rx - 16);
+			continue;
 		}
 
 		/* No errors; receive the packet. */