summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorCyril Bur <cyrilbur@gmail.com>2018-04-12 16:01:59 +1000
committerAlistair Popple <alistair@popple.id.au>2018-04-26 16:37:49 +1000
commit6269517b39fc90dce9fb7b4ff7d29f23900b1241 (patch)
tree41bce481d2f6c52855221321cfa512b6fd04b784 /src
parent1e32d6d0f5bb31049407bb248b42e28dbe40d4ae (diff)
downloadpdbg-6269517b39fc90dce9fb7b4ff7d29f23900b1241.tar.gz
pdbg-6269517b39fc90dce9fb7b4ff7d29f23900b1241.zip
pdbg/htm: Enforce powersave=off
Core HTM has a nasty habit of not working if the stars haven't aligned with the exact polar axis of Mars. To complicate matters if Zeus got up on the incorrect side of the bed Core HTM will likely reflect his mood. Core HTM requires that no threads be in powersave. It isn't clear if this restriction only applies to threads on the core being traced on or if this is a global thing. In order to be as safe as possible, pdbg will enforce that powersave be disabled globally. Signed-off-by: Cyril Bur <cyrilbur@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/htm.c44
-rw-r--r--src/main.c2
-rw-r--r--src/main.h2
3 files changed, 46 insertions, 2 deletions
diff --git a/src/htm.c b/src/htm.c
index 80501c5..4c41f0d 100644
--- a/src/htm.c
+++ b/src/htm.c
@@ -264,7 +264,9 @@ static void print_usage(enum htm_type type)
int run_htm(int optind, int argc, char *argv[])
{
+ struct pdbg_target *target;
enum htm_type type;
+ struct pdbg_target *core_target = NULL;
int i, rc = 0;
if (argc - optind < 2) {
@@ -283,9 +285,49 @@ int run_htm(int optind, int argc, char *argv[])
return 0;
}
- if (type == HTM_CORE)
+ if (type == HTM_CORE) {
fprintf(stderr, "Warning: Core HTM is currently experimental\n");
+ pdbg_for_each_class_target("core", target) {
+ if (target_selected(target)) {
+ if (!core_target) {
+ core_target = target;
+ } else {
+ fprintf(stderr, "It doesn't make sense to core trace on"
+ " multiple cores at once.\n");
+ fprintf(stderr, "What you probably want is -p 0 -c x\n");
+ return 0;
+ }
+ }
+ }
+
+ if (!core_target) {
+ fprintf(stderr, "You haven't selected any HTM Cores\n");
+ return 0;
+ }
+
+ /*
+ * Check that powersave is off.
+ *
+ * This is as easy as checking that every single
+ * thread is "ACTIVE" and hasn't gone into any sleep
+ * state.
+ */
+ pdbg_for_each_class_target("thread", target) {
+ pdbg_target_probe(target);
+
+ if (pdbg_target_status(target) == PDBG_TARGET_NONEXISTENT)
+ continue;
+
+ if ((thread_status(target) & THREAD_STATUS_ACTIVE) != THREAD_STATUS_ACTIVE) {
+ fprintf(stderr, "It appears powersave is on 0x%" PRIx64 "%p\n", thread_status(target), target);
+ fprintf(stderr, "core HTM needs to run with powersave off\n");
+ fprintf(stderr, "Hint: put powersave=off on the kernel commandline\n");
+ return 0;
+ }
+ }
+ }
+
optind++;
for (i = 0; i < ARRAY_SIZE(actions); i++) {
if (strcmp(argv[optind], actions[i].name) == 0) {
diff --git a/src/main.c b/src/main.c
index 64407f3..c91066f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -267,7 +267,7 @@ static void target_unselect(struct pdbg_target *target)
pdbg_target_priv_set(target, NULL);
}
-static bool target_selected(struct pdbg_target *target)
+bool target_selected(struct pdbg_target *target)
{
return (bool) pdbg_target_priv(target);
}
diff --git a/src/main.h b/src/main.h
index d5b7dd6..6db74aa 100644
--- a/src/main.h
+++ b/src/main.h
@@ -25,6 +25,8 @@ static inline bool target_is_disabled(struct pdbg_target *target)
pdbg_target_status(target) == PDBG_TARGET_NONEXISTENT;
}
+bool target_selected(struct pdbg_target *target);
+
/* Returns the sum of return codes. This can be used to count how many targets the callback was run on. */
int for_each_child_target(char *class, struct pdbg_target *parent,
int (*cb)(struct pdbg_target *, uint32_t, uint64_t *, uint64_t *),
OpenPOWER on IntegriCloud