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

Configure Feed

Select the types of activity you want to include in your feed.

arm: perf: Remove PMU locking

Currently the 32-bit arm PMU drivers use the pmu_hw_events::lock spinlock in
their arm_pmu::{start,stop,enable,disable}() callbacks to protect hardware
state and event data.

This locking is not necessary as the perf core code already provides mutual
exclusion, disabling interrupts to serialize against the IRQ handler, and
using perf_event_context::lock to protect against concurrent modifications of
events cross-cpu.

The locking was removed from the arm64 (now PMUv3) PMU driver in commit:

2a0e2a02e4b7 ("arm64: perf: Remove PMU locking")

... and the same reasoning applies to all the 32-bit PMU drivers.

Remove the locking from the 32-bit PMU drivers.

Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Russell King <linux@armlinux.org.uk>
Cc: linux-perf-users@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Link: https://lore.kernel.org/r/20231115092805.737822-2-anshuman.khandual@arm.com
Signed-off-by: Will Deacon <will@kernel.org>

authored by

Anshuman Khandual and committed by
Will Deacon
5cd7da19 38bbef72

+13 -103
+5 -23
arch/arm/kernel/perf_event_v6.c
··· 268 268 269 269 static void armv6pmu_enable_event(struct perf_event *event) 270 270 { 271 - unsigned long val, mask, evt, flags; 272 - struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 271 + unsigned long val, mask, evt; 273 272 struct hw_perf_event *hwc = &event->hw; 274 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 275 273 int idx = hwc->idx; 276 274 277 275 if (ARMV6_CYCLE_COUNTER == idx) { ··· 292 294 * Mask out the current event and set the counter to count the event 293 295 * that we're interested in. 294 296 */ 295 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 296 297 val = armv6_pmcr_read(); 297 298 val &= ~mask; 298 299 val |= evt; 299 300 armv6_pmcr_write(val); 300 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 301 301 } 302 302 303 303 static irqreturn_t ··· 358 362 359 363 static void armv6pmu_start(struct arm_pmu *cpu_pmu) 360 364 { 361 - unsigned long flags, val; 362 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 365 + unsigned long val; 363 366 364 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 365 367 val = armv6_pmcr_read(); 366 368 val |= ARMV6_PMCR_ENABLE; 367 369 armv6_pmcr_write(val); 368 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 369 370 } 370 371 371 372 static void armv6pmu_stop(struct arm_pmu *cpu_pmu) 372 373 { 373 - unsigned long flags, val; 374 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 374 + unsigned long val; 375 375 376 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 377 376 val = armv6_pmcr_read(); 378 377 val &= ~ARMV6_PMCR_ENABLE; 379 378 armv6_pmcr_write(val); 380 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 381 379 } 382 380 383 381 static int ··· 409 419 410 420 static void armv6pmu_disable_event(struct perf_event *event) 411 421 { 412 - unsigned long val, mask, evt, flags; 413 - struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 422 + unsigned long val, mask, evt; 414 423 struct hw_perf_event *hwc = &event->hw; 415 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 416 424 int idx = hwc->idx; 417 425 418 426 if (ARMV6_CYCLE_COUNTER == idx) { ··· 432 444 * of ETM bus signal assertion cycles. The external reporting should 433 445 * be disabled and so this should never increment. 434 446 */ 435 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 436 447 val = armv6_pmcr_read(); 437 448 val &= ~mask; 438 449 val |= evt; 439 450 armv6_pmcr_write(val); 440 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 441 451 } 442 452 443 453 static void armv6mpcore_pmu_disable_event(struct perf_event *event) 444 454 { 445 - unsigned long val, mask, flags, evt = 0; 446 - struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 455 + unsigned long val, mask, evt = 0; 447 456 struct hw_perf_event *hwc = &event->hw; 448 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 449 457 int idx = hwc->idx; 450 458 451 459 if (ARMV6_CYCLE_COUNTER == idx) { ··· 459 475 * Unlike UP ARMv6, we don't have a way of stopping the counters. We 460 476 * simply disable the interrupt reporting. 461 477 */ 462 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 463 478 val = armv6_pmcr_read(); 464 479 val &= ~mask; 465 480 val |= evt; 466 481 armv6_pmcr_write(val); 467 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 468 482 } 469 483 470 484 static int armv6_map_event(struct perf_event *event)
-44
arch/arm/kernel/perf_event_v7.c
··· 870 870 871 871 static void armv7pmu_enable_event(struct perf_event *event) 872 872 { 873 - unsigned long flags; 874 873 struct hw_perf_event *hwc = &event->hw; 875 874 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 876 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 877 875 int idx = hwc->idx; 878 876 879 877 if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) { ··· 884 886 * Enable counter and interrupt, and set the counter to count 885 887 * the event that we're interested in. 886 888 */ 887 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 888 889 889 890 /* 890 891 * Disable counter ··· 907 910 * Enable counter 908 911 */ 909 912 armv7_pmnc_enable_counter(idx); 910 - 911 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 912 913 } 913 914 914 915 static void armv7pmu_disable_event(struct perf_event *event) 915 916 { 916 - unsigned long flags; 917 917 struct hw_perf_event *hwc = &event->hw; 918 918 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 919 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 920 919 int idx = hwc->idx; 921 920 922 921 if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) { ··· 924 931 /* 925 932 * Disable counter and interrupt 926 933 */ 927 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 928 934 929 935 /* 930 936 * Disable counter ··· 934 942 * Disable interrupt for this counter 935 943 */ 936 944 armv7_pmnc_disable_intens(idx); 937 - 938 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 939 945 } 940 946 941 947 static irqreturn_t armv7pmu_handle_irq(struct arm_pmu *cpu_pmu) ··· 999 1009 1000 1010 static void armv7pmu_start(struct arm_pmu *cpu_pmu) 1001 1011 { 1002 - unsigned long flags; 1003 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 1004 - 1005 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 1006 1012 /* Enable all counters */ 1007 1013 armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E); 1008 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 1009 1014 } 1010 1015 1011 1016 static void armv7pmu_stop(struct arm_pmu *cpu_pmu) 1012 1017 { 1013 - unsigned long flags; 1014 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 1015 - 1016 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 1017 1018 /* Disable all counters */ 1018 1019 armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E); 1019 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 1020 1020 } 1021 1021 1022 1022 static int armv7pmu_get_event_idx(struct pmu_hw_events *cpuc, ··· 1472 1492 1473 1493 static void krait_pmu_disable_event(struct perf_event *event) 1474 1494 { 1475 - unsigned long flags; 1476 1495 struct hw_perf_event *hwc = &event->hw; 1477 1496 int idx = hwc->idx; 1478 - struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 1479 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 1480 1497 1481 1498 /* Disable counter and interrupt */ 1482 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 1483 1499 1484 1500 /* Disable counter */ 1485 1501 armv7_pmnc_disable_counter(idx); ··· 1488 1512 1489 1513 /* Disable interrupt for this counter */ 1490 1514 armv7_pmnc_disable_intens(idx); 1491 - 1492 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 1493 1515 } 1494 1516 1495 1517 static void krait_pmu_enable_event(struct perf_event *event) 1496 1518 { 1497 - unsigned long flags; 1498 1519 struct hw_perf_event *hwc = &event->hw; 1499 1520 int idx = hwc->idx; 1500 - struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 1501 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 1502 1521 1503 1522 /* 1504 1523 * Enable counter and interrupt, and set the counter to count 1505 1524 * the event that we're interested in. 1506 1525 */ 1507 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 1508 1526 1509 1527 /* Disable counter */ 1510 1528 armv7_pmnc_disable_counter(idx); ··· 1518 1548 1519 1549 /* Enable counter */ 1520 1550 armv7_pmnc_enable_counter(idx); 1521 - 1522 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 1523 1551 } 1524 1552 1525 1553 static void krait_pmu_reset(void *info) ··· 1793 1825 1794 1826 static void scorpion_pmu_disable_event(struct perf_event *event) 1795 1827 { 1796 - unsigned long flags; 1797 1828 struct hw_perf_event *hwc = &event->hw; 1798 1829 int idx = hwc->idx; 1799 - struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 1800 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 1801 1830 1802 1831 /* Disable counter and interrupt */ 1803 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 1804 1832 1805 1833 /* Disable counter */ 1806 1834 armv7_pmnc_disable_counter(idx); ··· 1809 1845 1810 1846 /* Disable interrupt for this counter */ 1811 1847 armv7_pmnc_disable_intens(idx); 1812 - 1813 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 1814 1848 } 1815 1849 1816 1850 static void scorpion_pmu_enable_event(struct perf_event *event) 1817 1851 { 1818 - unsigned long flags; 1819 1852 struct hw_perf_event *hwc = &event->hw; 1820 1853 int idx = hwc->idx; 1821 - struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 1822 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 1823 1854 1824 1855 /* 1825 1856 * Enable counter and interrupt, and set the counter to count 1826 1857 * the event that we're interested in. 1827 1858 */ 1828 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 1829 1859 1830 1860 /* Disable counter */ 1831 1861 armv7_pmnc_disable_counter(idx); ··· 1839 1881 1840 1882 /* Enable counter */ 1841 1883 armv7_pmnc_enable_counter(idx); 1842 - 1843 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 1844 1884 } 1845 1885 1846 1886 static void scorpion_pmu_reset(void *info)
+8 -36
arch/arm/kernel/perf_event_xscale.c
··· 203 203 204 204 static void xscale1pmu_enable_event(struct perf_event *event) 205 205 { 206 - unsigned long val, mask, evt, flags; 207 - struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 206 + unsigned long val, mask, evt; 208 207 struct hw_perf_event *hwc = &event->hw; 209 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 210 208 int idx = hwc->idx; 211 209 212 210 switch (idx) { ··· 227 229 return; 228 230 } 229 231 230 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 231 232 val = xscale1pmu_read_pmnc(); 232 233 val &= ~mask; 233 234 val |= evt; 234 235 xscale1pmu_write_pmnc(val); 235 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 236 236 } 237 237 238 238 static void xscale1pmu_disable_event(struct perf_event *event) 239 239 { 240 - unsigned long val, mask, evt, flags; 241 - struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 240 + unsigned long val, mask, evt; 242 241 struct hw_perf_event *hwc = &event->hw; 243 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 244 242 int idx = hwc->idx; 245 243 246 244 switch (idx) { ··· 257 263 return; 258 264 } 259 265 260 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 261 266 val = xscale1pmu_read_pmnc(); 262 267 val &= ~mask; 263 268 val |= evt; 264 269 xscale1pmu_write_pmnc(val); 265 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 266 270 } 267 271 268 272 static int ··· 292 300 293 301 static void xscale1pmu_start(struct arm_pmu *cpu_pmu) 294 302 { 295 - unsigned long flags, val; 296 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 303 + unsigned long val; 297 304 298 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 299 305 val = xscale1pmu_read_pmnc(); 300 306 val |= XSCALE_PMU_ENABLE; 301 307 xscale1pmu_write_pmnc(val); 302 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 303 308 } 304 309 305 310 static void xscale1pmu_stop(struct arm_pmu *cpu_pmu) 306 311 { 307 - unsigned long flags, val; 308 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 312 + unsigned long val; 309 313 310 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 311 314 val = xscale1pmu_read_pmnc(); 312 315 val &= ~XSCALE_PMU_ENABLE; 313 316 xscale1pmu_write_pmnc(val); 314 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 315 317 } 316 318 317 319 static inline u64 xscale1pmu_read_counter(struct perf_event *event) ··· 535 549 536 550 static void xscale2pmu_enable_event(struct perf_event *event) 537 551 { 538 - unsigned long flags, ien, evtsel; 539 - struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 552 + unsigned long ien, evtsel; 540 553 struct hw_perf_event *hwc = &event->hw; 541 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 542 554 int idx = hwc->idx; 543 555 544 556 ien = xscale2pmu_read_int_enable(); ··· 571 587 return; 572 588 } 573 589 574 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 575 590 xscale2pmu_write_event_select(evtsel); 576 591 xscale2pmu_write_int_enable(ien); 577 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 578 592 } 579 593 580 594 static void xscale2pmu_disable_event(struct perf_event *event) 581 595 { 582 - unsigned long flags, ien, evtsel, of_flags; 583 - struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 596 + unsigned long ien, evtsel, of_flags; 584 597 struct hw_perf_event *hwc = &event->hw; 585 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 586 598 int idx = hwc->idx; 587 599 588 600 ien = xscale2pmu_read_int_enable(); ··· 618 638 return; 619 639 } 620 640 621 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 622 641 xscale2pmu_write_event_select(evtsel); 623 642 xscale2pmu_write_int_enable(ien); 624 643 xscale2pmu_write_overflow_flags(of_flags); 625 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 626 644 } 627 645 628 646 static int ··· 641 663 642 664 static void xscale2pmu_start(struct arm_pmu *cpu_pmu) 643 665 { 644 - unsigned long flags, val; 645 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 666 + unsigned long val; 646 667 647 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 648 668 val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64; 649 669 val |= XSCALE_PMU_ENABLE; 650 670 xscale2pmu_write_pmnc(val); 651 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 652 671 } 653 672 654 673 static void xscale2pmu_stop(struct arm_pmu *cpu_pmu) 655 674 { 656 - unsigned long flags, val; 657 - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); 675 + unsigned long val; 658 676 659 - raw_spin_lock_irqsave(&events->pmu_lock, flags); 660 677 val = xscale2pmu_read_pmnc(); 661 678 val &= ~XSCALE_PMU_ENABLE; 662 679 xscale2pmu_write_pmnc(val); 663 - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 664 680 } 665 681 666 682 static inline u64 xscale2pmu_read_counter(struct perf_event *event)