Fix KTR_CPUMASK in order to accept a string representing a cpuset_t.

This introduce all the underlying support for making this possible (via
the function cpusetobj_strscan() and keeps ktr_cpumask exported.  sparc64
implements its own assembly primitives for tracing events and needs to
properly check it.  Anyway the sparc64 logic is not implemented yet due
to lack of knowledge (by me) and time (by marius), but it is just a
matter of using ktr_cpumask when possible.

Tested and fixed by:	pluknet
Reviewed by:		marius
This commit is contained in:
attilio 2011-05-31 20:48:58 +00:00
parent 066c7ac96c
commit a924571ff7
6 changed files with 101 additions and 13 deletions

View File

@ -432,7 +432,10 @@ options KTRACE_REQUEST_POOL=101
# defined by the KTR_* constants in <sys/ktr.h>. KTR_MASK defines the
# initial value of the ktr_mask variable which determines at runtime
# what events to trace. KTR_CPUMASK determines which CPU's log
# events, with bit X corresponding to CPU X. KTR_VERBOSE enables
# events, with bit X corresponding to CPU X. The layout of the string
# passed as KTR_CPUMASK must match a serie of bitmasks each of them
# separated by the ", " characters (ie:
# KTR_CPUMASK=("0xAF, 0xFFFFFFFFFFFFFFFF")). KTR_VERBOSE enables
# dumping of KTR events to the console by default. This functionality
# can be toggled via the debug.ktr_verbose sysctl and defaults to off
# if KTR_VERBOSE is not defined. See ktr(4) and ktrdump(8) for details.
@ -441,7 +444,7 @@ options KTR
options KTR_ENTRIES=1024
options KTR_COMPILE=(KTR_INTR|KTR_PROC)
options KTR_MASK=KTR_INTR
options KTR_CPUMASK=0x3
options KTR_CPUMASK=("0x3")
options KTR_VERBOSE
#

View File

@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
#include <sys/cpuset.h>
#include <sys/sx.h>
#include <sys/queue.h>
#include <sys/libkern.h>
#include <sys/limits.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
@ -659,6 +660,43 @@ cpusetobj_strprint(char *buf, const cpuset_t *set)
return (buf);
}
/*
* Build a valid cpuset_t object from a string representation.
* It expects an incoming buffer at least sized as CPUSETBUFSIZ.
*/
int
cpusetobj_strscan(cpuset_t *set, const char *buf)
{
u_int nwords;
int i, ret;
if (strlen(buf) > CPUSETBUFSIZ - 1)
return (-1);
/* Allow to pass a shorter version of the mask when necessary. */
nwords = 1;
for (i = 0; buf[i] != '\0'; i++)
if (buf[i] == ',')
nwords++;
if (nwords > _NCPUWORDS)
return (-1);
CPU_ZERO(set);
for (i = nwords - 1; i > 0; i--) {
ret = sscanf(buf, "%lx, ", &set->__bits[i]);
if (ret == 0 || ret == -1)
return (-1);
buf = strstr(buf, " ");
if (buf == NULL)
return (-1);
buf++;
}
ret = sscanf(buf, "%lx", &set->__bits[0]);
if (ret == 0 || ret == -1)
return (-1);
return (0);
}
/*
* Apply an anonymous mask to a single thread.
*/

View File

