Date: Tue, 12 Jan 2010 23:33:14 +0000 (UTC) From: Luigi Rizzo <luigi@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r202180 - user/luigi/ipfw3-head/sys/netinet/ipfw Message-ID: <201001122333.o0CNXEqw033215@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: luigi Date: Tue Jan 12 23:33:14 2010 New Revision: 202180 URL: http://svn.freebsd.org/changeset/base/202180 Log: mostly formatting changes. pipe flush still not working Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Tue Jan 12 22:28:59 2010 (r202179) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Tue Jan 12 23:33:14 2010 (r202180) @@ -143,10 +143,8 @@ SLIST_HEAD(dn_sched_head, dn_sched); * to be used by schedulers. */ -/* - * delete a queue, which we assume nobody references - */ -int dn_delete_queue(struct new_queue *q, int extract); +/* delete a queue, which we assume nobody references */ +int dn_delete_queue(struct new_queue *q); /* Allocate an hash table. * Returns the pointer to the table @@ -196,16 +194,15 @@ struct new_queue * dn_q_hash_id(struct i static __inline struct mbuf* dn_return_packet(struct new_queue *q) { - struct mbuf *m = q->mq.head; - KASSERT(m != NULL, ("empty queue to dn_return_packet")); - q->mq.head = m->m_nextpkt; - q->ni.length--; - q->si->ni.len_bytes -= m->m_pkthdr.len; - q->si->ni.len_bytes -= m->m_pkthdr.len; - if (q->mq.head == NULL && q->fs && q->fs->kflags & DN_DELETE) { - dn_delete_queue(q, 1 /* remove from ql_list */); - } - return m; + struct mbuf *m = q->mq.head; + KASSERT(m != NULL, ("empty queue to dn_return_packet")); + q->mq.head = m->m_nextpkt; + q->ni.length--; + q->si->ni.len_bytes -= m->m_pkthdr.len; + q->si->ni.len_bytes -= m->m_pkthdr.len; + if (q->mq.head == NULL && q->fs && q->fs->kflags & DN_DELETE) + dn_delete_queue(q); + return m; } int dn_sched_modevent(module_t mod, int cmd, void *arg); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Tue Jan 12 22:28:59 2010 (r202179) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Tue Jan 12 23:33:14 2010 (r202180) @@ -46,11 +46,10 @@ extern struct mtx dummynet_mtx; #define DUMMYNET_UNLOCK() mtx_unlock(&dummynet_mtx) #define DUMMYNET_LOCK_ASSERT() mtx_assert(&dummynet_mtx, MA_OWNED) -#define HASH(num) ((((num) >> 8) ^ ((num) >> 4) ^ (num)) & dn_cfg.hmask) - SLIST_HEAD(new_schk_head, new_schk); SLIST_HEAD(new_sch_inst_head, new_sch_inst); SLIST_HEAD(new_fsk_head, new_fsk); +SLIST_HEAD(new_queue_head, new_queue); /* * global configuration parameters. @@ -68,19 +67,20 @@ struct dn_parms { long pipe_slot_limit; int io_fast; - struct timeval prev_t; - struct dn_heap system_heap; + struct timeval prev_t; /* last time dummynet_tick ran */ + struct dn_heap system_heap; /* scheduled events */ - /* how many objects we have -- useful for reporting space */ + /* counters of objects -- used for reporting space */ int schk_count; int si_count; int fsk_count; int queue_count; - int buckets; /* for the two hash tables */ + int buckets; /* for the hash tables below */ struct dn_ht *fshash; struct dn_ht *schedhash; - struct new_fsk_head fsunlinked; /* use sch_chain */ + /* list of flowsets without a scheduler -- use sch_chain */ + struct new_fsk_head fsunlinked; }; static inline void @@ -91,14 +91,13 @@ set_oid(struct dn_id *o, int type, int s o->len = len; }; -struct mq { +struct mq { /* a basic queue of packets*/ struct mbuf *head, *tail; }; /* - * Delay line, contains all packets that will be sent out - * at certain time. - * Every scheduler instance has a delay line + * Delay line, contains all packets on output from a pipe. + * Every scheduler instance has one. */ struct delay_line { struct dn_id oid; @@ -107,77 +106,64 @@ struct delay_line { }; /* - * The kernel side of a flowset. Contains: - * - configuration parameters (fs, cmdline); - * - kernel info (kflags) - * - link field for the hash chain - * - reference to the scheduler; - * - a refcount (from queues) - * - link field for a list of fsk attached to sched (used when sched - * is deleted or reconfigured); - * The flowset does not know which queues are linked to it. - * When we remove a flowset, move it to the unlinked list and - * set the kflag. When the refcnt is 0 it can go away. - * the sched_nr to 0 + * The kernel side of a flowset. In addition to the user parameters + * and kernel flags, it is linked in a hash table of flowsets, + * and in a list of children of their parent scheduler. + * It also contains a hash table of children queues (or one, if + * there is no flow_mask). + * When we remove a flowset, mark as DN_DELETE so it can go away + * when the hash table will be empty. + * XXX refcnt is redundant. */ struct new_fsk { /* kernel side of a flowset */ struct new_fs fs; - SLIST_ENTRY(new_fsk) fsk_next; /* hash chain list */ - int kflags; /* kernel-side flags */ - /* - * Scheduler-specific parameters for this flowset - * (for examples, the weight parameter of wf2q+ algorithm goes here) - */ - int weight; - int quantum; - - /* Number of queues attached to this flowset */ - int refcnt; + SLIST_ENTRY(new_fsk) fsk_next; /* hash chain list */ + int kflags; /* kernel-side flags */ + int refcnt; /* entries in qht */ /* hash table of queues, or just our queue if we have no mask */ struct dn_ht *qht; - /* Scheduler associated with this flowset */ - struct new_schk *sched; - SLIST_ENTRY(new_fsk) sch_chain; /* list of fsk attached to sched */ + struct new_schk *sched; /* Sched we are linked to */ + SLIST_ENTRY(new_fsk) sch_chain; /* list of fsk attached to sched */ +}; + +/* + * The child of a flowset, is in a hash table + */ +struct new_queue { + struct new_inst ni; /* oid, flow_id, stats */ + struct mq mq; /* packets queue */ + SLIST_ENTRY(new_queue) ql__next; /* hash chain list */ + SLIST_ENTRY(new_queue) si_chain; /* linked list to sch_inst */ + struct new_sch_inst *si; /* owner scheduler instance */ + struct new_fsk *fs; /* parent flowset. */ + /* If fs->kflags & DN_DELETE, remove the queue when empty. */ }; +/* + * The kernel side of a scheduler. Contains the userland config, + * a pipe, pointer to extra config arguments from command line, + * kernel flags, and a pointer to the scheduler methods. + * It is stored in a hash table, and holds a list of all + * flowsets and scheduler instances. + */ struct new_schk { struct new_sch sch; + int kflags; + struct dn_sched *fp; /* Pointer to scheduler functions */ + struct new_pipe pipe; /* the pipe is embedded */ + struct dn_id *cfg; /* extra config arguments */ - /* This structure is in a list of schedulers where we do - * the lookup when necessary. 'next' is the link field. - * Also, all instances of this scheduler may be in a heap used - * to fetch them when they are ready. 'inst_counter' counts - * how many instances are in the heap and can be used - * as a reference count. - */ - SLIST_ENTRY(new_schk) schk_next; /* List of all templates */ - struct new_fsk_head fsk_list; /* all fsk linked to me */ + SLIST_ENTRY(new_schk) schk_next; /* hash chain list */ - struct new_pipe pipe; /* the pipe is embedded */ - struct dn_id *cfg; /* extra config arguments */ + struct new_fsk_head fsk_list; /* all fsk linked to me */ - /* Hash table of all children. Used to apply the sched_mask */ + /* Hash table of all instances (through sched_mask) */ struct dn_ht *siht; - int kflags; - - struct dn_sched *fp; /* Pointer to scheduler functions */ }; -/* The packets queue associated with a scheduler instance */ -struct new_queue { - struct new_inst ni; /* oid, flow_id, stats */ - struct mq mq; /* packets queue */ - - SLIST_ENTRY(new_queue) ql_next; /* linked list to sch_inst */ - struct new_sch_inst *si; /* owner scheduler instance */ - - struct new_fsk *fs; /* parent flowset. */ - /* If fs->kflags & DN_DELETE, remove the queue when empty. */ -}; -SLIST_HEAD(new_queue_head, new_queue); /* * Scheduler instance. Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Tue Jan 12 22:28:59 2010 (r202179) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Tue Jan 12 23:33:14 2010 (r202180) @@ -294,8 +294,7 @@ si_destroy(void *_si, void *arg) heap_extract(&dn_cfg.system_heap, dl); dn_free_pkts(dl->mq.head); while ( (q = SLIST_FIRST(&si->ql_list)) ) { - SLIST_REMOVE_HEAD(&si->ql_list, ql_next); - dn_delete_queue(q, 0); + dn_delete_queue(q); } free(si, M_DUMMYNET); dn_cfg.si_count--; @@ -336,10 +335,12 @@ destroy_fs(void *obj, void *arg) fs->kflags |= DN_DELETE; if (fs->refcnt == 0) { - fs->sched = NULL; dn_cfg.fsk_count--; - SLIST_REMOVE(&s->fsk_list, fs, new_fsk, sch_chain); + if (fs->sched) + SLIST_REMOVE(&s->fsk_list, fs, new_fsk, sch_chain); + fs->sched = NULL; free(fs, M_DUMMYNET); + printf("%s free done\n", __FUNCTION__); } return HEAP_SCAN_DEL; } @@ -369,7 +370,7 @@ dn_create_queue(struct new_sch_inst *si, if (si->sched->fp->new_queue) si->sched->fp->new_queue(q); - SLIST_INSERT_HEAD(&si->ql_list, q, ql_next); + SLIST_INSERT_HEAD(&si->ql_list, q, si_chain); dn_cfg.queue_count++; return q; } @@ -378,12 +379,12 @@ dn_create_queue(struct new_sch_inst *si, * Delete a queue (helper for the schedulers) */ int -dn_delete_queue(struct new_queue *q, int extract) +dn_delete_queue(struct new_queue *q) { struct new_fsk *fs = q->fs; - if (extract) - SLIST_REMOVE(&q->si->ql_list, q, new_queue, ql_next); + if (SLIST_FIRST(&q->si->ql_list)) + SLIST_REMOVE(&q->si->ql_list, q, new_queue, si_chain); if (q->mq.head) dn_free_pkts(q->mq.head); if (fs && fs->sched->fp->free_queue) @@ -430,7 +431,6 @@ schk_reset_credit(struct new_schk *s) reset_credit(s->siht, NULL); } - static int copy_obj(char **start, char *end, void *_o) { @@ -443,7 +443,7 @@ copy_obj(char **start, char *end, void * return 0; } -/* copy data, return 1 when full */ +/* argument for copy data, return 1 when full */ struct copy_args { char **start; char *end; @@ -497,6 +497,7 @@ dummynet_flush(void) printf("%s start\n", __FUNCTION__); /* first mark flowsets as delete, then go after queues */ dn_ht_scan(dn_cfg.fshash, destroy_fs, 0); + printf("%s destroy_fs done\n", __FUNCTION__); dn_ht_scan(dn_cfg.schedhash, schk_del_cb, 0); /* Reinitialize system heap... */ @@ -568,8 +569,7 @@ do_config(void *p, int l) return err; } -static inline -struct new_schk * +static inline struct new_schk * locate_scheduler(int i) { return dn_ht_find(dn_cfg.schedhash, i, 0); @@ -602,7 +602,7 @@ config_pipe(struct new_pipe *p, struct d i = p->pipe_nr; if (i <= 0 || i > DN_MAXID) return EINVAL; - printf("%s %d\n", __FUNCTION__, i); + // printf("%s %d\n", __FUNCTION__, i); /* * The config program passes parameters as follows: * bw = bits/second (0 means no limits), @@ -647,7 +647,7 @@ config_sched(struct new_sch *nsch, struc i = nsch->sched_nr; if (i <= 0 || i > DN_MAXID) return EINVAL; - printf("%s i %d\n", __FUNCTION__, i); + // printf("%s i %d\n", __FUNCTION__, i); /* XXX other sanity checks */ fp = load_scheduler(nsch->oid.subtype, nsch->type); if (fp == NULL) { @@ -680,7 +680,7 @@ config_sched(struct new_sch *nsch, struc } else if (s->fp != fp) { /* type changed, flush queues. */ // XXX we should reallocate the private data area. // how do we do it ? - /* preserve old pipe ? */ + /* preserve old pipe */ schk_flush(s); } /* complete initialization */ @@ -770,6 +770,7 @@ config_profile(struct new_profile *pf, s if (i <= 0 || i > DN_MAXID) return EINVAL; /* XXX other sanity checks */ + DUMMYNET_LOCK(); s = locate_scheduler(i); @@ -938,7 +939,7 @@ ip_dn_ctl(struct sockopt *sopt) error = EINVAL; break; - case IP_DUMMYNET3 : /* remove a pipe or queue */ + case IP_DUMMYNET3 : if (sopt->sopt_dir == SOPT_GET) { error = dummynet_get(sopt); break; @@ -964,7 +965,7 @@ ip_dn_ctl(struct sockopt *sopt) return error ; } -/* +/*------------------------------------------------------------ * Scheduler hash. When searching by index we pass sched_nr, * otherwise we pass struct new_sch * which is the first field in * struct new_schk so we can cast it. We need this info during the @@ -1013,16 +1014,13 @@ schk_new(uintptr_t key, int flags, void if (sch->flags & DN_HAVE_MASK) { s->siht = dn_ht_init(NULL, s->sch.buckets, offsetof(struct new_sch_inst, si_next), - si_hash, /* hash */ - si_match,/* MATCH */ - si_new, /* new */ - s /* arg */ ); + si_hash, si_match, si_new, s); } dn_cfg.schk_count++; return s; } -/* +/*------------------------------------------------------- * flowset hash support */ static int @@ -1034,7 +1032,7 @@ fsk_hash(uintptr_t key, int flags, void return ( (i>>8)^(i>>4)^i ); } -/* matck skips those marked as deleted */ +/* match skips entries those marked as deleted */ static int fsk_match(void *obj, uintptr_t key, int flags, void *arg) { @@ -1050,9 +1048,10 @@ fsk_new(uintptr_t key, int flags, void * struct new_fsk *fs; fs = malloc(sizeof(*fs), M_DUMMYNET, M_NOWAIT | M_ZERO); - if (fs) + if (fs) { dn_cfg.fsk_count++; - SLIST_INSERT_HEAD(&dn_cfg.fsunlinked, fs, sch_chain); + SLIST_INSERT_HEAD(&dn_cfg.fsunlinked, fs, sch_chain); + } return fs; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001122333.o0CNXEqw033215>