1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2007-2009 Robert N. M. Watson
5 * Copyright (c) 2010-2011 Juniper Networks, Inc.
6 * All rights reserved.
7 *
8 * This software was developed by Robert N. M. Watson under contract
9 * to Juniper Networks, Inc.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $FreeBSD$
33 */
34
35 #ifndef _NET_NETISR_INTERNAL_H_
36 #define _NET_NETISR_INTERNAL_H_
37
38 #ifndef _WANT_NETISR_INTERNAL
39 #error "no user-serviceable parts inside"
40 #endif
41
42 /*
43 * These definitions are private to the netisr implementation, but provided
44 * here for use by post-mortem crashdump analysis tools. They should not be
45 * used in any other context as they can and will change. Public definitions
46 * may be found in netisr.h.
47 */
48
49 #ifndef _KERNEL
50 typedef void *netisr_handler_t;
51 typedef void *netisr_m2flow_t;
52 typedef void *netisr_m2cpuid_t;
53 typedef void *netisr_drainedcpu_t;
54 #endif
55
56 /*
57 * Each protocol is described by a struct netisr_proto, which holds all
58 * global per-protocol information. This data structure is set up by
59 * netisr_register(), and derived from the public struct netisr_handler.
60 */
61 struct netisr_proto {
62 const char *np_name; /* Character string protocol name. */
63 netisr_handler_t *np_handler; /* Protocol handler. */
64 netisr_m2flow_t *np_m2flow; /* Query flow for untagged packet. */
65 netisr_m2cpuid_t *np_m2cpuid; /* Query CPU to process packet on. */
66 netisr_drainedcpu_t *np_drainedcpu; /* Callback when drained a queue. */
67 u_int np_qlimit; /* Maximum per-CPU queue depth. */
68 u_int np_policy; /* Work placement policy. */
69 u_int np_dispatch; /* Work dispatch policy. */
70 };
71
72 #define NETISR_MAXPROT 16 /* Compile-time limit. */
73
74 /*
75 * Protocol-specific work for each workstream is described by struct
76 * netisr_work. Each work descriptor consists of an mbuf queue and
77 * statistics.
78 */
79 struct netisr_work {
80 /*
81 * Packet queue, linked by m_nextpkt.
82 */
83 struct mbuf *nw_head;
84 struct mbuf *nw_tail;
85 u_int nw_len;
86 u_int nw_qlimit;
87 u_int nw_watermark;
88
89 /*
90 * Statistics -- written unlocked, but mostly from curcpu.
91 */
92 u_int64_t nw_dispatched; /* Number of direct dispatches. */
93 u_int64_t nw_hybrid_dispatched; /* "" hybrid dispatches. */
94 u_int64_t nw_qdrops; /* "" drops. */
95 u_int64_t nw_queued; /* "" enqueues. */
96 u_int64_t nw_handled; /* "" handled in worker. */
97 };
98
99 /*
100 * Workstreams hold a queue of ordered work across each protocol, and are
101 * described by netisr_workstream. Each workstream is associated with a
102 * worker thread, which in turn is pinned to a CPU. Work associated with a
103 * workstream can be processd in other threads during direct dispatch;
104 * concurrent processing is prevented by the NWS_RUNNING flag, which
105 * indicates that a thread is already processing the work queue. It is
106 * important to prevent a directly dispatched packet from "skipping ahead" of
107 * work already in the workstream queue.
108 */
109 struct netisr_workstream {
110 struct intr_event *nws_intr_event; /* Handler for stream. */
111 void *nws_swi_cookie; /* swi(9) cookie for stream. */
112 struct mtx nws_mtx; /* Synchronize work. */
113 u_int nws_cpu; /* CPU pinning. */
114 u_int nws_flags; /* Wakeup flags. */
115 u_int nws_pendingbits; /* Scheduled protocols. */
116
117 /*
118 * Each protocol has per-workstream data.
119 */
120 struct netisr_work nws_work[NETISR_MAXPROT];
121 } __aligned(CACHE_LINE_SIZE);
122
123 /*
124 * Per-workstream flags.
125 */
126 #define NWS_RUNNING 0x00000001 /* Currently running in a thread. */
127 #define NWS_DISPATCHING 0x00000002 /* Currently being direct-dispatched. */
128 #define NWS_SCHEDULED 0x00000004 /* Signal issued. */
129
130 #endif /* !_NET_NETISR_INTERNAL_H_ */
Cache object: 84223a4717ae5f5124f289417100f4cd
|