summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_cpuset.c38
-rw-r--r--sys/kern/kern_ktr.c61
2 files changed, 89 insertions, 10 deletions
diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c
index 3b2c653..e1f2801 100644
--- a/sys/kern/kern_cpuset.c
+++ b/sys/kern/kern_cpuset.c
@@ -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>
@@ -660,6 +661,43 @@ cpusetobj_strprint(char *buf, const cpuset_t *set)
}
/*
+ * 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.
*/
int
diff --git a/sys/kern/kern_ktr.c b/sys/kern/kern_ktr.c
index 2e5e06f..eff3d5b 100644
--- a/sys/kern/kern_ktr.c
+++ b/sys/kern/kern_ktr.c
@@ -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;
OpenPOWER on IntegriCloud