PKTQUEUE(9)

NAME
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

SYNOPSIS
#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);

DESCRIPTION
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.

FUNCTIONS

pktq_create(maxlen, intrh, arg)
    Create a packet queue that can store at most maxlen packets at one time. maxlen must not exceed PCQ_MAXLEN. The software interrupt handler intrh with argument arg will be established at SOFTINT_NET.

pktq_destroy(pq)
    Destroy the specified packet queue. The caller is responsible for ensuring that no packets remain in the queue prior to calling this function.

pktq_enqueue(pq, m, hash)
    Enqueue the packet m in the specified packet queue. The modulus of hash and the number of CPUs will be computed and used to select the per-CPU queue where the packet will be stored, and thus upon which CPU the packet will be processed. Once the CPU selection has been made and the packet placed in the queue, the software interrupt associated with packet queue will be scheduled.

pktq_dequeue(pq)
    Dequeue a packet from the current CPU's queue. If no packets remain, 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)
    Wait for a grace period when all packets enqueued at the moment of calling this function will have been dequeued.

pktq_ifdetach()
    This function is called when a network interface is detached from the system. It performs a pktq_barrier() operation on all packet queues.

pktq_flush(pq)
    This function removes and frees all packets in the specified queue. The caller is responsible for ensuring that no calls to pktq_enqueue() or pktq_dequeue() run concurrently with pktq_flush().

pktq_set_maxlen(pq, maxlen)
    Sets the maximum queue length to the value maxlen. If the new value of maxlen is smaller than the previous value, then this routine may block until all packets that were previously in the packet queue can be re-enqueued.

pktq_rps_hash(funcp, m)
    Calculates the RPS hash for the packet m using the hash function referenced by funcp. The available hash functions are “zero” (always returns 0), “curcpu” (returns the index of the current CPU), “toeplitz” (Toeplitz hash of an IPv4 or IPv6 packet), and “toeplitz-othercpus” ( same as “toeplitz” but always hashes to a CPU other than the current CPU). A default hash routine is provided by the global variable 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)
    This function registers standard sysctl handlers for pq at the parent sysctl node parent_node. qid allows the caller to specify the node ID at which to attach to parent_node; use CTL_CREATE to dynamically assign a node ID. The clog argument is passed directly to sysctl_createv().

sysctl_pktq_rps_hash_handler()
    This function provides a way for the user to select the preferred RPS hash function to be used by a caller of 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 *’).

CODE REFERENCES
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.

NOTES
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.

SEE ALSO
sysctl(8), kpreempt(9), pcq(9), softintr(9), sysctl(9)

HISTORY
The pktqueue interface first appeared in NetBSD 7.0.