Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 Jan 2010 08:53:01 +0000 (UTC)
From:      Luigi Rizzo <luigi@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r202735 - in user/luigi/ipfw3-head: sbin/ipfw sys/netinet sys/netinet/ipfw
Message-ID:  <201001210853.o0L8r12L075213@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: luigi
Date: Thu Jan 21 08:53:01 2010
New Revision: 202735
URL: http://svn.freebsd.org/changeset/base/202735

Log:
  - in new_sch, rename 'type' to 'name';
  - introduce macros D() and ND() to take care of debugging printfs
  - staticize function dn_delete_queue
  - adjust comments and formatting

Modified:
  user/luigi/ipfw3-head/sbin/ipfw/dummynet.c
  user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h
  user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h
  user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c
  user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c

Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c
==============================================================================
--- user/luigi/ipfw3-head/sbin/ipfw/dummynet.c	Thu Jan 21 03:49:18 2010	(r202734)
+++ user/luigi/ipfw3-head/sbin/ipfw/dummynet.c	Thu Jan 21 08:53:01 2010	(r202735)
@@ -299,7 +299,8 @@ list_pipes(struct dn_id *oid, struct dn_
 	case DN_SCH: {
 	    struct new_sch *s = (struct new_sch *)oid;
 	    flush_buf(buf);
-	    printf(" type %s flags 0x%x %d buckets\n", s->type, s->flags, s->buckets);
+	    printf(" type %s flags 0x%x %d buckets\n",
+			s->name, s->flags, s->buckets);
 	    if (s->flags & DN_HAVE_MASK)
 		print_mask(&s->sched_mask);
 	    }
@@ -1043,7 +1044,7 @@ end_mask:
 			l = strlen(av[0]);
 			if (l == 0 || l > 15)
 				errx(1, "type %s too long\n", av[0]);
-			strcpy(sch->type, av[0]);
+			strcpy(sch->name, av[0]);
 			sch->oid.subtype = 0; /* use string */
 			ac--; av++;
 			break;

Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h	Thu Jan 21 03:49:18 2010	(r202734)
+++ user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h	Thu Jan 21 08:53:01 2010	(r202735)
@@ -181,7 +181,7 @@ struct new_sch {
 	int buckets; /* number of buckets for the instances */
 	int flags;	/* have_mask, ... */
 
-	char type[16];	/* null terminated */
+	char name[16];	/* null terminated */
 	/* mask to select the appropriate scheduler instance */
 	struct ipfw_flow_id sched_mask; /* M */
 };

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h	Thu Jan 21 03:49:18 2010	(r202734)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h	Thu Jan 21 08:53:01 2010	(r202735)
@@ -120,12 +120,7 @@ struct dn_sched {
  * Additionally, dummynet exports some functions and macros
  * to be used by schedulers:
  */
-/* delete a queue, which we assume nobody references.
- * if do_free is set, propagate to the flowset and destroy it
- * if the refcount becomes 0
- */
 void dn_free_pkts(struct mbuf *mnext);
-void dn_delete_queue(struct new_queue *, int do_free);
 int dn_enqueue(struct new_queue *q, struct mbuf* m, int drop);
 
 /*

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c	Thu Jan 21 03:49:18 2010	(r202734)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c	Thu Jan 21 08:53:01 2010	(r202735)
@@ -208,6 +208,20 @@ mq_append(struct mq *q, struct mbuf *m)
 }
 
 /*
+ * Dispose a list of packet. Use a functions so if we need to do
+ * more work, this is a central point to do it.
+ */
+void dn_free_pkts(struct mbuf *mnext)
+{
+        struct mbuf *m;
+    
+        while ((m = mnext) != NULL) {
+                mnext = m->m_nextpkt;
+                FREE_PKT(m);
+        }
+}
+
+/*
  * Enqueue a packet in q, subject to space and queue management policy
  * (whose parameters are in q->fs).
  * Update stats for the queue and the scheduler.

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c	Thu Jan 21 03:49:18 2010	(r202734)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c	Thu Jan 21 08:53:01 2010	(r202735)
@@ -30,8 +30,13 @@ __FBSDID("$FreeBSD$");
 
 #include "opt_inet6.h"
 
+/* debug support */
+// #define D(fmt, args...) do {} while (0)
+#define ND(fmt, args...) do {} while (0)
+#define D(fmt, args...) printf("%s " fmt "\n", __FUNCTION__ , ## args)
+
 /*
- * configuration support for dummynet.
+ * Configuration and internal object management for dummynet.
  */
 
 #include <sys/param.h>
@@ -103,20 +108,6 @@ find_sched_type(int type, char *name)
 	return NULL; /* not found */
 }
 
-/*
- * Dispose a list of packet. Use a functions so if we need to do
- * more work, this is a central point to do it.
- */
-void dn_free_pkts(struct mbuf *mnext)
-{
-        struct mbuf *m;
-    
-        while ((m = mnext) != NULL) {
-                mnext = m->m_nextpkt;
-                FREE_PKT(m);
-        }
-}
-
 static int
 bound_var(int *v, int dflt, int lo, int hi, const char *msg)
 {
@@ -251,7 +242,7 @@ q_new(uintptr_t key, int flags, void *ar
 
 	q = malloc(size, M_DUMMYNET, M_NOWAIT | M_ZERO);
 	if (q == NULL) {
-		printf("%s: no memory for new queue\n", __FUNCTION__);
+		D("no memory for new queue");
 		return NULL;
 	}
 
@@ -272,12 +263,12 @@ q_new(uintptr_t key, int flags, void *ar
  * If (flags & DN_DELETE), also free the packets.
  * The version for callbacks is called q_delete_cb().
  */
-void
+static void
 dn_delete_queue(struct new_queue *q, int flags)
 {
 	struct new_fsk *fs = q->fs;
 
-	// printf("%s fs %p si %p\n", __FUNCTION__, fs, q->_si);
+	// D("fs %p si %p\n", 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);
@@ -307,10 +298,8 @@ q_delete_cb(void *q, void *arg)
 static void
 qht_delete(struct new_fsk *fs, int flags)
 {
-#if 0
-	printf("+++ %s fs %d start flags %d qht %p\n",
-		__FUNCTION__, fs->fs.fs_nr, flags, fs->_qht);
-#endif
+	ND("fs %d start flags %d qht %p",
+		fs->fs.fs_nr, flags, fs->_qht);
 	if (!fs->_qht)
 		return;
 	if (fs->fs.flags & DN_HAVE_MASK) {
@@ -329,7 +318,6 @@ qht_delete(struct new_fsk *fs, int flags
 /*
  * Find and possibly create the right queue for a MULTIQUEUE scheduler.
  * We never call it for !MULTIQUEUE (when the queue is in the sch_inst).
- * in a better way.
  */
 struct new_queue *
 ipdn_q_find(struct new_fsk *fs, struct new_sch_inst *si,
@@ -404,7 +392,8 @@ si_new(uintptr_t key, int flags, void *a
 		goto error;
 	/* Set length only for the part passed up to userland. */
 	set_oid(&si->ni.oid, DN_SCH_I, sizeof(struct new_inst));
-	set_oid(&(si->dline.oid), DN_DELAY_LINE, sizeof(struct delay_line));
+	set_oid(&(si->dline.oid), DN_DELAY_LINE,
+		sizeof(struct delay_line));
 	/* mark si and dline as outside the event queue */
 	si->ni.oid.id = si->dline.oid.id = -1;
 
@@ -412,7 +401,7 @@ si_new(uintptr_t key, int flags, void *a
 	si->dline.si = si;
 
 	if (s->fp->new_sched && s->fp->new_sched(si)) {
-		printf("%s: new_sched error\n", __FUNCTION__);
+		D("new_sched error");
 		goto error;
 	}
 	if (s->sch.flags & DN_HAVE_MASK)
@@ -458,6 +447,7 @@ si_destroy(void *_si, void *arg)
 /*
  * Find the scheduler instance for this packet. If we need to apply
  * a mask, do on a local copy of the flow_id to preserve the original.
+ * Assume siht is always initialized.
  */
 struct new_sch_inst *
 ipdn_si_find(struct new_schk *s, struct ipfw_flow_id *id)
@@ -469,8 +459,6 @@ ipdn_si_find(struct new_schk *s, struct 
 		return dn_ht_find(s->siht, (uintptr_t)&id_t,
 			DNHT_INSERT, s);
 	} else {
-		if (s->siht == NULL)
-			s->siht = si_new((uintptr_t)id, 0, s);
 		return (struct new_sch_inst *)s->siht;
 	}
 }
@@ -491,7 +479,7 @@ schk_reset_credit(struct new_schk *s)
 {
 	if (s->sch.flags & DN_HAVE_MASK)
 		dn_ht_scan(s->siht, si_reset_credit, NULL);
-	else if (s->siht)
+	else
 		si_reset_credit(s->siht, NULL);
 }
 /*---- end of sch_inst hashtable ---------------------*/
@@ -545,13 +533,11 @@ fsk_detach(struct new_fsk *fs, int flags
 {
 	if (flags & DN_DELETE_FS)
 		flags |= DN_DELETE;
-#if 0
-	printf("%s fs %d from sched %d flags %s %s %s\n",
-		__FUNCTION__, fs->fs.fs_nr, fs->fs.sched_nr,
+	ND("fs %d from sched %d flags %s %s %s",
+		fs->fs.fs_nr, fs->fs.sched_nr,
 		(flags & DN_DELETE_FS) ? "DEL_FS":"",
 		(flags & DN_DELETE) ? "DEL":"",
 		(flags & DN_DETACH) ? "DET":"");
-#endif
 	if (flags & DN_DETACH) { /* detach from the list */
 		struct new_fsk_head *h;
 		h = fs->sched ? &fs->sched->fsk_list : &dn_cfg.fsu;
@@ -583,13 +569,13 @@ fsk_detach_list(struct new_fsk_head *h, 
 	struct new_fsk *fs;
 	int n = 0; /* only for stats */
 
-	// printf("+++ %s head %p flags %x\n", __FUNCTION__, h, flags);
+	ND("head %p flags %x", h, flags);
 	while ((fs = SLIST_FIRST(h))) {
 		SLIST_REMOVE_HEAD(h, sch_chain);
 		n++;
 		fsk_detach(fs, flags);
 	}
-	// printf("+++ %s done flowsets\n", __FUNCTION__, n);
+	ND("done %d flowsets", n);
 }
 
 /*
@@ -606,7 +592,7 @@ delete_fs(int i, int locked)
 	if (!locked)
 		DN_BH_WLOCK();
 	fs = dn_ht_find(dn_cfg.fshash, i, DNHT_REMOVE, NULL);
-	// printf("%s fs %d found %p\n", __FUNCTION__, i, fs);
+	ND("fs %d found %p", i, fs);
 	if (fs) {
 		fsk_detach(fs, DN_DETACH | DN_DELETE_FS);
 		err = 0;
@@ -661,13 +647,15 @@ schk_new(uintptr_t key, int flags, void 
 	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,
+	/* initialize the hash table or create the single instance */
+	s->siht = (s->sch.flags & DN_HAVE_MASK) ?
+		dn_ht_init(NULL, s->sch.buckets,
 			offsetof(struct new_sch_inst, si_next),
-			si_hash, si_match, si_new);
+			si_hash, si_match, si_new) :
+		si_new(0, 0, s);
+	if (s->siht == NULL) {
+		free(s, M_DUMMYNET);
+		return NULL;
 	}
 	dn_cfg.schk_count++;
 	return s;
@@ -686,18 +674,17 @@ schk_delete_cb(void *obj, void *arg)
 {
 	struct new_schk *s = obj;
 #if 0
-	int i = s->sch.sched_nr;
 	int a = (int)arg;
-	printf(">>> %s sched %d arg %s%s\n",
-		__FUNCTION__, i,
+	ND("sched %d arg %s%s",
+		s->sch.sched_nr,
 		a&DN_DELETE ? "DEL ":"",
 		a&DN_DELETE_FS ? "DEL_FS":"");
 #endif
 	fsk_detach_list(&s->fsk_list, arg ? DN_DELETE : 0);
 	/* no more flowset pointing to us now */
-	if (s->sch.flags & DN_HAVE_MASK) {
+	if (s->sch.flags & DN_HAVE_MASK)
 		dn_ht_scan(s->siht, si_destroy, NULL);
-	} else if (s->siht)
+	else
 		si_destroy(s->siht, NULL);
 	s->siht = NULL;
 	if (s->fp->destroy)
@@ -719,16 +706,14 @@ delete_schk(int i)
 	struct new_schk *s;
 
 	s = dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL);
-	// printf("%s sched %d %p\n", __FUNCTION__, i, s);
+	ND("%d %p", i, s);
 	if (!s)
 		return EINVAL;
-	/* detach flowsets, delete traffic */
-	delete_fs(i + DN_MAX_ID, 1);	/* first remove internal pipe */
+	delete_fs(i + DN_MAX_ID, 1); /* first delete internal fs */
+	/* then detach flowsets, delete traffic */
 	schk_delete_cb(s, (void*)(uintptr_t)DN_DELETE);
 	return 0;
 }
-
-
 /*--- end of schk hashtable support ---*/
 
 static int
@@ -738,11 +723,11 @@ copy_obj(char **start, char *end, void *
 	int have = end - *start;
 
 	if (have < o->len || o->len == 0 || o->type == 0) {
-		printf("XXX %s ERROR type %d %s %d have %d need %d\n",
-			__FUNCTION__, o->type, msg, i, have, o->len);
+		D("ERROR type %d %s %d have %d need %d",
+			o->type, msg, i, have, o->len);
 		return 1;
 	}
-	// printf("%s type %d %s %d len %d\n", __FUNCTION__, o->type, msg, i, o->len);
+	ND("type %d %s %d len %d", o->type, msg, i, o->len);
 	bcopy(_o, *start, o->len);
 	*start += o->len;
 	return 0;
@@ -777,7 +762,8 @@ copy_si_cb(void *obj, void *arg)
 	struct new_sch_inst *si = obj;
 	struct copy_args *a = arg;
 	struct new_inst *ni = (struct new_inst *)(*a->start);
-	if (copy_obj(a->start, a->end, &si->ni, "inst", si->sched->sch.sched_nr))
+	if (copy_obj(a->start, a->end, &si->ni, "inst",
+			si->sched->sch.sched_nr))
 		return DNHT_SCAN_END;
 	ni->oid.type = DN_NI;
 	return 0;
@@ -786,12 +772,10 @@ copy_si_cb(void *obj, void *arg)
 static int
 copy_si(struct copy_args *a, struct new_schk *s, int flags)
 {
-	if (s->sch.flags & DN_HAVE_MASK) {
+	if (s->sch.flags & DN_HAVE_MASK)
 		dn_ht_scan(s->siht, copy_si_cb, a);
-	} else {
-		if (s->siht)
-			copy_si_cb(s->siht, a);
-	}
+	else
+		copy_si_cb(s->siht, a);
 	return 0;
 }
 
@@ -808,13 +792,15 @@ copy_data_helper(void *_o, void *_arg)
 		if (a->type == DN_PIPE && s->sch.sched_nr <= DN_MAX_ID)
 			return 0;	/* not valid pipe */
 		if (a->flags & DN_C_PIPE) {
-			if (copy_obj(a->start, a->end, &s->pipe, "pipe", s->sch.sched_nr))
+			if (copy_obj(a->start, a->end, &s->pipe,
+					"pipe", s->sch.sched_nr))
 				return DNHT_SCAN_END;
 			if (copy_flowset(a, s->fs, 0))
 				return DNHT_SCAN_END;
 		}
 		if (a->flags & DN_C_SCH) {
-			if (copy_obj(a->start, a->end, &s->sch, "sched", s->sch.sched_nr))
+			if (copy_obj(a->start, a->end, &s->sch,
+					"sched", s->sch.sched_nr))
 				return DNHT_SCAN_END;
 		}
 		if (a->flags & DN_C_SCH_INST) {
@@ -844,10 +830,8 @@ locate_scheduler(int i)
 static void
 fsk_attach(struct new_fsk *fs, struct new_schk *s)
 {
-#if 0
-	printf("remove fs %d from fsunlinked, link to sched %d\n",
+	ND("remove fs %d from fsunlinked, link to sched %d",
 		fs->fs.fs_nr, s->sch.sched_nr);
-#endif
 	SLIST_REMOVE(&dn_cfg.fsu, fs, new_fsk, sch_chain);
 	fs->sched = s;
 	SLIST_INSERT_HEAD(&s->fsk_list, fs, sch_chain);
@@ -855,8 +839,8 @@ fsk_attach(struct new_fsk *fs, struct ne
 		s->fp->new_fsk(fs);
 	if (!fs->_qht)
 		return;
-	printf("XXX %s TODO requeue from fs %d to sch %d\n",
-		__FUNCTION__, fs->fs.fs_nr, s->sch.sched_nr);
+	D("XXX TODO requeue from fs %d to sch %d",
+		fs->fs.fs_nr, s->sch.sched_nr);
 }
 
 /* update all flowsets which may refer to this scheduler */
@@ -867,7 +851,7 @@ update_fs(struct new_schk *s)
 
 	SLIST_FOREACH_SAFE(fs, &dn_cfg.fsu, sch_chain, tmp) {
 		if (s->sch.sched_nr != fs->fs.sched_nr) {
-			printf("fs %d for sch %d not %d still unlinked\n",
+			D("fs %d for sch %d not %d still unlinked",
 				fs->fs.fs_nr, fs->fs.sched_nr,
 				s->sch.sched_nr);
 			continue;
@@ -899,15 +883,15 @@ update_fs(struct new_schk *s)
  */
 
 /*
- * configure a pipe
+ * configure a pipe (and its FIFO instance)
  */
 static int
 config_pipe(struct new_pipe *p, struct dn_id *arg)
 {
 	int i;
 
-	if (p->oid.len < sizeof(*p)) {
-		printf("%s: short pipe\n", __FUNCTION__);
+	if (p->oid.len != sizeof(*p)) {
+		D("invalid pipe len %d", p->oid.len);
 		return EINVAL;
 	}
 	i = p->pipe_nr;
@@ -930,7 +914,7 @@ config_pipe(struct new_pipe *p, struct d
 	    struct new_schk *s = locate_scheduler(i);
 	    if (s == NULL) {
 		DN_BH_WUNLOCK();
-		printf("%s sched %d not found\n", __FUNCTION__, i);
+		D("sched %d not found", i);
 		return EINVAL;
 	    }
 	    /* copy all parameters */
@@ -955,14 +939,14 @@ config_fs(struct new_fs *nfs, struct dn_
 	int i;
 	struct new_fsk *fs;
 
-	if (nfs->oid.len < sizeof(*nfs)) {
-		printf("%s: short flowset\n", __FUNCTION__);
+	if (nfs->oid.len != sizeof(*nfs)) {
+		D("invalid flowset len %d", nfs->oid.len);
 		return NULL;
 	}
 	i = nfs->fs_nr;
 	if (i <= 0 || i >= 3*DN_MAX_ID)
 		return NULL;
-	// printf("%s flowset %d\n", __FUNCTION__, i);
+	ND("flowset %d", i);
 	/* XXX other sanity checks */
         if (nfs->flags & DN_QSIZE_BYTES) {
                 if (nfs->qsize > dn_cfg.pipe_byte_limit)
@@ -992,14 +976,14 @@ config_fs(struct new_fs *nfs, struct dn_
 		if (fs->fs.sched_nr != 0) { /* reuse */
 		    nfs->sched_nr = fs->fs.sched_nr;
 		} else {
-		    printf("missing sched for flowset %d\n", i);
+		    D("missing sched for flowset %d", i);
 		    fs = NULL;
 		    break;
 		}
 	    }
 	    dn_cfg.id++;
 	    if (bcmp(&fs->fs, nfs, sizeof(*nfs)) == 0) {
-		printf("%s flowset %d unchanged\n", __FUNCTION__, i);
+		D("flowset %d unchanged", i);
 		break; /* no change, nothing to do */
 	    }
 	    s = locate_scheduler(nfs->sched_nr);
@@ -1007,8 +991,8 @@ config_fs(struct new_fs *nfs, struct dn_
 	     * queues if we need to reattach. Then update the
 	     * configuration, and possibly attach to the new sched.
 	     */
-	    printf("%s fs %d changed args/sched %d %p to %d %p\n",
-		__FUNCTION__,  fs->fs.fs_nr,
+	    D("fs %d changed args/sched %d %p to %d %p",
+		fs->fs.fs_nr,
 		fs->fs.sched_nr, fs->sched, nfs->sched_nr, s);
 	    if (fs->sched) {
 		int flags = s ? DN_DETACH : (DN_DETACH | DN_DELETE);
@@ -1025,7 +1009,7 @@ config_fs(struct new_fs *nfs, struct dn_
 }
 
 /*
- * configure a scheduler and its FIFO variant.
+ * config/reconfig a scheduler and its FIFO variant.
  * For !MULTIQUEUE schedulers, also set up the flowset.
  *
  * On reconfigurations (detected because s->fp is set),
@@ -1042,7 +1026,7 @@ config_sched(struct new_sch *_nsch, stru
 
 	a.sch = _nsch;
 	if (a.sch->oid.len != sizeof(*a.sch)) {
-		printf("%s: bad sched len\n", __FUNCTION__);
+		D("bad sched len %d", a.sch->oid.len);
 		return EINVAL;
 	}
 	i = a.sch->sched_nr;
@@ -1056,53 +1040,55 @@ config_sched(struct new_sch *_nsch, stru
 	bzero(&p, sizeof(p));
 	DN_BH_WLOCK();
 again: /* run twice, for wfq and fifo */
-	a.fp = find_sched_type(a.sch->oid.subtype, a.sch->type);
+	/*
+	 * lookup the type. If not supplied, use the previous one
+	 * or default to WF2Q+. Otherwise, return an error.
+	 */
+	dn_cfg.id++;
+	a.fp = find_sched_type(a.sch->oid.subtype, a.sch->name);
 	if (a.fp != NULL) {
+		/* found. Lookup or create entry */
 		s = dn_ht_find(dn_cfg.schedhash, i, DNHT_INSERT, &a);
-	} else if (a.sch->oid.subtype != 0 || a.sch->type[0]) {
-		DN_BH_WUNLOCK();
-		printf("invalid scheduler type %d %s\n",
-			a.sch->oid.subtype, a.sch->type);
-		return EINVAL;
-	} else {
-		/* type not supplied. If it exist already, use
-		 * the existing one. Otherwise default to WF2Q+
-		 */
+	} else if (a.sch->oid.subtype == 0 && !a.sch->name[0]) {
+		/* No type. search existing s* or retry with WF2Q+ */
 		s = dn_ht_find(dn_cfg.schedhash, i, 0, &a);
-		if (s == NULL) {
+		if (s != NULL) {
+			a.fp = s->fp;
+		} else {
 			a.sch->oid.subtype = DN_SCHED_WF2QP;
 			goto again;
 		}
-		a.fp = s->fp;
+	} else {
+		DN_BH_WUNLOCK();
+		D("invalid scheduler type %d %s",
+			a.sch->oid.subtype, a.sch->name);
+		return EINVAL;
 	}
-	/* normalize type and subtype */
+	/* normalize name and subtype */
 	a.sch->oid.subtype = a.fp->type;
-	bzero(a.sch->type, sizeof(a.sch->type));
-	strlcpy(a.sch->type, a.fp->name, sizeof(a.sch->type));
+	bzero(a.sch->name, sizeof(a.sch->name));
+	strlcpy(a.sch->name, a.fp->name, sizeof(a.sch->name));
 	if (s == NULL) {
 		DN_BH_WUNLOCK();
-		printf("cannot allocate scheduler\n");
+		D("cannot allocate scheduler %d", i);
 		return ENOMEM;
 	}
 	/* restore existing pipe if any */
 	if (p.pipe_nr)
 		s->pipe = p;
 	p.pipe_nr = 0;
-	dn_cfg.id++;
 	if (s->fp == NULL) {
-		printf("%s sched %d new type %s\n", __FUNCTION__, i,
-			a.fp->name);
+		D("sched %d new type %s", i, a.fp->name);
 	} else if (s->fp != a.fp ||
 			bcmp(a.sch, &s->sch, sizeof(*a.sch)) ) {
 		/* already existing. */
-		printf("sched %d type changed from %s to %s\n",
+		D("sched %d type changed from %s to %s",
 			i, s->fp->name, a.fp->name);
-		printf("   type/sub %d/%d -> %d/%d\n",
+		D("   type/sub %d/%d -> %d/%d",
 			s->sch.oid.type, s->sch.oid.subtype, 
 			a.sch->oid.type, a.sch->oid.subtype);
 		if (s->pipe.pipe_nr == 0)
-			printf("XXX WARNING pipe 0 for sched %d\n",
-				s->sch.sched_nr);
+			D("XXX WARNING pipe 0 for sched %d", i);
 		p = s->pipe;	/* preserve pipe */
 		/* remove from the hash */
 		dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL);
@@ -1112,37 +1098,42 @@ again: /* run twice, for wfq and fifo */
 		schk_delete_cb(s, (void *)DN_DELETE);
 		goto again;
 	} else {
-		printf("%s sched %d unchanged type %s\n", __FUNCTION__, i,
-			a.fp->name);
+		D("sched %d unchanged type %s", i, a.fp->name);
 	}
 	/* complete initialization */
 	s->sch = *a.sch;
 	s->fp = a.fp;
 	s->cfg = arg;
 	// XXX schk_reset_credit(s);
-	/* create the internal flowset if needed */
+	/* create the internal flowset if needed,
+	 * trying to reuse existing ones if available
+	 */
 	if (!(s->fp->flags & DN_MULTIQUEUE) && !s->fs) {
-		struct new_fs fs;
-
-		bzero(&fs, sizeof(fs));
-		set_oid(&fs.oid, DN_FS, sizeof(fs));
-		fs.fs_nr = i + DN_MAX_ID;
-		fs.sched_nr = i;
-		s->fs = config_fs(&fs, NULL, 1 /* locked */);
-		printf("+++ sched %d fs %p len %d ty %d\n",
-			s->sch.sched_nr,
-			s->fs, s->fs->fs.oid.len, s->fs->fs.oid.type);
+	        s->fs = dn_ht_find(dn_cfg.fshash, i, 0, NULL);
+		if (!s->fs) {
+			struct new_fs fs;
+			bzero(&fs, sizeof(fs));
+			set_oid(&fs.oid, DN_FS, sizeof(fs));
+			fs.fs_nr = i + DN_MAX_ID;
+			fs.sched_nr = i;
+			s->fs = config_fs(&fs, NULL, 1 /* locked */);
+		}
+		if (!s->fs) {
+			schk_delete_cb(s, (void *)DN_DELETE);
+			D("error creating internal fs for %d", i);
+			DN_BH_WUNLOCK();
+			return ENOMEM;
+		}
 	}
 	/* call init function after the flowset is created */
 	if (s->fp->config)
 		s->fp->config(s);
 	update_fs(s);
-	if (i < DN_MAX_ID) { /* update the FIFO instance */
+	if (i < DN_MAX_ID) { /* now configure the FIFO instance */
 		i += DN_MAX_ID;
 		a.sch->sched_nr = i;
-		/* now configure a FIFO instance */
 		a.sch->oid.subtype = DN_SCHED_FIFO;
-		bzero(a.sch->type, sizeof(a.sch->type));
+		bzero(a.sch->name, sizeof(a.sch->name));
 		goto again;
 	}
 	DN_BH_WUNLOCK();
@@ -1159,7 +1150,7 @@ config_profile(struct new_profile *pf, s
 	int i;
 
 	if (pf->oid.len < sizeof(*pf)) {
-		printf("%s: short profile\n", __FUNCTION__);
+		D("short profile len %d", pf->oid.len);
 		return EINVAL;
 	}
 	i = pf->pipe_nr;
@@ -1171,7 +1162,7 @@ config_profile(struct new_profile *pf, s
 
 	if (s == NULL) {
 		DN_BH_WUNLOCK();
-		printf("%s: no scheduler %d\n", __FUNCTION__, i);
+		D("no scheduler %d", i);
 		return EINVAL;
 	}
 	dn_cfg.id++;
@@ -1195,7 +1186,7 @@ config_profile(struct new_profile *pf, s
 			    M_DUMMYNET, M_NOWAIT | M_ZERO);
 		if (s->profile == NULL) {
 			DN_BH_WUNLOCK();
-			printf("%s: no memory\n", __FUNCTION__);
+			D("no memory for profile %d", i);
 			return ENOMEM;
 		}
 		/* preserve larger length */
@@ -1220,7 +1211,7 @@ dummynet_flush(void)
 	dn_ht_scan(dn_cfg.schedhash, schk_delete_cb,
 		(void *)(uintptr_t)DN_DELETE_FS);
 	/* delete all remaining (unlinked) flowsets */
-	printf("%s still %d unlinked fs\n", __FUNCTION__, dn_cfg.fsk_count);
+	D("still %d unlinked fs", dn_cfg.fsk_count);
 	dn_ht_free(dn_cfg.fshash, DNHT_REMOVE);
 	fsk_detach_list(&dn_cfg.fsu, DN_DELETE_FS);
 	/* Reinitialize system heap... */
@@ -1241,10 +1232,13 @@ do_config(void *p, int l)
 	int err = 0, err2 = 0;
 	struct dn_id *arg = NULL;
 
+	/* XXX TODO require the first block to be a 'CONFIGURE'
+	 * or at least carry with a version number
+	 */
 	for (o = p; l >= sizeof(*o); o = next) {
 		struct dn_id *prev = arg;
 		if (o->len < sizeof(*o) || l < o->len) {
-			printf("bad len o->len %d len %d\n", o->len, l);
+			D("bad len o->len %d len %d", o->len, l);
 			err = EINVAL;
 			break;
 		}
@@ -1253,10 +1247,11 @@ do_config(void *p, int l)
 		err = 0;
 		switch (o->type) {
 		default:
-			printf("cmd %d not implemented\n", o->type);
+			D("cmd %d not implemented", o->type);
 			break;
 
 		case DN_CMD_CONFIGURE: /* simply a header */
+			/* XXX add a version check */
 			break;
 
 		case DN_CMD_DELETE:
@@ -1272,13 +1267,13 @@ do_config(void *p, int l)
 				break;
 
 			default:
-				printf("invalid delete type %d\n",
+				D("invalid delete type %d",
 					o->subtype);
 				err = EINVAL;
 				break;
 
 			case DN_FS:
-				err = (o->id < 1 || o->id >= DN_MAX_ID) ?
+				err = (o->id<1 || o->id >= DN_MAX_ID) ?
 					EINVAL : delete_fs(o->id, 0) ;
 				break;
 			}
@@ -1350,10 +1345,11 @@ compute_space(struct dn_id *cmd, int *to
 static int
 dummynet_get(struct sockopt *sopt)
 {
-	int have, i, need, error, to_copy = 0;
-	char *start = NULL, *buf, *end;
+	int have, i, need, error;
+	char *start = NULL, *buf;
 	size_t sopt_valsize;
 	struct dn_id cmd;
+	struct copy_args a;
 
 	/* save and restore original sopt_valsize around copyin */
 	sopt_valsize = sopt->sopt_valsize;
@@ -1367,7 +1363,7 @@ dummynet_get(struct sockopt *sopt)
 	 */
 	for (have = 0, i = 0; i < 10; i++) {
 		DN_BH_WLOCK();
-		need = compute_space(&cmd, &to_copy);
+		need = compute_space(&cmd, &a.flags);
 		if (need < 0) {
 			DN_BH_WUNLOCK();
 			return EINVAL;
@@ -1389,30 +1385,24 @@ dummynet_get(struct sockopt *sopt)
 	}
 	if (start == NULL)
 		return sooptcopyout(sopt, &cmd, sizeof(cmd));
-	printf("have %d:%d sched %d, %d:%d pipes %d, %d:%d flows %d, "
-		"%d:%d si %d, %d:%d queues %d\n",
+	ND("have %d:%d sched %d, %d:%d pipes %d, %d:%d flows %d, "
+		"%d:%d si %d, %d:%d queues %d",
 		dn_cfg.schk_count, sizeof(struct new_sch), DN_SCH,
 		dn_cfg.schk_count, sizeof(struct new_pipe), DN_PIPE,
 		dn_cfg.fsk_count, sizeof(struct new_fs), DN_FS,
 		dn_cfg.si_count, sizeof(struct new_inst), DN_SCH_I,
 		dn_cfg.queue_count, sizeof(struct new_queue), DN_QUEUE);
-	end = start + have;
 	sopt->sopt_valsize = sopt_valsize;
 	bcopy(&cmd, start, sizeof(cmd));
 	buf = start + sizeof(cmd);
+	a.start = &buf;
+	a.end = start + have;
+	a.type = cmd.subtype;
 	/* start copying other objects */
-	{
-		struct copy_args a;
-
-		a.start = &buf;
-		a.end = end;
-		a.flags = to_copy;
-		a.type = cmd.subtype;
-		if (a.type == DN_FS)
-			dn_ht_scan(dn_cfg.fshash, copy_data_helper, &a);
-		else
-			dn_ht_scan(dn_cfg.schedhash, copy_data_helper, &a);
-	}
+	if (a.type == DN_FS)
+		dn_ht_scan(dn_cfg.fshash, copy_data_helper, &a);
+	else
+		dn_ht_scan(dn_cfg.schedhash, copy_data_helper, &a);
 	DN_BH_WUNLOCK();
 	error = sooptcopyout(sopt, start, buf - start);
 	free(start, M_DUMMYNET);
@@ -1421,7 +1411,6 @@ dummynet_get(struct sockopt *sopt)
 
 /*
  * Handler for the various dummynet socket options
- * (get, flush, config, del)
  */
 static int
 ip_dn_ctl(struct sockopt *sopt)
@@ -1442,7 +1431,7 @@ ip_dn_ctl(struct sockopt *sopt)
 
 	switch (sopt->sopt_name) {
 	default :
-		printf("dummynet: unknown option %d", sopt->sopt_name);
+		D("dummynet: unknown option %d", sopt->sopt_name);
 		error = EINVAL;
 		break;
 
@@ -1450,7 +1439,7 @@ ip_dn_ctl(struct sockopt *sopt)
 	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);
+		D("dummynet: compat option %d", sopt->sopt_name);
 		error = EINVAL;
 		break;
 
@@ -1461,7 +1450,7 @@ ip_dn_ctl(struct sockopt *sopt)
 		}
 		l = sopt->sopt_valsize;
 		if (l < 0 || l > 12000) {
-			printf("argument len %d invalid\n", l);
+			D("argument len %d invalid", l);
 			break;
 		}
 		p = malloc(l, M_TEMP, M_WAITOK); // XXX can it fail ?
@@ -1545,28 +1534,23 @@ static int
 dummynet_modevent(module_t mod, int type, void *data)
 {
 
-	switch (type) {
-	case MOD_LOAD:
+	if (type == MOD_LOAD) {
 		if (ip_dn_io_ptr) {
 			printf("DUMMYNET already loaded\n");
 			return EEXIST ;
 		}
 		ip_dn_init();
-		break;
-
-	case MOD_UNLOAD:
+		return 0;
+	} else if (type == MOD_UNLOAD) {
 #if !defined(KLD_MODULE)
 		printf("dummynet statically compiled, cannot unload\n");
 		return EINVAL ;
 #else
 		ip_dn_destroy();
+		return 0;
 #endif
-		break ;
-	default:
+	} else
 		return EOPNOTSUPP;
-		break ;
-	}
-	return 0 ;
 }
 
 /* modevent helpers for the modules */
@@ -1581,7 +1565,7 @@ load_dn_sched(struct dn_sched *d)
 
 	/* Check that mandatory funcs exists */
 	if (d->enqueue == NULL || d->dequeue == NULL) {
-		printf("missing enqueue or dequeue for %s\n", d->name);
+		D("missing enqueue or dequeue for %s", d->name);
 		return 1;
 	}
 
@@ -1589,14 +1573,14 @@ load_dn_sched(struct dn_sched *d)
 	DN_BH_WLOCK();
 	SLIST_FOREACH(s, &dn_cfg.schedlist, next) {
 		if (strcmp(s->name, d->name) == 0) {
-			printf("%s %s already loaded\n", __FUNCTION__, d->name);
+			D("%s already loaded", d->name);
 			break; /* scheduler already exists */
 		}
 	}
 	if (s == NULL)
 		SLIST_INSERT_HEAD(&dn_cfg.schedlist, d, next);
 	DN_BH_WUNLOCK();
-	printf("dn_sched %s %sloaded\n", d->name, s ? "not ":"");
+	D("dn_sched %s %sloaded", d->name, s ? "not ":"");
 	return s ? 1 : 0;
 }
 
@@ -1606,20 +1590,20 @@ unload_dn_sched(struct dn_sched *s)
 	struct dn_sched *tmp, *r;
 	int err = EINVAL;
 
-	printf("%s %s called\n", __FUNCTION__, s->name);
+	D("called for %s", s->name);
 
 	DN_BH_WLOCK();
 	SLIST_FOREACH_SAFE(r, &dn_cfg.schedlist, next, tmp) {
 		if (strcmp(s->name, r->name) != 0)
 			continue;
-		printf("ref_count = %d\n", r->ref_count);
+		D("ref_count = %d", r->ref_count);
 		err = (r->ref_count != 0) ? EBUSY : 0;
 		if (err == 0)
 			SLIST_REMOVE(&dn_cfg.schedlist, r, dn_sched, next);
 		break;
 	}
 	DN_BH_WUNLOCK();
-	printf("dn_sched %s %sunloaded\n", s->name, err ? "not ":"");
+	D("dn_sched %s %sunloaded", s->name, err ? "not ":"");
 	return err;
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001210853.o0L8r12L075213>