33#include "opt_device_polling.h"
37#include <sys/kernel.h>
38#include <sys/kthread.h>
41#include <sys/eventhandler.h>
42#include <sys/resourcevar.h>
43#include <sys/socket.h>
44#include <sys/sockio.h>
45#include <sys/sysctl.h>
46#include <sys/syslog.h>
49#include <net/if_var.h>
50#include <net/netisr.h>
97#define MIN_POLL_BURST_MAX 10
98#define MAX_POLL_BURST_MAX 20000
104static SYSCTL_NODE(_kern, OID_AUTO, polling, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
105 "Device polling parameters");
108 &
poll_burst, 0,
"Current polling burst size");
120 if (error || !req->newptr )
136 CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
sizeof(uint32_t),
138 "Max Polling burst size");
146 if (error || !req->newptr )
162 CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
sizeof(uint32_t),
164 "Max size of each burst");
177 if (error || !req->newptr )
189 CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
sizeof(uint32_t),
191 "Desired user fraction of cpu time");
201 if (error || !req->newptr )
203 if (val < 1 || val >
hz)
215 CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
sizeof(uint32_t),
217 "Every this many cycles check registers");
221 &
short_ticks, 0,
"Hardclock ticks shorter than they should be");
225 &
lost_polls, 0,
"How many times we would have lost a poll tick");
241 &
phase, 0,
"Polling phase");
249 &
stalled, 0,
"potential stalls");
255#define POLL_LIST_LEN 128
274 mtx_init(&
poll_mtx,
"polling", NULL, MTX_DEF);
275 EVENTHANDLER_REGISTER(shutdown_post_sync,
poll_shutdown, NULL,
296 static struct timeval prev_t, t;
303 delta = (t.tv_usec - prev_t.tv_usec) +
304 (t.tv_sec - prev_t.tv_sec)*1000000;
305 if (delta *
hz < 500000)
339 struct epoch_tracker et;
349 pr[i].handler(
pr[i].ifp, POLL_ONLY,
count);
401 kern_load = (kern_load *
hz) / 10000;
437 enum poll_cmd arg = POLL_ONLY;
454 arg = POLL_AND_CHECK_STATUS;
465 pr[i].handler(
pr[i].ifp, arg, cycles);
483 KASSERT(h != NULL, (
"%s: handler is NULL", __func__));
484 KASSERT(ifp != NULL, (
"%s: ifp is NULL", __func__));
495 static int verbose = 10 ;
497 log(LOG_ERR,
"poll handlers list full, "
498 "maybe a broken driver ?\n");
506 if (
pr[i].ifp == ifp &&
pr[i].handler != NULL) {
508 log(LOG_DEBUG,
"ether_poll_register: %s: handler"
509 " already registered\n", ifp->if_xname);
530 KASSERT(ifp != NULL, (
"%s: ifp is NULL", __func__));
535 if (
pr[i].ifp == ifp)
538 log(LOG_DEBUG,
"ether_poll_deregister: %s: not found!\n",
555 struct thread *td = curthread;
558 rtp.prio = RTP_PRIO_MAX;
559 rtp.type = RTP_PRIO_IDLE;
560 PROC_SLOCK(td->td_proc);
562 PROC_SUNLOCK(td->td_proc);
void kproc_start(const void *udata)
static int user_frac_sysctl(SYSCTL_HANDLER_ARGS)
static uint32_t poll_burst
static void init_device_poll(void)
SYSINIT(device_poll, SI_SUB_SOFTINTR, SI_ORDER_MIDDLE, init_device_poll, NULL)
static struct pollrec pr[POLL_LIST_LEN]
static uint32_t poll_burst_max
SYSCTL_UINT(_kern_polling, OID_AUTO, burst, CTLFLAG_RD, &poll_burst, 0, "Current polling burst size")
static int reg_frac_sysctl(SYSCTL_HANDLER_ARGS)
static uint32_t lost_polls
static void poll_shutdown(void *arg, int howto)
void hardclock_device_poll(void)
static uint32_t idlepoll_sleeping
#define MIN_POLL_BURST_MAX
static struct timeval poll_start_t
#define MAX_POLL_BURST_MAX
static uint32_t poll_in_idle_loop
static int poll_each_burst_sysctl(SYSCTL_HANDLER_ARGS)
int ether_poll_deregister(if_t ifp)
int ether_poll_register(poll_handler_t *h, if_t ifp)
static int netisr_pollmore_scheduled
static uint32_t reg_frac_count
static uint32_t pending_polls
static struct mtx poll_mtx
static struct proc * idlepoll
SYSCTL_PROC(_kern_polling, OID_AUTO, burst_max, CTLTYPE_UINT|CTLFLAG_RW|CTLFLAG_MPSAFE, 0, sizeof(uint32_t), poll_burst_max_sysctl, "I", "Max Polling burst size")
static SYSCTL_NODE(_kern, OID_AUTO, polling, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "Device polling parameters")
static uint32_t user_frac
static int residual_burst
static int poll_shutting_down
static struct kproc_desc idlepoll_kp
static uint32_t poll_handlers
static void poll_idle(void)
static uint32_t poll_each_burst
static void ether_poll(int count)
static uint32_t short_ticks
SYSCTL_INT(_kern_polling, OID_AUTO, residual_burst, CTLFLAG_RD, &residual_burst, 0, "# of residual cycles in burst")
static int poll_burst_max_sysctl(SYSCTL_HANDLER_ARGS)
static int netisr_poll_scheduled
int rtp_to_pri(struct rtprio *rtp, struct thread *td)
void mi_switch(int flags)
void wakeup(const void *ident)
int sysctl_handle_int(SYSCTL_HANDLER_ARGS)
void microuptime(struct timeval *tvp)
void log(int level, const char *fmt,...)