| PKTQUEUE(9) | Kernel Developer's Manual | PKTQUEUE(9) |
pktqueue,
pktq_create, pktq_destroy,
pktq_enqueue, pktq_dequeue,
pktq_barrier, pktq_ifdetach,
pktq_flush, pktq_set_maxlen,
pktq_rps_hash,
pktq_sysctl_setup,
sysctl_pktq_rps_hash_handler —
Lockless network protocol input queues with integrated ISR
scheduling
#include
<net/pktqueue.h>
pktqueue_t *
pktq_create(size_t
maxlen, void
(*intrh)(void *), void
*arg);
void
pktq_destroy(pktqueue_t
*pq);
bool
pktq_enqueue(pktqueue_t
*pq, struct mbuf
*m, u_int
hash);
struct mbuf *
pktq_dequeue(pktqueue_t
*pq);
void
pktq_barrier(pktqueue_t
*pq);
void
pktq_ifdetach(void);
void
pktq_flush(pktqueue_t
*pq);
int
pktq_set_maxlen(pktqueue_t
*pq, size_t
maxlen);
uint32_t
pktq_rps_hash(const
pktq_rps_hash_func_t *funcp,
const struct mbuf
*m);
int
pktq_sysctl_setup(pktqueue_t
*pq, struct sysctllog
**clog, const struct
sysctlnode *parent_node,
int qid);
int
sysctl_pktq_rps_hash_handler(SYSCTLFN_ARGS);
The pktqueue functions provide a lockless
network protocol input queue interface with integrated software interrupt
scheduling and support for receiver-side packet steering (RPS). The
implementation is based around per-CPU producer-consumer queues; multiple
CPUs may enqueue packets into a CPU's queue, but only the owning CPU will
dequeue packets from any given queue.
pktq_create(maxlen,
intrh, arg)PCQ_MAXLEN. The software interrupt handler
intrh with argument arg will
be established at SOFTINT_NET.pktq_destroy(pq)pktq_enqueue(pq,
m, hash)pktq_dequeue(pq)NULL is returned. This function must be called
with kernel preemption disabled, which is always the case when running in
a software interrupt handler.pktq_barrier(pq)pktq_ifdetach()pktq_barrier() operation on
all packet queues.pktq_flush(pq)pktq_enqueue() or
pktq_dequeue() run concurrently with
pktq_flush().pktq_set_maxlen(pq,
maxlen)pktq_rps_hash(funcp,
m)pktq_rps_hash_default. The default routine is
guaranteed to be safe to use for any network protocol. The behavior of
“toeplitz” and “toeplitz-othercpus” is
undefined if used with protocols other than IPv4 or IPv6.pktq_sysctl_setup(pq,
clog, parent_node,
qid)CTL_CREATE
to dynamically assign a node ID. The clog argument
is passed directly to
sysctl_createv().sysctl_pktq_rps_hash_handler()pktq_rps_hash()
via sysctl(8). When calling
sysctl_createv() to create the sysctl node, pass
sysctl_pktq_rps_hash_handler() as the
func argument and the pointer to the RPS hash
function reference variable as the newp argument
(cast to ‘void *’).The pktqueue interface is implemented
within the file net/pktqueue.c.
An example of how to use
pktq_rps_hash()
can be found in the
ether_input()
function. An example of how to use
sysctl_pktq_rps_hash_handler()
can be found in the
ether_sysctl_setup()
function. Both reside within the file
net/if_ethersubr.c.
An example of how to use
pktq_sysctl_setup()
can be found in the
sysctl_net_inet_ip_setup()
function within the file netinet/ip_input.c.
The maxlen argument provided to
pktq_create() specifies the maximum number of
packets that can be stored in each per-CPU queue. This means that, in
theory, the maximum number of packets that can be enqueued is ‘maxlen
* ncpu’. However, as a practical matter, the number will be smaller
because the distribution of packets across the per-CPU queues is not
perfectly uniform.
Calls to
pktq_set_maxlen()
may result in re-ordering the delivery of packets currently in the
queue.
The pktqueue interface first appeared in
NetBSD 7.0.
| September 3, 2022 | NetBSD 11.0 |