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.
This commit is contained in:
parent
0e2ca4e625
commit
2a2134043c
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 Gleb Smirnoff <glebius@FreeBSD.org>
|
||||
* Copyright (c) 2010 Juniper Networks, Inc.
|
||||
* Copyright (c) 2009 Robert N. M. Watson
|
||||
* Copyright (c) 2009 Bjoern A. Zeeb <bz@FreeBSD.org>
|
||||
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user