Skip to content

Commit c3ef529

Browse files
committed
erts: Skip pollset update on scheduler-polled re-arm
An enif_select fd migrated to the scheduler pollset stays registered for IN events across triggers, but the trigger handler cleared IN from state->events, so every re-arming enif_select saw a changed event set and issued an erts_poll_control on the normal pollset: one epoll_ctl(MOD) per wakeup that changes nothing. Keep IN in state->events for fds enabled in the scheduler pollset so the re-arming enif_select becomes a no-op; repeat select messages are already prevented by the in.pid handshake in the trigger handler. With a pipelined request/response socket NIF workload (64 callers, 16 connections), epoll_ctl calls drop from one per wakeup (~156k per 350k requests) to connection setup only (~240), worth ~2% end-to-end throughput on 8 cores.
1 parent 5d651b9 commit c3ef529

1 file changed

Lines changed: 12 additions & 1 deletion

File tree

erts/emulator/sys/common/erl_check_io.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2148,7 +2148,18 @@ erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time, bool needs_th
21482148
state->driver.nif->err.mp = NULL;
21492149
}
21502150
}
2151-
state->events &= ~revents;
2151+
#if ERTS_POLL_USE_SCHEDULER_POLLING
2152+
/* An FD migrated to the scheduler pollset stays
2153+
* registered for IN across triggers; keeping the event
2154+
* in state->events lets the re-arming enif_select
2155+
* become a no-op instead of a pollset update. Repeat
2156+
* messages are already prevented by in.pid being
2157+
* cleared above. */
2158+
if (state->flags & ERTS_EV_FLAG_IN_SCHEDULER)
2159+
state->events &= ~(revents & ~ERTS_POLL_EV_IN);
2160+
else
2161+
#endif
2162+
state->events &= ~revents;
21522163
}
21532164
else if (revents & ERTS_POLL_EV_NVAL) {
21542165
bad_fd_in_pollset(state, NIL, NIL);

0 commit comments

Comments
 (0)