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
This commit is contained in:
parent
7fcdc9a26f
commit
d5880f9cdf
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user