From 147dda2e5e80203cec822fed13a97e3e1531cbaf Mon Sep 17 00:00:00 2001 From: glebius Date: Wed, 10 Apr 2013 20:26:53 +0000 Subject: o Provide function kvm_read_zpcpu() to access UMA_ZONE_PCPU allocations. o Provide function kvm_counter_u64_fetch() to fetch valut of a counter(9). Sponsored by: Nginx, Inc. --- lib/libkvm/Makefile | 6 ++++-- lib/libkvm/kvm.h | 2 ++ lib/libkvm/kvm_getpcpu.3 | 37 +++++++++++++++++++++++++++++++++-- lib/libkvm/kvm_pcpu.c | 51 +++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 89 insertions(+), 7 deletions(-) (limited to 'lib/libkvm') diff --git a/lib/libkvm/Makefile b/lib/libkvm/Makefile index 1250bf7..bf6424b 100644 --- a/lib/libkvm/Makefile +++ b/lib/libkvm/Makefile @@ -25,8 +25,10 @@ MAN= kvm.3 kvm_getcptime.3 kvm_geterr.3 kvm_getfiles.3 kvm_getloadavg.3 \ kvm_getpcpu.3 kvm_getprocs.3 kvm_getswapinfo.3 kvm_nlist.3 kvm_open.3 \ kvm_read.3 -MLINKS+=kvm_getpcpu.3 kvm_getmaxcpu.3 -MLINKS+=kvm_getpcpu.3 kvm_dpcpu_setcpu.3 +MLINKS+=kvm_getpcpu.3 kvm_getmaxcpu.3 \ + kvm_getpcpu.3 kvm_dpcpu_setcpu.3 \ + kvm_getpcpu.3 kvm_read_zpcpu.3 \ + kvm_getpcpu.3 kvm_counter_u64_fetch MLINKS+=kvm_getprocs.3 kvm_getargv.3 kvm_getprocs.3 kvm_getenvv.3 MLINKS+=kvm_open.3 kvm_close.3 kvm_open.3 kvm_openfiles.3 MLINKS+=kvm_read.3 kvm_write.3 diff --git a/lib/libkvm/kvm.h b/lib/libkvm/kvm.h index 912f1d4..2584f91 100644 --- a/lib/libkvm/kvm.h +++ b/lib/libkvm/kvm.h @@ -78,6 +78,7 @@ char *kvm_getfiles(kvm_t *, int, int, int *); int kvm_getloadavg(kvm_t *, double [], int); int kvm_getmaxcpu(kvm_t *); void *kvm_getpcpu(kvm_t *, int); +uint64_t kvm_counter_u64_fetch(kvm_t *, u_long); struct kinfo_proc * kvm_getprocs(kvm_t *, int, int, int *); int kvm_getswapinfo(kvm_t *, struct kvm_swap *, int, int); @@ -87,6 +88,7 @@ kvm_t *kvm_open kvm_t *kvm_openfiles (const char *, const char *, const char *, int, char *); ssize_t kvm_read(kvm_t *, unsigned long, void *, size_t); +ssize_t kvm_read_zpcpu(kvm_t *, void *, u_long, size_t, int); ssize_t kvm_uread (kvm_t *, const struct kinfo_proc *, unsigned long, char *, size_t); ssize_t kvm_write(kvm_t *, unsigned long, const void *, size_t); diff --git a/lib/libkvm/kvm_getpcpu.3 b/lib/libkvm/kvm_getpcpu.3 index 1e0c1f4..ac02fe1 100644 --- a/lib/libkvm/kvm_getpcpu.3 +++ b/lib/libkvm/kvm_getpcpu.3 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 28, 2010 +.Dd April 11, 2013 .Dt KVM_GETPCPU 3 .Os .Sh NAME @@ -49,6 +49,10 @@ .Fn kvm_getmaxcpu "kvm_t *kd" .Ft void * .Fn kvm_getpcpu "kvm_t *kd" "int cpu" +.Ft ssize_t +.Fn kvm_read_zpcpu "kvm_t *kd" "void *buf" "u_long base" "size_t size" "int cpu" +.Ft uint64_t +.Fn kvm_counter_u64_fetch "kvm_t *kd" "u_long base" .Sh DESCRIPTION The .Fn kvm_dpcpu_setcpu , @@ -83,6 +87,28 @@ is not active, then .Dv NULL is returned instead. .Pp +The +.Fn kvm_read_zpcpu +function is used to obtain private per-CPU copy from a +.Dv UMA_ZONE_PCPU +.Xr zone 9 . +It takes +.Fa base +argument as base address of an allocation and copyies +.Fa size +bytes into +.Fa buf +from the part of allocation that is private to +.Fa cpu . +.Pp +The +.Fn kvm_counter_u64_fetch +function fetches value of a +.Xr counter 9 +pointed by +.Fa base +address. +.Pp Symbols for dynamic per-CPU data are accessed via .Xr kvm_nlist 3 as with other symbols. @@ -122,9 +148,16 @@ On success, the .Fn kvm_dpcpu_setcpu call returns 0; if an error occurs, it returns -1 instead. .Pp +On success, the +.Fn kvm_read_zpcpu +function returns number of bytes copied. +If an error occurs, it returns -1 instead. +.Pp If any function encounters an error, then an error message may be retrieved via .Xr kvm_geterr 3 . .Sh SEE ALSO .Xr free 3 , -.Xr kvm 3 +.Xr kvm 3 , +.Xr counter 9 , +.Xr zone 9 diff --git a/lib/libkvm/kvm_pcpu.c b/lib/libkvm/kvm_pcpu.c index d7108b4..2d7fb41 100644 --- a/lib/libkvm/kvm_pcpu.c +++ b/lib/libkvm/kvm_pcpu.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2013 Gleb Smirnoff * Copyright (c) 2010 Juniper Networks, Inc. * Copyright (c) 2009 Robert N. M. Watson * Copyright (c) 2009 Bjoern A. Zeeb @@ -50,8 +51,12 @@ __FBSDID("$FreeBSD$"); static struct nlist kvm_pcpu_nl[] = { { .n_name = "_cpuid_to_pcpu" }, { .n_name = "_mp_maxcpus" }, + { .n_name = "_mp_ncpus" }, { .n_name = NULL }, }; +#define NL_CPUID_TO_PCPU 0 +#define NL_MP_MAXCPUS 1 +#define NL_MP_NCPUS 2 /* * Kernel per-CPU data state. We cache this stuff on the first @@ -63,9 +68,7 @@ static struct nlist kvm_pcpu_nl[] = { */ static void **pcpu_data; static int maxcpu; - -#define NL_CPUID_TO_PCPU 0 -#define NL_MP_MAXCPUS 1 +static int mp_ncpus; static int _kvm_pcpu_init(kvm_t *kd) @@ -89,6 +92,15 @@ _kvm_pcpu_init(kvm_t *kd) _kvm_err(kd, kd->program, "cannot read mp_maxcpus"); return (-1); } + if (kvm_pcpu_nl[NL_MP_NCPUS].n_value == 0) { + _kvm_err(kd, kd->program, "unable to find mp_ncpus"); + return (-1); + } + if (kvm_read(kd, kvm_pcpu_nl[NL_MP_NCPUS].n_value, &mp_ncpus, + sizeof(mp_ncpus)) != sizeof(mp_ncpus)) { + _kvm_err(kd, kd->program, "cannot read mp_ncpus"); + return (-1); + } len = max * sizeof(void *); data = malloc(len); if (data == NULL) { @@ -289,3 +301,36 @@ kvm_dpcpu_setcpu(kvm_t *kd, u_int cpu) return (_kvm_dpcpu_setcpu(kd, cpu, 1)); } + +/* + * Obtain a per-CPU copy for given cpu from UMA_ZONE_PCPU allocation. + */ +ssize_t +kvm_read_zpcpu(kvm_t *kd, void *buf, u_long base, size_t size, int cpu) +{ + + return (kvm_read(kd, (uintptr_t)(base + sizeof(struct pcpu) * cpu), + buf, size)); +} + +/* + * Fetch value of a counter(9). + */ +uint64_t +kvm_counter_u64_fetch(kvm_t *kd, u_long base) +{ + uint64_t r, c; + + if (mp_ncpus == 0) + if (_kvm_pcpu_init(kd) < 0) + return (0); + + r = 0; + for (int i = 0; i < mp_ncpus; i++) { + if (kvm_read_zpcpu(kd, &c, base, sizeof(c), i) != sizeof(c)) + return (0); + r += c; + } + + return (r); +} -- cgit v1.1 From b832dcf87e792d42ee4017a314d2cba7c1cb14d3 Mon Sep 17 00:00:00 2001 From: glebius Date: Thu, 11 Apr 2013 07:30:49 +0000 Subject: Include types.h for C99 uintXX_t types. --- lib/libkvm/kvm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/libkvm') diff --git a/lib/libkvm/kvm.h b/lib/libkvm/kvm.h index 2584f91..43b0551 100644 --- a/lib/libkvm/kvm.h +++ b/lib/libkvm/kvm.h @@ -34,7 +34,7 @@ #define _KVM_H_ #include -#include +#include #include /* Default version symbol. */ -- cgit v1.1 From a54e9276b36bb9bfc19f345cc226f68d514948ab Mon Sep 17 00:00:00 2001 From: glebius Date: Thu, 11 Apr 2013 10:14:28 +0000 Subject: Fix typo. --- lib/libkvm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/libkvm') diff --git a/lib/libkvm/Makefile b/lib/libkvm/Makefile index bf6424b..5b5ad43 100644 --- a/lib/libkvm/Makefile +++ b/lib/libkvm/Makefile @@ -28,7 +28,7 @@ MAN= kvm.3 kvm_getcptime.3 kvm_geterr.3 kvm_getfiles.3 kvm_getloadavg.3 \ MLINKS+=kvm_getpcpu.3 kvm_getmaxcpu.3 \ kvm_getpcpu.3 kvm_dpcpu_setcpu.3 \ kvm_getpcpu.3 kvm_read_zpcpu.3 \ - kvm_getpcpu.3 kvm_counter_u64_fetch + kvm_getpcpu.3 kvm_counter_u64_fetch.3 MLINKS+=kvm_getprocs.3 kvm_getargv.3 kvm_getprocs.3 kvm_getenvv.3 MLINKS+=kvm_open.3 kvm_close.3 kvm_open.3 kvm_openfiles.3 MLINKS+=kvm_read.3 kvm_write.3 -- cgit v1.1 From 3750352678548f8a9dd36ac77d8629dfe6f9b853 Mon Sep 17 00:00:00 2001 From: joel Date: Thu, 11 Apr 2013 13:05:38 +0000 Subject: Remove EOL whitespace. --- lib/libkvm/kvm_getpcpu.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/libkvm') diff --git a/lib/libkvm/kvm_getpcpu.3 b/lib/libkvm/kvm_getpcpu.3 index ac02fe1..4087f1c 100644 --- a/lib/libkvm/kvm_getpcpu.3 +++ b/lib/libkvm/kvm_getpcpu.3 @@ -94,7 +94,7 @@ function is used to obtain private per-CPU copy from a .Xr zone 9 . It takes .Fa base -argument as base address of an allocation and copyies +argument as base address of an allocation and copyies .Fa size bytes into .Fa buf -- cgit v1.1