@cryptotaxi247 / netdata-1 / commits / 417f41064

Add netisr (softnet) charts to FreeBSD plugin

Vladimir Kobal committed Dec 13, 2016 at 11:55 UTC 417f4106464da4b8a6fe26e42eb0ac7fbd2204e4
1 file changed +130 -10
src/freebsd_sysctl.c
+130 -10
@@ -12,6 +12,8 @@
12 #include <sys/shm.h>
13 #include <sys/msg.h>
14 #undef _KERNEL
15 +// NEEDED BY: struct sysctl_netisr_workstream, struct sysctl_netisr_work
16 +#include <net/netisr.h>
17 // NEEDED BY: do_disk_io
18 #define RRD_TYPE_DISK "disk"
19
@@ -24,7 +26,7 @@ int do_freebsd_sysctl(int update_every, usec_t dt) {
26 static int do_cpu = -1, do_cpu_cores = -1, do_interrupts = -1, do_context = -1, do_forks = -1, do_processes = -1,
27 do_loadavg = -1, do_all_processes = -1, do_disk_io = -1, do_swap = -1, do_ram = -1, do_swapio = -1,
28 do_pgfaults = -1, do_committed = -1, do_ipc_semaphores = -1, do_ipc_shared_mem = -1, do_ipc_msg_queues = -1,
27 - do_dev_intr = -1, do_soft_intr = -1;
29 + do_dev_intr = -1, do_soft_intr = -1, do_netisr = -1, do_netisr_per_core = -1;
30
31 if (unlikely(do_cpu == -1)) {
32 do_cpu = config_get_boolean("plugin:freebsd:sysctl", "cpu utilization", 1);
@@ -46,38 +48,43 @@ int do_freebsd_sysctl(int update_every, usec_t dt) {
48 do_ipc_semaphores = config_get_boolean("plugin:freebsd:sysctl", "ipc semaphores", 1);
49 do_ipc_shared_mem = config_get_boolean("plugin:freebsd:sysctl", "ipc shared memory", 1);
50 do_ipc_msg_queues = config_get_boolean("plugin:freebsd:sysctl", "ipc message queues", 1);
51 + do_netisr = config_get_boolean("plugin:freebsd:sysctl", "netisr", 1);
52 + do_netisr_per_core = config_get_boolean("plugin:freebsd:sysctl", "netisr per core", 1);
53 }
54
55 RRDSET *st;
56
57 int system_pagesize = getpagesize(); // wouldn't it be better to get value directly from hw.pagesize?
54 - int i;
58 + int i, n;
59 + int common_error = 0;
60
56 -// NEEDED BY: do_loadavg
61 + // NEEDED BY: do_loadavg
62 static usec_t last_loadavg_usec = 0;
63 struct loadavg sysload;
64
60 -// NEEDED BY: do_cpu, do_cpu_cores
65 + // NEEDED BY: do_cpu, do_cpu_cores
66 long cp_time[CPUSTATES];
67
63 -// NEEDED BY: do_cpu_cores
68 + // NEEDED BY: du_cpu_cores, do_netisr, do_netisr_per_core
69 int ncpus;
70 +
71 + // NEEDED BY: do_cpu_cores
72 static long *pcpu_cp_time = NULL;
73 char cpuid[8]; // no more than 4 digits expected
74
68 -// NEEDED BY: do_all_processes, do_processes
75 + // NEEDED BY: do_all_processes, do_processes
76 struct vmtotal vmtotal_data;
77
71 -// NEEDED BY: do_context, do_forks
78 + // NEEDED BY: do_context, do_forks
79 u_int u_int_data;
80
74 -// NEEDED BY: do_interrupts
81 + // NEEDED BY: do_interrupts
82 size_t intrcnt_size;
83 unsigned long nintr = 0;
84 static unsigned long *intrcnt = NULL;
85 unsigned long long totalintr = 0;
86
80 -// NEEDED BY: do_disk_io
87 + // NEEDED BY: do_disk_io
88 #define BINTIME_SCALE 5.42101086242752217003726400434970855712890625e-17 // this is 1000/2^64
89 int numdevs;
90 static void *devstat_data = NULL;
@@ -138,6 +145,20 @@ int do_freebsd_sysctl(int update_every, usec_t dt) {
145 } ipc_msq = {0, 0, 0, 0, 0};
146 static struct msqid_kernel *ipc_msq_data = NULL;
147
148 + // NEEDED BY: do_netisr, do_netisr_per_core
149 + size_t netisr_workstream_size;
150 + size_t netisr_work_size;
151 + unsigned long num_netisr_workstreams = 0, num_netisr_works = 0;
152 + static struct sysctl_netisr_workstream *netisr_workstream = NULL;
153 + static struct sysctl_netisr_work *netisr_work = NULL;
154 + static struct netisr_stats {
155 + collected_number dispatched;
156 + collected_number hybrid_dispatched;
157 + collected_number qdrops;
158 + collected_number queued;
159 + } *netisr_stats = NULL;
160 + char netstat_cpuid[21]; // no more than 4 digits expected
161 +
162 // --------------------------------------------------------------------
163
164 if (last_loadavg_usec <= dt) {
@@ -871,7 +892,7 @@ int do_freebsd_sysctl(int update_every, usec_t dt) {
892
893 st = rrdset_find("system.ipc_msq_queues");
894 if (unlikely(!st)) {
874 - st = rrdset_create("system", "ipc_msq_queues", NULL, "ipc message queues", NULL, "Number of IPC Message Queues", "queues", 900, rrd_update_every, RRDSET_TYPE_AREA);
895 + st = rrdset_create("system", "ipc_msq_queues", NULL, "ipc message queues", NULL, "Number of IPC Message Queues", "queues", 990, rrd_update_every, RRDSET_TYPE_AREA);
896 rrddim_add(st, "queues", NULL, 1, 1, RRDDIM_ABSOLUTE);
897 }
898 else rrdset_next(st);
@@ -909,5 +930,104 @@ int do_freebsd_sysctl(int update_every, usec_t dt) {
930 }
931 }
932
933 + // --------------------------------------------------------------------
934 +
935 + if (likely(do_netisr || do_netisr_per_core)) {
936 + if (unlikely(GETSYSCTL("kern.smp.cpus", ncpus))) {
937 + common_error = 1;
938 + } else if (unlikely(ncpus > 9999)) {
939 + error("FREEBSD: There are more than 4 digits in cpu cores number");
940 + common_error = 1;
941 + } else if (unlikely(sysctlbyname("net.isr.workstream", NULL, &netisr_workstream_size, NULL, 0) == -1)) {
942 + error("FREEBSD: sysctl(net.isr.workstream...) failed: %s", strerror(errno));
943 + common_error = 1;
944 + } else if (unlikely(sysctlbyname("net.isr.work", NULL, &netisr_work_size, NULL, 0) == -1)) {
945 + error("FREEBSD: sysctl(net.isr.work...) failed: %s", strerror(errno));
946 + common_error = 1;
947 + } else {
948 + num_netisr_workstreams = netisr_workstream_size / sizeof(struct sysctl_netisr_workstream);
949 + netisr_workstream = reallocz(netisr_workstream, num_netisr_workstreams * sizeof(struct sysctl_netisr_workstream));
950 + if (unlikely(getsysctl("net.isr.workstream", netisr_workstream, num_netisr_workstreams * sizeof(struct sysctl_netisr_workstream)))){
951 + common_error = 1;
952 + } else {
953 + num_netisr_works = netisr_work_size / sizeof(struct sysctl_netisr_work);
954 + netisr_work = reallocz(netisr_work, num_netisr_works * sizeof(struct sysctl_netisr_work));
955 + if (unlikely(getsysctl("net.isr.work", netisr_work, num_netisr_works * sizeof(struct sysctl_netisr_work)))){
956 + common_error = 1;
957 + }
958 + }
959 + }
960 + if (unlikely(common_error)) {
961 + do_netisr = 0;
962 + error("DISABLED: system.softnet_stat");
963 + do_netisr_per_core = 0;
964 + error("DISABLED: system.cpuX_softnet_stat");
965 + common_error = 0;
966 + } else {
967 + netisr_stats = reallocz(netisr_stats, (ncpus + 1) * sizeof(struct netisr_stats));
968 + bzero(netisr_stats, (ncpus + 1) * sizeof(struct netisr_stats));
969 + for (i = 0; i < num_netisr_workstreams; i++) {
970 + for (n = 0; n < num_netisr_works; n++) {
971 + if (netisr_workstream[i].snws_wsid == netisr_work[n].snw_wsid) {
972 + netisr_stats[netisr_workstream[i].snws_cpu].dispatched += netisr_work[n].snw_dispatched;
973 + netisr_stats[netisr_workstream[i].snws_cpu].hybrid_dispatched += netisr_work[n].snw_hybrid_dispatched;
974 + netisr_stats[netisr_workstream[i].snws_cpu].qdrops += netisr_work[n].snw_qdrops;
975 + netisr_stats[netisr_workstream[i].snws_cpu].queued += netisr_work[n].snw_queued;
976 + }
977 + }
978 + }
979 + for (i = 0; i < ncpus; i++) {
980 + netisr_stats[ncpus].dispatched += netisr_stats[i].dispatched;
981 + netisr_stats[ncpus].hybrid_dispatched += netisr_stats[i].hybrid_dispatched;
982 + netisr_stats[ncpus].qdrops += netisr_stats[i].qdrops;
983 + netisr_stats[ncpus].queued += netisr_stats[i].queued;
984 + }
985 + }
986 + }
987 +
988 + // --------------------------------------------------------------------
989 +
990 + if (likely(do_netisr)) {
991 + st = rrdset_find_bytype("system", "softnet_stat");
992 + if (unlikely(!st)) {
993 + st = rrdset_create("system", "softnet_stat", NULL, "softnet_stat", NULL, "System softnet_stat", "events/s", 955, update_every, RRDSET_TYPE_LINE);
994 + rrddim_add(st, "dispatched", NULL, 1, 1, RRDDIM_INCREMENTAL);
995 + rrddim_add(st, "hybrid_dispatched", NULL, 1, 1, RRDDIM_INCREMENTAL);
996 + rrddim_add(st, "qdrops", NULL, 1, 1, RRDDIM_INCREMENTAL);
997 + rrddim_add(st, "queued", NULL, 1, 1, RRDDIM_INCREMENTAL);
998 + }
999 + else rrdset_next(st);
1000 +
1001 + rrddim_set(st, "dispatched", netisr_stats[ncpus].dispatched);
1002 + rrddim_set(st, "hybrid_dispatched", netisr_stats[ncpus].hybrid_dispatched);
1003 + rrddim_set(st, "qdrops", netisr_stats[ncpus].qdrops);
1004 + rrddim_set(st, "queued", netisr_stats[ncpus].queued);
1005 + rrdset_done(st);
1006 + }
1007 +
1008 + // --------------------------------------------------------------------
1009 +
1010 + if (likely(do_netisr_per_core)) {
1011 + for (i = 0; i < ncpus ;i++) {
1012 + snprintfz(netstat_cpuid, 21, "cpu%d_softnet_stat", i);
1013 +
1014 + st = rrdset_find_bytype("cpu", netstat_cpuid);
1015 + if (unlikely(!st)) {
1016 + st = rrdset_create("cpu", netstat_cpuid, NULL, "softnet_stat", NULL, "Per CPU netisr statistics", "events/s", 1101 + i, update_every, RRDSET_TYPE_LINE);
1017 + rrddim_add(st, "dispatched", NULL, 1, 1, RRDDIM_INCREMENTAL);
1018 + rrddim_add(st, "hybrid_dispatched", NULL, 1, 1, RRDDIM_INCREMENTAL);
1019 + rrddim_add(st, "qdrops", NULL, 1, 1, RRDDIM_INCREMENTAL);
1020 + rrddim_add(st, "queued", NULL, 1, 1, RRDDIM_INCREMENTAL);
1021 + }
1022 + else rrdset_next(st);
1023 +
1024 + rrddim_set(st, "dispatched", netisr_stats[i].dispatched);
1025 + rrddim_set(st, "hybrid_dispatched", netisr_stats[i].hybrid_dispatched);
1026 + rrddim_set(st, "qdrops", netisr_stats[i].qdrops);
1027 + rrddim_set(st, "queued", netisr_stats[i].queued);
1028 + rrdset_done(st);
1029 + }
1030 + }
1031 +
1032 return 0;
1033 }