diff --git a/daemon/call.c b/daemon/call.c index 149f54ef9..03364ad02 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1422,21 +1422,18 @@ static void callmaster_timer(void *ptr) { if (ke->stats.packets != atomic64_get(&ps->kernel_stats.packets)) atomic64_set(&ps->last_packet, poller_now); - atomic64_set(&ps->stats.in_tos_tclass, ke->stats.in_tos); - atomic64_set(&m->statsps.in_tos_tclass, ke->stats.in_tos); + ps->stats.in_tos_tclass = ke->stats.in_tos; #if (RE_HAS_MEASUREDELAY) - mutex_lock(&m->statspslock); - ps->stats.delay_min = m->statsps.delay_min = ke->stats.delay_min; - ps->stats.delay_avg = m->statsps.delay_avg = ke->stats.delay_avg; - ps->stats.delay_max = m->statsps.delay_max = ke->stats.delay_max; - mutex_unlock(&m->statspslock); + /* XXX fix atomicity */ + ps->stats.delay_min = ke->stats.delay_min; + ps->stats.delay_avg = ke->stats.delay_avg; + ps->stats.delay_max = ke->stats.delay_max; #endif atomic64_set(&ps->kernel_stats.bytes, ke->stats.bytes); atomic64_set(&ps->kernel_stats.packets, ke->stats.packets); atomic64_set(&ps->kernel_stats.errors, ke->stats.errors); - atomic64_set(&ps->kernel_stats.in_tos_tclass, ke->stats.in_tos); for (j = 0; j < ke->target.num_payload_types; j++) { pt = ke->target.payload_types[j]; @@ -1453,14 +1450,6 @@ static void callmaster_timer(void *ptr) { atomic64_set(&rs->kernel_bytes, ke->rtp_stats[j].bytes); } -#if (RE_HAS_MEASUREDELAY) - mutex_lock(&m->statspslock); - ps->kernel_stats.delay_min = ke->stats.delay_min; - ps->kernel_stats.delay_avg = ke->stats.delay_avg; - ps->kernel_stats.delay_max = ke->stats.delay_max; - mutex_unlock(&m->statspslock); -#endif - update = 0; sink = packet_stream_sink(ps); @@ -2845,7 +2834,7 @@ void call_destroy(struct call *c) { cdrlinecnt, md->index, protocol, atomic64_get(&ps->last_packet), cdrlinecnt, md->index, protocol, - atomic64_get(&ps->stats.in_tos_tclass)); + ps->stats.in_tos_tclass); } else { #if (RE_HAS_MEASUREDELAY) cdrbufcur += sprintf(cdrbufcur, @@ -2856,10 +2845,10 @@ void call_destroy(struct call *c) { "ml%i_midx%u_%s_relayed_bytes="UINT64F", " "ml%i_midx%u_%s_relayed_errors="UINT64F", " "ml%i_midx%u_%s_last_packet="UINT64F", " - "ml%i_midx%u_%s_in_tos_tclass=%" PRIu8 ", " - "ml%i_midx%u_%s_delay_min=%llu.%09llu, " - "ml%i_midx%u_%s_delay_avg=%llu.%09llu, " - "ml%i_midx%u_%s_delay_max=%llu.%09llu, ", + "ml%i_midx%u_%s_in_tos_tclass=%" PRIu8 ", " + "ml%i_midx%u_%s_delay_min=%.9f, " + "ml%i_midx%u_%s_delay_avg=%.9f, " + "ml%i_midx%u_%s_delay_max=%.9f, ", cdrlinecnt, md->index, protocol, addr, cdrlinecnt, md->index, protocol, ps->endpoint.port, cdrlinecnt, md->index, protocol, (unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0), @@ -2872,10 +2861,10 @@ void call_destroy(struct call *c) { cdrlinecnt, md->index, protocol, atomic64_get(&ps->last_packet), cdrlinecnt, md->index, protocol, - atomic64_get(&ps->stats.in_tos_tclass), - cdrlinecnt, md->index, protocol, (unsigned long long) ps->stats.delay_min.tv_sec, (unsigned long long) ps->stats.delay_min.tv_nsec, - cdrlinecnt, md->index, protocol, (unsigned long long) ps->stats.delay_avg.tv_sec, (unsigned long long) ps->stats.delay_avg.tv_nsec, - cdrlinecnt, md->index, protocol, (unsigned long long) ps->stats.delay_max.tv_sec, (unsigned long long) ps->stats.delay_max.tv_nsec); + ps->stats.in_tos_tclass, + cdrlinecnt, md->index, protocol, (double) ps->stats.delay_min / 1000000, + cdrlinecnt, md->index, protocol, (double) ps->stats.delay_avg / 1000000, + cdrlinecnt, md->index, protocol, (double) ps->stats.delay_max / 1000000); #else cdrbufcur += sprintf(cdrbufcur, "ml%i_midx%u_%s_endpoint_ip=%s, " diff --git a/daemon/call.h b/daemon/call.h index 3914f8b7c..c7ca2cf0d 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -214,10 +214,10 @@ struct stats { atomic64 packets; atomic64 bytes; atomic64 errors; - struct timespec delay_min; - struct timespec delay_avg; - struct timespec delay_max; - atomic64 in_tos_tclass; + u_int64_t delay_min; + u_int64_t delay_avg; + u_int64_t delay_max; + u_int8_t in_tos_tclass; /* XXX shouldn't be here - not stats */ }; struct totalstats { @@ -454,7 +454,6 @@ struct callmaster { /* XXX rework these */ struct stats statsps; /* per second stats, running timer */ struct stats stats; /* copied from statsps once a second */ - mutex_t statspslock; struct totalstats totalstats; struct totalstats totalstats_interval; /* control_ng_stats stuff */ diff --git a/daemon/cli.c b/daemon/cli.c index e41397c08..be4d46ea0 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -166,7 +166,7 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m atomic64_get(&ps->last_packet)); } else { printlen = snprintf(replybuffer,(outbufend-replybuffer), "------ Media #%u, port %5u <> %15s:%-5hu%s, " - ""UINT64F" p, "UINT64F" b, "UINT64F" e, "UINT64F" last_packet, %llu.%09llu delay_min, %llu.%09llu delay_avg, %llu.%09llu delay_max\n", + ""UINT64F" p, "UINT64F" b, "UINT64F" e, "UINT64F" last_packet, %.9f delay_min, %.9f delay_avg, %.9f delay_max\n", md->index, (unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0), smart_ntop_p_buf(&ps->endpoint.ip46), ps->endpoint.port, @@ -175,12 +175,9 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m atomic64_get(&ps->stats.bytes), atomic64_get(&ps->stats.errors), atomic64_get(&ps->last_packet), - (unsigned long long) ps->stats.delay_min.tv_sec, - (unsigned long long) ps->stats.delay_min.tv_nsec, - (unsigned long long) ps->stats.delay_avg.tv_sec, - (unsigned long long) ps->stats.delay_avg.tv_nsec, - (unsigned long long) ps->stats.delay_max.tv_sec, - (unsigned long long) ps->stats.delay_max.tv_nsec); + (double) ps->stats.delay_min / 1000000, + (double) ps->stats.delay_avg / 1000000, + (double) ps->stats.delay_max / 1000000); } #else printlen = snprintf(replybuffer,(outbufend-replybuffer), "------ Media #%u, port %5u <> %15s:%-5hu%s, " diff --git a/kernel-module/xt_RTPENGINE.c b/kernel-module/xt_RTPENGINE.c index 86271d75f..f95393f20 100644 --- a/kernel-module/xt_RTPENGINE.c +++ b/kernel-module/xt_RTPENGINE.c @@ -149,9 +149,9 @@ struct rtpengine_stats_a { atomic64_t packets; atomic64_t bytes; atomic64_t errors; - struct timespec delay_min; - struct timespec delay_avg; - struct timespec delay_max; + u_int64_t delay_min; + u_int64_t delay_avg; + u_int64_t delay_max; atomic_t in_tos; }; struct rtpengine_rtp_stats_a { @@ -863,7 +863,7 @@ static ssize_t proc_blist_read(struct file *f, char __user *b, size_t l, loff_t op.stats.delay_min = g->stats.delay_min; op.stats.delay_max = g->stats.delay_max; op.stats.delay_avg = g->stats.delay_avg; - op.stats.in_tos = atomic64_read(&g->stats.in_tos); + op.stats.in_tos = atomic_read(&g->stats.in_tos); for (i = 0; i < g->target.num_payload_types; i++) { op.rtp_stats[i].packets = atomic64_read(&g->rtp_stats[i].packets); @@ -1483,6 +1483,7 @@ static int table_new_target(struct rtpengine_table *t, struct rtpengine_target_i g->stats.delay_min = og->stats.delay_min; g->stats.delay_max = og->stats.delay_max; g->stats.delay_avg = og->stats.delay_avg; + atomic_set(&g->stats.in_tos, atomic_read(&og->stats.in_tos)); for (j = 0; j < NUM_PAYLOAD_TYPES; j++) { atomic64_set(&g->rtp_stats[j].packets, atomic64_read(&og->rtp_stats[j].packets)); @@ -2194,48 +2195,7 @@ static inline int rtp_payload_type(const struct rtp_header *hdr, const struct rt return match - tg->payload_types; } -static void re_timespec_subtract (struct timespec *result, const struct timespec *a, const struct timespec *b) { - long long nanoseconds=0; - nanoseconds = ((long)a->tv_sec - (long long)b->tv_sec) * (long long)1000000000 + ((long long)a->tv_nsec - (long long)b->tv_nsec); - result->tv_sec = nanoseconds/(long long)1000000000; - result->tv_nsec = nanoseconds%(long long)1000000000; -} - -static void re_timespec_multiply(struct timespec *result, const struct timespec *a, const long long multiplier) { - long long nanoseconds=0; - nanoseconds = ((long)a->tv_sec * (long long)1000000000) + (long long)a->tv_nsec * multiplier; - result->tv_sec = nanoseconds/(long long)1000000000; - result->tv_nsec = nanoseconds%(long long)1000000000; -} - -static void re_timespec_devide(struct timespec *result, const struct timespec *a, const long devisor) { - long long nanoseconds=0; - nanoseconds = ((long)a->tv_sec * (long long)1000000000) + (long long)a->tv_nsec / devisor; - result->tv_sec = nanoseconds/(long long)1000000000; - result->tv_nsec = nanoseconds%(long long)1000000000; -} - -static void re_timespec_add(struct timespec *result, const struct timespec *a, const struct timespec *b) { - long long nanoseconds=0; - nanoseconds = ((long)a->tv_sec + (long long)b->tv_sec) * (long long)1000000000 + ((long long)a->tv_nsec + (long long)b->tv_nsec); - result->tv_sec = nanoseconds/(long long)1000000000; - result->tv_nsec = nanoseconds%(long long)1000000000; -} - -/* Return negative, zero, positive if A < B, A == B, A > B, respectively. - Assume the nanosecond components are in range, or close to it. */ -static int re_timespec_cmp (struct timespec *a, struct timespec *b) -{ - return (a->tv_sec < b->tv_sec ? -1 - : a->tv_sec > b->tv_sec ? 1 - : a->tv_nsec - b->tv_nsec); -} - -#if (RE_HAS_MEASUREDELAY) - static unsigned int rtpengine46(struct sk_buff *skb, struct rtpengine_table *t, struct re_address *src, struct timespec *starttime, u_int8_t in_tos) { -#else - static unsigned int rtpengine46(struct sk_buff *skb, struct rtpengine_table *t, struct re_address *src, u_int8_t in_tos) { -#endif +static unsigned int rtpengine46(struct sk_buff *skb, struct rtpengine_table *t, struct re_address *src, u_int8_t in_tos) { struct udphdr *uh; struct rtpengine_target *g; struct sk_buff *skb2; @@ -2246,7 +2206,7 @@ static int re_timespec_cmp (struct timespec *a, struct timespec *b) u_int64_t pkt_idx = 0, pkt_idx_u; #if (RE_HAS_MEASUREDELAY) - struct timespec endtime, delay; + u_int64_t starttime, endtime, delay; #endif skb_reset_transport_header(skb); @@ -2369,25 +2329,27 @@ out: atomic64_add(datalen, &g->rtp_stats[rtp_pt_idx].bytes); #if (RE_HAS_MEASUREDELAY) - getnstimeofday(&endtime); + starttime = ktime_to_ns(skb->tstamp); + endtime = ktime_to_ns(ktime_get_real()); - re_timespec_subtract(&delay,&endtime, starttime); + delay = endtime - starttime; + /* XXX needs locking - not atomic */ if (atomic64_read(&g->stats.packets)==1) { g->stats.delay_min=delay; g->stats.delay_avg=delay; g->stats.delay_max=delay; } else { - if (re_timespec_cmp(&g->stats.delay_min,&delay)>0) { + if (g->stats.delay_min > delay) { g->stats.delay_min = delay; } - if (re_timespec_cmp(&g->stats.delay_max,&delay)<0) { + if (g->stats.delay_max < delay) { g->stats.delay_max = delay; } - re_timespec_multiply(&g->stats.delay_avg,&g->stats.delay_avg,atomic64_read(&g->stats.packets)-1); - re_timespec_add(&g->stats.delay_avg,&g->stats.delay_avg,&delay); - re_timespec_devide(&g->stats.delay_avg,&g->stats.delay_avg,atomic64_read(&g->stats.packets)); + g->stats.delay_avg = g->stats.delay_avg * (atomic64_read(&g->stats.packets)-1); + g->stats.delay_avg = g->stats.delay_avg + delay; + g->stats.delay_avg = g->stats.delay_avg / atomic64_read(&g->stats.packets); } #endif } @@ -2427,11 +2389,6 @@ static unsigned int rtpengine4(struct sk_buff *oskb, const struct xt_action_para struct rtpengine_table *t; struct re_address src; -#if (RE_HAS_MEASUREDELAY) - struct timespec starttime; - getnstimeofday(&starttime); -#endif - t = get_table(pinfo->id); if (!t) goto skip; @@ -2450,11 +2407,7 @@ static unsigned int rtpengine4(struct sk_buff *oskb, const struct xt_action_para src.family = AF_INET; src.u.ipv4 = ih->saddr; -#if (RE_HAS_MEASUREDELAY) - return rtpengine46(skb, t, &src, &starttime, (u_int8_t)ih->tos); -#else return rtpengine46(skb, t, &src, (u_int8_t)ih->tos); -#endif skip2: kfree_skb(skb); @@ -2478,11 +2431,6 @@ static unsigned int rtpengine6(struct sk_buff *oskb, const struct xt_action_para struct rtpengine_table *t; struct re_address src; -#if (RE_HAS_MEASUREDELAY) - struct timespec starttime; - getnstimeofday(&starttime); -#endif - t = get_table(pinfo->id); if (!t) goto skip; @@ -2502,11 +2450,7 @@ static unsigned int rtpengine6(struct sk_buff *oskb, const struct xt_action_para src.family = AF_INET6; memcpy(&src.u.ipv6, &ih->saddr, sizeof(src.u.ipv6)); -#if (RE_HAS_MEASUREDELAY) - return rtpengine46(skb, t, &src, &starttime, ipv6_get_dsfield(ih)); -#else return rtpengine46(skb, t, &src, ipv6_get_dsfield(ih)); -#endif skip2: kfree_skb(skb); diff --git a/kernel-module/xt_RTPENGINE.h b/kernel-module/xt_RTPENGINE.h index d285f8353..5d3e4b27c 100644 --- a/kernel-module/xt_RTPENGINE.h +++ b/kernel-module/xt_RTPENGINE.h @@ -15,9 +15,9 @@ struct rtpengine_stats { u_int64_t packets; u_int64_t bytes; u_int64_t errors; - struct timespec delay_min; - struct timespec delay_avg; - struct timespec delay_max; + u_int64_t delay_min; + u_int64_t delay_avg; + u_int64_t delay_max; u_int8_t in_tos; }; struct rtpengine_rtp_stats {