linux-stable/tools/perf/util/header.h
Kan Liang 2bb00d2f95 perf tools: Store the cpu socket and core ids in the perf.data header
This patch stores the cpu socket_id and core_id in a perf.data header,
and reads them into the perf_env struct when processing perf.data files.

The changes modifies the CPU_TOPOLOGY section, making sure it is
backward/forward compatible.

The patch checks the section size before reading the core and socket ids.

It never reads data crossing the section boundary.  An old perf binary
without this patch can also correctly read the perf.data from a new perf
with this patch.

Because the new info is added at the end of the cpu_topology section, an
old perf tool ignores the extra data.

Examples:

1. New perf with this patch read perf.data from an old perf without the
   patch:

  $ perf_new report -i perf_old.data --header-only -I
  ......
  # sibling threads : 33
  # sibling threads : 34
  # sibling threads : 35
  # Core ID and Socket ID information is not available
  # node0 meminfo  : total = 32823872 kB, free = 29315548 kB
  # node0 cpu list : 0-17,36-53
  ......

2. Old perf without the patch reads perf.data from a new perf with the
   patch:

  $ perf_old report -i perf_new.data --header-only -I
  ......
  # sibling threads : 33
  # sibling threads : 34
  # sibling threads : 35
  # node0 meminfo  : total = 32823872 kB, free = 29190932 kB
  # node0 cpu list : 0-17,36-53
  ......

3. New perf read new perf.data:

  $ perf_new report -i perf_new.data --header-only -I
  ......
  # sibling threads : 33
  # sibling threads : 34
  # sibling threads : 35
  # CPU 0: Core ID 0, Socket ID 0
  # CPU 1: Core ID 1, Socket ID 0
  ......
  # CPU 61: Core ID 10, Socket ID 1
  # CPU 62: Core ID 11, Socket ID 1
  # CPU 63: Core ID 16, Socket ID 1
  # node0 meminfo  : total = 32823872 kB, free = 29190932 kB
  # node0 cpu list : 0-17,36-53

Signed-off-by: Kan Liang <kan.liang@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Link: http://lkml.kernel.org/r/1441115893-22006-2-git-send-email-kan.liang@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-09-02 16:30:47 -03:00

167 lines
4 KiB
C

#ifndef __PERF_HEADER_H
#define __PERF_HEADER_H
#include <linux/perf_event.h>
#include <sys/types.h>
#include <stdbool.h>
#include <linux/bitmap.h>
#include <linux/types.h>
#include "event.h"
enum {
HEADER_RESERVED = 0, /* always cleared */
HEADER_FIRST_FEATURE = 1,
HEADER_TRACING_DATA = 1,
HEADER_BUILD_ID,
HEADER_HOSTNAME,
HEADER_OSRELEASE,
HEADER_VERSION,
HEADER_ARCH,
HEADER_NRCPUS,
HEADER_CPUDESC,
HEADER_CPUID,
HEADER_TOTAL_MEM,
HEADER_CMDLINE,
HEADER_EVENT_DESC,
HEADER_CPU_TOPOLOGY,
HEADER_NUMA_TOPOLOGY,
HEADER_BRANCH_STACK,
HEADER_PMU_MAPPINGS,
HEADER_GROUP_DESC,
HEADER_AUXTRACE,
HEADER_LAST_FEATURE,
HEADER_FEAT_BITS = 256,
};
enum perf_header_version {
PERF_HEADER_VERSION_1,
PERF_HEADER_VERSION_2,
};
struct perf_file_section {
u64 offset;
u64 size;
};
struct perf_file_header {
u64 magic;
u64 size;
u64 attr_size;
struct perf_file_section attrs;
struct perf_file_section data;
/* event_types is ignored */
struct perf_file_section event_types;
DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS);
};
struct perf_pipe_file_header {
u64 magic;
u64 size;
};
struct perf_header;
int perf_file_header__read(struct perf_file_header *header,
struct perf_header *ph, int fd);
struct cpu_topology_map {
int socket_id;
int core_id;
};
struct perf_env {
char *hostname;
char *os_release;
char *version;
char *arch;
int nr_cpus_online;
int nr_cpus_avail;
char *cpu_desc;
char *cpuid;
unsigned long long total_mem;
int nr_cmdline;
int nr_sibling_cores;
int nr_sibling_threads;
int nr_numa_nodes;
int nr_pmu_mappings;
int nr_groups;
char *cmdline;
const char **cmdline_argv;
char *sibling_cores;
char *sibling_threads;
char *numa_nodes;
char *pmu_mappings;
struct cpu_topology_map *cpu;
};
struct perf_header {
enum perf_header_version version;
bool needs_swap;
u64 data_offset;
u64 data_size;
u64 feat_offset;
DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS);
struct perf_env env;
};
struct perf_evlist;
struct perf_session;
int perf_session__read_header(struct perf_session *session);
int perf_session__write_header(struct perf_session *session,
struct perf_evlist *evlist,
int fd, bool at_exit);
int perf_header__write_pipe(int fd);
void perf_header__set_feat(struct perf_header *header, int feat);
void perf_header__clear_feat(struct perf_header *header, int feat);
bool perf_header__has_feat(const struct perf_header *header, int feat);
int perf_header__set_cmdline(int argc, const char **argv);
int perf_header__process_sections(struct perf_header *header, int fd,
void *data,
int (*process)(struct perf_file_section *section,
struct perf_header *ph,
int feat, int fd, void *data));
int perf_header__fprintf_info(struct perf_session *s, FILE *fp, bool full);
int perf_event__synthesize_attr(struct perf_tool *tool,
struct perf_event_attr *attr, u32 ids, u64 *id,
perf_event__handler_t process);
int perf_event__synthesize_attrs(struct perf_tool *tool,
struct perf_session *session,
perf_event__handler_t process);
int perf_event__process_attr(struct perf_tool *tool, union perf_event *event,
struct perf_evlist **pevlist);
int perf_event__synthesize_tracing_data(struct perf_tool *tool,
int fd, struct perf_evlist *evlist,
perf_event__handler_t process);
int perf_event__process_tracing_data(struct perf_tool *tool,
union perf_event *event,
struct perf_session *session);
int perf_event__synthesize_build_id(struct perf_tool *tool,
struct dso *pos, u16 misc,
perf_event__handler_t process,
struct machine *machine);
int perf_event__process_build_id(struct perf_tool *tool,
union perf_event *event,
struct perf_session *session);
bool is_perf_magic(u64 magic);
#define NAME_ALIGN 64
int write_padded(int fd, const void *bf, size_t count, size_t count_aligned);
/*
* arch specific callback
*/
int get_cpuid(char *buffer, size_t sz);
#endif /* __PERF_HEADER_H */