Skip site navigation (1)Skip section navigation (2)
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>