svn commit: r202424 - user/luigi/ipfw3-head/sys/netinet/ipfw

Luigi Rizzo luigi at FreeBSD.org
Fri Jan 15 23:03:51 UTC 2010


Author: luigi
Date: Fri Jan 15 23:03:51 2010
New Revision: 202424
URL: http://svn.freebsd.org/changeset/base/202424

Log:
  a bit of renaming and cleanup.
  implement update_fs() -- seems to be working.

Modified:
  user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h
  user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c
  user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c
  user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c
  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	Fri Jan 15 23:02:46 2010	(r202423)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h	Fri Jan 15 23:03:51 2010	(r202424)
@@ -1,6 +1,5 @@
 /*
- * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
- * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa
+ * Copyright (c) 2010 Riccardo Panicucci, Luigi Rizzo, Universita` di Pisa
  * All rights reserved
  *
  * Redistribution and use in source and binary forms, with or without
@@ -110,19 +109,22 @@ struct dn_sched {
 };
 
 /*
- * Additionally, dummynet exports some variables, functions and macros
- * to be used by schedulers.
+ * Additionally, dummynet exports some functions and macros
+ * to be used by schedulers:
  */
-/* delete a queue, which we assume nobody references */
-int dn_delete_queue(void *, void *propagate);
-int dn_queue_packet(struct new_queue *q, struct mbuf* m, int drop);
+/* 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
+ */
+int dn_delete_queue(void *, void *do_free);
+int dn_enqueue(struct new_queue *q, struct mbuf* m, int drop);
 
 /*
  * Extract the head of a queue, update stats. Must be the very last
  * thing done on a dequeue as the queue itself may go away.
  */
 static __inline struct mbuf*
-dn_return_packet(struct new_queue *q)
+dn_dequeue(struct new_queue *q)
 {
 	struct mbuf *m = q->mq.head;
 	KASSERT(m != NULL, ("empty queue to dn_return_packet"));
@@ -134,7 +136,7 @@ dn_return_packet(struct new_queue *q)
 		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, (void *)1 /* possibly flush flowset */);
+		dn_delete_queue(q, (void *)1 /* free if possible */);
 	return m;
 }
 

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c	Fri Jan 15 23:02:46 2010	(r202423)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c	Fri Jan 15 23:03:51 2010	(r202424)
@@ -42,66 +42,34 @@
 #include <netinet/ipfw/dn_heap.h>
 #include <netinet/ipfw/ip_dn_private.h>
 #include <netinet/ipfw/dn_sched.h>
+
 /*
- * This file implements a FIFO scheduler.
- * A FIFO scheduler is a simple scheduler algorithm that can be use to
- * scheduling internet packets.
- * The scheduler receive a packet (by enqueue() function) and put in in the
- * unique queue that manages.
- * When the scheduler can transmit, the first packet in the queue is sent
- * out (First In First Out)
- * The complexity of this algorithm is O(1), all flows use the same queue.
- * 
- * No parameters are required to configure a FIFO scheduler or a
- * FIFO flowset.
- *
+ * This file implements a FIFO scheduler for a single queue.
+ * The queue is allocated as part of the scheduler instance,
+ * and there is a single flowset is in the template which stores
+ * queue-related information.
+ * No parameters are used except queue sizes and management policy.
+ * Enqueue and dequeue use the default library functions.
  */
-
 static int 
-fifo_enqueue(struct new_sch_inst *_si, struct new_queue *q, struct mbuf *m)
+fifo_enqueue(struct new_sch_inst *si, struct new_queue *q, struct mbuf *m)
 {
-	int ret;
-	q = (struct new_queue *)(_si+1);
-	ret = dn_queue_packet(q, m, 0);
-	if (ret) {
-		printf("%s dn_queue_packet dropped\n", __FUNCTION__);
-		return 1;
-	}
-	return 0;
+	return dn_enqueue((struct new_queue *)(si+1), m, 0);
 }
 
 static struct mbuf *
