1 /* 2 * Copyright (c) 2004 Jeffrey M. Hsu. All rights reserved. 3 * Copyright (c) 2004 The DragonFly Project. All rights reserved. 4 * 5 * This code is derived from software contributed to The DragonFly Project 6 * by Jeffrey M. Hsu. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of The DragonFly Project nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific, prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 /* 35 * Copyright (c) 1980, 1986, 1989, 1993 36 * The Regents of the University of California. All rights reserved. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. Neither the name of the University nor the names of its contributors 47 * may be used to endorse or promote products derived from this software 48 * without specific prior written permission. 49 * 50 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60 * SUCH DAMAGE. 61 * 62 * @(#)netisr.h 8.1 (Berkeley) 6/10/93 63 * $FreeBSD: src/sys/net/netisr.h,v 1.21.2.5 2002/02/09 23:02:39 luigi Exp $ 64 */ 65 66 #ifndef _NET_NETISR2_H_ 67 #define _NET_NETISR2_H_ 68 69 #ifndef _KERNEL 70 #error "kernel only header file" 71 #endif 72 73 #include <sys/systm.h> 74 #include <sys/msgport2.h> 75 #include <sys/thread.h> 76 #include <net/netisr.h> 77 78 extern struct thread *netisr_threads[MAXCPU]; 79 80 /* 81 * Return the message port for the general protocol message servicing 82 * thread for a particular cpu. 83 */ 84 static __inline lwkt_port_t 85 netisr_cpuport(int cpu) 86 { 87 KKASSERT(cpu >= 0 && cpu < ncpus); 88 return &netisr_threads[cpu]->td_msgport; 89 } 90 91 /* 92 * Return the current cpu's network protocol thread. 93 */ 94 static __inline lwkt_port_t 95 netisr_curport(void) 96 { 97 return netisr_cpuport(mycpuid); 98 } 99 100 /* 101 * Return the LSB of the hash. 102 */ 103 static __inline uint32_t 104 netisr_hashlsb(uint32_t hash) 105 { 106 107 return (hash & NETISR_CPUMASK); 108 } 109 110 /* 111 * Return the cpu for the hash. 112 */ 113 static __inline int 114 netisr_hashcpu(uint16_t hash) 115 { 116 117 return (netisr_hashlsb(hash) % netisr_ncpus); 118 } 119 120 /* 121 * Return the message port for the general protocol message servicing 122 * thread for the hash. 123 */ 124 static __inline lwkt_port_t 125 netisr_hashport(uint16_t hash) 126 { 127 return netisr_cpuport(netisr_hashcpu(hash)); 128 } 129 130 #define IN_NETISR(n) \ 131 (&curthread->td_msgport == netisr_cpuport((n))) 132 #define IN_NETISR_NCPUS(n) \ 133 ((n) < netisr_ncpus && IN_NETISR((n))) 134 #define ASSERT_NETISR0 \ 135 KASSERT(IN_NETISR(0), ("thread %p is not netisr0", curthread)) 136 #define ASSERT_NETISR_NCPUS(n) \ 137 KASSERT(IN_NETISR_NCPUS(n), \ 138 ("thread %p cpu%d is not within netisr_ncpus %d", \ 139 curthread, (n), netisr_ncpus)) 140 141 static __inline int 142 netisr_domsg_port(struct netmsg_base *nm, lwkt_port_t port) 143 { 144 145 #ifdef INVARIANTS 146 /* 147 * Only netisr0, netisrN itself, or non-netisr threads 148 * can perform synchronous message sending to netisrN. 149 */ 150 KASSERT(curthread->td_type != TD_TYPE_NETISR || 151 IN_NETISR(0) || port == &curthread->td_msgport, 152 ("can't domsg to netisr port %p from thread %p", port, curthread)); 153 #endif 154 return (lwkt_domsg(port, &nm->lmsg, 0)); 155 } 156 157 static __inline int 158 netisr_domsg(struct netmsg_base *nm, int cpu) 159 { 160 161 return (netisr_domsg_port(nm, netisr_cpuport(cpu))); 162 } 163 164 static __inline int 165 netisr_domsg_global(struct netmsg_base *nm) 166 { 167 168 /* Start from netisr0. */ 169 return (netisr_domsg(nm, 0)); 170 } 171 172 static __inline void 173 netisr_sendmsg(struct netmsg_base *nm, int cpu) 174 { 175 176 lwkt_sendmsg(netisr_cpuport(cpu), &nm->lmsg); 177 } 178 179 static __inline void 180 netisr_sendmsg_oncpu(struct netmsg_base *nm) 181 { 182 183 lwkt_sendmsg_oncpu(netisr_cpuport(mycpuid), &nm->lmsg); 184 } 185 186 static __inline void 187 netisr_replymsg(struct netmsg_base *nm, int error) 188 { 189 190 lwkt_replymsg(&nm->lmsg, error); 191 } 192 193 static __inline void 194 netisr_dropmsg(struct netmsg_base *nm) 195 { 196 197 lwkt_dropmsg(&nm->lmsg); 198 } 199 200 /* 201 * To all netisrs, instead of netisr_ncpus. 202 */ 203 static __inline void 204 netisr_forwardmsg_all(struct netmsg_base *nm, int next_cpu) 205 { 206 207 KKASSERT(next_cpu > mycpuid && next_cpu <= ncpus); 208 if (next_cpu < ncpus) 209 lwkt_forwardmsg(netisr_cpuport(next_cpu), &nm->lmsg); 210 else 211 netisr_replymsg(nm, 0); 212 } 213 214 /* 215 * To netisr_ncpus. 216 */ 217 static __inline void 218 netisr_forwardmsg_error(struct netmsg_base *nm, int next_cpu, 219 int error) 220 { 221 222 KKASSERT(next_cpu > mycpuid && next_cpu <= netisr_ncpus); 223 if (next_cpu < netisr_ncpus) 224 lwkt_forwardmsg(netisr_cpuport(next_cpu), &nm->lmsg); 225 else 226 netisr_replymsg(nm, error); 227 } 228 229 /* 230 * To netisr_ncpus. 231 */ 232 static __inline void 233 netisr_forwardmsg(struct netmsg_base *nm, int next_cpu) 234 { 235 236 netisr_forwardmsg_error(nm, next_cpu, 0); 237 } 238 239 #endif /* _NET_NETISR2_H_ */ 240