Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf/core: Drop PERF_EVENT_TXN

We currently use PERF_EVENT_TXN flag to determine if we are in the middle
of a transaction. If in a transaction, we defer the schedulability checks
from pmu->add() operation to the pmu->commit() operation.

Now that we have "transaction types" (PERF_PMU_TXN_ADD, PERF_PMU_TXN_READ)
we can use the type to determine if we are in a transaction and drop the
PERF_EVENT_TXN flag.

When PERF_EVENT_TXN is dropped, the cpuhw->group_flag on some architectures
becomes unused, so drop that field as well.

This is an extension of the Powerpc patch from Peter Zijlstra to s390,
Sparc and x86 architectures.

Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Link: http://lkml.kernel.org/r/1441336073-22750-11-git-send-email-sukadev@linux.vnet.ibm.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Sukadev Bhattiprolu and committed by
Ingo Molnar
8f3e5684 88a48613

+5 -22
+1 -5
arch/powerpc/perf/core-book3s.c
··· 48 48 unsigned long amasks[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES]; 49 49 unsigned long avalues[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES]; 50 50 51 - unsigned int group_flag; 52 51 unsigned int txn_flags; 53 52 int n_txn_start; 54 53 ··· 1441 1442 * skip the schedulability test here, it will be performed 1442 1443 * at commit time(->commit_txn) as a whole 1443 1444 */ 1444 - if (cpuhw->group_flag & PERF_EVENT_TXN) 1445 + if (cpuhw->txn_flags & PERF_PMU_TXN_ADD) 1445 1446 goto nocheck; 1446 1447 1447 1448 if (check_excludes(cpuhw->event, cpuhw->flags, n0, 1)) ··· 1602 1603 return; 1603 1604 1604 1605 perf_pmu_disable(pmu); 1605 - cpuhw->group_flag |= PERF_EVENT_TXN; 1606 1606 cpuhw->n_txn_start = cpuhw->n_events; 1607 1607 } 1608 1608 ··· 1622 1624 if (txn_flags & ~PERF_PMU_TXN_ADD) 1623 1625 return; 1624 1626 1625 - cpuhw->group_flag &= ~PERF_EVENT_TXN; 1626 1627 perf_pmu_enable(pmu); 1627 1628 } 1628 1629 ··· 1656 1659 for (i = cpuhw->n_txn_start; i < n; ++i) 1657 1660 cpuhw->event[i]->hw.config = cpuhw->events[i]; 1658 1661 1659 - cpuhw->group_flag &= ~PERF_EVENT_TXN; 1660 1662 cpuhw->txn_flags = 0; 1661 1663 perf_pmu_enable(pmu); 1662 1664 return 0;
+1 -4
arch/s390/kernel/perf_cpum_cf.c
··· 536 536 * For group events transaction, the authorization check is 537 537 * done in cpumf_pmu_commit_txn(). 538 538 */ 539 - if (!(cpuhw->flags & PERF_EVENT_TXN)) 539 + if (!(cpuhw->txn_flags & PERF_PMU_TXN_ADD)) 540 540 if (validate_ctr_auth(&event->hw)) 541 541 return -EPERM; 542 542 ··· 590 590 return; 591 591 592 592 perf_pmu_disable(pmu); 593 - cpuhw->flags |= PERF_EVENT_TXN; 594 593 cpuhw->tx_state = cpuhw->state; 595 594 } 596 595 ··· 612 613 613 614 WARN_ON(cpuhw->tx_state != cpuhw->state); 614 615 615 - cpuhw->flags &= ~PERF_EVENT_TXN; 616 616 perf_pmu_enable(pmu); 617 617 } 618 618 ··· 638 640 if ((state & cpuhw->info.auth_ctl) != state) 639 641 return -EPERM; 640 642 641 - cpuhw->flags &= ~PERF_EVENT_TXN; 642 643 cpuhw->txn_flags = 0; 643 644 perf_pmu_enable(pmu); 644 645 return 0;
+1 -5
arch/sparc/kernel/perf_event.c
··· 108 108 /* Enabled/disable state. */ 109 109 int enabled; 110 110 111 - unsigned int group_flag; 112 111 unsigned int txn_flags; 113 112 }; 114 113 static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, }; ··· 1379 1380 * skip the schedulability test here, it will be performed 1380 1381 * at commit time(->commit_txn) as a whole 1381 1382 */ 1382 - if (cpuc->group_flag & PERF_EVENT_TXN) 1383 + if (cpuc->txn_flags & PERF_PMU_TXN_ADD) 1383 1384 goto nocheck; 1384 1385 1385 1386 if (check_excludes(cpuc->event, n0, 1)) ··· 1505 1506 return; 1506 1507 1507 1508 perf_pmu_disable(pmu); 1508 - cpuhw->group_flag |= PERF_EVENT_TXN; 1509 1509 } 1510 1510 1511 1511 /* ··· 1524 1526 if (txn_flags & ~PERF_PMU_TXN_ADD) 1525 1527 return; 1526 1528 1527 - cpuhw->group_flag &= ~PERF_EVENT_TXN; 1528 1529 perf_pmu_enable(pmu); 1529 1530 } 1530 1531 ··· 1553 1556 if (sparc_check_constraints(cpuc->event, cpuc->events, n)) 1554 1557 return -EAGAIN; 1555 1558 1556 - cpuc->group_flag &= ~PERF_EVENT_TXN; 1557 1559 cpuc->txn_flags = 0; 1558 1560 perf_pmu_enable(pmu); 1559 1561 return 0;
+2 -5
arch/x86/kernel/cpu/perf_event.c
··· 1175 1175 * skip the schedulability test here, it will be performed 1176 1176 * at commit time (->commit_txn) as a whole. 1177 1177 */ 1178 - if (cpuc->group_flag & PERF_EVENT_TXN) 1178 + if (cpuc->txn_flags & PERF_PMU_TXN_ADD) 1179 1179 goto done_collect; 1180 1180 1181 1181 ret = x86_pmu.schedule_events(cpuc, n, assign); ··· 1326 1326 * XXX assumes any ->del() called during a TXN will only be on 1327 1327 * an event added during that same TXN. 1328 1328 */ 1329 - if (cpuc->group_flag & PERF_EVENT_TXN) 1329 + if (cpuc->txn_flags & PERF_PMU_TXN_ADD) 1330 1330 return; 1331 1331 1332 1332 /* ··· 1764 1764 return; 1765 1765 1766 1766 perf_pmu_disable(pmu); 1767 - __this_cpu_or(cpu_hw_events.group_flag, PERF_EVENT_TXN); 1768 1767 __this_cpu_write(cpu_hw_events.n_txn, 0); 1769 1768 } 1770 1769 ··· 1784 1785 if (txn_flags & ~PERF_PMU_TXN_ADD) 1785 1786 return; 1786 1787 1787 - __this_cpu_and(cpu_hw_events.group_flag, ~PERF_EVENT_TXN); 1788 1788 /* 1789 1789 * Truncate collected array by the number of events added in this 1790 1790 * transaction. See x86_pmu_add() and x86_pmu_*_txn(). ··· 1828 1830 */ 1829 1831 memcpy(cpuc->assign, assign, n*sizeof(int)); 1830 1832 1831 - cpuc->group_flag &= ~PERF_EVENT_TXN; 1832 1833 cpuc->txn_flags = 0; 1833 1834 perf_pmu_enable(pmu); 1834 1835 return 0;
-1
arch/x86/kernel/cpu/perf_event.h
··· 195 195 196 196 int n_excl; /* the number of exclusive events */ 197 197 198 - unsigned int group_flag; 199 198 unsigned int txn_flags; 200 199 int is_fake; 201 200
-2
include/linux/perf_event.h
··· 199 199 /* 200 200 * Common implementation detail of pmu::{start,commit,cancel}_txn 201 201 */ 202 - #define PERF_EVENT_TXN 0x1 203 - 204 202 #define PERF_PMU_TXN_ADD 0x1 /* txn to add/schedule event on PMU */ 205 203 #define PERF_PMU_TXN_READ 0x2 /* txn to read event group from PMU */ 206 204