-fifo_dequeue(struct new_sch_inst *_si)
+fifo_dequeue(struct new_sch_inst *si)
 {
-    /*
-     * The dequeue() function is called  by the system when the scheduler
-     * instance can transmit packets. The dequeue() is called until the
-     * instance has credit and packet to send.
-     * If the scheduler wants to dequeue a packet, it should call the
-     * dn_return_packet() function, that take a packet pkt and the relative
-     * queue and update.
-     * If the queue is empty, no packet can be send and the dequeue() must
-     * return NULL.
-     */
-    
-    /* Access scheduler instance private data */
-    struct new_queue *q = (struct new_queue *)(_si + 1);
-
-    if (q->mq.head == NULL)
-        return NULL;
-
-    return dn_return_packet(q);
+	return dn_dequeue((struct new_queue *)(si + 1));
 }
 
 static int
 fifo_new_sched(struct new_sch_inst *si)
 {
-	/* This scheduler instance only has a queue pointer. */
+	/* This scheduler instance contains the queue */
 	struct new_queue *q = (struct new_queue *)(si + 1);
 
-        set_oid(&q->ni.oid, DN_QUEUE, 0, sizeof(*q));
-	// XXX       SLIST_INSERT_HEAD(&si->ql_list, q, si_chain);
-
+        set_oid(&q->ni.oid, DN_QUEUE, sizeof(*q));
 	q->si = si;
 	q->fs = si->sched->fs;
 	return 0;
@@ -109,20 +77,18 @@ fifo_new_sched(struct new_sch_inst *si)
 
 /*
  * FIFO scheduler descriptor
- * contains the type of the scheduler, the name, the size of the various
- * structures and function pointers. If a function is not implemented,
- * the pointer is initialized to NULL
+ * contains the type of the scheduler, the name, the size of extra
+ * data structures, and function pointers.
  */
 static struct dn_sched fifo_desc = {
-    .type = DN_SCHED_FIFO,
-    .name = "FIFO",
-
-    .sch_inst_len = sizeof(struct new_queue),
+	.type = DN_SCHED_FIFO,
+	.name = "FIFO",
 
-    .enqueue = fifo_enqueue,
-    .dequeue = fifo_dequeue,
+	.sch_inst_len = sizeof(struct new_queue),
 
-    .new_sched = fifo_new_sched,
+	.enqueue = fifo_enqueue,
+	.dequeue = fifo_dequeue,
+	.new_sched = fifo_new_sched,
 };
 
 DECLARE_DNSCHED_MODULE(dn_fifo, &fifo_desc);

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c	Fri Jan 15 23:02:46 2010	(r202423)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c	Fri Jan 15 23:03:51 2010	(r202424)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  */
 
-/* XXX this is only a stub for wf2q+ */
+#ifdef _KERNEL
 #include <sys/malloc.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
@@ -35,69 +35,41 @@
 #include <netinet/in.h>
 #include <netinet/ip_var.h>		/* ipfw_rule_ref */
 #include <netinet/ip_fw.h>	/* flow_id */
+#else
+#include "dn_test.h"
+#endif
 #include <netinet/ip_dummynet.h>
 #include <netinet/ipfw/dn_heap.h>
 #include <netinet/ipfw/ip_dn_private.h>
 #include <netinet/ipfw/dn_sched.h>
 
 /*
- * This file implements a FIFO scheduler.
- * A FIFO scheduler is a simple scheduler algorithm that can be use to
- * scheduling internet packets.
- * The scheduler receive a packet (by enqueue() function) and put in in the
- * unique queue that manages.
- * When the scheduler can transmit, the first packet in the queue is sent
- * out (First In First Out)
- * The complexity of this algorithm is O(1), all flows use the same queue.
- * 
- * No parameters are required to configure a FIFO scheduler or a
- * FIFO flowset.
- *
+ * This file implements a FIFO scheduler for a single queue.
+ * The queue is allocated as part of the scheduler instance,
+ * and there is a single flowset is in the template which stores
+ * queue-related information.
+ * No parameters are used except queue sizes and management policy.
+ * Enqueue and dequeue use the default library functions.
  */
-
 static int 
 fifo_enqueue(struct new_sch_inst *si, struct new_queue *q, struct mbuf *m)
 {
-    q = (struct new_queue *)(si+1);
-    if (dn_queue_packet(q, m, 0))
-        return 1;
-
-    /* Ok, the packet is now in the queue.
-     * The dequeue() function will be called when the scheduler
-     * instance has credit to transmit packets
-     */
-    return 0;
+	return dn_enqueue((struct new_queue *)(si+1), m, 0);
 }
 
 static struct mbuf *
-fifo_dequeue(struct new_sch_inst *_si)
+fifo_dequeue(struct new_sch_inst *si)
 {
-    /*
-     * The dequeue() function is called  by the system when the scheduler
-     * instance can transmit packets. The dequeue() is called until the
-     * instance has credit and packet to send.
-     * If the scheduler wants to dequeue a packet, it should call the
-     * dn_return_packet() function, that take a packet pkt and the relative
-     * queue and update.
-     * If the queue is empty, no packet can be send and the dequeue() must
-     * return NULL.
-     */
-    
-    /* Access scheduler instance private data */
-    struct new_queue *q = (struct new_queue *)(_si + 1);
-
-    if (q->mq.head == NULL)
-        return NULL;
-
-    return dn_return_packet(q);
+	return dn_dequeue((struct new_queue *)(si + 1));
 }
 
 static int
-wf2q_new_sched(struct new_sch_inst *si)
+wf2qp_new_sched(struct new_sch_inst *si)
 {
-	/* This scheduler instance only has a queue pointer. */
+	/* This scheduler instance contains the queue */
 	struct new_queue *q = (struct new_queue *)(si + 1);
 
+        set_oid(&q->ni.oid, DN_QUEUE, sizeof(*q));
 	q->si = si;
 	q->fs = si->sched->fs;
 	return 0;
@@ -105,20 +77,18 @@ wf2q_new_sched(struct new_sch_inst *si)
 
 /*
  * FIFO scheduler descriptor
- * contains the type of the scheduler, the name, the size of the various
- * structures and function pointers. If a function is not implemented,
- * the pointer is initialized to NULL
+ * contains the type of the scheduler, the name, the size of extra
+ * data structures, and function pointers.
  */
 static struct dn_sched fifo_desc = {
-    .type = DN_SCHED_WF2QP,
-    .name = "WF2Q+",
-
-    .sch_inst_len = sizeof(struct new_queue),
+	.type = DN_SCHED_WF2QP,
+	.name = "WF2QP",
 
-    .enqueue = fifo_enqueue,
-    .dequeue = fifo_dequeue,
+	.sch_inst_len = sizeof(struct new_queue),
 
-    .new_sched = wf2q_new_sched,
+	.enqueue = fifo_enqueue,
+	.dequeue = fifo_dequeue,
+	.new_sched = wf2qp_new_sched,
 };
 
 DECLARE_DNSCHED_MODULE(dn_wf2qp, &fifo_desc);

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c	Fri Jan 15 23:02:46 2010	(r202423)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c	Fri Jan 15 23:03:51 2010	(r202424)
@@ -215,7 +215,7 @@ mq_append(struct mq *q, struct mbuf *m)
  * Return 0 on success, 1 on drop. The packet is consumed anyways.
  */
 int
-dn_queue_packet(struct new_queue *q, struct mbuf* m, int drop)
+dn_enqueue(struct new_queue *q, struct mbuf* m, int drop)
 {   
 	struct new_fs *f;
 	struct new_inst *ni;	/* stats for scheduler instance */

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h	Fri Jan 15 23:02:46 2010	(r202423)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h	Fri Jan 15 23:03:51 2010	(r202424)
@@ -30,7 +30,6 @@
 /*
  * internal dummynet APIs.
  */
-#define div64(a, b)     ((int64_t)(a) / (int64_t)(b))
 
 MALLOC_DECLARE(M_DUMMYNET);
 
@@ -53,13 +52,15 @@ SLIST_HEAD(new_queue_head, new_queue);
 SLIST_HEAD(dn_sched_head, dn_sched);
 
 /*
- * global configuration parameters.
+ * configuration and global data for a dummynet instance
  *
  * When a configuration is modified from userland, 'id' is incremented
  * so we can use the value to check for stale pointers.
  */
 struct dn_parms {
 	uint32_t	id;		/* configuration version */
+
+	/* defaults (sysctl-accessible) */
 	int	red_lookup_depth;
 	int	red_avg_pkt_size;
 	int	red_max_pkt_size;
@@ -68,6 +69,8 @@ struct dn_parms {
 	long	pipe_slot_limit;
 
 	int	io_fast;
+
+	/* timekeeping */
 	struct timeval prev_t;		/* last time dummynet_tick ran */
 	struct dn_heap	evheap;	/* scheduled events */
 
@@ -77,6 +80,10 @@ struct dn_parms {
 	int	fsk_count;
 	int	queue_count;
 
+	/* flowsets and schedulers are in hash tables, whose size
+	 * is programmable. fshash is looked up at every packet arrival
+	 * so better be generous if we expect many entries.
+	 */
 	int	buckets;		/* for the hash tables below */
 	struct dn_ht	*fshash;
 	struct dn_ht	*schedhash;
@@ -86,11 +93,11 @@ struct dn_parms {
 };
 
 static inline void
-set_oid(struct dn_id *o, int type, int subtype, int len)
+set_oid(struct dn_id *o, int type, int len)
 {
 	o->type = type;
-	o->subtype = subtype;
 	o->len = len;
+	o->subtype = 0;
 };
 
 struct mq {	/* a basic queue of packets*/
@@ -184,10 +191,7 @@ struct new_sch_inst {
 	SLIST_ENTRY(new_sch_inst) si_next; /* next item in the bucket */
 	struct delay_line dline;
 	struct new_schk *sched;		/* the template */
-	int kflags;    /* DN_SCHED_ACTIVE */
-
-	/* queues attached to this scheduler instance */
-	struct new_queue_head ql_list;
+	int kflags;		/* DN_ACTIVE */
 
 	int64_t credit;       /* bits I can transmit (more or less). */
 	dn_key sched_time ;     /* time pipe was scheduled in ready_heap */
@@ -196,24 +200,17 @@ struct new_sch_inst {
 
 /* kernel-side flags */
 enum {
-    DN_DELETE               = 0x0004, /* destroy when refcnt=0 */
-    DN_REENQUEUE            = 0x0008, /* (k) */
-    DN_ACTIVE               = 0x0010, /* (k) */
-    DN_FORCE		= 0x0080
+    DN_DELETE	= 0x0004, /* destroy when refcnt=0 */
+    DN_ACTIVE	= 0x0010, /* object is in evheap */
+    DN_F_DLINE	= 0x0020, /* object is a delay line */
+    DN_F_SCHI	= 0x0030, /* object is a sched.instance */
 };
 
 extern struct dn_parms dn_cfg;
 
-struct new_pipe *ipdn_locate_pipe(int);
-struct new_fsk *ipdn_locate_flowset(int);
 int     dummynet_io(struct mbuf **, int , struct ip_fw_args *);
 void dummynet_task(void *context, int pending);
 void dn_reschedule(void);
-int dn_fs_config(struct new_fsk *);
-struct new_queue *
-dn_create_queue(struct new_sch_inst *si, struct new_fsk *f,
-        struct ipfw_flow_id *id);
-
 
 struct new_sch_inst *ipdn_si_find(struct new_schk *s, struct ipfw_flow_id *id);
 

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c	Fri Jan 15 23:02:46 2010	(r202423)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c	Fri Jan 15 23:03:51 2010	(r202424)
@@ -58,8 +58,6 @@ __FBSDID("$FreeBSD$");
 #include <netinet/ipfw/ip_dn_private.h>
 #include <netinet/ipfw/dn_sched.h>
 
-static int	ip_dn_ctl(struct sockopt *sopt);
-
 /* which objects to copy */
 #define DN_C_PIPE 	0x01
 #define DN_C_SCH	0x02
@@ -104,7 +102,7 @@ find_sched_type(int type, char *name)
  * need to free extra state associated to a packet, this is a
  * central point to do it.
  */
-static __inline void dn_free_pkts(struct mbuf *mnext)
+static void dn_free_pkts(struct mbuf *mnext)
 {
         struct mbuf *m;
     
@@ -226,7 +224,7 @@ q_match(void *obj, uintptr_t key, int fl
 }
 
 /*
- * create a new queue instance for the given 'key'
+ * create a new queue instance for the given 'key'.
  */
 static void *
 q_new(uintptr_t key, int flags, void *arg)
@@ -242,7 +240,7 @@ q_new(uintptr_t key, int flags, void *ar
 		return NULL;
 	}
 
-	set_oid(&q->ni.oid, DN_QUEUE, 0, size);
+	set_oid(&q->ni.oid, DN_QUEUE, size);
 	q->ni.id = *id;
 	q->fs = fs;
 	q->si = template->si;
@@ -298,8 +296,8 @@ si_new(uintptr_t key, int flags, void *a
 	/* XXX note we set the length only for the initial part which
 	 * is passed up to userland.
 	 */
-	set_oid(&si->ni.oid, DN_SCH_I, 0, sizeof(struct new_inst));
-	set_oid(&(si->dline.oid), DN_DELAY_LINE, 0, sizeof(struct delay_line));
+	set_oid(&si->ni.oid, DN_SCH_I, sizeof(struct new_inst));
+	set_oid(&(si->dline.oid), DN_DELAY_LINE, sizeof(struct delay_line));
 	si->ni.oid.id = si->dline.oid.id = -1; /* mark outside scheduler */
 
 	si->sched = s;
@@ -404,7 +402,7 @@ fsk_new(uintptr_t key, int flags, void *
 
 	fs = malloc(sizeof(*fs), M_DUMMYNET, M_NOWAIT | M_ZERO);
 	if (fs) {
-		set_oid(&fs->fs.oid, DN_FS, 0, sizeof(fs->fs));
+		set_oid(&fs->fs.oid, DN_FS, sizeof(fs->fs));
 		dn_cfg.fsk_count++;
 		SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain);
 	}
@@ -416,23 +414,24 @@ fsk_new(uintptr_t key, int flags, void *
  * Return 1 if freed, o otherwise.
  * Removal from the hashtable must be done outside this function.
  */
-static int
-fsk_destroy(struct new_fsk *fs)
+static void
+fsk_destroy(struct new_fsk *fs, int do_free)
 {
 	struct new_fsk_head *h;
 
 	fs->kflags |= DN_DELETE;
 	if (fs->refcnt != 0)
-		return 0;
+		return;
 	/* find the container list */
 	h = fs->sched ? &fs->sched->fsk_list : &dn_cfg.fsu;
 	SLIST_REMOVE(h, fs, new_fsk, sch_chain);
 	dn_cfg.fsk_count--;
 	fs->sched = NULL;
-	if (fs->qht)
-		dn_ht_free(fs->qht, 0);
-	free(fs, M_DUMMYNET);
-	return 1; /* can remove from the ht */
+	if (do_free) {
+		if (fs->qht)
+			dn_ht_free(fs->qht, 0);
+		free(fs, M_DUMMYNET);
+	}
 }
 /*----- end of flowset hashtable support -------------*/
 
@@ -449,10 +448,6 @@ fsk_destroy_list(struct new_fsk_head *h,
 
 	while ((fs = SLIST_FIRST(h))) {
 		/* remember if the flowset is dying */
-		int dying;
-		if (h == &dn_cfg.fsu)
-			fs->kflags |= DN_DELETE;
-		dying = fs->kflags & DN_DELETE;
 		printf("%s unlink flowset %d\n",
 			__FUNCTION__, fs->fs.fs_nr);
 		SLIST_REMOVE_HEAD(h, sch_chain);
@@ -462,17 +457,23 @@ fsk_destroy_list(struct new_fsk_head *h,
 			 */
 			free(fs, M_DUMMYNET);
 			dn_cfg.fsk_count--;
-		} else if (fs->qht)
-			dn_ht_scan(fs->qht, dn_delete_queue, NULL);
-			
-		/* if not already gone, move to fsunlinked.
-		 * The internal fs is marked DN_DELETE so it
-		 * will go away. Also, we scan all flowsets
-		 * so we are guaranteed that those marked DN_DELETE
-		 * will be deleted.
+			continue;
+		}
+		/* drain queues, but pass NULL so the fs is not deleted.
+		 * We cannot destroy it from the callback or it
+		 * would kill the hashtable as well. After the pass,
+		 * refcnt is surely 0.
+		 * If the flowset was marked delete, destroy it.
+		 * otherwise move it to fsunlinked.
 		 */
-		if (!dying) {
-			fs->sched = NULL;
+		if (fs->qht)
+			dn_ht_scan(fs->qht, dn_delete_queue, NULL);
+		fs->sched = NULL;
+		if (fs->kflags & DN_DELETE) {
+			if (fs->qht)
+				dn_ht_free(fs->qht, 0);
+			free(fs, M_DUMMYNET);
+		} else {
 			SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain);
 		}
 	}
@@ -480,10 +481,9 @@ fsk_destroy_list(struct new_fsk_head *h,
 
 /*
  * Delete a queue (helper for the schedulers and callback)
- * Call th
  */
 int
-dn_delete_queue(void *_q, void *foo)
+dn_delete_queue(void *_q, void *do_free)
 {
 	struct new_queue *q = _q;
 	struct new_fsk *fs = q->fs;
@@ -496,7 +496,7 @@ dn_delete_queue(void *_q, void *foo)
 	dn_cfg.queue_count--;
 	fs->refcnt--;
 	if (fs->refcnt == 0 && fs->kflags & DN_DELETE)
-		fsk_destroy(fs);
+		fsk_destroy(fs, (int)do_free);
 	return 0;
 }
 
@@ -632,7 +632,19 @@ locate_scheduler(int i)
 static void
 update_fs(struct new_schk *s)
 {
-	printf("%s to be implemented\n", __FUNCTION__);
+	struct new_fsk *fs, *tmp;
+	printf("%s XXX chech be implemented\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);
+			continue;
+		}
+		printf("remove fs %d from fsunlinked, link to sched %d\n",
+			fs->fs.fs_nr, s->sch.sched_nr);
+		SLIST_REMOVE(&dn_cfg.fsu, fs, new_fsk, sch_chain);
+		fs->sched = s;
+		SLIST_INSERT_HEAD(&s->fsk_list, fs, sch_chain);
+	}
 #if 0 // XXX to be completed
 	scan the children of s and see if they still apply.
 	scan fsunlinked and link all schedulers to s;
@@ -827,7 +839,7 @@ again: /* run twice, for wfq and fifo */
 		struct new_fs fs;
 
 		bzero(&fs, sizeof(fs));
-		set_oid(&fs.oid, DN_FS, 0, 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 */);
@@ -917,12 +929,13 @@ del_fs(int i)
 	struct new_fsk *fs = dn_ht_find(dn_cfg.fshash, i, DNHT_REMOVE, NULL);
 
 	printf("%s fs %d found %p\n", __FUNCTION__, i, fs);
-	if (fs) {
-		fsk_destroy(fs);
-		return 0;
-	} else {
+	if (fs == NULL)
 		return EINVAL;
-	}
+	// XXX not sure if we want to kill the queues now
+	if (0 && fs->qht)
+		dn_ht_scan(fs->qht, dn_delete_queue, NULL);
+	fsk_destroy(fs, 1 /* do free the object */);
+	return 0;
 }
 
 static int
@@ -1207,8 +1220,8 @@ schk_match(void *obj, uintptr_t key, int
 
 /*
  * Create the entry and intialize with the sched hash if needed.
- * XXX how do we tell between an old and a brand new thing ?
- * perhaps do not initialize s->fp ?
+ * 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 *_fp)
@@ -1222,7 +1235,7 @@ schk_new(uintptr_t key, int flags, void 
 	s = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO);
 	if (s == NULL)
 		return NULL;
-	set_oid(&s->pipe.oid, DN_PIPE, 0, sizeof(s->pipe));
+	set_oid(&s->pipe.oid, DN_PIPE, sizeof(s->pipe));
 	s->sch = *sch; // copy initial values
 	s->pipe.pipe_nr = sch->sched_nr;
 	SLIST_INIT(&s->fsk_list);
@@ -1238,7 +1251,6 @@ schk_new(uintptr_t key, int flags, void 
 	return s;
 }
 
-
 static void
 ip_dn_init(void)
 {
@@ -1284,16 +1296,16 @@ ip_dn_init(void)
 static void
 ip_dn_destroy(void)
 {
+	DUMMYNET_LOCK();
 	ip_dn_ctl_ptr = NULL;
 	ip_dn_io_ptr = NULL;
 
-	DUMMYNET_LOCK();
 	callout_stop(&dn_timeout);
+	dummynet_flush();
 	DUMMYNET_UNLOCK();
 	taskqueue_drain(dn_tq, &dn_task);
 	taskqueue_free(dn_tq);
 
-	dummynet_flush();
 	dn_ht_free(dn_cfg.schedhash, 0);
 	dn_ht_free(dn_cfg.fshash, 0);
 	heap_free(&dn_cfg.evheap);
@@ -1332,7 +1344,7 @@ dummynet_modevent(module_t mod, int type
 
 /* modevent helpers for the modules */
 static int
-load_descriptor(struct dn_sched *d)
+load_dn_sched(struct dn_sched *d)
 {
 	struct dn_sched *s;
 
@@ -1362,7 +1374,7 @@ load_descriptor(struct dn_sched *d)
 }
 
 static int
-unload_descriptor(struct dn_sched *s)
+unload_dn_sched(struct dn_sched *s)
 {
 	struct dn_sched *tmp, *r;
 	int err = EINVAL;
@@ -1390,9 +1402,9 @@ dn_sched_modevent(module_t mod, int cmd,
 	struct dn_sched *sch = arg;
 
 	if (cmd == MOD_LOAD)
-		return load_descriptor(sch);
+		return load_dn_sched(sch);
 	else if (cmd == MOD_UNLOAD)
-		return unload_descriptor(sch);
+		return unload_dn_sched(sch);
 	else
 		return EINVAL;
 }


More information about the svn-src-user mailing list