kvm_pcpu.c (223758) | kvm_pcpu.c (249344) |
---|---|
1/*- | 1/*- |
2 * Copyright (c) 2013 Gleb Smirnoff <glebius@FreeBSD.org> |
|
2 * Copyright (c) 2010 Juniper Networks, Inc. 3 * Copyright (c) 2009 Robert N. M. Watson 4 * Copyright (c) 2009 Bjoern A. Zeeb <bz@FreeBSD.org> 5 * Copyright (c) 2008 Yahoo!, Inc. 6 * All rights reserved. 7 * 8 * Written by: John Baldwin <jhb@FreeBSD.org> 9 * --- 21 unchanged lines hidden (view full) --- 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 38#include <sys/cdefs.h> | 3 * Copyright (c) 2010 Juniper Networks, Inc. 4 * Copyright (c) 2009 Robert N. M. Watson 5 * Copyright (c) 2009 Bjoern A. Zeeb <bz@FreeBSD.org> 6 * Copyright (c) 2008 Yahoo!, Inc. 7 * All rights reserved. 8 * 9 * Written by: John Baldwin <jhb@FreeBSD.org> 10 * --- 21 unchanged lines hidden (view full) --- 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 */ 38 39#include <sys/cdefs.h> |
39__FBSDID("$FreeBSD: head/lib/libkvm/kvm_pcpu.c 223758 2011-07-04 12:04:52Z attilio $"); | 40__FBSDID("$FreeBSD: head/lib/libkvm/kvm_pcpu.c 249344 2013-04-10 20:26:53Z glebius $"); |
40 41#include <sys/param.h> 42#include <sys/pcpu.h> 43#include <sys/sysctl.h> 44#include <kvm.h> 45#include <limits.h> 46#include <stdlib.h> 47 48#include "kvm_private.h" 49 50static struct nlist kvm_pcpu_nl[] = { 51 { .n_name = "_cpuid_to_pcpu" }, 52 { .n_name = "_mp_maxcpus" }, | 41 42#include <sys/param.h> 43#include <sys/pcpu.h> 44#include <sys/sysctl.h> 45#include <kvm.h> 46#include <limits.h> 47#include <stdlib.h> 48 49#include "kvm_private.h" 50 51static struct nlist kvm_pcpu_nl[] = { 52 { .n_name = "_cpuid_to_pcpu" }, 53 { .n_name = "_mp_maxcpus" }, |
54 { .n_name = "_mp_ncpus" }, |
|
53 { .n_name = NULL }, 54}; | 55 { .n_name = NULL }, 56}; |
57#define NL_CPUID_TO_PCPU 0 58#define NL_MP_MAXCPUS 1 59#define NL_MP_NCPUS 2 |
|
55 56/* 57 * Kernel per-CPU data state. We cache this stuff on the first 58 * access. 59 * 60 * XXXRW: Possibly, this (and kvmpcpu_nl) should be per-kvm_t, in case the 61 * consumer has multiple handles in flight to differently configured 62 * kernels/crashdumps. 63 */ 64static void **pcpu_data; 65static int maxcpu; | 60 61/* 62 * Kernel per-CPU data state. We cache this stuff on the first 63 * access. 64 * 65 * XXXRW: Possibly, this (and kvmpcpu_nl) should be per-kvm_t, in case the 66 * consumer has multiple handles in flight to differently configured 67 * kernels/crashdumps. 68 */ 69static void **pcpu_data; 70static int maxcpu; |
71static int mp_ncpus; |
|
66 | 72 |
67#define NL_CPUID_TO_PCPU 0 68#define NL_MP_MAXCPUS 1 69 | |
70static int 71_kvm_pcpu_init(kvm_t *kd) 72{ 73 size_t len; 74 int max; 75 void *data; 76 77 if (kvm_nlist(kd, kvm_pcpu_nl) < 0) --- 6 unchanged lines hidden (view full) --- 84 _kvm_err(kd, kd->program, "unable to find mp_maxcpus"); 85 return (-1); 86 } 87 if (kvm_read(kd, kvm_pcpu_nl[NL_MP_MAXCPUS].n_value, &max, 88 sizeof(max)) != sizeof(max)) { 89 _kvm_err(kd, kd->program, "cannot read mp_maxcpus"); 90 return (-1); 91 } | 73static int 74_kvm_pcpu_init(kvm_t *kd) 75{ 76 size_t len; 77 int max; 78 void *data; 79 80 if (kvm_nlist(kd, kvm_pcpu_nl) < 0) --- 6 unchanged lines hidden (view full) --- 87 _kvm_err(kd, kd->program, "unable to find mp_maxcpus"); 88 return (-1); 89 } 90 if (kvm_read(kd, kvm_pcpu_nl[NL_MP_MAXCPUS].n_value, &max, 91 sizeof(max)) != sizeof(max)) { 92 _kvm_err(kd, kd->program, "cannot read mp_maxcpus"); 93 return (-1); 94 } |
95 if (kvm_pcpu_nl[NL_MP_NCPUS].n_value == 0) { 96 _kvm_err(kd, kd->program, "unable to find mp_ncpus"); 97 return (-1); 98 } 99 if (kvm_read(kd, kvm_pcpu_nl[NL_MP_NCPUS].n_value, &mp_ncpus, 100 sizeof(mp_ncpus)) != sizeof(mp_ncpus)) { 101 _kvm_err(kd, kd->program, "cannot read mp_ncpus"); 102 return (-1); 103 } |
|
92 len = max * sizeof(void *); 93 data = malloc(len); 94 if (data == NULL) { 95 _kvm_err(kd, kd->program, "out of memory"); 96 return (-1); 97 } 98 if (kvm_read(kd, kvm_pcpu_nl[NL_CPUID_TO_PCPU].n_value, data, len) != 99 (ssize_t)len) { --- 184 unchanged lines hidden (view full) --- 284 _kvm_err(kd, kd->program, "%s: init failed", 285 __func__); 286 return (ret); 287 } 288 } 289 290 return (_kvm_dpcpu_setcpu(kd, cpu, 1)); 291} | 104 len = max * sizeof(void *); 105 data = malloc(len); 106 if (data == NULL) { 107 _kvm_err(kd, kd->program, "out of memory"); 108 return (-1); 109 } 110 if (kvm_read(kd, kvm_pcpu_nl[NL_CPUID_TO_PCPU].n_value, data, len) != 111 (ssize_t)len) { --- 184 unchanged lines hidden (view full) --- 296 _kvm_err(kd, kd->program, "%s: init failed", 297 __func__); 298 return (ret); 299 } 300 } 301 302 return (_kvm_dpcpu_setcpu(kd, cpu, 1)); 303} |
304 305/* 306 * Obtain a per-CPU copy for given cpu from UMA_ZONE_PCPU allocation. 307 */ 308ssize_t 309kvm_read_zpcpu(kvm_t *kd, void *buf, u_long base, size_t size, int cpu) 310{ 311 312 return (kvm_read(kd, (uintptr_t)(base + sizeof(struct pcpu) * cpu), 313 buf, size)); 314} 315 316/* 317 * Fetch value of a counter(9). 318 */ 319uint64_t 320kvm_counter_u64_fetch(kvm_t *kd, u_long base) 321{ 322 uint64_t r, c; 323 324 if (mp_ncpus == 0) 325 if (_kvm_pcpu_init(kd) < 0) 326 return (0); 327 328 r = 0; 329 for (int i = 0; i < mp_ncpus; i++) { 330 if (kvm_read_zpcpu(kd, &c, base, sizeof(c), i) != sizeof(c)) 331 return (0); 332 r += c; 333 } 334 335 return (r); 336} |
|