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