.bitmap = &cpu_bitmap
};
+/* Pressure-stall CPU activity */
+struct activity psi_cpu_act = {
+ .id = A_PSI_CPU,
+ .options = AO_COLLECTED,
+ .magic = ACTIVITY_MAGIC_BASE,
+ .group = G_DEFAULT,
+#ifdef SOURCE_SADC
+ .f_count_index = -1,
+ .f_count2 = NULL,
+ .f_read = wrap_read_psicpu,
+#endif
+#ifdef SOURCE_SAR
+ .f_print = print_psicpu_stats,
+ .f_print_avg = print_avg_psicpu_stats,
+#endif
+#if defined(SOURCE_SAR) || defined(SOURCE_SADF)
+ .hdr_line = "s_acpu10;s_acpu60;s_acpu300;s_totcpu",
+#endif
+ .gtypes_nr = {STATS_PSI_CPU_ULL, STATS_PSI_CPU_UL, STATS_PSI_CPU_U},
+ .ftypes_nr = {0, 0, 0},
+#ifdef SOURCE_SADF
+//FIX .f_render = render_psicpu_stats,
+//FIX .f_xml_print = xml_print_psicpu_stats,
+//FIX .f_json_print = json_print_psicpu_stats,
+//FIX .f_svg_print = svg_print_psicpu_stats,
+//FIX .f_raw_print = raw_print_psicpu_stats,
+//FIX .f_pcp_print = pcp_print_psicpu_stats,
+ .f_count_new = NULL,
+ .item_list = NULL,
+ .desc = "Pressure-stall CPU statistics",
+#endif
+ .name = "A_PSI_CPU",
+ .item_list_sz = 0,
+ .g_nr = 2,
+ .nr_ini = 1,
+ .nr2 = 1,
+ .nr_max = 1,
+ .nr = {1, 1, 1},
+ .nr_allocated = 0,
+ .fsize = STATS_PSI_CPU_SIZE,
+ .msize = STATS_PSI_CPU_SIZE,
+ .opt_flags = 0,
+ .buf = {NULL, NULL, NULL},
+ .bitmap = NULL
+};
+
+/* Pressure-stall I/O activity */
+struct activity psi_io_act = {
+ .id = A_PSI_IO,
+ .options = AO_COLLECTED,
+ .magic = ACTIVITY_MAGIC_BASE,
+ .group = G_DEFAULT,
+#ifdef SOURCE_SADC
+ .f_count_index = -1,
+ .f_count2 = NULL,
+ .f_read = wrap_read_psiio,
+#endif
+#ifdef SOURCE_SAR
+ .f_print = print_psiio_stats,
+ .f_print_avg = print_avg_psiio_stats,
+#endif
+#if defined(SOURCE_SAR) || defined(SOURCE_SADF)
+ .hdr_line = "s_aio10;s_aio60;s_aio300;s_totio;f_aio10;f_aio60;f_aio300;f_totio",
+#endif
+ .gtypes_nr = {STATS_PSI_IO_ULL, STATS_PSI_IO_UL, STATS_PSI_IO_U},
+ .ftypes_nr = {0, 0, 0},
+#ifdef SOURCE_SADF
+//FIX .f_render = render_psiio_stats,
+//FIX .f_xml_print = xml_print_psiio_stats,
+//FIX .f_json_print = json_print_psiio_stats,
+//FIX .f_svg_print = svg_print_psiio_stats,
+//FIX .f_raw_print = raw_print_psiio_stats,
+//FIX .f_pcp_print = pcp_print_psiio_stats,
+ .f_count_new = NULL,
+ .item_list = NULL,
+ .desc = "Pressure-stall I/O statistics",
+#endif
+ .name = "A_PSI_IO",
+ .item_list_sz = 0,
+ .g_nr = 4,
+ .nr_ini = 1,
+ .nr2 = 1,
+ .nr_max = 1,
+ .nr = {1, 1, 1},
+ .nr_allocated = 0,
+ .fsize = STATS_PSI_IO_SIZE,
+ .msize = STATS_PSI_IO_SIZE,
+ .opt_flags = 0,
+ .buf = {NULL, NULL, NULL},
+ .bitmap = NULL
+};
+
+/* Pressure-stall memory activity */
+struct activity psi_mem_act = {
+ .id = A_PSI_MEM,
+ .options = AO_COLLECTED,
+ .magic = ACTIVITY_MAGIC_BASE,
+ .group = G_DEFAULT,
+#ifdef SOURCE_SADC
+ .f_count_index = -1,
+ .f_count2 = NULL,
+ .f_read = wrap_read_psimem,
+#endif
+#ifdef SOURCE_SAR
+ .f_print = print_psimem_stats,
+ .f_print_avg = print_avg_psimem_stats,
+#endif
+#if defined(SOURCE_SAR) || defined(SOURCE_SADF)
+ .hdr_line = "s_amem10;s_amem60;s_amem300;s_totmem;f_amem10;f_amem60;f_amem300;f_totmem",
+#endif
+ .gtypes_nr = {STATS_PSI_MEM_ULL, STATS_PSI_MEM_UL, STATS_PSI_MEM_U},
+ .ftypes_nr = {0, 0, 0},
+#ifdef SOURCE_SADF
+//FIX .f_render = render_psimem_stats,
+//FIX .f_xml_print = xml_print_psimem_stats,
+//FIX .f_json_print = json_print_psimem_stats,
+//FIX .f_svg_print = svg_print_psimem_stats,
+//FIX .f_raw_print = raw_print_psimem_stats,
+//FIX .f_pcp_print = pcp_print_psimem_stats,
+ .f_count_new = NULL,
+ .item_list = NULL,
+ .desc = "Pressure-stall memory statistics",
+#endif
+ .name = "A_PSI_MEM",
+ .item_list_sz = 0,
+ .g_nr = 4,
+ .nr_ini = 1,
+ .nr2 = 1,
+ .nr_max = 1,
+ .nr = {1, 1, 1},
+ .nr_allocated = 0,
+ .fsize = STATS_PSI_MEM_SIZE,
+ .msize = STATS_PSI_MEM_SIZE,
+ .opt_flags = 0,
+ .buf = {NULL, NULL, NULL},
+ .bitmap = NULL
+};
+
#ifdef SOURCE_SADC
/*
* Array of functions used to count number of items.
&pwr_wghfreq_act,
&pwr_usb_act, /* AO_CLOSE_MARKUP */
/* </power-management> */
- &filesystem_act
+ &filesystem_act,
+ &psi_cpu_act,
+ &psi_io_act,
+ &psi_mem_act
};
printf("\n");
}
}
+
+/*
+ ***************************************************************************
+ * Display pressure-stall CPU statistics. This function is used to display
+ * instantaneous and average statistics.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @curr Index in array for current sample statistics.
+ * @dispavg TRUE if displaying average statistics.
+ ***************************************************************************
+ */
+void stub_print_psicpu_stats(struct activity *a, int curr, int dispavg)
+{
+#if 0
+//FIX
+ struct stats_queue
+ *sqc = (struct stats_queue *) a->buf[curr];
+ static unsigned long long
+ avg_nr_running = 0,
+ avg_nr_threads = 0,
+ avg_load_avg_1 = 0,
+ avg_load_avg_5 = 0,
+ avg_load_avg_15 = 0,
+ avg_procs_blocked = 0;
+
+ if (dish) {
+ print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
+ }
+
+ if (!dispavg) {
+ /* Display instantaneous values */
+ printf("%-11s", timestamp[curr]);
+ cprintf_u64(NO_UNIT, 2, 9,
+ (unsigned long long) sqc->nr_running,
+ (unsigned long long) sqc->nr_threads);
+ cprintf_f(NO_UNIT, 3, 9, 2,
+ (double) sqc->load_avg_1 / 100,
+ (double) sqc->load_avg_5 / 100,
+ (double) sqc->load_avg_15 / 100);
+ cprintf_u64(NO_UNIT, 1, 9,
+ (unsigned long long) sqc->procs_blocked);
+ printf("\n");
+
+ /* Will be used to compute the average */
+ avg_nr_running += sqc->nr_running;
+ avg_nr_threads += sqc->nr_threads;
+ avg_load_avg_1 += sqc->load_avg_1;
+ avg_load_avg_5 += sqc->load_avg_5;
+ avg_load_avg_15 += sqc->load_avg_15;
+ avg_procs_blocked += sqc->procs_blocked;
+ }
+ else {
+ /* Display average values */
+ printf("%-11s", timestamp[curr]);
+ cprintf_f(NO_UNIT, 2, 9, 0,
+ (double) avg_nr_running / avg_count,
+ (double) avg_nr_threads / avg_count);
+ cprintf_f(NO_UNIT, 3, 9, 2,
+ (double) avg_load_avg_1 / (avg_count * 100),
+ (double) avg_load_avg_5 / (avg_count * 100),
+ (double) avg_load_avg_15 / (avg_count * 100));
+ cprintf_f(NO_UNIT, 1, 9, 0,
+ (double) avg_procs_blocked / avg_count);
+ printf("\n");
+
+ /* Reset average counters */
+ avg_nr_running = avg_nr_threads = 0;
+ avg_load_avg_1 = avg_load_avg_5 = avg_load_avg_15 = 0;
+ avg_procs_blocked = 0;
+ }
+#endif
+}
+
+/*
+ ***************************************************************************
+ * Display pressure-stall CPU statistics.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @prev Index in array where stats used as reference are.
+ * @curr Index in array for current sample statistics.
+ * @itv Interval of time in 1/100th of a second.
+ ***************************************************************************
+ */
+__print_funct_t print_psicpu_stats(struct activity *a, int prev, int curr,
+ unsigned long long itv)
+{
+ stub_print_psicpu_stats(a, curr, FALSE);
+}
+
+/*
+ ***************************************************************************
+ * Display average pressure-stall CPU statistics.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @prev Index in array where stats used as reference are.
+ * @curr Index in array for current sample statistics.
+ * @itv Interval of time in 1/100th of a second.
+ ***************************************************************************
+ */
+__print_funct_t print_avg_psicpu_stats(struct activity *a, int prev, int curr,
+ unsigned long long itv)
+{
+ stub_print_psicpu_stats(a, curr, TRUE);
+}
+
+/*
+ ***************************************************************************
+ * Display pressure-stall I/O statistics. This function is used to display
+ * instantaneous and average statistics.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @curr Index in array for current sample statistics.
+ * @dispavg TRUE if displaying average statistics.
+ ***************************************************************************
+ */
+void stub_print_psiio_stats(struct activity *a, int curr, int dispavg)
+{
+}
+
+/*
+ ***************************************************************************
+ * Display pressure-stall I/O statistics.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @prev Index in array where stats used as reference are.
+ * @curr Index in array for current sample statistics.
+ * @itv Interval of time in 1/100th of a second.
+ ***************************************************************************
+ */
+__print_funct_t print_psiio_stats(struct activity *a, int prev, int curr,
+ unsigned long long itv)
+{
+ stub_print_psiio_stats(a, curr, FALSE);
+}
+
+/*
+ ***************************************************************************
+ * Display average pressure-stall I/O statistics.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @prev Index in array where stats used as reference are.
+ * @curr Index in array for current sample statistics.
+ * @itv Interval of time in 1/100th of a second.
+ ***************************************************************************
+ */
+__print_funct_t print_avg_psiio_stats(struct activity *a, int prev, int curr,
+ unsigned long long itv)
+{
+ stub_print_psiio_stats(a, curr, TRUE);
+}
+
+/*
+ ***************************************************************************
+ * Display pressure-stall memory statistics. This function is used to display
+ * instantaneous and average statistics.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @curr Index in array for current sample statistics.
+ * @dispavg TRUE if displaying average statistics.
+ ***************************************************************************
+ */
+void stub_print_psimem_stats(struct activity *a, int curr, int dispavg)
+{
+}
+
+/*
+ ***************************************************************************
+ * Display pressure-stall memory statistics.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @prev Index in array where stats used as reference are.
+ * @curr Index in array for current sample statistics.
+ * @itv Interval of time in 1/100th of a second.
+ ***************************************************************************
+ */
+__print_funct_t print_psimem_stats(struct activity *a, int prev, int curr,
+ unsigned long long itv)
+{
+ stub_print_psimem_stats(a, curr, FALSE);
+}
+
+/*
+ ***************************************************************************
+ * Display average pressure-stall memory statistics.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @prev Index in array where stats used as reference are.
+ * @curr Index in array for current sample statistics.
+ * @itv Interval of time in 1/100th of a second.
+ ***************************************************************************
+ */
+__print_funct_t print_avg_psimem_stats(struct activity *a, int prev, int curr,
+ unsigned long long itv)
+{
+ stub_print_psimem_stats(a, curr, TRUE);
+}
(struct activity *, int, int, unsigned long long);
__print_funct_t print_softnet_stats
(struct activity *, int, int, unsigned long long);
+__print_funct_t print_psicpu_stats
+ (struct activity *, int, int, unsigned long long);
+__print_funct_t print_psiio_stats
+ (struct activity *, int, int, unsigned long long);
+__print_funct_t print_psimem_stats
+ (struct activity *, int, int, unsigned long long);
/* Functions used to display average statistics */
__print_funct_t print_avg_memory_stats
(struct activity *, int, int, unsigned long long);
__print_funct_t print_avg_filesystem_stats
(struct activity *, int, int, unsigned long long);
+__print_funct_t print_avg_psicpu_stats
+ (struct activity *, int, int, unsigned long long);
+__print_funct_t print_avg_psiio_stats
+ (struct activity *, int, int, unsigned long long);
+__print_funct_t print_avg_psimem_stats
+ (struct activity *, int, int, unsigned long long);
#endif /* _PR_STATS_H */
#define NET_RPC_NFSD PRE "/proc/net/rpc/nfsd"
#define NET_SOFTNET PRE "/proc/net/softnet_stat"
#define LOADAVG PRE "/proc/loadavg"
+#define PSI_CPU PRE "/proc/pressure/cpu"
+#define PSI_IO PRE "/proc/pressure/io"
+#define PSI_MEM PRE "/proc/pressure/mem"
#define VMSTAT PRE "/proc/vmstat"
#define NET_SNMP PRE "/proc/net/snmp"
#define NET_SNMP6 PRE "/proc/net/snmp6"
#define STATS_SOFTNET_UL 0
#define STATS_SOFTNET_U 5
+/* Structure for pressure-stall CPU statistics */
+struct stats_psi_cpu {
+ unsigned long long some_cpu_total;
+ unsigned long some_acpu_10;
+ unsigned long some_acpu_60;
+ unsigned long some_acpu_300;
+};
+
+#define STATS_PSI_CPU_SIZE (sizeof(struct stats_psi_cpu))
+#define STATS_PSI_CPU_ULL 1
+#define STATS_PSI_CPU_UL 3
+#define STATS_PSI_CPU_U 0
+
+/* Structure for pressure-stall I/O statistics */
+struct stats_psi_io {
+ unsigned long long some_io_total;
+ unsigned long long full_io_total;
+ unsigned long some_aio_10;
+ unsigned long some_aio_60;
+ unsigned long some_aio_300;
+ unsigned long full_aio_10;
+ unsigned long full_aio_60;
+ unsigned long full_aio_300;
+};
+
+#define STATS_PSI_IO_SIZE (sizeof(struct stats_psi_io))
+#define STATS_PSI_IO_ULL 2
+#define STATS_PSI_IO_UL 6
+#define STATS_PSI_IO_U 0
+
+/* Structure for pressure-stall memory statistics */
+struct stats_psi_mem {
+ unsigned long long some_mem_total;
+ unsigned long long full_mem_total;
+ unsigned long some_amem_10;
+ unsigned long some_amem_60;
+ unsigned long some_amem_300;
+ unsigned long full_amem_10;
+ unsigned long full_amem_60;
+ unsigned long full_amem_300;
+};
+
+#define STATS_PSI_MEM_SIZE (sizeof(struct stats_psi_mem))
+#define STATS_PSI_MEM_ULL 2
+#define STATS_PSI_MEM_UL 6
+#define STATS_PSI_MEM_U 0
+
/*
***************************************************************************
* Prototypes for functions used to read system statistics
*/
/* Number of activities */
-#define NR_ACT 39
+#define NR_ACT 42
/* The value below is used for sanity check */
#define MAX_NR_ACT 256
#define A_FS 37
#define A_NET_FC 38
#define A_NET_SOFT 39
+#define A_PSI_CPU 40
+#define A_PSI_IO 41
+#define A_PSI_MEM 42
/* Macro used to flag an activity that should be collected */
/* Keywords */
#define K_A_NULL "A_NULL"
#define K_CPU "CPU"
+#define K_PSI_CPU "CPU"
#define K_DEV "DEV"
#define K_EDEV "EDEV"
#define K_EICMP "EICMP"
#define K_ICMP "ICMP"
#define K_ICMP6 "ICMP6"
#define K_IN "IN"
+#define K_PSI_IO "IO"
#define K_IP "IP"
#define K_IP6 "IP6"
+#define K_LOAD "LOAD"
+#define K_PSI_MEM "MEM"
#define K_MOUNT "MOUNT"
#define K_NFS "NFS"
#define K_NFSD "NFSD"
(struct activity *);
__read_funct_t wrap_read_softnet
(struct activity *);
+__read_funct_t wrap_read_psicpu
+ (struct activity *);
+__read_funct_t wrap_read_psiio
+ (struct activity *);
+__read_funct_t wrap_read_psimem
+ (struct activity *);
/* Other functions */
int check_alt_sa_dir
(char * [], int *, struct activity * []);
int parse_sar_n_opt
(char * [], int *, struct activity * []);
+int parse_sar_q_opt
+ (char * [], int *, struct activity * []);
int parse_timestamp
(char * [], int *, struct tstamp *, const char *);
void print_report_hdr
break;
case 'q':
+ /* Option -q grouped with other ones */
SELECT_ACTIVITY(A_QUEUE);
break;
return 0;
}
+/*
+ ***************************************************************************
+ * Parse sar "-q" option.
+ *
+ * IN:
+ * @argv Arguments list.
+ * @opt Index in list of arguments.
+ *
+ * OUT:
+ * @act Array of selected activities.
+ *
+ * RETURNS:
+ * 0 on success, 1 otherwise.
+ ***************************************************************************
+ */
+int parse_sar_q_opt(char *argv[], int *opt, struct activity *act[])
+{
+ char *t;
+
+ for (t = strtok(argv[*opt], ","); t; t = strtok(NULL, ",")) {
+ if (!strcmp(t, K_LOAD)) {
+ SELECT_ACTIVITY(A_QUEUE);
+ }
+ else if (!strcmp(t, K_PSI_CPU)) {
+ SELECT_ACTIVITY(A_PSI_CPU);
+ }
+ else if (!strcmp(t, K_PSI_IO)) {
+ SELECT_ACTIVITY(A_PSI_IO);
+ }
+ else if (!strcmp(t, K_PSI_MEM)) {
+ SELECT_ACTIVITY(A_PSI_MEM);
+ }
+ else if (!strcmp(t, K_ALL)) {
+ SELECT_ACTIVITY(A_QUEUE);
+ SELECT_ACTIVITY(A_PSI_CPU);
+ SELECT_ACTIVITY(A_PSI_IO);
+ SELECT_ACTIVITY(A_PSI_MEM);
+ }
+ else
+ return 1;
+ }
+
+ (*opt)++;
+ return 0;
+}
+
/*
***************************************************************************
* Parse sar "-I" option.
return;
}
+/*
+ ***************************************************************************
+ * Read pressure-stall CPU statistics.
+ *
+ * IN:
+ * @a Activity structure.
+ *
+ * OUT:
+ * @a Activity structure with statistics.
+ ***************************************************************************
+ */
+__read_funct_t wrap_read_psicpu(struct activity *a)
+{
+ struct stats_psi_cpu *st_psicpu
+ = (struct stats_psi_cpu *) a->_buf0;
+
+ /* Read pressure-stall CPU stats */
+// read_psicpu(st_psicpu);
+
+ return;
+}
+
+/*
+ ***************************************************************************
+ * Read pressure-stall I/O statistics.
+ *
+ * IN:
+ * @a Activity structure.
+ *
+ * OUT:
+ * @a Activity structure with statistics.
+ ***************************************************************************
+ */
+__read_funct_t wrap_read_psiio(struct activity *a)
+{
+ struct stats_psi_io *st_psiio
+ = (struct stats_psi_io *) a->_buf0;
+
+ /* Read pressure-stall I/O stats */
+// read_psiio(st_psiio);
+
+ return;
+}
+
+/*
+ ***************************************************************************
+ * Read pressure-stall memory statistics.
+ *
+ * IN:
+ * @a Activity structure.
+ *
+ * OUT:
+ * @a Activity structure with statistics.
+ ***************************************************************************
+ */
+__read_funct_t wrap_read_psimem(struct activity *a)
+{
+ struct stats_psi_mem *st_psimem
+ = (struct stats_psi_mem *) a->_buf0;
+
+ /* Read pressure-stall memory stats */
+// read_psimem(st_psimem);
+
+ return;
+}
+
/*
***************************************************************************
* Count number of interrupts that are in /proc/stat file.
print_usage_title(stderr, progname);
fprintf(stderr, _("Options are:\n"
"[ -A ] [ -B ] [ -b ] [ -C ] [ -D ] [ -d ] [ -F [ MOUNT ] ] [ -H ] [ -h ]\n"
- "[ -p ] [ -q ] [ -r [ ALL ] ] [ -S ] [ -t ] [ -u [ ALL ] ] [ -V ]\n"
+ "[ -p ] [ -r [ ALL ] ] [ -S ] [ -t ] [ -u [ ALL ] ] [ -V ]\n"
"[ -v ] [ -W ] [ -w ] [ -y ] [ -z ]\n"
"[ -I { <int_list> | SUM | ALL } ] [ -P { <cpu_list> | ALL } ]\n"
"[ -m { <keyword> [,...] | ALL } ] [ -n { <keyword> [,...] | ALL } ]\n"
+ "[ -q [ <keyword> [,...] | ALL ] ]\n"
"[ --dev=<dev_list> ] [ --fs=<fs_list> ] [ --iface=<iface_list> ]\n"
"[ --dec={ 0 | 1 | 2 } ] [ --help ] [ --human ] [ --sadc ]\n"
"[ -j { SID | ID | LABEL | PATH | UUID | ... } ]\n"
"\t\tFC\tFibre channel HBAs\n"
"\t\tSOFT\tSoftware-based network processing\n"));
printf(_("\t-q\tQueue length and load average statistics [A_QUEUE]\n"));
+ printf(_("\t-q [ <keyword> [,...] | ALL ]\n"
+ "\t\tSystem load and pressure-stall statistics\n"
+ "\t\tKeywords are:\n"
+ "\t\tLOAD\tQueue length and load average statistics [A_QUEUE]\n"
+ "\t\tCPU\tPressure-stall CPU statistics [A_PSI_CPU]\n"
+ "\t\tIO\tPressure-stall I/O statistics [A_PSI_IO]\n"
+ "\t\tMEM\tPressure-stall memory statistics [A_PSI_MEM]\n"));
printf(_("\t-r [ ALL ]\n"
"\t\tMemory utilization statistics [A_MEMORY]\n"));
printf(_("\t-S\tSwap space utilization statistics [A_MEMORY]\n"));
}
}
+ else if (!strcmp(argv[opt], "-q")) {
+ if (!argv[++opt]) {
+ SELECT_ACTIVITY(A_QUEUE);
+ }
+ /* Parse option -q */
+ else if (parse_sar_q_opt(argv, &opt, act)) {
+ SELECT_ACTIVITY(A_QUEUE);
+ }
+ }
+
#ifdef TEST
else if (!strncmp(argv[opt], "--getenv", 8)) {
__env = TRUE;