@ -40,8 +40,10 @@ __FBSDID("$FreeBSD$");
#include "opt_alq.h"
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/alq.h>
#include <sys/cons.h>
#include <sys/cpuset.h>
#include <sys/kernel.h>
#include <sys/ktr.h>
#include <sys/libkern.h>
@ -68,10 +70,6 @@ __FBSDID("$FreeBSD$");
#define KTR_MASK (0)
#endif
#ifndef KTR_CPUMASK
#define KTR_CPUMASK (~0)
#endif
#ifndef KTR_TIME
#define KTR_TIME get_cyclecount()
#endif
@ -84,11 +82,6 @@ FEATURE(ktr, "Kernel support for KTR kernel tracing facility");
SYSCTL_NODE(_debug, OID_AUTO, ktr, CTLFLAG_RD, 0, "KTR options");
int ktr_cpumask = KTR_CPUMASK;
TUNABLE_INT("debug.ktr.cpumask", &ktr_cpumask);
SYSCTL_INT(_debug_ktr, OID_AUTO, cpumask, CTLFLAG_RW,
&ktr_cpumask, 0, "Bitmask of CPUs on which KTR logging is enabled");
int ktr_mask = KTR_MASK;
TUNABLE_INT("debug.ktr.mask", &ktr_mask);
SYSCTL_INT(_debug_ktr, OID_AUTO, mask, CTLFLAG_RW,
@ -106,6 +99,54 @@ int ktr_version = KTR_VERSION;
SYSCTL_INT(_debug_ktr, OID_AUTO, version, CTLFLAG_RD,
&ktr_version, 0, "Version of the KTR interface");
cpuset_t ktr_cpumask;
static char ktr_cpumask_str[CPUSETBUFSIZ];
TUNABLE_STR("debug.ktr.cpumask", ktr_cpumask_str, sizeof(ktr_cpumask_str));
static void
ktr_cpumask_initializer(void *dummy __unused)
{
CPU_FILL(&ktr_cpumask);
#ifdef KTR_CPUMASK
if (cpusetobj_strscan(&ktr_cpumask, KTR_CPUMASK) == -1)
CPU_FILL(&ktr_cpumask);
#endif
/*
* TUNABLE_STR() runs with SI_ORDER_MIDDLE priority, thus it must be
* already set, if necessary.
*/
if (ktr_cpumask_str[0] != '\0' &&
cpusetobj_strscan(&ktr_cpumask, ktr_cpumask_str) == -1)
CPU_FILL(&ktr_cpumask);
}
SYSINIT(ktr_cpumask_initializer, SI_SUB_TUNABLES, SI_ORDER_ANY,
ktr_cpumask_initializer, NULL);
static int
sysctl_debug_ktr_cpumask(SYSCTL_HANDLER_ARGS)
{
char lktr_cpumask_str[CPUSETBUFSIZ];
cpuset_t imask;
int error;
cpusetobj_strprint(lktr_cpumask_str, &ktr_cpumask);
error = sysctl_handle_string(oidp, lktr_cpumask_str,
sizeof(lktr_cpumask_str), req);
if (error != 0 || req->newptr == NULL)
return (error);
if (cpusetobj_strscan(&imask, lktr_cpumask_str) == -1)
return (EINVAL);
CPU_COPY(&imask, &ktr_cpumask);
return (error);
}
SYSCTL_PROC(_debug_ktr, OID_AUTO, cpumask,
CTLFLAG_RW | CTLFLAG_MPSAFE | CTLTYPE_STRING, NULL, 0,
sysctl_debug_ktr_cpumask, "S",
"Bitmask of CPUs on which KTR logging is enabled");
volatile int ktr_idx = 0;
struct ktr_entry ktr_buf[KTR_ENTRIES];
@ -213,7 +254,7 @@ ktr_tracepoint(u_int mask, const char *file, int line, const char *format,
if ((ktr_mask & mask) == 0)
return;
cpu = KTR_CPU;
if (((1 << cpu) & ktr_cpumask) == 0)
if (!CPU_ISSET(cpu, &ktr_cpumask))
return;
#if defined(KTR_VERBOSE) || defined(KTR_ALQ)
td = curthread;

View File

@ -85,7 +85,9 @@ l2: add r2, 1, r3 ; \
lduw [PCPU(MID)], r1 ; \
mov 1, r2 ; \
sllx r2, r1, r1 ; \
#ifdef notyet \
TEST(ktr_cpumask, r1, r2, r3, l3) ; \
#endif \
ATR(desc, r1, r2, r3, l1, l2)
#endif /* LOCORE */

View File

@ -214,6 +214,7 @@ int cpuset_create_root(struct prison *, struct cpuset **);
int cpuset_setproc_update_set(struct proc *, struct cpuset *);
int cpusetobj_ffs(const cpuset_t *);
char *cpusetobj_strprint(char *, const cpuset_t *);
int cpusetobj_strscan(cpuset_t *, const char *);
#else
__BEGIN_DECLS

View File

@ -97,6 +97,9 @@
#ifndef LOCORE
#include <sys/param.h>
#include <sys/_cpuset.h>
struct ktr_entry {
u_int64_t ktr_timestamp;
int ktr_cpu;
@ -107,7 +110,7 @@ struct ktr_entry {
u_long ktr_parms[KTR_PARMS];
};
extern int ktr_cpumask;
extern cpuset_t ktr_cpumask;
extern int ktr_mask;
extern int ktr_entries;
extern int ktr_verbose;