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