// This script tracks time between packet queue and xmit. // The information is provided to userspace using Memory Mapped Values (mmv) // which are updated every second and are readable by a PCP pmda. global inst, instance_latency, instance_count // Set up the mmv and make it available probe begin { indom = mmv_add_indom(1, "xmit device", "list of network transmit devices") // fallback instance device "eth0" if none specified if (argc == 0) { argv[1] = "eth0" argc++ } // create instances for each network device for (i=1; i<=argc; i++) { dev = argv[i] inst[dev] = i - 1 printf("%s %d\n", dev, inst[dev]) mmv_add_instance(inst[dev], dev) mmv_add_indom_instance(indom, inst[dev]) } // create the metrics xmit_count_metric = mmv_add_metric("xmit_count", 1, MMV_TYPE_NUMBER, MMV_SEM_COUNTER, mmv_units(0, 0, 1, 0, 0, 0), 1, "xmit count metric", "number of packets for xmit device") xmit_latency_metric = mmv_add_metric("xmit_latency", 2, MMV_TYPE_NUMBER, MMV_SEM_COUNTER, mmv_units(0, 1, 0, 0, MMV_TIME_NSEC, 0), 1, "xmit latency metric", "sum of latency for xmit device") mmv_stats_start(43, 0) // provide mappings for all the instance metrics for (i=1; i<=argc; i++) { dev = argv[i] printf("argv[%d] = %s, inst[%s] = %d\n", i, dev, dev, inst[dev]) instance_count[dev] = mmv_lookup_value(xmit_count_metric, inst[dev]) instance_latency[dev] = mmv_lookup_value(xmit_latency_metric, inst[dev]) } } probe end { mmv_stats_stop() } // probes to track the information global skb_queue_start_t probe kernel.trace("net_dev_queue") { skb_queue_start_t[$skb] = gettimeofday_ns(); } probe kernel.trace("net_dev_start_xmit"), kernel.trace("net_dev_xmit") { t = gettimeofday_ns(); st = skb_queue_start_t[$skb] if (st){ dev = kernel_string($dev->name) if ( dev in instance_latency) { mmv_inc_value(instance_latency[dev], t - st) mmv_inc_value(instance_count[dev], 1) } delete skb_queue_start_t[$skb] } }