|
18 | 18 | #include <asm/plpar_wrappers.h>
|
19 | 19 | #include <asm/machdep.h>
|
20 | 20 |
|
| 21 | +#ifdef CONFIG_DTL |
21 | 22 | struct dtl {
|
22 | 23 | struct dtl_entry *buf;
|
23 | 24 | int cpu;
|
@@ -57,78 +58,6 @@ static DEFINE_PER_CPU(struct dtl_ring, dtl_rings);
|
57 | 58 |
|
58 | 59 | static atomic_t dtl_count;
|
59 | 60 |
|
60 |
| -/* |
61 |
| - * Scan the dispatch trace log and count up the stolen time. |
62 |
| - * Should be called with interrupts disabled. |
63 |
| - */ |
64 |
| -static notrace u64 scan_dispatch_log(u64 stop_tb) |
65 |
| -{ |
66 |
| - u64 i = local_paca->dtl_ridx; |
67 |
| - struct dtl_entry *dtl = local_paca->dtl_curr; |
68 |
| - struct dtl_entry *dtl_end = local_paca->dispatch_log_end; |
69 |
| - struct lppaca *vpa = local_paca->lppaca_ptr; |
70 |
| - u64 tb_delta; |
71 |
| - u64 stolen = 0; |
72 |
| - u64 dtb; |
73 |
| - |
74 |
| - if (!dtl) |
75 |
| - return 0; |
76 |
| - |
77 |
| - if (i == be64_to_cpu(vpa->dtl_idx)) |
78 |
| - return 0; |
79 |
| - while (i < be64_to_cpu(vpa->dtl_idx)) { |
80 |
| - dtb = be64_to_cpu(dtl->timebase); |
81 |
| - tb_delta = be32_to_cpu(dtl->enqueue_to_dispatch_time) + |
82 |
| - be32_to_cpu(dtl->ready_to_enqueue_time); |
83 |
| - barrier(); |
84 |
| - if (i + N_DISPATCH_LOG < be64_to_cpu(vpa->dtl_idx)) { |
85 |
| - /* buffer has overflowed */ |
86 |
| - i = be64_to_cpu(vpa->dtl_idx) - N_DISPATCH_LOG; |
87 |
| - dtl = local_paca->dispatch_log + (i % N_DISPATCH_LOG); |
88 |
| - continue; |
89 |
| - } |
90 |
| - if (dtb > stop_tb) |
91 |
| - break; |
92 |
| - if (dtl_consumer) |
93 |
| - dtl_consumer(dtl, i); |
94 |
| - stolen += tb_delta; |
95 |
| - ++i; |
96 |
| - ++dtl; |
97 |
| - if (dtl == dtl_end) |
98 |
| - dtl = local_paca->dispatch_log; |
99 |
| - } |
100 |
| - local_paca->dtl_ridx = i; |
101 |
| - local_paca->dtl_curr = dtl; |
102 |
| - return stolen; |
103 |
| -} |
104 |
| - |
105 |
| -/* |
106 |
| - * Accumulate stolen time by scanning the dispatch trace log. |
107 |
| - * Called on entry from user mode. |
108 |
| - */ |
109 |
| -void notrace pseries_accumulate_stolen_time(void) |
110 |
| -{ |
111 |
| - u64 sst, ust; |
112 |
| - struct cpu_accounting_data *acct = &local_paca->accounting; |
113 |
| - |
114 |
| - sst = scan_dispatch_log(acct->starttime_user); |
115 |
| - ust = scan_dispatch_log(acct->starttime); |
116 |
| - acct->stime -= sst; |
117 |
| - acct->utime -= ust; |
118 |
| - acct->steal_time += ust + sst; |
119 |
| -} |
120 |
| - |
121 |
| -u64 pseries_calculate_stolen_time(u64 stop_tb) |
122 |
| -{ |
123 |
| - if (!firmware_has_feature(FW_FEATURE_SPLPAR)) |
124 |
| - return 0; |
125 |
| - |
126 |
| - if (get_paca()->dtl_ridx != be64_to_cpu(get_lppaca()->dtl_idx)) |
127 |
| - return scan_dispatch_log(stop_tb); |
128 |
| - |
129 |
| - return 0; |
130 |
| -} |
131 |
| - |
132 | 61 | /*
|
133 | 62 | * The cpu accounting code controls the DTL ring buffer, and we get
|
134 | 63 | * given entries as they are processed.
|
@@ -436,3 +365,81 @@ static int dtl_init(void)
|
436 | 365 | return 0;
|
437 | 366 | }
|
438 | 367 | machine_arch_initcall(pseries, dtl_init);
|
| 368 | +#endif /* CONFIG_DTL */ |
| 369 | + |
| 370 | +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
| 371 | +/* |
| 372 | + * Scan the dispatch trace log and count up the stolen time. |
| 373 | + * Should be called with interrupts disabled. |
| 374 | + */ |
| 375 | +static notrace u64 scan_dispatch_log(u64 stop_tb) |
| 376 | +{ |
| 377 | + u64 i = local_paca->dtl_ridx; |
| 378 | + struct dtl_entry *dtl = local_paca->dtl_curr; |
| 379 | + struct dtl_entry *dtl_end = local_paca->dispatch_log_end; |
| 380 | + struct lppaca *vpa = local_paca->lppaca_ptr; |
| 381 | + u64 tb_delta; |
| 382 | + u64 stolen = 0; |
| 383 | + u64 dtb; |
| 384 | + |
| 385 | + if (!dtl) |
| 386 | + return 0; |
| 387 | + |
| 388 | + if (i == be64_to_cpu(vpa->dtl_idx)) |
| 389 | + return 0; |
| 390 | + while (i < be64_to_cpu(vpa->dtl_idx)) { |
| 391 | + dtb = be64_to_cpu(dtl->timebase); |
| 392 | + tb_delta = be32_to_cpu(dtl->enqueue_to_dispatch_time) + |
| 393 | + be32_to_cpu(dtl->ready_to_enqueue_time); |
| 394 | + barrier(); |
| 395 | + if (i + N_DISPATCH_LOG < be64_to_cpu(vpa->dtl_idx)) { |
| 396 | + /* buffer has overflowed */ |
| 397 | + i = be64_to_cpu(vpa->dtl_idx) - N_DISPATCH_LOG; |
| 398 | + dtl = local_paca->dispatch_log + (i % N_DISPATCH_LOG); |
| 399 | + continue; |
| 400 | + } |
| 401 | + if (dtb > stop_tb) |
| 402 | + break; |
| 403 | +#ifdef CONFIG_DTL |
| 404 | + if (dtl_consumer) |
| 405 | + dtl_consumer(dtl, i); |
| 406 | +#endif |
| 407 | + stolen += tb_delta; |
| 408 | + ++i; |
| 409 | + ++dtl; |
| 410 | + if (dtl == dtl_end) |
| 411 | + dtl = local_paca->dispatch_log; |
| 412 | + } |
| 413 | + local_paca->dtl_ridx = i; |
| 414 | + local_paca->dtl_curr = dtl; |
| 415 | + return stolen; |
| 416 | +} |
| 417 | + |
| 418 | +/* |
| 419 | + * Accumulate stolen time by scanning the dispatch trace log. |
| 420 | + * Called on entry from user mode. |
| 421 | + */ |
| 422 | +void notrace pseries_accumulate_stolen_time(void) |
| 423 | +{ |
| 424 | + u64 sst, ust; |
| 425 | + struct cpu_accounting_data *acct = &local_paca->accounting; |
| 426 | + |
| 427 | + sst = scan_dispatch_log(acct->starttime_user); |
| 428 | + ust = scan_dispatch_log(acct->starttime); |
| 429 | + acct->stime -= sst; |
| 430 | + acct->utime -= ust; |
| 431 | + acct->steal_time += ust + sst; |
| 432 | +} |
| 433 | + |
| 434 | +u64 pseries_calculate_stolen_time(u64 stop_tb) |
| 435 | +{ |
| 436 | + if (!firmware_has_feature(FW_FEATURE_SPLPAR)) |
| 437 | + return 0; |
| 438 | + |
| 439 | + if (get_paca()->dtl_ridx != be64_to_cpu(get_lppaca()->dtl_idx)) |
| 440 | + return scan_dispatch_log(stop_tb); |
| 441 | + |
| 442 | + return 0; |
| 443 | +} |
| 444 | + |
| 445 | +#endif |
0 commit comments