mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
rtlplayground: take several packets per loop in handle_rx()
handle_rx() picked up exactly one packet per iteration of the main loop. Since the loop sleeps until the next tick, that capped the CPU port at roughly one packet per tick no matter how little work it had to do. A burst of broadcast, ARP or IGMP traffic aimed at the CPU queued up behind that and pushed out the STP and LACP timers. Drain up to RX_BUDGET packets in one pass instead. The budget matters: without one a sustained flood would spin here and starve everything else in the loop. The two register reads in the loop take their result straight from SFR_DATA_U16 rather than going through reg_read_m() and the sfr_data[] copy, which is what the rest of the tree already does. Measured on SWTGW218AS with a one-way UDP stream, counting the packets the CPU actually processed, with this change alone: before 159 packets/s RX_BUDGET 4 245 packets/s, loop iteration ~16 ms RX_BUDGET 8 298 packets/s, loop iteration ~26 ms Throughput is already most of the way there at 4, so the larger budget mostly buys a longer worst-case delay for the other phases. STP stayed responsive in both cases. Costs 71 bytes of code and no extra XDATA.
This commit is contained in:
1 parent
d556d634ca
commit
0d17dd563f
1 file changed
+11
-6
+11
-6
@@ -973,14 +973,19 @@ void tcpip_output(void)
|
||||
}
|
||||
|
||||
|
||||
#define RX_BUDGET 4
|
||||
|
||||
void handle_rx(void)
|
||||
{
|
||||
// Check the amount of data available on the NIC/ASIC side
|
||||
reg_read_m(RTL837X_REG_NIC_RX_BUFF_DATA);
|
||||
if (sfr_data[2] != 0 || sfr_data[3] != 0) {
|
||||
reg_read_m(RTL837X_REG_CPU_RX_CURR_PKT);
|
||||
uint16_t ring_ptr = ((uint16_t)sfr_data[2]) << 8;
|
||||
ring_ptr |= sfr_data[3];
|
||||
__xdata uint8_t budget = RX_BUDGET;
|
||||
|
||||
while (budget--) {
|
||||
// Check the amount of data available on the NIC/ASIC side
|
||||
reg_read(RTL837X_REG_NIC_RX_BUFF_DATA);
|
||||
if (!SFR_DATA_U16)
|
||||
break;
|
||||
reg_read(RTL837X_REG_CPU_RX_CURR_PKT);
|
||||
uint16_t ring_ptr = SFR_DATA_U16;
|
||||
ring_ptr <<= 3;
|
||||
if (!nic_rx_header(ring_ptr)) {
|
||||
REG_SET(RTL837X_REG_NIC_RXCMD, 1);
|
||||
|
||||
Reference in new issue
Block a user