From owner-svn-src-user@FreeBSD.ORG Mon Jan 18 22:39:33 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CFEFE106568F; Mon, 18 Jan 2010 22:39:33 +0000 (UTC) (envelope-from luigi@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id BF0528FC13; Mon, 18 Jan 2010 22:39:33 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o0IMdXof098784; Mon, 18 Jan 2010 22:39:33 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0IMdXna098776; Mon, 18 Jan 2010 22:39:33 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001182239.o0IMdXna098776@svn.freebsd.org> From: Luigi Rizzo Date: Mon, 18 Jan 2010 22:39:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202597 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Jan 2010 22:39:33 -0000 Author: luigi Date: Mon Jan 18 22:39:33 2010 New Revision: 202597 URL: http://svn.freebsd.org/changeset/base/202597 Log: various formatting fixes Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h 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_heap.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Mon Jan 18 21:56:08 2010 (r202596) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Mon Jan 18 22:39:33 2010 (r202597) @@ -141,7 +141,8 @@ int heap_scan(struct dn_heap *, int (*)( * * DNHT_MATCH_PTR during a lookup, match pointers instead * of calling match(). Normally used when removing specific - * entries. XXX should it imply DNHT_KEY_IS_OBJ ? + * entries. Does not imply KEY_IS_OBJ as the latter _is_ used + * by the match function. * * DNHT_INSERT insert the element if not found. * Calls new() to allocates a new object unless Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Mon Jan 18 21:56:08 2010 (r202596) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Mon Jan 18 22:39:33 2010 (r202597) @@ -53,14 +53,14 @@ struct dn_sched { /* + parameters attached to the template, e.g. * default queue sizes, weights, quantum size, and so on; */ - size_t schk_len; + size_t schk_datalen; /* + per-instance parameters, such as timestamps, * containers for queues, etc; */ - size_t sch_inst_len; + size_t si_datalen; - size_t queue_len; /* per-queue parameters (e.g. S,F) */ + size_t q_datalen; /* per-queue parameters (e.g. S,F) */ SLIST_ENTRY(dn_sched) next; /* Next scheduler in the list */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Mon Jan 18 21:56:08 2010 (r202596) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Mon Jan 18 22:39:33 2010 (r202597) @@ -84,7 +84,7 @@ static struct dn_sched fifo_desc = { .type = DN_SCHED_FIFO, .name = "FIFO", - .sch_inst_len = sizeof(struct new_queue), + .si_datalen = sizeof(struct new_queue), .enqueue = fifo_enqueue, .dequeue = fifo_dequeue, Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Mon Jan 18 21:56:08 2010 (r202596) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Mon Jan 18 22:39:33 2010 (r202597) @@ -305,8 +305,8 @@ static struct dn_sched wf2qp_desc = { .name = "WF2Q+", .flags = DN_MULTIQUEUE, - .sch_inst_len = sizeof(struct wf2qp_si), - .queue_len = sizeof(struct wf2qp_queue), + .si_datalen = sizeof(struct wf2qp_si), + .q_datalen = sizeof(struct wf2qp_queue), .enqueue = wf2qp_enqueue, .dequeue = wf2qp_dequeue, Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Mon Jan 18 21:56:08 2010 (r202596) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Mon Jan 18 22:39:33 2010 (r202597) @@ -576,7 +576,7 @@ dummynet_io(struct mbuf **m0, int dir, s goto dropit; /* This queue/pipe does not exist! */ if (fs->sched == NULL) /* should not happen */ goto dropit; - /* dn_si_find can be fast */ + /* find scheduler instance, possibly applying mask */ si = ipdn_si_find(fs->sched, &(fwa->f_id)); if (si == NULL) goto dropit; @@ -591,13 +591,16 @@ dummynet_io(struct mbuf **m0, int dir, s struct new_queue template; template.si = si; template.fs = fs; - /* XXX could be simplified if no flow_mask */ - q = dn_ht_find(fs->qht, (uintptr_t)&(fwa->f_id), - DNHT_INSERT, &template); + if (fs->fs.flags & DN_HAVE_MASK) { + q = dn_ht_find(fs->qht, (uintptr_t)&(fwa->f_id), + DNHT_INSERT, &template); + } else { /* qht is simply a queue */ + if (fs->qht == NULL) + fs->qht = q_new(0, 0, &template); + q = (struct new_queue *)fs->qht; + } if (q == NULL) goto dropit; - } else { - q = NULL; } if (fs->sched->fp->enqueue(si, q, m)) { printf("%s dropped by enqueue\n", __FUNCTION__); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Mon Jan 18 21:56:08 2010 (r202596) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Mon Jan 18 22:39:33 2010 (r202597) @@ -219,5 +219,7 @@ void dummynet_task(void *context, int pe void dn_reschedule(void); struct new_sch_inst *ipdn_si_find(struct new_schk *s, struct ipfw_flow_id *id); +void * q_new(uintptr_t key, int flags, void *arg); + #endif /* _IP_DN_PRIVATE_H */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Mon Jan 18 21:56:08 2010 (r202596) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Mon Jan 18 22:39:33 2010 (r202597) @@ -65,6 +65,12 @@ __FBSDID("$FreeBSD$"); #define DN_C_FS 0x08 #define DN_C_QUEUE 0x10 +/* we use this argument in case of a schk_new */ +struct schk_new_arg { + struct dn_sched *fp; + struct new_sch *sch; +}; + /*---- callout hooks. ----*/ static struct callout dn_timeout; static struct task dn_task; @@ -98,9 +104,8 @@ find_sched_type(int type, char *name) } /* - * Dispose a list of packet. Use an inline functions so if we - * need to free extra state associated to a packet, this is a - * central point to do it. + * Dispose a list of packet. Use a functions so if we need to do + * more work, this is a central point to do it. */ static void dn_free_pkts(struct mbuf *mnext) { @@ -130,7 +135,6 @@ flow_id_mask(struct ipfw_flow_id *mask, id->dst_ip &= mask->dst_ip; id->src_ip &= mask->src_ip; } - return id; } @@ -226,13 +230,12 @@ q_match(void *obj, uintptr_t key, int fl /* * create a new queue instance for the given 'key'. */ -static void * +void * q_new(uintptr_t key, int flags, void *arg) { - struct ipfw_flow_id *id = (struct ipfw_flow_id *)key; struct new_queue *q, *template = arg; struct new_fsk *fs = template->fs; - int size = sizeof(*q) + fs->sched->fp->queue_len; + int size = sizeof(*q) + fs->sched->fp->q_datalen; q = malloc(size, M_DUMMYNET, M_NOWAIT | M_ZERO); if (q == NULL) { @@ -241,7 +244,8 @@ q_new(uintptr_t key, int flags, void *ar } set_oid(&q->ni.oid, DN_QUEUE, size); - q->ni.id = *id; + if (fs->fs.flags & DN_HAVE_MASK) + q->ni.id = *(struct ipfw_flow_id *)key; q->fs = fs; q->si = template->si; fs->refcnt++; @@ -288,24 +292,22 @@ si_new(uintptr_t key, int flags, void *a { struct new_schk *s = arg; struct new_sch_inst *si; - int l = sizeof(*si) + s->fp->sch_inst_len; + int l = sizeof(*si) + s->fp->si_datalen; si = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO); if (si == NULL) goto error; - /* XXX note we set the length only for the initial part which - * is passed up to userland. - */ + /* 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)); - si->ni.oid.id = si->dline.oid.id = -1; /* mark outside scheduler */ + /* mark si and dline as outside the event queue */ + si->ni.oid.id = si->dline.oid.id = -1; si->sched = s; si->dline.si = si; if (s->fp->new_sched) { - int ret; - ret = s->fp->new_sched(si); + int ret = s->fp->new_sched(si); if (ret) { printf("%s: new_sched error %d\n", __FUNCTION__, ret); goto error; @@ -389,7 +391,7 @@ static int fsk_match(void *obj, uintptr_t key, int flags, void *arg) { struct new_fsk *fs = obj; - int i = ((flags & DNHT_KEY_IS_OBJ) == 0) ? key : + int i = !(flags & DNHT_KEY_IS_OBJ) ? key : ((struct new_fsk *)key)->fs.fs_nr; return !(fs->kflags & DN_DELETE) && (fs->fs.fs_nr == i); @@ -440,7 +442,7 @@ fsk_destroy(struct new_fsk *fs, int do_f fs->sched = NULL; if (do_free) { - if (fs->qht) + if (fs->qht) /* only if DN_HAVE_MASK */ dn_ht_free(fs->qht, 0); free(fs, M_DUMMYNET); } @@ -448,6 +450,20 @@ fsk_destroy(struct new_fsk *fs, int do_f /*----- end of flowset hashtable support -------------*/ /* + * delete the queues in qht, consider the presence of a flow_mask + */ +static void +delete_qht(struct new_fsk *fs) +{ + if (fs->fs.flags & DN_HAVE_MASK) + dn_ht_scan(fs->qht, dn_delete_queue, NULL); + else { + dn_delete_queue(fs->qht, NULL); + fs->qht = NULL; + } +} + +/* * Destroy all flowsets in a list. Used when deleting a scheduler, * or for all those in fsunlinked. * For 'ipfw queue flush' we need a callback. @@ -473,8 +489,7 @@ fsk_destroy_list(struct new_fsk_head *h, * If the flowset was marked delete, destroy it. * otherwise move it to fsunlinked. */ - if (fs->qht) - dn_ht_scan(fs->qht, dn_delete_queue, NULL); + delete_qht(fs); fs->sched = NULL; if (fs->kflags & DN_DELETE) { if (fs->qht) @@ -521,9 +536,9 @@ reset_credit(void *_si, void *arg) static void schk_reset_credit(struct new_schk *s) { - if (s->sch.flags & DN_HAVE_MASK) { + if (s->sch.flags & DN_HAVE_MASK) dn_ht_scan(s->siht, reset_credit, NULL); - } else if (s->siht) + else if (s->siht) reset_credit(s->siht, NULL); } @@ -585,9 +600,8 @@ copy_data_helper(void *_o, void *_arg) } /* - * callback for sched delete. - * Tell all attached flowsets to remove their queues, - * unlink the flowsets. + * Callback for sched delete. Tell all attached flowsets to + * remove their queues, unlink the flowsets. */ static int schk_del_cb(void *obj, void *arg) @@ -681,7 +695,6 @@ update_fs(struct new_schk *s) static int config_pipe(struct new_pipe *p, struct dn_id *arg) { - struct new_schk *s; int i; if (p->oid.len < sizeof(*p)) { @@ -703,21 +716,19 @@ config_pipe(struct new_pipe *p, struct d p->burst *= 8 * hz; DUMMYNET_LOCK(); - again: - s = locate_scheduler(i); - if (s == NULL) { + /* do it twice, base pipe and FIFO pipe */ + for (; i < 2*DN_MAX_ID; i += DN_MAX_ID) { + struct new_schk *s = locate_scheduler(i); + if (s == NULL) { DUMMYNET_UNLOCK(); printf("%s sched %d not found\n", __FUNCTION__, i); return EINVAL; - } - /* copy all parameters */ - s->pipe.delay = p->delay; - s->pipe.bandwidth = p->bandwidth; - s->pipe.burst = p->burst; - schk_reset_credit(s); - if (i < DN_MAX_ID) { /* repeat for the FIFO pipe */ - i += DN_MAX_ID; - goto again; + } + /* copy all parameters */ + s->pipe.delay = p->delay; + s->pipe.bandwidth = p->bandwidth; + s->pipe.burst = p->burst; + schk_reset_credit(s); } dn_cfg.id++; DUMMYNET_UNLOCK(); @@ -762,42 +773,49 @@ config_fs(struct new_fs *nfs, struct dn_ } if (!locked) DUMMYNET_LOCK(); -again: - fs = dn_ht_find(dn_cfg.fshash, i, DNHT_INSERT, NULL); - if (fs == NULL) - goto done; - dn_cfg.id++; - if (bcmp(&fs->fs, nfs, sizeof(*nfs)) == 0) - goto done; /* no change, nothing to do */ - fs->fs = *nfs; /* update config */ - /* - * XXX note that if we modify some scheduler-specific parameter, - * such as weights, we must notify the scheduler otherwise things - * might go really badly, such as sum-of-weights mismatches. - */ - s = locate_scheduler(nfs->sched_nr); - if (fs->sched != NULL) { - /* we had a scheduler before, let the flowset die - * and create a new one with the new parameters. + do { /* exit with break when done */ + fs = dn_ht_find(dn_cfg.fshash, i, DNHT_INSERT, NULL); + if (fs == NULL) + break; + dn_cfg.id++; + if (bcmp(&fs->fs, nfs, sizeof(*nfs)) == 0) + break; /* no change, nothing to do */ + fs->fs = *nfs; /* update config */ + /* + * XXX note that if we modify some scheduler-specific + * parameter, e.g. weights, we must notify the + * scheduler otherwise things might go really badly, + * such as sum-of-weights mismatches. */ - fs->kflags |= DN_DELETE; - goto again; - } - if (s) { + s = locate_scheduler(nfs->sched_nr); + if (fs->sched != NULL) { + /* we had a scheduler before, let the flowset + * die and create a new one with the new + * parameters. + */ + fs->kflags |= DN_DELETE; + continue; + } + if (s == NULL) + break; + /* have a new scheduler, remove from unlinked * and add to the list of children of s */ SLIST_REMOVE(&dn_cfg.fsu, fs, new_fsk, sch_chain); fs->sched = s; SLIST_INSERT_HEAD(&s->fsk_list, fs, sch_chain); - if (s->fp->flags & DN_MULTIQUEUE) + /* only create the hash table if the scheduler supports + * multiple queues and we have a flow mask. + */ + if (s->fp->flags & DN_MULTIQUEUE && + fs->fs.flags & DN_HAVE_MASK) fs->qht = dn_ht_init(NULL, nfs->buckets, - offsetof(struct new_queue, q_next), - q_hash, q_match, q_new); + offsetof(struct new_queue, q_next), + q_hash, q_match, q_new); if (s->fp->new_fsk) s->fp->new_fsk(fs); - } -done: + } while (0); if (!locked) DUMMYNET_UNLOCK(); return fs; @@ -808,32 +826,33 @@ done: * For !MULTIQUEUE schedulers, also set up the flowset. */ static int -config_sched(struct new_sch *nsch, struct dn_id *arg) +config_sched(struct new_sch *_nsch, struct dn_id *arg) { struct new_schk *s; - struct dn_sched *fp; + struct schk_new_arg a; /* argument for schk_new */ struct new_fsk_head *pending = NULL; int i, notify_fs = 0; - if (nsch->oid.len != sizeof(*nsch)) { + a.sch = _nsch; + if (a.sch->oid.len != sizeof(*a.sch)) { printf("%s: bad sched len\n", __FUNCTION__); return EINVAL; } - i = nsch->sched_nr; + i = a.sch->sched_nr; if (i <= 0 || i >= DN_MAX_ID) return EINVAL; /* XXX other sanity checks */ DUMMYNET_LOCK(); again: /* run twice, for wfq and fifo */ - fp = find_sched_type(nsch->oid.subtype, nsch->type); - if (fp == NULL) { + a.fp = find_sched_type(a.sch->oid.subtype, a.sch->type); + if (a.fp == NULL) { DUMMYNET_UNLOCK(); - printf("invalid scheduler type %d\n", nsch->oid.subtype); + printf("invalid scheduler type %s %d\n", + a.sch->type, a.sch->oid.subtype); return EINVAL; } - nsch->oid.subtype = fp->type; - s = dn_ht_find(dn_cfg.schedhash, (uintptr_t)nsch, - DNHT_KEY_IS_OBJ | DNHT_INSERT, fp); + a.sch->oid.subtype = a.fp->type; + s = dn_ht_find(dn_cfg.schedhash, i, DNHT_INSERT, &a); if (s == NULL) { DUMMYNET_UNLOCK(); printf("cannot allocate scheduler\n"); @@ -843,19 +862,17 @@ again: /* run twice, for wfq and fifo */ notify_fs = 0; if (s->fp == NULL) { /* new scheduler, nothing to clean up */ notify_fs = 1; - } else if (s->fp != fp) { + } else if (s->fp != a.fp) { printf("sched %d type changed from %s to %s" " let it drain and reallocate\n", - i, s->fp->name, fp->name); + i, s->fp->name, a.fp->name); /* mark delete so it won't be matched. * XXX todo: make it die when its queues are done. * XXX otherwise do a real delete. - * XXX MISSING: - * The flowsets are still linked to the old scheduler. - * we should clone the flowsets, put them in the - * fsunlinked list, and mark the old flowsets as DELETE, - * so they die as the queues drain out. We must postpone - * the cloning to after the new scheduler has been created. + * XXX Reconfiguration should be done differently, + * removing packets from the old scheduler and + * requeueing to the new one. Otherwise we can have + * reordering and unwanted effects. */ s->kflags |= DN_DELETE; notify_fs = 1; @@ -863,7 +880,7 @@ again: /* run twice, for wfq and fifo */ goto again; } /* complete initialization */ - s->fp = fp; + s->fp = a.fp; s->cfg = arg; // XXX schk_reset_credit(s); /* create the internal flowset if needed */ @@ -884,6 +901,7 @@ again: /* run twice, for wfq and fifo */ s->fp->config(s, 1); if (pending) { struct new_fsk *fs; + /* XXX should do the requeue here */ /* mark and clone flowsets for the old scheduler */ SLIST_FOREACH(fs, pending, sch_chain) { int dying = fs->kflags & DN_DELETE; @@ -897,8 +915,8 @@ again: /* run twice, for wfq and fifo */ update_fs(s); if (i < DN_MAX_ID) { /* update the FIFO instance */ i += DN_MAX_ID; - nsch->sched_nr = i; - nsch->oid.subtype = DN_SCHED_FIFO; + a.sch->sched_nr = i; + a.sch->oid.subtype = DN_SCHED_FIFO; goto again; } DUMMYNET_UNLOCK(); @@ -968,8 +986,9 @@ config_profile(struct new_profile *pf, s static int del_fs(int i) { - struct new_fsk *fs = dn_ht_find(dn_cfg.fshash, i, DNHT_REMOVE, NULL); + struct new_fsk *fs; + fs = dn_ht_find(dn_cfg.fshash, i, DNHT_REMOVE, NULL); printf("%s fs %d found %p\n", __FUNCTION__, i, fs); if (fs == NULL) return EINVAL; @@ -983,7 +1002,9 @@ del_fs(int i) static int del_schk(int i) { - struct new_schk *s = dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL); + struct new_schk *s; + + s = dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL); printf("%s sched %d %p\n", __FUNCTION__, i, s); if (s) { schk_del_cb(s, NULL); @@ -1031,9 +1052,9 @@ do_config(void *p, int l) /* delete base and derived schedulers */ if ( (err = del_schk(o->id)) ) break; - if ( (err = del_schk(o->id + DN_MAX_ID)) ) - break; + err = del_schk(o->id + DN_MAX_ID); break; + default: printf("invalid delete type %d\n", o->subtype); @@ -1043,7 +1064,6 @@ do_config(void *p, int l) case DN_FS: err = (o->id < 1 || o->id >= DN_MAX_ID) ? EINVAL : del_fs(o->id) ; - break; break; } break; @@ -1075,6 +1095,7 @@ do_config(void *p, int l) } return err; } + static int compute_space(struct dn_id *cmd, int *to_copy) { @@ -1155,6 +1176,7 @@ dummynet_get(struct sockopt *sopt) /* start copying other objects */ { struct copy_args a; + a.start = &buf; a.end = end; a.flags = to_copy; @@ -1170,7 +1192,8 @@ dummynet_get(struct sockopt *sopt) } /* - * Handler for the various dummynet socket options (get, flush, config, del) + * Handler for the various dummynet socket options + * (get, flush, config, del) */ static int ip_dn_ctl(struct sockopt *sopt) @@ -1226,20 +1249,14 @@ ip_dn_ctl(struct sockopt *sopt) if (p != NULL) free(p, M_TEMP); - return error ; + return error ; } /*------------------------------------------------------------ * Scheduler hash. When searching by index we pass sched_nr, * otherwise we pass struct new_sch * which is the first field in * struct new_schk so we can cast between the two. We use this trick - * because in the create phase we need to pass an additional argument - * (struct dn_sched *)and the hash table API does not support that. - * To work around the problem, we pass a struct new_sch *, store the - * struct dn_sched * in sch->oid.id, and set DNHT_KEY_IS_OBJ but - * not - * XXX the way to remove this restriction is adding an argument to - * the 'find' call, which is passed to the various functions. + * because in the create phase (but it should be fixed). */ static int schk_hash(uintptr_t key, int flags, void *_arg) @@ -1264,25 +1281,23 @@ schk_match(void *obj, uintptr_t key, int * a new object or a previously existing one. */ static void * -schk_new(uintptr_t key, int flags, void *_fp) +schk_new(uintptr_t key, int flags, void *arg) { + struct schk_new_arg *a = arg; struct new_schk *s; - struct new_sch *sch = (struct new_sch *)key; - int l; + int l = sizeof(*s) +a->fp->schk_datalen; - l = sizeof(*s) + ((struct dn_sched *)_fp)->schk_len; - s = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO); if (s == NULL) return NULL; set_oid(&s->pipe.oid, DN_PIPE, sizeof(s->pipe)); - s->sch = *sch; // copy initial values - s->pipe.pipe_nr = sch->sched_nr; + 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 (sch->flags & DN_HAVE_MASK) { + if (s->sch.flags & DN_HAVE_MASK) { s->siht = dn_ht_init(NULL, s->sch.buckets, offsetof(struct new_sch_inst, si_next), si_hash, si_match, si_new); @@ -1304,7 +1319,6 @@ ip_dn_init(void) /* create hash tables for schedulers and flowsets. * In both we search by key and by pointer. - * Insertion in schedhash uses externally allocated objects. */ dn_cfg.schedhash = dn_ht_init(NULL, dn_cfg.hash_size, offsetof(struct new_schk, schk_next),