mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Increase initial update interval from 200ms to 1 seconds to avoid fluctuations on the initial data output. Signed-off-by: Mete Durlu <meted@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
515 lines
12 KiB
C
515 lines
12 KiB
C
/*
|
|
* hyptop - Show hypervisor performance data on System z
|
|
*
|
|
* System data module: Provide database for system data (e.g. CPU and memory)
|
|
*
|
|
* Copyright IBM Corp. 2010, 2017
|
|
*
|
|
* s390-tools is free software; you can redistribute it and/or modify
|
|
* it under the terms of the MIT license. See LICENSE for details.
|
|
*/
|
|
|
|
#ifndef SD_H
|
|
#define SD_H
|
|
|
|
#include "lib/util_list.h"
|
|
|
|
#include "helper.h"
|
|
#include "table.h"
|
|
|
|
#define SD_DG_INIT_INTERVAL_SEC 1
|
|
#define SD_SYS_ID_SIZE 9
|
|
|
|
/*
|
|
* CPU info
|
|
*/
|
|
struct sd_cpu_info {
|
|
u64 cpu_time_us;
|
|
u64 thread_time_us;
|
|
u64 mgm_time_us_set;
|
|
u64 mgm_time_us;
|
|
u64 wait_time_us;
|
|
s64 steal_time_us;
|
|
u64 online_time_us;
|
|
};
|
|
|
|
/*
|
|
* Memory Info
|
|
*/
|
|
struct sd_mem {
|
|
u64 min_kib;
|
|
u64 max_kib;
|
|
u64 use_kib;
|
|
};
|
|
|
|
/*
|
|
* Weight
|
|
*/
|
|
struct sd_weight {
|
|
u16 cur;
|
|
u16 min;
|
|
u16 max;
|
|
};
|
|
|
|
/*
|
|
* System Name
|
|
*/
|
|
struct sd_sys_name {
|
|
char os[9];
|
|
};
|
|
|
|
struct sd_sys;
|
|
|
|
/*
|
|
* SD info
|
|
*/
|
|
struct sd_info {
|
|
u8 active;
|
|
struct sd_sys *parent;
|
|
};
|
|
|
|
struct sd_cpu;
|
|
|
|
/*
|
|
* SD System (can be e.g. CEC, VM or guest/LPAR)
|
|
*/
|
|
struct sd_sys {
|
|
struct util_list_node list;
|
|
struct sd_info i;
|
|
u64 update_time_us;
|
|
u32 child_cnt;
|
|
u32 child_cnt_active;
|
|
struct util_list child_list;
|
|
u32 cpu_cnt;
|
|
u32 cpu_cnt_active;
|
|
struct util_list cpu_list;
|
|
u32 threads_per_core;
|
|
char id[SD_SYS_ID_SIZE];
|
|
struct sd_sys_name name;
|
|
struct sd_mem mem;
|
|
struct sd_weight weight;
|
|
};
|
|
|
|
#define sd_sys_id(sys) ((sys)->id)
|
|
#define sd_sys_name_os(sys) ((sys)->name.os)
|
|
|
|
void sd_sys_update_start(struct sd_sys *sys);
|
|
void sd_sys_update_end(struct sd_sys *sys, u64 update_time_us);
|
|
struct sd_sys *sd_sys_root_get(void);
|
|
struct sd_sys *sd_sys_get(struct sd_sys *parent, const char *id);
|
|
struct sd_sys *sd_sys_new(struct sd_sys *parent, const char *id);
|
|
|
|
static inline void sd_sys_weight_cur_set(struct sd_sys *sys, u64 value)
|
|
{
|
|
sys->weight.cur = value;
|
|
}
|
|
|
|
static inline void sd_sys_weight_min_set(struct sd_sys *sys, u64 value)
|
|
{
|
|
sys->weight.min = value;
|
|
}
|
|
|
|
static inline void sd_sys_weight_max_set(struct sd_sys *sys, u64 value)
|
|
{
|
|
sys->weight.max = value;
|
|
}
|
|
|
|
static inline void sd_sys_mem_use_kib_set(struct sd_sys *sys, u64 value)
|
|
{
|
|
sys->mem.use_kib = value;
|
|
}
|
|
|
|
static inline void sd_sys_mem_min_kib_set(struct sd_sys *sys, u64 value)
|
|
{
|
|
sys->mem.min_kib = value;
|
|
}
|
|
|
|
static inline void sd_sys_mem_max_kib_set(struct sd_sys *sys, u64 value)
|
|
{
|
|
sys->mem.max_kib = value;
|
|
}
|
|
|
|
static inline void sd_sys_update_time_us_set(struct sd_sys *sys, u64 value)
|
|
{
|
|
sys->update_time_us = value;
|
|
}
|
|
|
|
/*
|
|
* CPU type
|
|
*/
|
|
#define CPU_TYPE_ID_LEN 16
|
|
#define CPU_TYPE_DESC_LEN 64
|
|
|
|
#define SD_CPU_TYPE_STR_IFL "IFL"
|
|
#define SD_CPU_TYPE_STR_CP "CP"
|
|
#define SD_CPU_TYPE_STR_UN "UN"
|
|
|
|
struct sd_cpu_type {
|
|
char id[CPU_TYPE_ID_LEN];
|
|
char desc[CPU_TYPE_DESC_LEN];
|
|
u32 idx;
|
|
int cpu_cnt;
|
|
char hotkey;
|
|
};
|
|
|
|
#define sd_cpu_type_id(type) (type->id)
|
|
#define sd_cpu_type_desc(type) (type->desc)
|
|
|
|
int sd_cpu_type_selected(struct sd_cpu_type *cpu_type);
|
|
void sd_cpu_type_select_toggle(struct sd_cpu_type *cpu_type);
|
|
void sd_cpu_type_select(struct sd_cpu_type *cpu_type);
|
|
void sd_cpu_type_select_all(void);
|
|
void sd_cpu_type_select_none(void);
|
|
struct sd_cpu_type *sd_cpu_type_by_id(const char *id);
|
|
|
|
static inline int sd_cpu_type_cpu_cnt(struct sd_cpu_type *type)
|
|
{
|
|
return type->cpu_cnt;
|
|
}
|
|
|
|
static inline void sd_sys_commit(struct sd_sys *sys)
|
|
{
|
|
struct sd_sys *parent = sys->i.parent;
|
|
|
|
sys->i.active = 1;
|
|
if (parent)
|
|
parent->child_cnt_active++;
|
|
}
|
|
|
|
extern struct sd_cpu_type sd_cpu_type_ifl;
|
|
extern struct sd_cpu_type sd_cpu_type_cp;
|
|
extern struct sd_cpu_type sd_cpu_type_un;
|
|
|
|
/*
|
|
* SD CPU
|
|
*/
|
|
enum sd_cpu_state {
|
|
SD_CPU_STATE_UNKNOWN = 0,
|
|
SD_CPU_STATE_OPERATING = 1,
|
|
SD_CPU_STATE_STOPPED = 2,
|
|
SD_CPU_STATE_DECONFIG = 3,
|
|
};
|
|
|
|
struct sd_cpu {
|
|
struct util_list_node list;
|
|
struct sd_info i;
|
|
char id[9];
|
|
struct sd_cpu_type *type;
|
|
struct sd_cpu_info d1;
|
|
struct sd_cpu_info d2;
|
|
struct sd_cpu_info *d_cur;
|
|
struct sd_cpu_info *d_prev;
|
|
u16 cnt;
|
|
enum sd_cpu_state state;
|
|
};
|
|
|
|
static inline char *sd_cpu_state_str(enum sd_cpu_state state)
|
|
{
|
|
static char *state_str[] = {"UK", "OP", "ST", "DC"};
|
|
|
|
return state_str[(int) state];
|
|
}
|
|
|
|
#define sd_cpu_has_diff(cpu) (cpu->d_prev != NULL)
|
|
#define sd_cpu_diff(cpu, member) (cpu->d_cur->member - cpu->d_prev->member)
|
|
|
|
#define sd_cpu_id(cpu) (cpu->id)
|
|
#define sd_cpu_cnt(cpu) (cpu->cnt)
|
|
#define sd_cpu_type_str(cpu) (cpu->type->id)
|
|
#define sd_cpu_state(cpu) (cpu->state)
|
|
|
|
struct sd_cpu *sd_cpu_get(struct sd_sys *sys, const char *cpu_id);
|
|
struct sd_cpu *sd_cpu_new(struct sd_sys *parent, const char *id,
|
|
const char *type, int cnt);
|
|
|
|
static inline void sd_cpu_state_set(struct sd_cpu *cpu, enum sd_cpu_state state)
|
|
{
|
|
cpu->state = state;
|
|
}
|
|
|
|
static inline void sd_cpu_cpu_time_us_set(struct sd_cpu *cpu, u64 value)
|
|
{
|
|
cpu->d_cur->cpu_time_us = value;
|
|
}
|
|
|
|
static inline void sd_cpu_thread_time_us_set(struct sd_cpu *cpu, u64 value)
|
|
{
|
|
cpu->d_cur->thread_time_us = value;
|
|
}
|
|
|
|
static inline void sd_cpu_mgm_time_us_set(struct sd_cpu *cpu, u64 value)
|
|
{
|
|
cpu->d_cur->mgm_time_us_set = 1;
|
|
cpu->d_cur->mgm_time_us = value;
|
|
}
|
|
|
|
static inline void sd_cpu_wait_time_us_set(struct sd_cpu *cpu, u64 value)
|
|
{
|
|
cpu->d_cur->wait_time_us = value;
|
|
}
|
|
|
|
static inline void sd_cpu_steal_time_us_set(struct sd_cpu *cpu, s64 value)
|
|
{
|
|
cpu->d_cur->steal_time_us = value;
|
|
}
|
|
|
|
static inline void sd_cpu_online_time_us_set(struct sd_cpu *cpu, u64 value)
|
|
{
|
|
cpu->d_cur->online_time_us = value;
|
|
}
|
|
|
|
static inline void sd_cpu_commit(struct sd_cpu *cpu)
|
|
{
|
|
struct sd_sys *parent = cpu->i.parent;
|
|
|
|
cpu->i.active = 1;
|
|
if (parent)
|
|
parent->cpu_cnt_active++;
|
|
}
|
|
|
|
/*
|
|
* Item types
|
|
*/
|
|
enum sd_item_type {
|
|
SD_TYPE_U16,
|
|
SD_TYPE_U32,
|
|
SD_TYPE_U64,
|
|
SD_TYPE_S64,
|
|
SD_TYPE_STR,
|
|
};
|
|
|
|
/*
|
|
* CPU item
|
|
*/
|
|
struct sd_cpu_item {
|
|
struct table_col table_col;
|
|
enum sd_item_type type;
|
|
int offset;
|
|
char *desc;
|
|
int (*fn_set)(struct sd_cpu_item *, struct sd_cpu *);
|
|
u64 (*fn_u64)(struct sd_cpu_item *, struct sd_cpu *);
|
|
s64 (*fn_s64)(struct sd_cpu_item *, struct sd_cpu *);
|
|
char *(*fn_str)(struct sd_cpu_item *, struct sd_cpu *);
|
|
};
|
|
|
|
#define sd_cpu_item_type(x) ((x)->type)
|
|
#define sd_cpu_item_table_col(item) (&(item)->table_col)
|
|
|
|
extern int sd_cpu_item_available(struct sd_cpu_item *item);
|
|
extern int sd_cpu_item_cnt(void);
|
|
|
|
/*
|
|
* Item access functions
|
|
*/
|
|
static inline u64 sd_cpu_item_set(struct sd_cpu_item *item, struct sd_cpu *cpu)
|
|
{
|
|
return (item->fn_set == NULL) ? 1 : item->fn_set(item, cpu);
|
|
}
|
|
|
|
static inline u64 sd_cpu_item_u64(struct sd_cpu_item *item,
|
|
struct sd_cpu *cpu)
|
|
{
|
|
return item->fn_u64(item, cpu);
|
|
}
|
|
|
|
static inline u64 sd_cpu_item_s64(struct sd_cpu_item *item,
|
|
struct sd_cpu *cpu)
|
|
{
|
|
return item->fn_s64(item, cpu);
|
|
}
|
|
|
|
static inline char *sd_cpu_item_str(struct sd_cpu_item *item,
|
|
struct sd_cpu *cpu)
|
|
{
|
|
if (item->fn_str)
|
|
return item->fn_str(item, cpu);
|
|
else
|
|
return ((char *) cpu) + item->offset;
|
|
}
|
|
|
|
/*
|
|
* Predefined CPU items
|
|
*/
|
|
extern struct sd_cpu_item sd_cpu_item_type;
|
|
extern struct sd_cpu_item sd_cpu_item_state;
|
|
extern struct sd_cpu_item sd_cpu_item_cpu_diff;
|
|
extern struct sd_cpu_item sd_cpu_item_core_diff;
|
|
extern struct sd_cpu_item sd_cpu_item_thread_diff;
|
|
extern struct sd_cpu_item sd_cpu_item_mgm_diff;
|
|
extern struct sd_cpu_item sd_cpu_item_wait_diff;
|
|
extern struct sd_cpu_item sd_cpu_item_steal_diff;
|
|
extern struct sd_cpu_item sd_cpu_item_cpu;
|
|
extern struct sd_cpu_item sd_cpu_item_core;
|
|
extern struct sd_cpu_item sd_cpu_item_thread;
|
|
extern struct sd_cpu_item sd_cpu_item_mgm;
|
|
extern struct sd_cpu_item sd_cpu_item_wait;
|
|
extern struct sd_cpu_item sd_cpu_item_steal;
|
|
extern struct sd_cpu_item sd_cpu_item_online;
|
|
|
|
/*
|
|
* System item
|
|
*/
|
|
struct sd_sys_item {
|
|
struct table_col table_col;
|
|
enum sd_item_type type;
|
|
int offset;
|
|
char *desc;
|
|
int info;
|
|
int (*fn_set)(struct sd_sys_item *, struct sd_sys *);
|
|
u64 (*fn_u64)(struct sd_sys_item *, struct sd_sys *);
|
|
s64 (*fn_s64)(struct sd_sys_item *, struct sd_sys *);
|
|
};
|
|
|
|
#define sd_sys_item_table_col(item) (&item->table_col)
|
|
#define sd_sys_item_type(item) (item->type)
|
|
|
|
extern int sd_sys_item_available(struct sd_sys_item *item);
|
|
extern int sd_sys_item_cnt(void);
|
|
|
|
/*
|
|
* Item access functions
|
|
*/
|
|
static inline int sd_sys_item_set(struct sd_sys *sys, struct sd_sys_item *item)
|
|
{
|
|
return (item->fn_set == NULL) ? 1 : item->fn_set(item, sys);
|
|
}
|
|
|
|
static inline u64 sd_sys_item_u64(struct sd_sys *sys,
|
|
struct sd_sys_item *item)
|
|
{
|
|
return item->fn_u64(item, sys);
|
|
}
|
|
|
|
static inline s64 sd_sys_item_s64(struct sd_sys *sys,
|
|
struct sd_sys_item *item)
|
|
{
|
|
return item->fn_s64(item, sys);
|
|
}
|
|
|
|
static inline char *sd_sys_item_str(struct sd_sys *sys,
|
|
struct sd_sys_item *item)
|
|
{
|
|
return ((char *) sys) + item->offset;
|
|
}
|
|
|
|
/*
|
|
* Predefined System items
|
|
*/
|
|
extern struct sd_sys_item sd_sys_item_cpu_cnt;
|
|
extern struct sd_sys_item sd_sys_item_core_cnt;
|
|
extern struct sd_sys_item sd_sys_item_thread_cnt;
|
|
extern struct sd_sys_item sd_sys_item_cpu_oper_cnt;
|
|
extern struct sd_sys_item sd_sys_item_cpu_deconf_cnt;
|
|
extern struct sd_sys_item sd_sys_item_cpu_stop_cnt;
|
|
extern struct sd_sys_item sd_sys_item_cpu_diff;
|
|
extern struct sd_sys_item sd_sys_item_core_diff;
|
|
extern struct sd_sys_item sd_sys_item_thread_diff;
|
|
extern struct sd_sys_item sd_sys_item_mgm_diff;
|
|
extern struct sd_sys_item sd_sys_item_wait_diff;
|
|
extern struct sd_sys_item sd_sys_item_steal_diff;
|
|
|
|
extern struct sd_sys_item sd_sys_item_cpu;
|
|
extern struct sd_sys_item sd_sys_item_core;
|
|
extern struct sd_sys_item sd_sys_item_thread;
|
|
extern struct sd_sys_item sd_sys_item_mgm;
|
|
extern struct sd_sys_item sd_sys_item_wait;
|
|
extern struct sd_sys_item sd_sys_item_steal;
|
|
extern struct sd_sys_item sd_sys_item_online;
|
|
|
|
extern struct sd_sys_item sd_sys_item_mem_max;
|
|
extern struct sd_sys_item sd_sys_item_mem_min;
|
|
extern struct sd_sys_item sd_sys_item_mem_use;
|
|
|
|
extern struct sd_sys_item sd_sys_item_weight_cur;
|
|
extern struct sd_sys_item sd_sys_item_weight_min;
|
|
extern struct sd_sys_item sd_sys_item_weight_max;
|
|
|
|
extern struct sd_sys_item sd_sys_item_os_name;
|
|
|
|
extern struct sd_sys_item sd_sys_item_samples_total;
|
|
extern struct sd_sys_item sd_sys_item_samples_cpu_using;
|
|
|
|
/*
|
|
* Data gatherer backend
|
|
*/
|
|
struct sd_dg {
|
|
void (*update_sys)(void);
|
|
struct sd_cpu_type **cpu_type_vec;
|
|
struct sd_sys_item **sys_item_vec;
|
|
struct sd_sys_item **sys_item_enable_vec;
|
|
struct sd_cpu_item **cpu_item_vec;
|
|
struct sd_cpu_item **cpu_item_enable_vec;
|
|
};
|
|
|
|
void sd_dg_register(struct sd_dg *, int);
|
|
int sd_dg_has_core_data(void);
|
|
|
|
/*
|
|
* Iterators
|
|
*/
|
|
#define sd_sys_iterate(parent, sys) \
|
|
util_list_iterate(&parent->child_list, sys)
|
|
|
|
#define sd_cpu_iterate(parent, cpu) \
|
|
util_list_iterate(&parent->cpu_list, cpu)
|
|
|
|
#define sd_sys_item_iterate(ptr, i) \
|
|
for (i = 0; (ptr = sd.dg->sys_item_vec[i]); i++)
|
|
|
|
#define sd_sys_item_enable_iterate(ptr, i) \
|
|
for (i = 0; (ptr = sd.dg->sys_item_enable_vec[i]); i++)
|
|
|
|
#define sd_cpu_item_iterate(ptr, i) \
|
|
for (i = 0; (ptr = sd.dg->cpu_item_vec[i]); i++)
|
|
|
|
#define sd_cpu_item_enable_iterate(ptr, i) \
|
|
for (i = 0; (ptr = sd.dg->cpu_item_enable_vec[i]); i++)
|
|
|
|
#define sd_cpu_type_iterate(ptr, i) \
|
|
for (i = 0; (ptr = sd.dg->cpu_type_vec[i]); i++)
|
|
|
|
|
|
/*
|
|
* Offset macros
|
|
*/
|
|
#define SD_SYSTEM_OFFSET(x) \
|
|
((unsigned long)(void *)&(((struct sd_sys *) NULL)->x))
|
|
#define SD_CPU_INFO_OFFSET(x) \
|
|
((unsigned long)(void *)&(((struct sd_cpu_info *) NULL)->x))
|
|
|
|
static inline int l_cpu_info_set(struct sd_cpu_info *info, unsigned long offset)
|
|
{
|
|
return (int)*(u64 *)(((char *) info) + offset - 8);
|
|
}
|
|
|
|
static inline u64 l_cpu_info_u64(struct sd_cpu_info *info,
|
|
unsigned long offset)
|
|
{
|
|
return *(u64 *)(((char *) info) + offset);
|
|
}
|
|
|
|
static inline s64 l_cpu_info_s64(struct sd_cpu_info *info,
|
|
unsigned long offset)
|
|
{
|
|
return *(s64 *)(((char *) info) + offset);
|
|
}
|
|
|
|
/*
|
|
* Misc
|
|
*/
|
|
void sd_update(void);
|
|
extern void sd_init(void);
|
|
|
|
static inline u64 l_sub_64(u64 x, u64 y)
|
|
{
|
|
return x < y ? 0 : x - y;
|
|
}
|
|
|
|
struct sd_globals {
|
|
struct sd_dg *dg;
|
|
};
|
|
|
|
extern struct sd_globals sd;
|
|
|
|
#endif /* SD_H */
|