Date: Fri, 15 Jan 2010 18:31:44 +0000 (UTC) From: Luigi Rizzo <luigi@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r202407 - in user/luigi/ipfw3-head: sbin/ipfw sys/netinet sys/netinet/ipfw Message-ID: <201001151831.o0FIViJF054933@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: luigi Date: Fri Jan 15 18:31:44 2010 New Revision: 202407 URL: http://svn.freebsd.org/changeset/base/202407 Log: move profile to a better place. fix printing of queue parameters 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/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/sbin/ipfw/dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Fri Jan 15 17:55:18 2010 (r202406) +++ user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Fri Jan 15 18:31:44 2010 (r202407) @@ -58,7 +58,7 @@ static struct _s_x dummynet_params[] = { { "proto", TOK_PROTO }, { "weight", TOK_WEIGHT }, { "all", TOK_ALL }, - //{ "mask", TOK_MASK }, + { "mask", TOK_MASK }, /* alias for both */ { "sched_mask", TOK_SCHED_MASK }, { "flow_mask", TOK_FLOW_MASK }, { "droptail", TOK_DROPTAIL }, @@ -68,7 +68,7 @@ static struct _s_x dummynet_params[] = { { "bandwidth", TOK_BW }, { "delay", TOK_DELAY }, { "pipe", TOK_PIPE }, - { "queue", TOK_FLOWSET }, + { "queue", TOK_QUEUE }, { "flowset", TOK_FLOWSET }, { "sched", TOK_SCHED }, { "pri", TOK_PRI }, @@ -245,9 +245,10 @@ list_queues(struct dn_flow_set *fs, stru align_uint64(&q[l].F)); } } +#endif static void -print_flowset_parms(struct dn_flow_set *fs, char *prefix) +print_flowset_parms(struct new_fs *fs, char *prefix) { int l; char qs[30]; @@ -255,7 +256,7 @@ print_flowset_parms(struct dn_flow_set * char red[90]; /* Display RED parameters */ l = fs->qsize; - if (fs->flags_fs & DN_QSIZE_IS_BYTES) { + if (fs->flags & DN_QSIZE_IS_BYTES) { if (l >= 8192) sprintf(qs, "%d KB", l / 1024); else @@ -266,6 +267,7 @@ print_flowset_parms(struct dn_flow_set * sprintf(plr, "plr %f", 1.0 * fs->plr / (double)(0x7fffffff)); else plr[0] = '\0'; +#if 0 if (fs->flags_fs & DN_IS_RED) /* RED parameters */ sprintf(red, "\n\t %cRED w_q %f min_th %d max_th %d max_p %f", @@ -275,14 +277,16 @@ print_flowset_parms(struct dn_flow_set * SCALE_VAL(fs->max_th), 1.0 * fs->max_p / (double)(1 << SCALE_RED)); else +#endif sprintf(red, "droptail"); printf("%s %s%s %d queues (%d buckets) %s\n", - prefix, qs, plr, fs->rq_elements, fs->rq_size, red); + prefix, qs, plr, fs->oid.id, fs->buckets, red); + prefix[0] = '\0'; } static void -print_extra_delay_parms(struct dn_pipe *p) +print_extra_delay_parms(struct new_profile *p) { double loss; if (p->samples_no <= 0) @@ -293,7 +297,6 @@ print_extra_delay_parms(struct dn_pipe * printf("\t profile: name \"%s\" loss %f samples %d\n", p->name, loss, p->samples_no); } -#endif static void flush_buf(char *buf) @@ -311,11 +314,10 @@ flush_buf(char *buf) static void list_pipes(struct dn_id *oid, struct dn_id *end, int *filt) { - char buf[80]; /* pending buffer */ + char buf[160]; /* pending buffer */ buf[0] = '\0'; for (; oid != end; oid = O_NEXT(oid, oid->len)) { - /* XXX check oid->len */ if (oid->len < sizeof(*oid)) errx(1, "invalid oid len %d\n", oid->len); @@ -342,14 +344,15 @@ list_pipes(struct dn_id *oid, struct dn_ sprintf(burst, "%ju Byte\n", p->burst); sprintf(buf, "%05d: %s %4d ms burst %s", p->pipe_nr, bwbuf, p->delay, burst); - // print_flowset_parms(&(p->fs), prefix); - // print_extra_delay_parms(p); } break; + case DN_FS: - flush_buf(buf); - printf("XXX flowset unimplemented\n"); + print_flowset_parms((struct new_fs *)oid, buf); break; + case DN_PROFILE: + flush_buf(buf); + print_extra_delay_parms((struct new_profile *)oid); } } flush_buf(buf); @@ -863,10 +866,12 @@ ipfw_config_pipe(int ac, char **av) case TOK_BUCKETS: NEED(fs, "buckets is only for pipes or flowsets"); NEED1("buckets needs argument\n"); - // XXX fs->rq_size = strtoul(av[0], NULL, 0); + fs->buckets = strtoul(av[0], NULL, 0); ac--; av++; break; + case TOK_FLOW_MASK: + case TOK_SCHED_MASK: case TOK_MASK: NEED(mask, "tok_mask"); NEED1("mask needs mask specifier\n"); Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Fri Jan 15 17:55:18 2010 (r202406) +++ user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Fri Jan 15 18:31:44 2010 (r202407) @@ -119,12 +119,10 @@ struct new_pipe { * The kernel converts this back and forth to bits/tick and ticks. * XXX what about burst ? */ - int32_t pipe_nr ; /* N, number */ - int bandwidth; /* B, really, bits/tick. */ - int delay ; /* D, really, ticks */ - uint64_t burst; /* burst size, scaled. bits*Hz XXX */ - - struct new_profile *profile; + int32_t pipe_nr; + int bandwidth; /* bit/s or bits/tick. */ + int delay; /* ms and ticks */ + uint64_t burst; /* scaled. bits*Hz XXX */ }; /* 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 17:55:18 2010 (r202406) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Fri Jan 15 18:31:44 2010 (r202407) @@ -287,16 +287,16 @@ transmit_event(struct mq *q, struct dela * in milliseconds so we need to divide by 1000. */ static uint64_t -extra_bits(struct mbuf *m, struct new_pipe *p) +extra_bits(struct mbuf *m, struct new_schk *s) { int index; uint64_t bits; - struct new_profile *pf = p->profile; + struct new_profile *pf = s->profile; if (!pf || pf->samples_no == 0) return 0; index = random() % pf->samples_no; - bits = div64((uint64_t)pf->samples[index] * p->bandwidth, 1000); + bits = div64((uint64_t)pf->samples[index] * s->pipe.bandwidth, 1000); if (index >= pf->loss_level) { struct dn_pkt_tag *dt = dn_tag_get(m); if (dt) @@ -339,7 +339,7 @@ serve_sched(struct mq *q, struct new_sch uint64_t len_scaled; done++; len_scaled = bw == 0 ? 0 : hz * - (m->m_pkthdr.len * 8 + extra_bits(m, &s->pipe)); + (m->m_pkthdr.len * 8 + extra_bits(m, s)); si->credit -= len_scaled; /* Move packet in the delay line */ dn_tag_get(m)->output_time += s->pipe.delay ; 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 17:55:18 2010 (r202406) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Fri Jan 15 18:31:44 2010 (r202407) @@ -115,7 +115,7 @@ struct delay_line { * there is no flow_mask). * When we remove a flowset, mark as DN_DELETE so it can go away * when the hash table will be empty. - * XXX refcnt is redundant. + * XXX refcnt is redundant, the info is already in qht->entries */ struct new_fsk { /* kernel side of a flowset */ struct new_fs fs; @@ -160,6 +160,7 @@ struct new_schk { int kflags; struct dn_sched *fp; /* Pointer to scheduler functions */ struct new_pipe pipe; /* the pipe is embedded */ + struct new_profile *profile; struct dn_id *cfg; /* extra config arguments */ SLIST_ENTRY(new_schk) schk_next; /* hash chain list */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Fri Jan 15 17:55:18 2010 (r202406) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Fri Jan 15 18:31:44 2010 (r202407) @@ -90,7 +90,7 @@ dn_reschedule(void) static struct dn_sched * find_sched_type(int type, char *name) { - struct dn_sched *d = NULL; + struct dn_sched *d; SLIST_FOREACH(d, &dn_cfg.schedlist, next) { if (d->type == type || (name && !strcmp(d->name, name))) @@ -168,9 +168,10 @@ static int flow_id_cmp(struct ipfw_flow_id *id1, struct ipfw_flow_id *id2) { int is_v6 = IS_IP6_FLOW_ID(id1); + if (is_v6 != IS_IP6_FLOW_ID(id2)) return 1; /* a ipv4 and a ipv6 flow */ - + if (!is_v6 && id1->dst_ip == id2->dst_ip && id1->src_ip == id2->src_ip && id1->dst_port == id2->dst_port && @@ -204,6 +205,7 @@ q_hash(uintptr_t key, int flags, void *a struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ? &((struct new_queue *)key)->ni.id : (struct ipfw_flow_id *)key; + return flow_id_hash(id); } @@ -263,22 +265,19 @@ si_hash(uintptr_t key, int flags, void * struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ? &((struct new_sch_inst *)key)->ni.id : (struct ipfw_flow_id *)key; + return flow_id_hash(id); } static int si_match(void *obj, uintptr_t key, int flags, void *arg) { - struct new_sch_inst *o; + struct new_sch_inst *o = obj; struct ipfw_flow_id *id2; - if (flags & DNHT_KEY_IS_OBJ) { - /* compare pointers */ - id2 = &((struct new_sch_inst *)key)->ni.id; - } else { - id2 = (struct ipfw_flow_id *)key; - } - o = (struct new_sch_inst *)obj; + id2 = (flags & DNHT_KEY_IS_OBJ) ? + &((struct new_sch_inst *)key)->ni.id : + (struct ipfw_flow_id *)key; return flow_id_cmp(&o->ni.id, id2) == 0; } @@ -361,7 +360,7 @@ ipdn_si_find(struct new_schk *s, struct { struct new_sch_inst *si; - if ( 0 == (s->sch.flags & DN_HAVE_MASK) ) { + if (!(s->sch.flags & DN_HAVE_MASK)) { if (s->siht == NULL) s->siht = si_new((uintptr_t)id, 0, s); si = (struct new_sch_inst *)s->siht; @@ -394,6 +393,7 @@ fsk_match(void *obj, uintptr_t key, int struct new_fsk *fs = obj; int i = ((flags & DNHT_KEY_IS_OBJ) == 0) ? key : ((struct new_fsk *)key)->fs.fs_nr; + return !(fs->kflags & DN_DELETE) && (fs->fs.fs_nr == i); } @@ -404,6 +404,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)); dn_cfg.fsk_count++; SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain); } @@ -523,9 +524,14 @@ static int copy_obj(char **start, char *end, void *_o) { struct dn_id *o = _o; + int have = end - *start; - if (end - *start < o->len) + if (have < o->len) { + printf("%s overflow type %d have %d need %d\n", + __FUNCTION__, o->type, have, o->len); return 1; + } + printf("%s type %d len %d\n", __FUNCTION__, o->type, o->len); bcopy(_o, *start, o->len); *start += o->len; return 0; @@ -542,12 +548,15 @@ struct copy_args { static int copy_data_helper(void *_o, void *_arg) { - struct copy_args *a = (struct copy_args *)_arg; + struct copy_args *a = _arg; + if (a->type == DN_SCH) { /* scanning schedulers */ struct new_schk *s = _o; if (a->flags & DN_C_PIPE) { if (copy_obj(a->start, a->end, &s->pipe)) return HEAP_SCAN_END; + if (s->fs && copy_obj(a->start, a->end, &s->fs->fs)) + return HEAP_SCAN_END; } if (a->flags & DN_C_SCH) { if (copy_obj(a->start, a->end, &s->sch)) @@ -556,19 +565,14 @@ copy_data_helper(void *_o, void *_arg) if (a->flags & DN_C_SCH_INST) { printf("XXX todo: scan sched instances\n"); } - if (a->flags & DN_C_FS) { - struct new_fsk *fs = _o; - if (copy_obj(a->start, a->end, &fs->fs)) - return HEAP_SCAN_END; - } - if (a->flags & DN_C_QUEUE) { - printf("XXX todo: scan queue instances\n"); - } } if (a->type == DN_FS) { /* scanning flowsets */ struct new_fsk *fs = _o; + struct new_fs *ufs = + (struct new_fs *)(*a->start); if (copy_obj(a->start, a->end, &fs->fs)) return HEAP_SCAN_END; + ufs->oid.id = fs->refcnt; } return 0; } @@ -827,6 +831,9 @@ again: /* run twice, for wfq and fifo */ 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); } /* call init function after the flowset is created */ if (s->fp->config) @@ -850,7 +857,6 @@ static int config_profile(struct new_profile *pf, struct dn_id *arg) { struct new_schk *s; - struct new_pipe *p; int i; if (pf->oid.len < sizeof(*pf)) { @@ -870,16 +876,15 @@ config_profile(struct new_profile *pf, s printf("%s: no scheduler %d\n", __FUNCTION__, i); return EINVAL; } - p = &s->pipe; dn_cfg.id++; /* * If we had a profile and the new one does not fit, * or it is deleted, then we need to free memory. */ - if (p->profile && (pf->samples_no == 0 || - p->profile->oid.len < pf->oid.len)) { - free(p->profile, M_DUMMYNET); - p->profile = NULL; + if (s->profile && (pf->samples_no == 0 || + s->profile->oid.len < pf->oid.len)) { + free(s->profile, M_DUMMYNET); + s->profile = NULL; } /* * if we have a new profile, possibly allocate memory @@ -887,20 +892,20 @@ config_profile(struct new_profile *pf, s */ if (pf->samples_no > 0) { int olen; - if (p->profile == NULL) - p->profile = malloc(pf->oid.len, + if (s->profile == NULL) + s->profile = malloc(pf->oid.len, M_DUMMYNET, M_NOWAIT | M_ZERO); - if (p->profile == NULL) { + if (s->profile == NULL) { DUMMYNET_UNLOCK(); printf("%s: no memory\n", __FUNCTION__); return ENOMEM; } /* preserve larger length */ - olen = p->profile->oid.len; + olen = s->profile->oid.len; if (olen < pf->oid.len) olen = pf->oid.len; - bcopy(pf, p->profile, pf->oid.len); - p->profile->oid.len = olen; + bcopy(pf, s->profile, pf->oid.len); + s->profile->oid.len = olen; } DUMMYNET_UNLOCK(); return 0; @@ -1018,23 +1023,31 @@ do_config(void *p, int l) static int compute_space(struct dn_id *cmd, int *to_copy) { - int need; + int x = 0, need = 0; - *to_copy = 0; switch (cmd->subtype) { default: return -1; case DN_SCH: /* pipe show */ - *to_copy = DN_C_SCH | DN_C_PIPE | DN_C_SCH_INST | DN_C_QUEUE; - need = dn_cfg.schk_count * - (sizeof(struct new_sch) + sizeof(struct new_pipe)); - need += dn_cfg.si_count * sizeof(struct new_inst); + x = DN_C_SCH | DN_C_PIPE | DN_C_FS | + DN_C_SCH_INST | DN_C_QUEUE; break; case DN_FS: /* queue show */ - *to_copy = DN_C_FS | DN_C_QUEUE; - need = dn_cfg.fsk_count * (sizeof(struct new_fs)); + x = DN_C_FS | DN_C_QUEUE; break; } + *to_copy = x; + if (x & DN_C_SCH) + need += dn_cfg.schk_count * sizeof(struct new_sch); + if (x & DN_C_FS) + need += dn_cfg.fsk_count * sizeof(struct new_fs); + if (x & DN_C_PIPE) + need += dn_cfg.schk_count * sizeof(struct new_pipe); + /* XXX queue space might be variable */ + if (x & DN_C_QUEUE) + need += dn_cfg.queue_count * sizeof(struct new_queue); + if (x & DN_C_SCH_INST) + need += dn_cfg.si_count * sizeof(struct new_inst); return need; } @@ -1092,8 +1105,10 @@ dummynet_get(struct sockopt *sopt) a.flags = to_copy; a.type = DN_SCH; dn_ht_scan(dn_cfg.schedhash, copy_data_helper, &a); +#if 0 // XXX temporarily disable a.type = DN_FS; dn_ht_scan(dn_cfg.fshash, copy_data_helper, &a); +#endif } DUMMYNET_UNLOCK(); error = sooptcopyout(sopt, start, buf - start);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001151831.o0FIViJF054933>