Deleted Added
full compact
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}