summaryrefslogtreecommitdiffstats
path: root/lib/libkvm/kvm.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2010-03-01 00:27:55 +0000
committerrwatson <rwatson@FreeBSD.org>2010-03-01 00:27:55 +0000
commit2c2940cdf7c5fa033c50f9c80a5b9f860d82d858 (patch)
tree04416be9d793aa3a6797065cfdbdfbee0a289fde /lib/libkvm/kvm.c
parent67dd56fb510222481fc77553f9ef25a5fd1f9620 (diff)
downloadFreeBSD-src-2c2940cdf7c5fa033c50f9c80a5b9f860d82d858.zip
FreeBSD-src-2c2940cdf7c5fa033c50f9c80a5b9f860d82d858.tar.gz
A first cut at teaching libkvm how to deal with dynamic per-CPU storage
(DPCPU): A new API, kvm_dpcpu_setcpu(3), selects the active CPU for the purposes of DPCPU. Calls to kvm_nlist(3) will automatically translate DPCPU symbols and return a pointer to the current CPU's version of the data. Consumers needing to read the same symbol on several CPUs will invoke a series of setcpu/nlist calls, one per CPU of interest. This addition makes it possible for tools like netstat(1) to query the values of DPCPU variables during crashdump analysis, and is based on similar code handling virtualized global variables. MFC after: 1 week Sponsored by: Juniper Networks, Inc.
Diffstat (limited to 'lib/libkvm/kvm.c')
-rw-r--r--lib/libkvm/kvm.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/lib/libkvm/kvm.c b/lib/libkvm/kvm.c
index 50f752a..37f6a72 100644
--- a/lib/libkvm/kvm.c
+++ b/lib/libkvm/kvm.c
@@ -416,6 +416,8 @@ _kvm_nlist(kvm_t *kd, struct nlist *nl, int initialize)
struct kld_sym_lookup lookup;
int error;
char *prefix = "", symname[1024]; /* XXX-BZ symbol name length limit? */
+ int tried_vnet, tried_dpcpu;
+
/*
* If we can't use the kld symbol lookup, revert to the
* slow library call.
@@ -429,6 +431,10 @@ _kvm_nlist(kvm_t *kd, struct nlist *nl, int initialize)
error = kvm_fdnlist_prefix(kd, nl, error,
VNET_SYMPREFIX, _kvm_vnet_validaddr);
+ if (error > 0 && _kvm_dpcpu_initialized(kd, initialize))
+ error = kvm_fdnlist_prefix(kd, nl, error,
+ "pcpu_entry_", _kvm_dpcpu_validaddr);
+
return (error);
}
@@ -437,6 +443,8 @@ _kvm_nlist(kvm_t *kd, struct nlist *nl, int initialize)
* and look it up with a kldsym(2) syscall.
*/
nvalid = 0;
+ tried_vnet = 0;
+ tried_dpcpu = 0;
again:
for (p = nl; p->n_name && p->n_name[0]; ++p) {
if (p->n_type != N_UNDF)
@@ -464,6 +472,10 @@ again:
!strcmp(prefix, VNET_SYMPREFIX))
p->n_value =
_kvm_vnet_validaddr(kd, lookup.symvalue);
+ else if (_kvm_dpcpu_initialized(kd, initialize) &&
+ !strcmp(prefix, "pcpu_entry_"))
+ p->n_value =
+ _kvm_dpcpu_validaddr(kd, lookup.symvalue);
else
p->n_value = lookup.symvalue;
++nvalid;
@@ -473,14 +485,19 @@ again:
/*
* Check the number of entries that weren't found. If they exist,
- * try again with a prefix for virtualized symbol names.
+ * try again with a prefix for virtualized or DPCPU symbol names.
*/
error = ((p - nl) - nvalid);
- if (error && _kvm_vnet_initialized(kd, initialize) &&
- strcmp(prefix, VNET_SYMPREFIX)) {
+ if (error && _kvm_vnet_initialized(kd, initialize) && !tried_vnet) {
+ tried_vnet = 1;
prefix = VNET_SYMPREFIX;
goto again;
}
+ if (error && _kvm_dpcpu_initialized(kd, initialize) && !tried_dpcpu) {
+ tried_dpcpu = 1;
+ prefix = "pcpu_entry_";
+ goto again;
+ }
/*
* Return the number of entries that weren't found. If they exist,
OpenPOWER on IntegriCloud