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