X-Git-Url: http://git.onelab.eu/?p=ipfw.git;a=blobdiff_plain;f=dummynet2%2Finclude%2Fnetinet%2Fipfw%2Fip_dn_private.h;fp=dummynet2%2Finclude%2Fnetinet%2Fipfw%2Fip_dn_private.h;h=ecb4fe21966061aa68b0ed6cf1db91e72f1b4f29;hp=47cc5e8c6cf0b5d8ea9a81b54706697c3ce7bd74;hb=28a7fe9d930667786b902af6697c01eb87694173;hpb=2a8b6c544cf5ea3c84f763144c7ecfa79daea969 diff --git a/dummynet2/include/netinet/ipfw/ip_dn_private.h b/dummynet2/include/netinet/ipfw/ip_dn_private.h index 47cc5e8..ecb4fe2 100644 --- a/dummynet2/include/netinet/ipfw/ip_dn_private.h +++ b/dummynet2/include/netinet/ipfw/ip_dn_private.h @@ -49,10 +49,6 @@ MALLOC_DECLARE(M_DUMMYNET); -#ifndef FREE_PKT -#define FREE_PKT(m) m_freem(m) -#endif - #ifndef __linux__ #define div64(a, b) ((int64_t)(a) / (int64_t)(b)) #endif @@ -97,6 +93,17 @@ set_oid(struct dn_id *o, int type, int len) o->subtype = 0; }; +uint64_t readTSC (void); +/* + * see if tsc (ot other timer) is supported. + * - FreeBSD has rdtsc macro for i386 and amd64 + * - Linux has rdtscll and/or rdtsc (also for openWRT patched kernel source) + * - Windows has KeQueryPerformanceCounter() function that use tsc or other + * timer + */ +#if defined(rdtscll) || defined(rdtsc) || defined(_WIN32) +#define HAVE_TSC +#endif /* * configuration and global data for a dummynet instance * @@ -129,7 +136,21 @@ struct dn_parms { int queue_count; /* ticks and other stuff */ - uint64_t curr_time; + uint64_t curr_time; /* in ticks */ + + /* + * Variables to manage the time spent in the drain routines. + * max_drain is max the fraction of a tick (0..100) to be used + * for draining. + * We also need some variables to store the average number of + * timecounter ticks between calls to the periodic task, etc. + */ + int drain_ratio; + uint64_t cycle_task_new; /* TSC when dummynet_task() starts */ + uint64_t cycle_task_old; /* TSC when prev. dummynet_task() starts */ + uint64_t cycle_task; + uint64_t cycle_task_avg; /* Moving average of cicle_task */ + /* flowsets and schedulers are in hash tables, with 'hash_size' * buckets. fshash is looked up at every packet arrival * so better be generous if we expect many entries. @@ -140,16 +161,33 @@ struct dn_parms { struct dn_fsk_head fsu; /* list of unlinked flowsets */ struct dn_alg_head schedlist; /* list of algorithms */ - /* Store the fs/sch to scan when draining. The value is the - * bucket number of the hash table. Expire can be disabled - * with net.inet.ip.dummynet.expire=0, or it happens every - * expire ticks. - **/ - int drain_fs; - int drain_sch; - uint32_t expire; - uint32_t expire_cycle; /* tick count */ - + /* Counter of idle objects -- used by drain routine + * We scan when idle_queue (or idle_si) > expire_object. + * The drain routine is called every 'expire' cycles (the counter + * used is expire_cycle). + * We can disable the expire routine by setting expire to 0. + * An object is kept alive for at least object_idle_tick after it + * becomes idle. During the scan, we count the number of objects + * that are idle but not ready in 'idle_si_wait' and 'idle_queue_wait' + */ + int idle_queue; + int idle_queue_wait; /* idle but not expired yet */ + int idle_si; + int idle_si_wait; /* idle but not expired yet */ + uint32_t expire_object; /* threshold for expires */ + uint32_t expire; /* how often to expire */ + uint32_t expire_cycle; + uint32_t object_idle_tick; /* lifetime of objs */ + uint32_t expire_object_examined; /* Burst of object examined */ + + /* drain_fs and drain_sch point to the next bucket to scan when + * draining. + */ + uint32_t drain_fs; + uint32_t drain_sch; + + int init_done; + /* if the upper half is busy doing something long, * can set the busy flag and we will enqueue packets in * a queue for later processing. @@ -310,37 +348,14 @@ struct dn_sch_inst { * The counter is incremented or decremented when * a reference from the queue is created or deleted. * It is used to make sure that a scheduler instance can be safely - * deleted by the drain routine. See notes below. + * deleted by the drain routine. */ int q_count; }; -/* - * NOTE about object drain. - * The system will automatically (XXX check when) drain queues and - * scheduler instances when they are idle. - * A queue is idle when it has no packets; an instance is idle when - * it is not in the evheap heap, and the corresponding delay line is empty. - * A queue can be safely deleted when it is idle because of the scheduler - * function xxx_free_queue() will remove any references to it. - * An instance can be only deleted when no queues reference it. To be sure - * of that, a counter (q_count) stores the number of queues that are pointing - * to the instance. - * - * XXX - * Order of scan: - * - take all flowset in a bucket for the flowset hash table - * - take all queues in a bucket for the flowset - * - increment the queue bucket - * - scan next flowset bucket - * Nothing is done if a bucket contains no entries. - * - * The same schema is used for sceduler instances - */ - -/* kernel-side flags. Linux has DN_DELETE in fcntl.h +/* kernel-side flags. Linux has DN_DELETE in fcntl.h */ enum { /* 1 and 2 are reserved for the SCAN flags */ @@ -349,18 +364,20 @@ enum { DN_DETACH = 0x0010, DN_ACTIVE = 0x0020, /* object is in evheap */ DN_F_DLINE = 0x0040, /* object is a delay line */ - DN_F_SCHI = 0x00C0, /* object is a sched.instance */ + DN_DEL_SAFE = 0x0080, /* delete a queue only if no longer needed + * by scheduler */ DN_QHT_IS_Q = 0x0100, /* in flowset, qht is a single queue */ }; extern struct dn_parms dn_cfg; +//VNET_DECLARE(struct dn_parms, _base_dn_cfg); +//#define dn_cfg VNET(_base_dn_cfg) int dummynet_io(struct mbuf **, int , struct ip_fw_args *); void dummynet_task(void *context, int pending); void dn_reschedule(void); -struct dn_queue *ipdn_q_find(struct dn_fsk *, struct dn_sch_inst *, - struct ipfw_flow_id *); +struct dn_queue *ipdn_q_find(struct dn_fsk *, struct ipfw_flow_id *); struct dn_sch_inst *ipdn_si_find(struct dn_schk *, struct ipfw_flow_id *); /*