Commit 8e63dd6e1c589ba99a18df9cbaa41c3178607641
Exists in
master
and in
38 other branches
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: powerpc: Fix unpaired __trace_hcall_entry and __trace_hcall_exit powerpc: Fix RCU idle and hcall tracing
Showing 3 changed files Side-by-side Diff
arch/powerpc/kernel/idle.c
... | ... | @@ -50,12 +50,6 @@ |
50 | 50 | } |
51 | 51 | __setup("powersave=off", powersave_off); |
52 | 52 | |
53 | -#if defined(CONFIG_PPC_PSERIES) && defined(CONFIG_TRACEPOINTS) | |
54 | -static const bool idle_uses_rcu = 1; | |
55 | -#else | |
56 | -static const bool idle_uses_rcu; | |
57 | -#endif | |
58 | - | |
59 | 53 | /* |
60 | 54 | * The body of the idle task. |
61 | 55 | */ |
... | ... | @@ -67,8 +61,7 @@ |
67 | 61 | set_thread_flag(TIF_POLLING_NRFLAG); |
68 | 62 | while (1) { |
69 | 63 | tick_nohz_idle_enter(); |
70 | - if (!idle_uses_rcu) | |
71 | - rcu_idle_enter(); | |
64 | + rcu_idle_enter(); | |
72 | 65 | |
73 | 66 | while (!need_resched() && !cpu_should_die()) { |
74 | 67 | ppc64_runlatch_off(); |
... | ... | @@ -106,8 +99,7 @@ |
106 | 99 | |
107 | 100 | HMT_medium(); |
108 | 101 | ppc64_runlatch_on(); |
109 | - if (!idle_uses_rcu) | |
110 | - rcu_idle_exit(); | |
102 | + rcu_idle_exit(); | |
111 | 103 | tick_nohz_idle_exit(); |
112 | 104 | preempt_enable_no_resched(); |
113 | 105 | if (cpu_should_die()) |
arch/powerpc/platforms/pseries/hvCall.S
... | ... | @@ -36,6 +36,7 @@ |
36 | 36 | b 1f; \ |
37 | 37 | END_FTR_SECTION(0, 1); \ |
38 | 38 | ld r12,hcall_tracepoint_refcount@toc(r2); \ |
39 | + std r12,32(r1); \ | |
39 | 40 | cmpdi r12,0; \ |
40 | 41 | beq+ 1f; \ |
41 | 42 | mflr r0; \ |
... | ... | @@ -74,7 +75,7 @@ |
74 | 75 | BEGIN_FTR_SECTION; \ |
75 | 76 | b 1f; \ |
76 | 77 | END_FTR_SECTION(0, 1); \ |
77 | - ld r12,hcall_tracepoint_refcount@toc(r2); \ | |
78 | + ld r12,32(r1); \ | |
78 | 79 | cmpdi r12,0; \ |
79 | 80 | beq+ 1f; \ |
80 | 81 | mflr r0; \ |
arch/powerpc/platforms/pseries/lpar.c
... | ... | @@ -546,6 +546,13 @@ |
546 | 546 | unsigned long flags; |
547 | 547 | unsigned int *depth; |
548 | 548 | |
549 | + /* | |
550 | + * We cannot call tracepoints inside RCU idle regions which | |
551 | + * means we must not trace H_CEDE. | |
552 | + */ | |
553 | + if (opcode == H_CEDE) | |
554 | + return; | |
555 | + | |
549 | 556 | local_irq_save(flags); |
550 | 557 | |
551 | 558 | depth = &__get_cpu_var(hcall_trace_depth); |
... | ... | @@ -556,8 +563,6 @@ |
556 | 563 | (*depth)++; |
557 | 564 | preempt_disable(); |
558 | 565 | trace_hcall_entry(opcode, args); |
559 | - if (opcode == H_CEDE) | |
560 | - rcu_idle_enter(); | |
561 | 566 | (*depth)--; |
562 | 567 | |
563 | 568 | out: |
... | ... | @@ -570,6 +575,9 @@ |
570 | 575 | unsigned long flags; |
571 | 576 | unsigned int *depth; |
572 | 577 | |
578 | + if (opcode == H_CEDE) | |
579 | + return; | |
580 | + | |
573 | 581 | local_irq_save(flags); |
574 | 582 | |
575 | 583 | depth = &__get_cpu_var(hcall_trace_depth); |
... | ... | @@ -578,8 +586,6 @@ |
578 | 586 | goto out; |
579 | 587 | |
580 | 588 | (*depth)++; |
581 | - if (opcode == H_CEDE) | |
582 | - rcu_idle_exit(); | |
583 | 589 | trace_hcall_exit(opcode, retval, retbuf); |
584 | 590 | preempt_enable(); |
585 | 591 | (*depth)--; |