netisr.c (177253) | netisr.c (180239) |
---|---|
1/*- 2 * Copyright (c) 2001,2002,2003 Jonathan Lemon <jlemon@FreeBSD.org> 3 * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 10 unchanged lines hidden (view full) --- 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * | 1/*- 2 * Copyright (c) 2001,2002,2003 Jonathan Lemon <jlemon@FreeBSD.org> 3 * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 10 unchanged lines hidden (view full) --- 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * |
27 * $FreeBSD: head/sys/net/netisr.c 177253 2008-03-16 10:58:09Z rwatson $ | 27 * $FreeBSD: head/sys/net/netisr.c 180239 2008-07-04 00:21:38Z rwatson $ |
28 */ 29 30#include "opt_device_polling.h" 31 32#include <sys/param.h> 33#include <sys/bus.h> 34#include <sys/rtprio.h> 35#include <sys/systm.h> --- 36 unchanged lines hidden (view full) --- 72} 73 74void 75netisr_register(int num, netisr_t *handler, struct ifqueue *inq, int flags) 76{ 77 78 KASSERT(!(num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs))), 79 ("bad isr %d", num)); | 28 */ 29 30#include "opt_device_polling.h" 31 32#include <sys/param.h> 33#include <sys/bus.h> 34#include <sys/rtprio.h> 35#include <sys/systm.h> --- 36 unchanged lines hidden (view full) --- 72} 73 74void 75netisr_register(int num, netisr_t *handler, struct ifqueue *inq, int flags) 76{ 77 78 KASSERT(!(num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs))), 79 ("bad isr %d", num)); |
80 KASSERT(flags == 0 || flags == NETISR_FORCEQUEUE, 81 ("netisr_register: bad flags 0x%x\n", flags)); |
|
80 netisrs[num].ni_handler = handler; 81 netisrs[num].ni_queue = inq; 82 netisrs[num].ni_flags = flags; 83} 84 85void 86netisr_unregister(int num) 87{ --- 68 unchanged lines hidden (view full) --- 156 KASSERT(!(num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs))), 157 ("bad isr %d", num)); 158 ni = &netisrs[num]; 159 if (ni->ni_queue == NULL) { 160 isrstat.isrs_drop++; 161 m_freem(m); 162 return; 163 } | 82 netisrs[num].ni_handler = handler; 83 netisrs[num].ni_queue = inq; 84 netisrs[num].ni_flags = flags; 85} 86 87void 88netisr_unregister(int num) 89{ --- 68 unchanged lines hidden (view full) --- 158 KASSERT(!(num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs))), 159 ("bad isr %d", num)); 160 ni = &netisrs[num]; 161 if (ni->ni_queue == NULL) { 162 isrstat.isrs_drop++; 163 m_freem(m); 164 return; 165 } |
166 |
|
164 /* | 167 /* |
165 * Do direct dispatch only for MPSAFE netisrs (and 166 * only when enabled). Note that when a netisr is 167 * marked MPSAFE we permit multiple concurrent instances 168 * to run. We guarantee only the order in which 169 * packets are processed for each "dispatch point" in 170 * the system (i.e. call to netisr_dispatch or 171 * netisr_queue). This insures ordering of packets 172 * from an interface but does not guarantee ordering 173 * between multiple places in the system (e.g. IP 174 * dispatched from interfaces vs. IP queued from IPSec). | 168 * Unless NETISR_FORCEQUEUE is set on the netisr (generally 169 * indicating that the handler still requires Giant, which cannot be 170 * acquired in arbitrary order with respect to a caller), directly 171 * dispatch handling of this packet. Source ordering is maintained 172 * by virtue of callers consistently calling one of queued or direct 173 * dispatch, and the forcequeue flag being immutable after 174 * registration. |
175 */ | 175 */ |
176 if (netisr_direct && (ni->ni_flags & NETISR_MPSAFE)) { | 176 if (netisr_direct && !(ni->ni_flags & NETISR_FORCEQUEUE)) { |
177 isrstat.isrs_directed++; | 177 isrstat.isrs_directed++; |
178 /* 179 * NB: We used to drain the queue before handling 180 * the packet but now do not. Doing so here will 181 * not preserve ordering so instead we fallback to 182 * guaranteeing order only from dispatch points 183 * in the system (see above). 184 */ | |
185 ni->ni_handler(m); 186 } else { 187 isrstat.isrs_deferred++; 188 if (IF_HANDOFF(ni->ni_queue, m, NULL)) 189 schednetisr(num); 190 } 191} 192 --- 44 unchanged lines hidden (view full) --- 237 isrstat.isrs_swi_count++; 238 i--; 239 bits &= ~(1 << i); 240 ni = &netisrs[i]; 241 if (ni->ni_handler == NULL) { 242 printf("swi_net: unregistered isr %d.\n", i); 243 continue; 244 } | 178 ni->ni_handler(m); 179 } else { 180 isrstat.isrs_deferred++; 181 if (IF_HANDOFF(ni->ni_queue, m, NULL)) 182 schednetisr(num); 183 } 184} 185 --- 44 unchanged lines hidden (view full) --- 230 isrstat.isrs_swi_count++; 231 i--; 232 bits &= ~(1 << i); 233 ni = &netisrs[i]; 234 if (ni->ni_handler == NULL) { 235 printf("swi_net: unregistered isr %d.\n", i); 236 continue; 237 } |
245 if ((ni->ni_flags & NETISR_MPSAFE) == 0) { 246 mtx_lock(&Giant); 247 if (ni->ni_queue == NULL) 248 ni->ni_handler(NULL); 249 else 250 netisr_processqueue(ni); 251 mtx_unlock(&Giant); 252 } else { 253 if (ni->ni_queue == NULL) 254 ni->ni_handler(NULL); 255 else 256 netisr_processqueue(ni); 257 } | 238 if (ni->ni_queue == NULL) 239 ni->ni_handler(NULL); 240 else 241 netisr_processqueue(ni); |
258 } 259 } while (polling); 260} 261 262static void 263start_netisr(void *dummy) 264{ 265 266 if (swi_add(NULL, "net", swi_net, NULL, SWI_NET, INTR_MPSAFE, &net_ih)) 267 panic("start_netisr"); 268} 269SYSINIT(start_netisr, SI_SUB_SOFTINTR, SI_ORDER_FIRST, start_netisr, NULL); | 242 } 243 } while (polling); 244} 245 246static void 247start_netisr(void *dummy) 248{ 249 250 if (swi_add(NULL, "net", swi_net, NULL, SWI_NET, INTR_MPSAFE, &net_ih)) 251 panic("start_netisr"); 252} 253SYSINIT(start_netisr, SI_SUB_SOFTINTR, SI_ORDER_FIRST, start_netisr, NULL); |