diff options
author | Yan, Zheng <zheng.z.yan@intel.com> | 2013-08-07 02:17:24 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-08-16 11:55:49 -0400 |
commit | fd1ec259ba814f0ef35dc8ae2cbd0844541b917d (patch) | |
tree | 9851cdf21e6324d9c0c20bb05a3e5735a5ae7f18 /arch | |
parent | 899396cf7b4b31e08be358411ad5c0c066069ebc (diff) |
perf/x86/intel/uncore: Add filter support for QPI boxes
The QPI uncore boxes have two pairs of MATCH/MASK registers that
user to filter packet traffic serviced by QPI link layer. These
registers are in auxiliary PCI devices.
This patch adds the auxiliary PCI devices to snbep_uncore_pci_ids
and adds field definitions for the MATCH/MASK registers.
Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1375856245-10717-2-git-send-email-zheng.z.yan@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_uncore.c | 139 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_uncore.h | 2 |
2 files changed, 123 insertions, 18 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 7ce9b35851dc..6b8b9c951aad 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c | |||
@@ -47,6 +47,24 @@ DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7"); | |||
47 | DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15"); | 47 | DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15"); |
48 | DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23"); | 48 | DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23"); |
49 | DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31"); | 49 | DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31"); |
50 | DEFINE_UNCORE_FORMAT_ATTR(match_rds, match_rds, "config1:48-51"); | ||
51 | DEFINE_UNCORE_FORMAT_ATTR(match_rnid30, match_rnid30, "config1:32-35"); | ||
52 | DEFINE_UNCORE_FORMAT_ATTR(match_rnid4, match_rnid4, "config1:31"); | ||
53 | DEFINE_UNCORE_FORMAT_ATTR(match_dnid, match_dnid, "config1:13-17"); | ||
54 | DEFINE_UNCORE_FORMAT_ATTR(match_mc, match_mc, "config1:9-12"); | ||
55 | DEFINE_UNCORE_FORMAT_ATTR(match_opc, match_opc, "config1:5-8"); | ||
56 | DEFINE_UNCORE_FORMAT_ATTR(match_vnw, match_vnw, "config1:3-4"); | ||
57 | DEFINE_UNCORE_FORMAT_ATTR(match0, match0, "config1:0-31"); | ||
58 | DEFINE_UNCORE_FORMAT_ATTR(match1, match1, "config1:32-63"); | ||
59 | DEFINE_UNCORE_FORMAT_ATTR(mask_rds, mask_rds, "config2:48-51"); | ||
60 | DEFINE_UNCORE_FORMAT_ATTR(mask_rnid30, mask_rnid30, "config2:32-35"); | ||
61 | DEFINE_UNCORE_FORMAT_ATTR(mask_rnid4, mask_rnid4, "config2:31"); | ||
62 | DEFINE_UNCORE_FORMAT_ATTR(mask_dnid, mask_dnid, "config2:13-17"); | ||
63 | DEFINE_UNCORE_FORMAT_ATTR(mask_mc, mask_mc, "config2:9-12"); | ||
64 | DEFINE_UNCORE_FORMAT_ATTR(mask_opc, mask_opc, "config2:5-8"); | ||
65 | DEFINE_UNCORE_FORMAT_ATTR(mask_vnw, mask_vnw, "config2:3-4"); | ||
66 | DEFINE_UNCORE_FORMAT_ATTR(mask0, mask0, "config2:0-31"); | ||
67 | DEFINE_UNCORE_FORMAT_ATTR(mask1, mask1, "config2:32-63"); | ||
50 | 68 | ||
51 | static u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event) | 69 | static u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event) |
52 | { | 70 | { |
@@ -303,6 +321,24 @@ static struct attribute *snbep_uncore_qpi_formats_attr[] = { | |||
303 | &format_attr_edge.attr, | 321 | &format_attr_edge.attr, |
304 | &format_attr_inv.attr, | 322 | &format_attr_inv.attr, |
305 | &format_attr_thresh8.attr, | 323 | &format_attr_thresh8.attr, |
324 | &format_attr_match_rds.attr, | ||
325 | &format_attr_match_rnid30.attr, | ||
326 | &format_attr_match_rnid4.attr, | ||
327 | &format_attr_match_dnid.attr, | ||
328 | &format_attr_match_mc.attr, | ||
329 | &format_attr_match_opc.attr, | ||
330 | &format_attr_match_vnw.attr, | ||
331 | &format_attr_match0.attr, | ||
332 | &format_attr_match1.attr, | ||
333 | &format_attr_mask_rds.attr, | ||
334 | &format_attr_mask_rnid30.attr, | ||
335 | &format_attr_mask_rnid4.attr, | ||
336 | &format_attr_mask_dnid.attr, | ||
337 | &format_attr_mask_mc.attr, | ||
338 | &format_attr_mask_opc.attr, | ||
339 | &format_attr_mask_vnw.attr, | ||
340 | &format_attr_mask0.attr, | ||
341 | &format_attr_mask1.attr, | ||
306 | NULL, | 342 | NULL, |
307 | }; | 343 | }; |
308 | 344 | ||
@@ -358,13 +394,16 @@ static struct intel_uncore_ops snbep_uncore_msr_ops = { | |||
358 | SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), | 394 | SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), |
359 | }; | 395 | }; |
360 | 396 | ||
397 | #define SNBEP_UNCORE_PCI_OPS_COMMON_INIT() \ | ||
398 | .init_box = snbep_uncore_pci_init_box, \ | ||
399 | .disable_box = snbep_uncore_pci_disable_box, \ | ||
400 | .enable_box = snbep_uncore_pci_enable_box, \ | ||
401 | .disable_event = snbep_uncore_pci_disable_event, \ | ||
402 | .read_counter = snbep_uncore_pci_read_counter | ||
403 | |||
361 | static struct intel_uncore_ops snbep_uncore_pci_ops = { | 404 | static struct intel_uncore_ops snbep_uncore_pci_ops = { |
362 | .init_box = snbep_uncore_pci_init_box, | 405 | SNBEP_UNCORE_PCI_OPS_COMMON_INIT(), |
363 | .disable_box = snbep_uncore_pci_disable_box, | 406 | .enable_event = snbep_uncore_pci_enable_event, \ |
364 | .enable_box = snbep_uncore_pci_enable_box, | ||
365 | .disable_event = snbep_uncore_pci_disable_event, | ||
366 | .enable_event = snbep_uncore_pci_enable_event, | ||
367 | .read_counter = snbep_uncore_pci_read_counter, | ||
368 | }; | 407 | }; |
369 | 408 | ||
370 | static struct event_constraint snbep_uncore_cbox_constraints[] = { | 409 | static struct event_constraint snbep_uncore_cbox_constraints[] = { |
@@ -728,6 +767,61 @@ static struct intel_uncore_type *snbep_msr_uncores[] = { | |||
728 | NULL, | 767 | NULL, |
729 | }; | 768 | }; |
730 | 769 | ||
770 | enum { | ||
771 | SNBEP_PCI_QPI_PORT0_FILTER, | ||
772 | SNBEP_PCI_QPI_PORT1_FILTER, | ||
773 | }; | ||
774 | |||
775 | static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event) | ||
776 | { | ||
777 | struct hw_perf_event *hwc = &event->hw; | ||
778 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
779 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
780 | |||
781 | if ((hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK) == 0x38) { | ||
782 | reg1->idx = 0; | ||
783 | reg1->reg = SNBEP_Q_Py_PCI_PMON_PKT_MATCH0; | ||
784 | reg1->config = event->attr.config1; | ||
785 | reg2->reg = SNBEP_Q_Py_PCI_PMON_PKT_MASK0; | ||
786 | reg2->config = event->attr.config2; | ||
787 | } | ||
788 | return 0; | ||
789 | } | ||
790 | |||
791 | static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
792 | { | ||
793 | struct pci_dev *pdev = box->pci_dev; | ||
794 | struct hw_perf_event *hwc = &event->hw; | ||
795 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
796 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
797 | |||
798 | if (reg1->idx != EXTRA_REG_NONE) { | ||
799 | int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER; | ||
800 | struct pci_dev *filter_pdev = extra_pci_dev[box->phys_id][idx]; | ||
801 | WARN_ON_ONCE(!filter_pdev); | ||
802 | if (filter_pdev) { | ||
803 | pci_write_config_dword(filter_pdev, reg1->reg, | ||
804 | (u32)reg1->config); | ||
805 | pci_write_config_dword(filter_pdev, reg1->reg + 4, | ||
806 | (u32)(reg1->config >> 32)); | ||
807 | pci_write_config_dword(filter_pdev, reg2->reg, | ||
808 | (u32)reg2->config); | ||
809 | pci_write_config_dword(filter_pdev, reg2->reg + 4, | ||
810 | (u32)(reg2->config >> 32)); | ||
811 | } | ||
812 | } | ||
813 | |||
814 | pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); | ||
815 | } | ||
816 | |||
817 | static struct intel_uncore_ops snbep_uncore_qpi_ops = { | ||
818 | SNBEP_UNCORE_PCI_OPS_COMMON_INIT(), | ||
819 | .enable_event = snbep_qpi_enable_event, | ||
820 | .hw_config = snbep_qpi_hw_config, | ||
821 | .get_constraint = uncore_get_constraint, | ||
822 | .put_constraint = uncore_put_constraint, | ||
823 | }; | ||
824 | |||
731 | #define SNBEP_UNCORE_PCI_COMMON_INIT() \ | 825 | #define SNBEP_UNCORE_PCI_COMMON_INIT() \ |
732 | .perf_ctr = SNBEP_PCI_PMON_CTR0, \ | 826 | .perf_ctr = SNBEP_PCI_PMON_CTR0, \ |
733 | .event_ctl = SNBEP_PCI_PMON_CTL0, \ | 827 | .event_ctl = SNBEP_PCI_PMON_CTL0, \ |
@@ -757,17 +851,18 @@ static struct intel_uncore_type snbep_uncore_imc = { | |||
757 | }; | 851 | }; |
758 | 852 | ||
759 | static struct intel_uncore_type snbep_uncore_qpi = { | 853 | static struct intel_uncore_type snbep_uncore_qpi = { |
760 | .name = "qpi", | 854 | .name = "qpi", |
761 | .num_counters = 4, | 855 | .num_counters = 4, |
762 | .num_boxes = 2, | 856 | .num_boxes = 2, |
763 | .perf_ctr_bits = 48, | 857 | .perf_ctr_bits = 48, |
764 | .perf_ctr = SNBEP_PCI_PMON_CTR0, | 858 | .perf_ctr = SNBEP_PCI_PMON_CTR0, |
765 | .event_ctl = SNBEP_PCI_PMON_CTL0, | 859 | .event_ctl = SNBEP_PCI_PMON_CTL0, |
766 | .event_mask = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK, | 860 | .event_mask = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK, |
767 | .box_ctl = SNBEP_PCI_PMON_BOX_CTL, | 861 | .box_ctl = SNBEP_PCI_PMON_BOX_CTL, |
768 | .ops = &snbep_uncore_pci_ops, | 862 | .num_shared_regs = 1, |
769 | .event_descs = snbep_uncore_qpi_events, | 863 | .ops = &snbep_uncore_qpi_ops, |
770 | .format_group = &snbep_uncore_qpi_format_group, | 864 | .event_descs = snbep_uncore_qpi_events, |
865 | .format_group = &snbep_uncore_qpi_format_group, | ||
771 | }; | 866 | }; |
772 | 867 | ||
773 | 868 | ||
@@ -847,6 +942,16 @@ static DEFINE_PCI_DEVICE_TABLE(snbep_uncore_pci_ids) = { | |||
847 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1), | 942 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1), |
848 | .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 1), | 943 | .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 1), |
849 | }, | 944 | }, |
945 | { /* QPI Port 0 filter */ | ||
946 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c86), | ||
947 | .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, | ||
948 | SNBEP_PCI_QPI_PORT0_FILTER), | ||
949 | }, | ||
950 | { /* QPI Port 0 filter */ | ||
951 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c96), | ||
952 | .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, | ||
953 | SNBEP_PCI_QPI_PORT1_FILTER), | ||
954 | }, | ||
850 | { /* end: all zeroes */ } | 955 | { /* end: all zeroes */ } |
851 | }; | 956 | }; |
852 | 957 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index ede5a8c1d29e..628500e65d0b 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h | |||
@@ -16,7 +16,7 @@ | |||
16 | #define UNCORE_PCI_DEV_TYPE(data) ((data >> 8) & 0xff) | 16 | #define UNCORE_PCI_DEV_TYPE(data) ((data >> 8) & 0xff) |
17 | #define UNCORE_PCI_DEV_IDX(data) (data & 0xff) | 17 | #define UNCORE_PCI_DEV_IDX(data) (data & 0xff) |
18 | #define UNCORE_EXTRA_PCI_DEV 0xff | 18 | #define UNCORE_EXTRA_PCI_DEV 0xff |
19 | #define UNCORE_EXTRA_PCI_DEV_MAX 0 | 19 | #define UNCORE_EXTRA_PCI_DEV_MAX 2 |
20 | 20 | ||
21 | /* support up to 8 sockets */ | 21 | /* support up to 8 sockets */ |
22 | #define UNCORE_SOCKET_MAX 8 | 22 | #define UNCORE_SOCKET_MAX 8 |