CVSROOT: /cvs
Module name: src
Changes by: [email protected] 2025/12/10 23:52:31
Modified files:
sys/net : if.c if_var.h
Log message:
extend struct netstack to queue packet processing in the existing context
at the moment if_input_process runs packets in an mbuf_list, generally
produced by an ifiq, through the network stack. as the headers on
the packet are parsed, subsequent protocol handlers are called to
process the next layer of the packet. currently these handlers are
dispatched by by directly calling functions, which consumes the
stack on the kernel threads running the network stack. if you have
a deep topology of virtual interfaces (eg, carp on vlan on aggr on
physical ports), you have a deep call stack.
the usual alternative to this is to queue packets handled by virtual
interfaces and get them processed by their own ifiq and their own
if_input_process call. this is what the stack used to do, but the
cost of locking and queueing and dispatching it to a softnet thread
to process (even if it was the same thread) adds significant overhead,
so we moved to direct dispatch to speed things up.
this change is kind of a hybrid approach, where input handling is
queued, but on lists in struct netstack. because struct netstack
is local to each softnet thread, there's no locking needed to queue
packets, and no trip through the scheduler to wake up another thread.
the work is then run by if_input_process when the currently running
protocol handler returns.
this dequeue and run of work is largely the same as the existing
processing loop in if_input_process. the difference is that where
if_input_process assumes all mbufs to be processed are from the
interface that produced the original list of mbufs, now it has to
get an interface reference itself for these requeued mbufs.
the overhead of taking and releasing interface refs has been mitigated
by making softnet threads special, and letting them use interface
refs without accounting for them.
this is just the machinery to run requeued packets, nothing currently
uses it yet. this paves the way to be able to call if_vinput and
if_input_proto from an smr critical section, and/or without the net
lock, by letting them queue the work for if_input_process to run
later with the right locks and interface references.