perf tools: Assorted fixes
Jiri Olsa
reviewerv2 cover perf tools: Assorted fixes
hi,
sending assorted general fixes that queued
up in my other branches.
v2 changes:
- renamed the interface to struct cpu_topology/numa_topology plus related changes in function names
- adding missing Fixes tag
Also available in here:
https://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
perf/fixes
thanks,
jirka
---
Jiri Olsa (3):
perf header: Fix wrong node write in NUMA_TOPOLOGY feature perf tools: Add cpu_topology object
perf tools: Add numa_topology object
tools/perf/util/Build | 1 + tools/perf/util/cputopo.c | 264 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/cputopo.h | 33 ++++++++++++++++++++++ tools/perf/util/header.c | 269 ++++++++++++++++++++-------------------------------------------------------------------------------------------------------------------------------------------------------------- 4 files changed, 328 insertions(+), 239 deletions(-) create mode 100644 tools/perf/util/cputopo.c create mode 100644 tools/perf/util/cputopo.h
Jiri Olsa
reviewerPATCH v2 1/3 perf header: Fix wrong node write in NUMA_TOPOLOGY feature
We are currently passing the node index instead of the real node number.
--- tools/perf/util/header.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/header.c +1 -1
@@ -879,7 +879,7 @@ static int write_numa_topology(struct feat_fd *ff,if (ret <0 )break ; - ret =write_topo_node (ff, i); + ret =write_topo_node (ff, j);if (ret <0 )break ; }
Signature · 1 line
2.17.2
Jiri Olsa
reviewerPATCH v2 2/3 perf tools: Add cpu_topology object
In reply to Jiri OlsaMaking struct cpu_topo global and renaming it to struct cpu_topology, so it can be used from record command in following patches.
Adding following interface functions to load/free cpu topology details:
struct cpu_topology *cpu_topology__new(void); void cpu_topology__delete(struct cpu_topology *tp);
Moving it into separate object file cputopo.c together with numa related object in following patches.
No functional change, the new interface will be used in upcoming changes.
--- tools/perf/util/Build | 1 + tools/perf/util/cputopo.c | 144 ++++++++++++++++++++++++++++++++++++ tools/perf/util/cputopo.h | 17 +++++ tools/perf/util/header.c | 150 +------------------------------------- 4 files changed, 166 insertions(+), 146 deletions(-) create mode 100644 tools/perf/util/cputopo.c create mode 100644 tools/perf/util/cputopo.h
tools/perf/util/Build +1 -0
@@ -69,6 +69,7 @@ perf-y += hist.o perf-y += util.o perf-y += xyarray.o perf-y += cpumap.o +perf-y += cputopo.o perf-y += cgroup.o perf-y += target.o perf-y += rblist.o
tools/perf/util/cputopo.c new file +144 -0
144 lines not on this page · raw message
tools/perf/util/cputopo.h new file +17 -0
@@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_CPUTOPO_H +#define __PERF_CPUTOPO_H + +#include <linux/types.h> + +struct cpu_topology { +u32 core_sib; +u32 thread_sib; +char **core_siblings; +char **thread_siblings; +}; + +struct cpu_topology *cpu_topology__new (void ); +void cpu_topology__delete (struct cpu_topology *tp); + +#endif /* __PERF_CPUTOPO_H */
tools/perf/util/header.c +4 -146
175 lines not on this page · raw message
Signature · 1 line
2.17.2
Jiri Olsa
reviewerPATCH v2 3/3 perf tools: Add numa_topology object
In reply to Jiri OlsaAdding numa_topology object to return the list of numa nodes together with their cpus. It will replace the numa code in header.c and will be used from perf record code in following patches.
Adding following interface functions to load numa details:
struct numa_topology *numa_topology__new(void); void numa_topology__delete(struct numa_topology *tp);
And replacing current (copied) local interface, with no functional changes.
--- tools/perf/util/cputopo.c | 120 ++++++++++++++++++++++++++++++++++++++ tools/perf/util/cputopo.h | 16 +++++ tools/perf/util/header.c | 119 +++++++++---------------------------- 3 files changed, 162 insertions(+), 93 deletions(-)
tools/perf/util/cputopo.c +120 -0
@@ -1,9 +1,11 @@// SPDX-License-Identifier: GPL-2.0 #include <sys/param.h> +#include <inttypes.h> #include "cputopo.h" #include "cpumap.h" #include "util.h" +#include "env.h" #define CORE_SIB_FMT \
@@ -142,3 +144,121 @@ struct cpu_topology *cpu_topology__new(void) }return tp; } + +static int load_numa_node (struct numa_topology_node *node,int nr) +{ +char str[MAXPATHLEN ]; +char field[32 ]; +char *buf =NULL , *p; +size_t len =0 ; +int ret =-1 ; +FILE *fp; +u64 mem; + + node->node = (u32 ) nr; + +sprintf (str,"/sys/devices/system/node/node%d/meminfo" , nr); + fp =fopen (str,"r" ); +if (!fp) +return -1 ; + +while (getline (&buf, &len, fp) >0 ) { +/* skip over invalid lines */ +if (!strchr (buf,':' )) +continue ; +if (sscanf (buf,"%*s %*d %31s %" PRIu64, field, &mem) !=2 ) + goto err; +if (!strcmp (field,"MemTotal:" )) + node->mem_total = mem; +if (!strcmp (field,"MemFree:" )) + node->mem_free = mem; +if (node->mem_total && node->mem_free) +break ; + } + +fclose (fp); + fp =NULL ; + buf =NULL ; + + ret =-1 ; +sprintf (str,"/sys/devices/system/node/node%d/cpulist" , nr); + + fp =fopen (str,"r" ); +if (!fp) +return -1 ; + +if (getline (&buf, &len, fp) <=0 ) + goto err; + + p =strchr (buf,'\n' ); +if (p) + *p ='\0' ; + + node->cpus = buf; +fclose (fp); +return 0 ; + +err: +free (buf); +if (fp) +fclose (fp); +return ret; +} + +struct numa_topology *numa_topology__new (void ) +{ +struct cpu_map *node_map =NULL ; +struct numa_topology *tp =NULL ; +char *buf =NULL ; +size_t len =0 ; +u32 nr, i; +FILE *fp; +char *c; + + fp =fopen ("/sys/devices/system/node/online" ,"r" ); +if (!fp) +return NULL ; + +if (getline (&buf, &len, fp) <=0 ) + goto out; + + c =strchr (buf,'\n' ); +if (c) + *c ='\0' ; + + node_map =cpu_map__new (buf); +if (!node_map) + goto out; + + nr = (u32 ) node_map->nr; + + tp =zalloc (sizeof (*tp) +sizeof (tp->nodes[0 ])*nr); +if (!tp) + goto out; + + tp->nr = nr; + +for (i =0 ; i < nr; i++) { +if (load_numa_node (&tp->nodes[i], node_map->map[i])) { +numa_topology__delete (tp); + tp =NULL ; +break ; + } + } + +out: +free (buf); +fclose (fp); +cpu_map__put (node_map); +return tp; +} + +void numa_topology__delete (struct numa_topology *tp) +{ +u32 i; + +for (i =0 ; i < tp->nr; i++) +free (tp->nodes[i].cpus); + +free (tp); +}
tools/perf/util/cputopo.h +16 -0
@@ -3,6 +3,7 @@#define __PERF_CPUTOPO_H#include <linux/types.h> +#include "env.h" struct cpu_topology {u32 core_sib;
@@ -11,7 +12,22 @@ struct cpu_topology { char **thread_siblings; }; +struct numa_topology_node { +char *cpus; +u32 node; +u64 mem_total; +u64 mem_free; +}; + +struct numa_topology { +u32 nr; +struct numa_topology_node nodes[0 ]; +}; +struct cpu_topology *cpu_topology__new (void );void cpu_topology__delete (struct cpu_topology *tp); +struct numa_topology *numa_topology__new (void ); +void numa_topology__delete (struct numa_topology *tp); +#endif /* __PERF_CPUTOPO_H */
tools/perf/util/header.c +26 -93
138 lines not on this page · raw message
Signature · 1 line
2.17.2
Namhyung Kim
maintainerRe: [PATCH 3/3] perf tools: Add numa_topology object
Hi Jirka,
Quoted 46 lines · Jiri Olsa
Adding
numa_topologyobject to return the list of numa nodes together with their cpus. It will replace the numa code inheader.cand will be used from perf record code in following patches.Adding following interface functions to load numa details:
struct numa_topology *numa_topology__new(void); void numa_topology__delete(struct numa_topology *tp);And replacing current (copied) local interface, with no functional changes.
Signed-off-by Jiri Olsa <[email protected]>--- tools/perf/util/cputopo.c | 120 ++++++++++++++++++++++++++++++++++++++ tools/perf/util/cputopo.h | 16 +++++ tools/perf/util/header.c | 119 +++++++++---------------------------- 3 files changed, 162 insertions(+), 93 deletions(-)tools/perf/util/cputopo.c +6
-0@@ -1,9 +1,11 @@// SPDX-License-Identifier: GPL-2.0 #include <sys/param.h> +#include <inttypes.h> #include "cputopo.h" #include "cpumap.h" #include "util.h" +#include "env.h" #define CORE_SIB_FMT \@@ -142,3 +144,121 @@ struct cpu_topology *cpu_topology__new(void) }return tp; } + +static int load_numa_node (struct numa_topology_node *node,int nr) +{ +char str[MAXPATHLEN ];
tools/perf/util/cputopo.c struct cpu_topology *cpu_topology__new(void) · line 160
Quoted 10 lines
tools/perf/util/cputopo.c +10
-0+char field[32 ]; +char *buf =NULL , *p; +size_t len =0 ; +int ret =-1 ; +FILE *fp; +u64 mem; + + node->node = (u32 ) nr; + +sprintf (str,"/sys/devices/system/node/node%d/meminfo" , nr);
Why not using similar macro like NODE_MEMINFO_FMT? Also it'd be better using snprintf() or scnprintf() instead.
Quoted 11 lines
tools/perf/util/cputopo.c +11
-0+ fp =fopen (str,"r" ); +if (!fp) +return -1 ; + +while (getline (&buf, &len, fp) >0 ) { +/* skip over invalid lines */ +if (!strchr (buf,':' )) +continue ; +if (sscanf (buf,"%*s %*d %31s %" PRIu64, field, &mem) !=2 ) + goto err; +if (!strcmp (field,"MemTotal:" ))
tools/perf/util/cputopo.c struct cpu_topology *cpu_topology__new(void) · line 181
Quoted 10 lines
tools/perf/util/cputopo.c +10
-0+ node->mem_total = mem; +if (!strcmp (field,"MemFree:" )) + node->mem_free = mem; +if (node->mem_total && node->mem_free) +break ; + } + +fclose (fp); + fp =NULL ; + buf =NULL ;
No need to make them NULL. Also it'd leak buf..
tools/perf/util/cputopo.c struct cpu_topology *cpu_topology__new(void) · line 183
Quoted 2 lines
tools/perf/util/cputopo.c +2
-0+ + ret =-1 ;
It's not changed yet.
Thanks,
Namhyung
Quoted 262 lines
tools/perf/util/cputopo.c +81
-0+sprintf (str,"/sys/devices/system/node/node%d/cpulist" , nr); + + fp =fopen (str,"r" ); +if (!fp) +return -1 ; + +if (getline (&buf, &len, fp) <=0 ) + goto err; + + p =strchr (buf,'\n' ); +if (p) + *p ='\0' ; + + node->cpus = buf; +fclose (fp); +return 0 ; + +err: +free (buf); +if (fp) +fclose (fp); +return ret; +} + +struct numa_topology *numa_topology__new (void ) +{ +struct cpu_map *node_map =NULL ; +struct numa_topology *tp =NULL ; +char *buf =NULL ; +size_t len =0 ; +u32 nr, i; +FILE *fp; +char *c; + + fp =fopen ("/sys/devices/system/node/online" ,"r" ); +if (!fp) +return NULL ; + +if (getline (&buf, &len, fp) <=0 ) + goto out; + + c =strchr (buf,'\n' ); +if (c) + *c ='\0' ; + + node_map =cpu_map__new (buf); +if (!node_map) + goto out; + + nr = (u32 ) node_map->nr; + + tp =zalloc (sizeof (*tp) +sizeof (tp->nodes[0 ])*nr); +if (!tp) + goto out; + + tp->nr = nr; + +for (i =0 ; i < nr; i++) { +if (load_numa_node (&tp->nodes[i], node_map->map[i])) { +numa_topology__delete (tp); + tp =NULL ; +break ; + } + } + +out: +free (buf); +fclose (fp); +cpu_map__put (node_map); +return tp; +} + +void numa_topology__delete (struct numa_topology *tp) +{ +u32 i; + +for (i =0 ; i < tp->nr; i++) +free (tp->nodes[i].cpus); + +free (tp); +}tools/perf/util/cputopo.h +16
-0@@ -3,6 +3,7 @@#define __PERF_CPUTOPO_H#include <linux/types.h> +#include "env.h" struct cpu_topology {u32 core_sib;@@ -11,7 +12,22 @@ struct cpu_topology { char **thread_siblings; }; +struct numa_topology_node { +char *cpus; +u32 node; +u64 mem_total; +u64 mem_free; +}; + +struct numa_topology { +u32 nr; +struct numa_topology_node nodes[0 ]; +}; +struct cpu_topology *cpu_topology__new (void );void cpu_topology__delete (struct cpu_topology *tp); +struct numa_topology *numa_topology__new (void ); +void numa_topology__delete (struct numa_topology *tp); +#endif /* __PERF_CPUTOPO_H */ tools/perf/util/header.c +26
-94@@ -639,112 +639,45 @@ static int write_total_mem(struct feat_fd *ff,return ret; } -static int write_topo_node (struct feat_fd *ff,int node) -{ -char str[MAXPATHLEN ]; -char field[32 ]; -char *buf =NULL , *p; -size_t len =0 ; -FILE *fp; -u64 mem_total, mem_free, mem; -int ret =-1 ; - -sprintf (str,"/sys/devices/system/node/node%d/meminfo" , node); - fp =fopen (str,"r" ); -if (!fp) -return -1 ; - -while (getline (&buf, &len, fp) >0 ) { -/* skip over invalid lines */ -if (!strchr (buf,':' )) -continue ; -if (sscanf (buf,"%*s %*d %31s %" PRIu64, field, &mem) !=2 ) - goto done; -if (!strcmp (field,"MemTotal:" )) - mem_total = mem; -if (!strcmp (field,"MemFree:" )) - mem_free = mem; - } - -fclose (fp); - fp =NULL ; - - ret =do_write (ff, &mem_total,sizeof (u64)); -if (ret) - goto done; - - ret =do_write (ff, &mem_free,sizeof (u64)); -if (ret) - goto done; - - ret =-1 ; -sprintf (str,"/sys/devices/system/node/node%d/cpulist" , node); - - fp =fopen (str,"r" ); -if (!fp) - goto done; - -if (getline (&buf, &len, fp) <=0 ) - goto done; - - p =strchr (buf,'\n' ); -if (p) - *p ='\0' ; - - ret =do_write_string (ff, buf); -done: -free (buf); -if (fp) -fclose (fp); -return ret; -} -static int write_numa_topology (struct feat_fd *ff,struct perf_evlist *evlist__maybe_unused ) { -char *buf =NULL ; -size_t len =0 ; -FILE *fp; -struct cpu_map *node_map =NULL ; -char *c; -u32 nr, i, j; +struct numa_topology *tp;int ret =-1 ; +u32 i; - fp =fopen ("/sys/devices/system/node/online" ,"r" ); -if (!fp) -return -1 ; + tp =numa_topology__new (); +if (!tp) +return -ENOMEM ; -if (getline (&buf, &len, fp) <=0 ) - goto done; + ret =do_write (ff, &tp->nr,sizeof (u32)); +if (ret <0 ) + goto err; - c =strchr (buf,'\n' ); -if (c) - *c ='\0' ; +for (i =0 ; i < tp->nr; i++) { +struct numa_topology_node *n = &tp->nodes[i]; - node_map =cpu_map__new (buf); -if (!node_map) - goto done; - - nr = (u32 )node_map->nr; + ret =do_write (ff, &n->node,sizeof (u32)); +if (ret <0 ) + goto err; - ret =do_write (ff, &nr,sizeof (nr)); -if (ret <0 ) - goto done; + ret =do_write (ff, &n->mem_total,sizeof (u64)); +if (ret) + goto err; -for (i =0 ; i < nr; i++) { - j = (u32 )node_map->map[i]; - ret =do_write (ff, &j,sizeof (j)); -if (ret <0 ) -break ; + ret =do_write (ff, &n->mem_free,sizeof (u64)); +if (ret) + goto err; - ret =write_topo_node (ff, j); + ret =do_write_string (ff, n->cpus);if (ret <0 ) -break ; + goto err; } -done: -free (buf); -fclose (fp); -cpu_map__put (node_map); + + ret =0 ; + +err: +numa_topology__delete (tp);return ret; } --2.17.2
Signature · 2 lines
Thanks, Namhyung
Re: [PATCH 3/3] perf tools: Add numa_topology object
Quoted 54 lines · Namhyung Kim
Hi Jirka,
Quoted 51 lines · Jiri Olsa
Adding
numa_topologyobject to return the list of numa nodes together with their cpus. It will replace the numa code inheader.cand will be used from perf record code in following patches.Adding following interface functions to load numa details:
struct numa_topology *numa_topology__new(void); void numa_topology__delete(struct numa_topology *tp);And replacing current (copied) local interface, with no functional changes.
Signed-off-by Jiri Olsa <[email protected]>--- tools/perf/util/cputopo.c | 120 ++++++++++++++++++++++++++++++++++++++ tools/perf/util/cputopo.h | 16 +++++ tools/perf/util/header.c | 119 +++++++++---------------------------- 3 files changed, 162 insertions(+), 93 deletions(-)tools/perf/util/cputopo.c +11
-0@@ -1,9 +1,11 @@// SPDX-License-Identifier: GPL-2.0 #include <sys/param.h> +#include <inttypes.h> #include "cputopo.h" #include "cpumap.h" #include "util.h" +#include "env.h" #define CORE_SIB_FMT \@@ -142,3 +144,121 @@ struct cpu_topology *cpu_topology__new(void) }return tp; } + +static int load_numa_node (struct numa_topology_node *node,int nr) +{ +char str[MAXPATHLEN ]; +char field[32 ]; +char *buf =NULL , *p; +size_t len =0 ; +int ret =-1 ; +FILE *fp;
Quoted 8 lines
tools/perf/util/cputopo.c struct cpu_topology *cpu_topology__new(void) · line 160
Quoted 5 lines
tools/perf/util/cputopo.c +5
-0+u64 mem; + + node->node = (u32 ) nr; + +sprintf (str,"/sys/devices/system/node/node%d/meminfo" , nr);Why not using similar macro like
NODE_MEMINFO_FMT? Also it'd be better usingsnprintf()orscnprintf()instead.
right, that code needs to be changed to take /sys from sysfs__mountpoint
but I wanted just to move the code now, with only necessary changes, like the issues you found below ;-)
Quoted 17 lines
Quoted 17 lines
tools/perf/util/cputopo.c +15
-0+ fp =fopen (str,"r" ); +if (!fp) +return -1 ; + +while (getline (&buf, &len, fp) >0 ) { +/* skip over invalid lines */ +if (!strchr (buf,':' )) +continue ; +if (sscanf (buf,"%*s %*d %31s %" PRIu64, field, &mem) !=2 ) + goto err; +if (!strcmp (field,"MemTotal:" )) + node->mem_total = mem; +if (!strcmp (field,"MemFree:" )) + node->mem_free = mem; +if (node->mem_total && node->mem_free)
Quoted 8 lines
tools/perf/util/cputopo.c struct cpu_topology *cpu_topology__new(void) · line 181
Quoted 6 lines
tools/perf/util/cputopo.c +6
-0+break ; + } + +fclose (fp); + fp =NULL ; + buf =NULL ;No need to make them NULL. Also it'd leak buf..
oops, I'll put free in here
Quoted 6 lines
tools/perf/util/cputopo.c struct cpu_topology *cpu_topology__new(void) · line 183
Quoted 4 lines
tools/perf/util/cputopo.c +2
-0+ + ret =-1 ;It's not changed yet.
right, will change
thanks,
jirka