1/*- 2 * Copyright (c) 2001-2002 Luigi Rizzo 3 * 4 * Supported by: the Xorp Project (www.xorp.org) 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/kern/kern_poll.c 111888 2003-03-04 23:19:55Z jlemon $ |
28 */ 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/kernel.h> 33#include <sys/socket.h> /* needed by net/if.h */ 34#include <sys/sysctl.h> 35 --- 6 unchanged lines hidden (view full) --- 42 43#ifdef SMP 44#ifndef COMPILING_LINT 45#error DEVICE_POLLING is not compatible with SMP 46#endif 47#endif 48 49static void netisr_poll(void); /* the two netisr handlers */ |
50static void netisr_pollmore(void); |
51 |
52void hardclock_device_poll(void); /* hook from hardclock */ 53void ether_poll(int); /* polling while in trap */ 54 55/* 56 * Polling support for [network] device drivers. 57 * 58 * Drivers which support this feature try to register with the 59 * polling code. --- 117 unchanged lines hidden (view full) --- 177#define POLL_LIST_LEN 128 178struct pollrec { 179 poll_handler_t *handler; 180 struct ifnet *ifp; 181}; 182 183static struct pollrec pr[POLL_LIST_LEN]; 184 |
185static void |
186init_device_poll(void) 187{ |
188 189 netisr_register(NETISR_POLL, (netisr_t *)netisr_poll, NULL); 190 netisr_register(NETISR_POLLMORE, (netisr_t *)netisr_pollmore, NULL); |
191} |
192SYSINIT(device_poll, SI_SUB_CLOCKS, SI_ORDER_MIDDLE, init_device_poll, NULL) |
193 |
194 |
195/* 196 * Hook from hardclock. Tries to schedule a netisr, but keeps track 197 * of lost ticks due to the previous handler taking too long. 198 * Normally, this should not happen, because polling handler should 199 * run for a short time. However, in some cases (e.g. when there are 200 * changes in link status etc.) the drivers take a very long time 201 * (even in the order of milliseconds) to reset and reconfigure the 202 * device, causing apparent lost polls. --- 28 unchanged lines hidden (view full) --- 231 pending_polls = 0; 232 phase = 0; 233 } 234 235 if (phase <= 2) { 236 if (phase != 0) 237 suspect++; 238 phase = 1; |
239 schednetisrbits(1 << NETISR_POLL | 1 << NETISR_POLLMORE); |
240 phase = 2; 241 } 242 if (pending_polls++ > 0) 243 lost_polls++; 244} 245 246/* 247 * ether_poll is called from the idle loop or from the trap handler. --- 36 unchanged lines hidden (view full) --- 284netisr_pollmore() 285{ 286 struct timeval t; 287 int kern_load; 288 /* XXX run at splhigh() or equivalent */ 289 290 phase = 5; 291 if (residual_burst > 0) { |
292 schednetisrbits(1 << NETISR_POLL | 1 << NETISR_POLLMORE); |
293 /* will run immediately on return, followed by netisrs */ |
294 return; |
295 } 296 /* here we can account time spent in netisr's in this tick */ 297 microuptime(&t); 298 kern_load = (t.tv_usec - poll_start_t.tv_usec) + 299 (t.tv_sec - poll_start_t.tv_sec)*1000000; /* us */ 300 kern_load = (kern_load * hz) / 10000; /* 0..100 */ 301 if (kern_load > (100 - user_frac)) { /* try decrease ticks */ 302 if (poll_burst > 1) --- 10 unchanged lines hidden (view full) --- 313 /* 314 * Last cycle was long and caused us to miss one or more 315 * hardclock ticks. Restart processing again, but slightly 316 * reduce the burst size to prevent that this happens again. 317 */ 318 poll_burst -= (poll_burst / 8); 319 if (poll_burst < 1) 320 poll_burst = 1; |
321 schednetisrbits(1 << NETISR_POLL | 1 << NETISR_POLLMORE); |
322 phase = 6; 323 } 324} 325 326/* 327 * netisr_poll is scheduled by schednetisr when appropriate, typically once 328 * per tick. It is called at splnet() so first thing to do is to upgrade to 329 * splimp(), and call all registered handlers. --- 193 unchanged lines hidden --- |