Updated: 2022/Sep/29

Please read Privacy Policy. It's for your privacy.


PKTQUEUE(9)                Kernel Developer's Manual               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.

NetBSD 10.99                   September 3, 2022                  NetBSD 10.99