svn commit: r202627 - user/luigi/ipfw3-head/sys/netinet/ipfw
Luigi Rizzo
luigi at FreeBSD.org
Tue Jan 19 14:45:58 UTC 2010
Author: luigi
Date: Tue Jan 19 14:45:58 2010
New Revision: 202627
URL: http://svn.freebsd.org/changeset/base/202627
Log:
shuffle functions to pack them by class
Modified:
user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c
Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Tue Jan 19 13:36:12 2010 (r202626)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Tue Jan 19 14:45:58 2010 (r202627)
@@ -256,6 +256,60 @@ q_new(uintptr_t key, int flags, void *ar
return q;
}
+/*
+ * Delete a queue. The version for callbacks is called q_delete_cb().
+ * Call the 'free_queue' routine on the scheduler.
+ * If do_free is set, also free the packets.
+ */
+struct new_queue *
+dn_delete_queue(struct new_queue *q, int do_free)
+{
+ struct new_fsk *fs = q->fs;
+
+ printf(" +++ %s fs %p si %p\n", __FUNCTION__, fs, q->si);
+ /* notify the parent scheduler that the queue is going away */
+ if (fs && fs->sched->fp->free_queue)
+ fs->sched->fp->free_queue(q);
+ if (!do_free)
+ return q;
+ if (q->mq.head)
+ dn_free_pkts(q->mq.head);
+ free(q, M_DUMMYNET);
+ dn_cfg.queue_count--;
+ fs->refcnt--;
+ return NULL;
+}
+
+static int
+q_delete_cb(void *q, void *arg)
+{
+ (void)dn_delete_queue(q, (int)(uintptr_t)arg);
+ return 0;
+}
+
+/*
+ * calls dn_delete_queue/q_delete_cb on all queues,
+ * which notifies the parent scheduler and possibly drains packets.
+ * flags & DN_DELETE: drains queues and destroy qht;
+ */
+static void
+qht_delete(struct new_fsk *fs, int flags)
+{
+ printf("+++ %s fs %d start\n", __FUNCTION__, fs->fs.fs_nr);
+ if (!fs->_qht)
+ return;
+ if (fs->kflags & DN_QHT_IS_Q) {
+ fs->_qht = (struct dn_ht *)dn_delete_queue((struct new_queue *)(fs->_qht), flags);
+ } else {
+ dn_ht_scan(fs->_qht, q_delete_cb, (void *)flags);
+ if (flags & DN_DELETE) {
+ dn_ht_free(fs->_qht, 0);
+ fs->_qht = NULL;
+ }
+ }
+}
+/*--- end of queue hash table ---*/
+
/*--- support functions for the sch_inst hashtable ----
*
* These are hashed by flow-id
@@ -349,7 +403,6 @@ si_destroy(void *_si, void *arg)
dn_cfg.si_count--;
return 0;
}
-/*---- end of sch_inst hashtable ---------------------*/
/*
* Find the scheduler instance for this packet. If we need to apply
@@ -371,6 +424,7 @@ ipdn_si_find(struct new_schk *s, struct
}
return si;
}
+/*---- end of sch_inst hashtable ---------------------*/
/*-------------------------------------------------------
* flowset hash (fshash) support. Entries are hashed by fs_nr.
@@ -410,72 +464,16 @@ fsk_new(uintptr_t key, int flags, void *
}
return fs;
}
-/*----- end of flowset hashtable support -------------*/
/*
- * Delete a queue. The version for callbacks is called q_delete_cb().
- * Call the 'free_queue' routine on the scheduler.
- * If do_free is set, also free the packets.
- */
-struct new_queue *
-dn_delete_queue(struct new_queue *q, int do_free)
-{
- struct new_fsk *fs = q->fs;
-
- printf(" +++ %s fs %p si %p\n", __FUNCTION__, fs, q->si);
- /* notify the parent scheduler that the queue is going away */
- if (fs && fs->sched->fp->free_queue)
- fs->sched->fp->free_queue(q);
- if (!do_free)
- return q;
- if (q->mq.head)
- dn_free_pkts(q->mq.head);
- free(q, M_DUMMYNET);
- dn_cfg.queue_count--;
- fs->refcnt--;
- return NULL;
-}
-
-static int
-q_delete_cb(void *q, void *arg)
-{
- (void)dn_delete_queue(q, (int)(uintptr_t)arg);
- return 0;
-}
-
-/*
- * calls dn_delete_queue/q_delete_cb on all queues,
- * which notifies the parent scheduler and possibly drains packets.
- * flags & DN_DELETE: drains queues and destroy qht;
- */
-static void
-qht_delete(struct new_fsk *fs, int flags)
-{
- printf("+++ %s fs %d start\n", __FUNCTION__, fs->fs.fs_nr);
- if (!fs->_qht)
- return;
- if (fs->kflags & DN_QHT_IS_Q) {
- fs->_qht = (struct dn_ht *)dn_delete_queue((struct new_queue *)(fs->_qht), flags);
- } else {
- dn_ht_scan(fs->_qht, q_delete_cb, (void *)flags);
- if (flags & DN_DELETE) {
- dn_ht_free(fs->_qht, 0);
- fs->_qht = NULL;
- }
- }
-}
-
-/*
- * Detach or destroy all flowsets in a list. Used when deleting a scheduler,
- * or for all those in fsunlinked.
- * int_fs points to an internal flowset which must be handled differently.
+ * Detach or destroy all flowsets in a list.
* flags specifies what to do:
* DN_DELETE flush all queues
* DN_DELETE_FS DN_DELETE + destroy flowset
* DN_DELETE_FS implies DN_DELETE
*/
static void
-fsk_detach_list(struct new_fsk_head *h, struct new_fsk *int_fs, int flags)
+fsk_detach_list(struct new_fsk_head *h, int flags)
{
struct new_fsk *fs;
@@ -485,12 +483,6 @@ fsk_detach_list(struct new_fsk_head *h,
while ((fs = SLIST_FIRST(h))) {
SLIST_REMOVE_HEAD(h, sch_chain);
printf(" +++ %s child fs %d\n", __FUNCTION__, fs->fs.fs_nr);
- if (fs == int_fs) {
- /* free the internal flowset. */
- free(fs, M_DUMMYNET);
- dn_cfg.fsk_count--;
- continue;
- }
/* detach queues from the scheduler and possibly drain them */
qht_delete(fs, flags);
fs->sched = NULL;
@@ -502,7 +494,61 @@ fsk_detach_list(struct new_fsk_head *h,
}
}
}
+/*----- end of flowset hashtable support -------------*/
+/*------------------------------------------------------------
+ * 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 between the two. We use this trick
+ * because in the create phase (but it should be fixed).
+ */
+static int
+schk_hash(uintptr_t key, int flags, void *_arg)
+{
+ int i = !(flags & DNHT_KEY_IS_OBJ) ? key :
+ ((struct new_schk *)key)->sch.sched_nr;
+ return ( (i>>8)^(i>>4)^i );
+}
+
+static int
+schk_match(void *obj, uintptr_t key, int flags, void *_arg)
+{
+ struct new_schk *s = ((struct new_schk *)obj);
+ int i = !(flags & DNHT_KEY_IS_OBJ) ? key :
+ ((struct new_schk *)key)->sch.sched_nr;
+ return !(s->kflags & DN_DELETE) && (s->sch.sched_nr == i);
+}
+
+/*
+ * Create the entry and intialize with the sched hash if needed.
+ * Leave s->fp unset so we can tell whether a dn_ht_find() returns
+ * a new object or a previously existing one.
+ */
+static void *
+schk_new(uintptr_t key, int flags, void *arg)
+{
+ struct schk_new_arg *a = arg;
+ struct new_schk *s;
+ int l = sizeof(*s) +a->fp->schk_datalen;
+
+ s = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO);
+ if (s == NULL)
+ return NULL;
+ set_oid(&s->pipe.oid, DN_PIPE, sizeof(s->pipe));
+ s->sch = *a->sch; // copy initial values
+ s->pipe.pipe_nr = s->sch.sched_nr;
+ SLIST_INIT(&s->fsk_list);
+ /* initialize the hash table if needed. Otherwise,
+ * ht points to the single instance we own
+ */
+ if (s->sch.flags & DN_HAVE_MASK) {
+ s->siht = dn_ht_init(NULL, s->sch.buckets,
+ offsetof(struct new_sch_inst, si_next),
+ si_hash, si_match, si_new);
+ }
+ dn_cfg.schk_count++;
+ return s;
+}
/* callback to flush credit for the pipe */
static int
@@ -524,6 +570,41 @@ schk_reset_credit(struct new_schk *s)
reset_credit(s->siht, NULL);
}
+/*
+ * Callback for sched delete. Notify all attached flowsets to
+ * detach from the scheduler, destroy the internal flowset, and
+ * all instances.
+ * arg is 0 (only detach flowsets and destroy instances)
+ * DN_DELETE (detach & delete queues, delete schk)
+ * or DN_DELETE_FS (delete queues and flowsets, delete schk)
+ */
+static int
+schk_delete_cb(void *obj, void *arg)
+{
+ struct new_schk *s = obj;
+
+ printf("+++ %s sched %d arg %d\n", __FUNCTION__, s->sch.sched_nr, (int)arg);
+ if (0 && arg && s->fs) {
+ /* remove the internal flowset from the hashtab */
+ dn_ht_find(dn_cfg.fshash, s->fs->fs.fs_nr, DNHT_REMOVE, NULL);
+ }
+ fsk_detach_list(&s->fsk_list, arg ? DN_DELETE : 0);
+ /* we should not have any flowset pointing to us now */
+ if (s->sch.flags & DN_HAVE_MASK) {
+ dn_ht_scan(s->siht, si_destroy, NULL);
+ } else if (s->siht)
+ si_destroy(s->siht, NULL);
+ s->siht = NULL;
+ if (arg) {
+ bzero(s, sizeof(*s));
+ free(obj, M_DUMMYNET);
+ dn_cfg.schk_count--;
+ return HEAP_SCAN_DEL;
+ } else
+ return 0;
+}
+/*--- end of schk hashtable support ---*/
+
static int
copy_obj(char **start, char *end, void *_o)
{
@@ -581,37 +662,6 @@ copy_data_helper(void *_o, void *_arg)
return 0;
}
-/*
- * Callback for sched delete. Notify all attached flowsets to
- * detach from the scheduler, destroy the internal flowset, and
- * all instances.
- * arg is 0 (only detach flowsets and destroy instances)
- * DN_DELETE (detach & delete queues, delete schk)
- * or DN_DELETE_FS (delete queues and flowsets, delete schk)
- */
-static int
-schk_delete_cb(void *obj, void *arg)
-{
- struct new_schk *s = obj;
-
- printf("+++ %s sched %d arg %d\n", __FUNCTION__, s->sch.sched_nr, (int)arg);
- if (arg && s->fs) {
- /* remove the internal flowset from the hashtab */
- dn_ht_find(dn_cfg.fshash, s->fs->fs.fs_nr, DNHT_REMOVE, NULL);
- }
- fsk_detach_list(&s->fsk_list, s->fs, arg ? DN_DELETE : 0);
- /* we should not have any flowset pointing to us now */
- if (s->sch.flags & DN_HAVE_MASK) {
- dn_ht_scan(s->siht, si_destroy, NULL);
- } else if (s->siht)
- si_destroy(s->siht, NULL);
- if (arg) {
- free(obj, M_DUMMYNET);
- dn_cfg.schk_count--;
- return HEAP_SCAN_DEL;
- } else
- return 0;
-}
/*
@@ -656,9 +706,12 @@ static void
update_fs(struct new_schk *s)
{
struct new_fsk *fs, *tmp;
+ printf("%s start\n", __FUNCTION__);
SLIST_FOREACH_SAFE(fs, &dn_cfg.fsu, sch_chain, tmp) {
- if (s->sch.sched_nr != fs->fs.fs_nr) {
- printf("fs %d still unlinked\n", fs->fs.fs_nr);
+ if (s->sch.sched_nr != fs->fs.sched_nr) {
+ printf("fs %d for sch %d not %d still unlinked\n",
+ fs->fs.fs_nr, fs->fs.sched_nr,
+ s->sch.sched_nr);
continue;
}
printf("remove fs %d from fsunlinked, link to sched %d\n",
@@ -671,6 +724,7 @@ update_fs(struct new_schk *s)
printf("+++ %s requeue from fs %d to sch %d\n",
__FUNCTION__, fs->fs.fs_nr, s->sch.sched_nr);
}
+ printf("%s end\n", __FUNCTION__);
}
/*
@@ -758,6 +812,7 @@ config_fs(struct new_fs *nfs, struct dn_
i = nfs->fs_nr;
if (i <= 0 || i >= 3*DN_MAX_ID)
return NULL;
+ printf("%s flowset %d\n", __FUNCTION__, i);
/* XXX other sanity checks */
if (nfs->flags & DN_QSIZE_IS_BYTES) {
if (nfs->qsize > dn_cfg.pipe_byte_limit)
@@ -853,6 +908,7 @@ config_sched(struct new_sch *_nsch, stru
struct schk_new_arg a; /* argument for schk_new */
int i, notify_fs = 0;
+ printf("%s start\n", __FUNCTION__);
a.sch = _nsch;
if (a.sch->oid.len != sizeof(*a.sch)) {
printf("%s: bad sched len\n", __FUNCTION__);
@@ -880,7 +936,7 @@ again: /* run twice, for wfq and fifo */
}
dn_cfg.id++;
if (s->fp != NULL) {
- /* in all other cases, remove from the heaps,
+ /* Already existing -- remove from the heaps,
* and detach flowsets from
* the old one almost as in sched_delete, but
* preserve traffic.
@@ -889,6 +945,7 @@ again: /* run twice, for wfq and fifo */
printf("sched %d type changed from %s to %s\n",
i, s->fp->name, a.fp->name);
schk_delete_cb(s, NULL);
+ printf("schk_delete_cb done\n");
notify_fs = 1;
/* now we have nothing pointing to us */
}
@@ -921,6 +978,7 @@ again: /* run twice, for wfq and fifo */
goto again;
}
DUMMYNET_UNLOCK();
+ printf("%s end\n", __FUNCTION__);
return 0;
}
@@ -1028,6 +1086,7 @@ delete_schk(int i)
return EINVAL;
/* detach flowsets, delete traffic */
schk_delete_cb(s, (void*)(uintptr_t)DN_DELETE);
+ delete_fs(i + DN_MAX_ID); /* remove internal pipe */
return 0;
}
@@ -1043,7 +1102,7 @@ dummynet_flush(void)
dn_ht_scan(dn_cfg.schedhash, schk_delete_cb,
(void *)(uintptr_t)DN_DELETE_FS);
/* all remaining (unlinked) flowsets */
- fsk_detach_list(&dn_cfg.fsu, NULL, DN_DELETE_FS);
+ fsk_detach_list(&dn_cfg.fsu, DN_DELETE_FS);
/* Reinitialize system heap... */
heap_init(&dn_cfg.evheap, 16, offsetof(struct dn_id, id));
@@ -1247,21 +1306,21 @@ ip_dn_ctl(struct sockopt *sopt)
/* Disallow sets in really-really secure mode. */
if (sopt->sopt_dir == SOPT_SET) {
error = securelevel_ge(sopt->sopt_td->td_ucred, 3);
- if (error)
- return (error);
+ if (error)
+ return (error);
}
switch (sopt->sopt_name) {
default :
- printf("dummynet: -- unknown option %d", sopt->sopt_name);
+ printf("dummynet: unknown option %d", sopt->sopt_name);
error = EINVAL;
break;
- case IP_DUMMYNET_FLUSH :
- case IP_DUMMYNET_CONFIGURE :
- case IP_DUMMYNET_DEL : /* remove a pipe or queue */
- case IP_DUMMYNET_GET :
- printf("dummynet: -- compat option %d", sopt->sopt_name);
+ case IP_DUMMYNET_FLUSH:
+ case IP_DUMMYNET_CONFIGURE:
+ case IP_DUMMYNET_DEL: /* remove a pipe or queue */
+ case IP_DUMMYNET_GET:
+ printf("dummynet: compat option %d", sopt->sopt_name);
error = EINVAL;
break;
@@ -1280,7 +1339,6 @@ ip_dn_ctl(struct sockopt *sopt)
error = sooptcopyin(sopt, p, l, l);
if (error)
break ;
-
error = do_config(p, l);
break;
}
@@ -1291,59 +1349,6 @@ 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 between the two. We use this trick
- * because in the create phase (but it should be fixed).
- */
-static int
-schk_hash(uintptr_t key, int flags, void *_arg)
-{
- int i = !(flags & DNHT_KEY_IS_OBJ) ? key :
- ((struct new_schk *)key)->sch.sched_nr;
- return ( (i>>8)^(i>>4)^i );
-}
-
-static int
-schk_match(void *obj, uintptr_t key, int flags, void *_arg)
-{
- struct new_schk *s = ((struct new_schk *)obj);
- int i = !(flags & DNHT_KEY_IS_OBJ) ? key :
- ((struct new_schk *)key)->sch.sched_nr;
- return !(s->kflags & DN_DELETE) && (s->sch.sched_nr == i);
-}
-
-/*
- * Create the entry and intialize with the sched hash if needed.
- * Leave s->fp unset so we can tell whether a dn_ht_find() returns
- * a new object or a previously existing one.
- */
-static void *
-schk_new(uintptr_t key, int flags, void *arg)
-{
- struct schk_new_arg *a = arg;
- struct new_schk *s;
- int l = sizeof(*s) +a->fp->schk_datalen;
-
- s = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO);
- if (s == NULL)
- return NULL;
- set_oid(&s->pipe.oid, DN_PIPE, sizeof(s->pipe));
- s->sch = *a->sch; // copy initial values
- s->pipe.pipe_nr = s->sch.sched_nr;
- SLIST_INIT(&s->fsk_list);
- /* initialize the hash table if needed. Otherwise,
- * ht points to the single instance we own
- */
- if (s->sch.flags & DN_HAVE_MASK) {
- s->siht = dn_ht_init(NULL, s->sch.buckets,
- offsetof(struct new_sch_inst, si_next),
- si_hash, si_match, si_new);
- }
- dn_cfg.schk_count++;
- return s;
-}
static void
ip_dn_init(void)
More information about the svn-src-user
mailing list