Date: Fri, 27 May 2011 15:50:14 +0000 (UTC) From: Attilio Rao <attilio@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r222360 - in projects/largeSMP: lib/libkvm sys/sys Message-ID: <201105271550.p4RFoEtc041957@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: attilio Date: Fri May 27 15:50:14 2011 New Revision: 222360 URL: http://svn.freebsd.org/changeset/base/222360 Log: In the near future cpuset_t objects in struct pcpu will be axed out, but as long as this does not happen, we need to fix interfaces to userland in order to not break run-time accesses to the structure. Reviwed by: kib Tested by: pluknet Modified: projects/largeSMP/lib/libkvm/kvm_pcpu.c projects/largeSMP/sys/sys/pcpu.h Modified: projects/largeSMP/lib/libkvm/kvm_pcpu.c ============================================================================== --- projects/largeSMP/lib/libkvm/kvm_pcpu.c Fri May 27 15:29:39 2011 (r222359) +++ projects/largeSMP/lib/libkvm/kvm_pcpu.c Fri May 27 15:50:14 2011 (r222360) @@ -39,11 +39,13 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> +#include <sys/cpuset.h> #include <sys/pcpu.h> #include <sys/sysctl.h> #include <kvm.h> #include <limits.h> #include <stdlib.h> +#include <unistd.h> #include "kvm_private.h" @@ -118,6 +120,9 @@ _kvm_pcpu_clear(void) void * kvm_getpcpu(kvm_t *kd, int cpu) { + long kcpusetsize; + ssize_t nbytes; + uintptr_t readptr; char *buf; if (kd == NULL) { @@ -125,6 +130,10 @@ kvm_getpcpu(kvm_t *kd, int cpu) return (NULL); } + kcpusetsize = sysconf(_SC_CPUSET_SIZE); + if (kcpusetsize == -1 || (u_long)kcpusetsize > sizeof(cpuset_t)) + return ((void *)-1); + if (maxcpu == 0) if (_kvm_pcpu_init(kd) < 0) return ((void *)-1); @@ -137,8 +146,26 @@ kvm_getpcpu(kvm_t *kd, int cpu) _kvm_err(kd, kd->program, "out of memory"); return ((void *)-1); } - if (kvm_read(kd, (uintptr_t)pcpu_data[cpu], buf, sizeof(struct pcpu)) != - sizeof(struct pcpu)) { + nbytes = sizeof(struct pcpu) - 2 * kcpusetsize; + readptr = (uintptr_t)pcpu_data[cpu]; + if (kvm_read(kd, readptr, buf, nbytes) != nbytes) { + _kvm_err(kd, kd->program, "unable to read per-CPU data"); + free(buf); + return ((void *)-1); + } + + /* Fetch the valid cpuset_t objects. */ + CPU_ZERO((cpuset_t *)(buf + nbytes)); + CPU_ZERO((cpuset_t *)(buf + nbytes + sizeof(cpuset_t))); + readptr += nbytes; + if (kvm_read(kd, readptr, buf + nbytes, kcpusetsize) != kcpusetsize) { + _kvm_err(kd, kd->program, "unable to read per-CPU data"); + free(buf); + return ((void *)-1); + } + readptr += kcpusetsize; + if (kvm_read(kd, readptr, buf + nbytes + sizeof(cpuset_t), + kcpusetsize) != kcpusetsize) { _kvm_err(kd, kd->program, "unable to read per-CPU data"); free(buf); return ((void *)-1); Modified: projects/largeSMP/sys/sys/pcpu.h ============================================================================== --- projects/largeSMP/sys/sys/pcpu.h Fri May 27 15:29:39 2011 (r222359) +++ projects/largeSMP/sys/sys/pcpu.h Fri May 27 15:50:14 2011 (r222360) @@ -163,8 +163,6 @@ struct pcpu { uint64_t pc_switchtime; /* cpu_ticks() at last csw */ int pc_switchticks; /* `ticks' at last csw */ u_int pc_cpuid; /* This cpu number */ - cpuset_t pc_cpumask; /* This cpu mask */ - cpuset_t pc_other_cpus; /* Mask of all other cpus */ SLIST_ENTRY(pcpu) pc_allcpu; struct lock_list_entry *pc_spinlocks; #ifdef KTR @@ -198,6 +196,18 @@ struct pcpu { * if only to make kernel debugging easier. */ PCPU_MD_FIELDS; + + /* + * XXX + * For the time being, keep the cpuset_t objects as the very last + * members of the structure. + * They are actually tagged to be removed soon, but as long as this + * does not happen, it is necessary to find a way to implement + * easilly interfaces to userland and leaving them last makes that + * possible. + */ + cpuset_t pc_cpumask; /* This cpu mask */ + cpuset_t pc_other_cpus; /* Mask of all other cpus */ } __aligned(CACHE_LINE_SIZE); #ifdef _KERNEL
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105271550.p4RFoEtc041957>