svn commit: r202735 - in user/luigi/ipfw3-head: sbin/ipfw
sys/netinet sys/netinet/ipfw
Luigi Rizzo
luigi at FreeBSD.org
Thu Jan 21 08:53:01 UTC 2010
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;
}
More information about the svn-src-user
mailing list