aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2013-08-07 02:17:23 -0400
committerIngo Molnar <mingo@kernel.org>2013-08-16 11:55:48 -0400
commit899396cf7b4b31e08be358411ad5c0c066069ebc (patch)
treea13070ed31402d56457d6f2eefd14bff7abe713e /arch
parent894e8d089079caf99ea5d6a52c52506b38dee347 (diff)
perf/x86/intel/uncore: Add auxiliary pci device support
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 changes the meaning of (struct pci_device_id)->driver_data. The first 8 bits are device index of the same uncore type, the second 8 bytes are uncore type index. Auxiliary PCI device's type is defined as UNCORE_EXTRA_PCI_DEV(0xff) 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-1-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.c111
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore.h9
2 files changed, 68 insertions, 52 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
index cad791dbde95..7ce9b35851dc 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
@@ -6,6 +6,8 @@ static struct intel_uncore_type **pci_uncores = empty_uncore;
6/* pci bus to socket mapping */ 6/* pci bus to socket mapping */
7static int pcibus_to_physid[256] = { [0 ... 255] = -1, }; 7static int pcibus_to_physid[256] = { [0 ... 255] = -1, };
8 8
9static struct pci_dev *extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX];
10
9static DEFINE_RAW_SPINLOCK(uncore_box_lock); 11static DEFINE_RAW_SPINLOCK(uncore_box_lock);
10 12
11/* mask of cpus that collect uncore events */ 13/* mask of cpus that collect uncore events */
@@ -807,43 +809,43 @@ static struct intel_uncore_type *snbep_pci_uncores[] = {
807static DEFINE_PCI_DEVICE_TABLE(snbep_uncore_pci_ids) = { 809static DEFINE_PCI_DEVICE_TABLE(snbep_uncore_pci_ids) = {
808 { /* Home Agent */ 810 { /* Home Agent */
809 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA), 811 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA),
810 .driver_data = SNBEP_PCI_UNCORE_HA, 812 .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_HA, 0),
811 }, 813 },
812 { /* MC Channel 0 */ 814 { /* MC Channel 0 */
813 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0), 815 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0),
814 .driver_data = SNBEP_PCI_UNCORE_IMC, 816 .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 0),
815 }, 817 },
816 { /* MC Channel 1 */ 818 { /* MC Channel 1 */
817 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1), 819 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1),
818 .driver_data = SNBEP_PCI_UNCORE_IMC, 820 .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 1),
819 }, 821 },
820 { /* MC Channel 2 */ 822 { /* MC Channel 2 */
821 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2), 823 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2),
822 .driver_data = SNBEP_PCI_UNCORE_IMC, 824 .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 2),
823 }, 825 },
824 { /* MC Channel 3 */ 826 { /* MC Channel 3 */
825 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3), 827 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3),
826 .driver_data = SNBEP_PCI_UNCORE_IMC, 828 .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 3),
827 }, 829 },
828 { /* QPI Port 0 */ 830 { /* QPI Port 0 */
829 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0), 831 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0),
830 .driver_data = SNBEP_PCI_UNCORE_QPI, 832 .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 0),
831 }, 833 },
832 { /* QPI Port 1 */ 834 { /* QPI Port 1 */
833 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1), 835 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1),
834 .driver_data = SNBEP_PCI_UNCORE_QPI, 836 .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 1),
835 }, 837 },
836 { /* R2PCIe */ 838 { /* R2PCIe */
837 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE), 839 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE),
838 .driver_data = SNBEP_PCI_UNCORE_R2PCIE, 840 .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R2PCIE, 0),
839 }, 841 },
840 { /* R3QPI Link 0 */ 842 { /* R3QPI Link 0 */
841 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0), 843 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0),
842 .driver_data = SNBEP_PCI_UNCORE_R3QPI, 844 .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 0),
843 }, 845 },
844 { /* R3QPI Link 1 */ 846 { /* R3QPI Link 1 */
845 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1), 847 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1),
846 .driver_data = SNBEP_PCI_UNCORE_R3QPI, 848 .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 1),
847 }, 849 },
848 { /* end: all zeroes */ } 850 { /* end: all zeroes */ }
849}; 851};
@@ -1256,71 +1258,71 @@ static struct intel_uncore_type *ivt_pci_uncores[] = {
1256static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = { 1258static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = {
1257 { /* Home Agent 0 */ 1259 { /* Home Agent 0 */
1258 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30), 1260 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30),
1259 .driver_data = IVT_PCI_UNCORE_HA, 1261 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_HA, 0),
1260 }, 1262 },
1261 { /* Home Agent 1 */ 1263 { /* Home Agent 1 */
1262 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38), 1264 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38),
1263 .driver_data = IVT_PCI_UNCORE_HA, 1265 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_HA, 1),
1264 }, 1266 },
1265 { /* MC0 Channel 0 */ 1267 { /* MC0 Channel 0 */
1266 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4), 1268 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4),
1267 .driver_data = IVT_PCI_UNCORE_IMC, 1269 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 0),
1268 }, 1270 },
1269 { /* MC0 Channel 1 */ 1271 { /* MC0 Channel 1 */
1270 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5), 1272 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5),
1271 .driver_data = IVT_PCI_UNCORE_IMC, 1273 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 1),
1272 }, 1274 },
1273 { /* MC0 Channel 3 */ 1275 { /* MC0 Channel 3 */
1274 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0), 1276 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0),
1275 .driver_data = IVT_PCI_UNCORE_IMC, 1277 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 2),
1276 }, 1278 },
1277 { /* MC0 Channel 4 */ 1279 { /* MC0 Channel 4 */
1278 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1), 1280 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1),
1279 .driver_data = IVT_PCI_UNCORE_IMC, 1281 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 3),
1280 }, 1282 },
1281 { /* MC1 Channel 0 */ 1283 { /* MC1 Channel 0 */
1282 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4), 1284 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4),
1283 .driver_data = IVT_PCI_UNCORE_IMC, 1285 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 4),
1284 }, 1286 },
1285 { /* MC1 Channel 1 */ 1287 { /* MC1 Channel 1 */
1286 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5), 1288 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5),
1287 .driver_data = IVT_PCI_UNCORE_IMC, 1289 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 5),
1288 }, 1290 },
1289 { /* MC1 Channel 3 */ 1291 { /* MC1 Channel 3 */
1290 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0), 1292 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0),
1291 .driver_data = IVT_PCI_UNCORE_IMC, 1293 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 6),
1292 }, 1294 },
1293 { /* MC1 Channel 4 */ 1295 { /* MC1 Channel 4 */
1294 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1), 1296 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1),
1295 .driver_data = IVT_PCI_UNCORE_IMC, 1297 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 7),
1296 }, 1298 },
1297 { /* QPI0 Port 0 */ 1299 { /* QPI0 Port 0 */
1298 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32), 1300 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32),
1299 .driver_data = IVT_PCI_UNCORE_QPI, 1301 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 0),
1300 }, 1302 },
1301 { /* QPI0 Port 1 */ 1303 { /* QPI0 Port 1 */
1302 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33), 1304 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33),
1303 .driver_data = IVT_PCI_UNCORE_QPI, 1305 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 1),
1304 }, 1306 },
1305 { /* QPI1 Port 2 */ 1307 { /* QPI1 Port 2 */
1306 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a), 1308 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a),
1307 .driver_data = IVT_PCI_UNCORE_QPI, 1309 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 2),
1308 }, 1310 },
1309 { /* R2PCIe */ 1311 { /* R2PCIe */
1310 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34), 1312 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34),
1311 .driver_data = IVT_PCI_UNCORE_R2PCIE, 1313 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R2PCIE, 0),
1312 }, 1314 },
1313 { /* R3QPI0 Link 0 */ 1315 { /* R3QPI0 Link 0 */
1314 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36), 1316 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36),
1315 .driver_data = IVT_PCI_UNCORE_R3QPI, 1317 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 0),
1316 }, 1318 },
1317 { /* R3QPI0 Link 1 */ 1319 { /* R3QPI0 Link 1 */
1318 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37), 1320 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37),
1319 .driver_data = IVT_PCI_UNCORE_R3QPI, 1321 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 1),
1320 }, 1322 },
1321 { /* R3QPI1 Link 2 */ 1323 { /* R3QPI1 Link 2 */
1322 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e), 1324 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e),
1323 .driver_data = IVT_PCI_UNCORE_R3QPI, 1325 .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 2),
1324 }, 1326 },
1325 { /* end: all zeroes */ } 1327 { /* end: all zeroes */ }
1326}; 1328};
@@ -3167,16 +3169,24 @@ static bool pcidrv_registered;
3167/* 3169/*
3168 * add a pci uncore device 3170 * add a pci uncore device
3169 */ 3171 */
3170static int uncore_pci_add(struct intel_uncore_type *type, struct pci_dev *pdev) 3172static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3171{ 3173{
3172 struct intel_uncore_pmu *pmu; 3174 struct intel_uncore_pmu *pmu;
3173 struct intel_uncore_box *box; 3175 struct intel_uncore_box *box;
3174 int i, phys_id; 3176 struct intel_uncore_type *type;
3177 int phys_id;
3175 3178
3176 phys_id = pcibus_to_physid[pdev->bus->number]; 3179 phys_id = pcibus_to_physid[pdev->bus->number];
3177 if (phys_id < 0) 3180 if (phys_id < 0)
3178 return -ENODEV; 3181 return -ENODEV;
3179 3182
3183 if (UNCORE_PCI_DEV_TYPE(id->driver_data) == UNCORE_EXTRA_PCI_DEV) {
3184 extra_pci_dev[phys_id][UNCORE_PCI_DEV_IDX(id->driver_data)] = pdev;
3185 pci_set_drvdata(pdev, NULL);
3186 return 0;
3187 }
3188
3189 type = pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)];
3180 box = uncore_alloc_box(type, 0); 3190 box = uncore_alloc_box(type, 0);
3181 if (!box) 3191 if (!box)
3182 return -ENOMEM; 3192 return -ENOMEM;
@@ -3185,21 +3195,11 @@ static int uncore_pci_add(struct intel_uncore_type *type, struct pci_dev *pdev)
3185 * for performance monitoring unit with multiple boxes, 3195 * for performance monitoring unit with multiple boxes,
3186 * each box has a different function id. 3196 * each box has a different function id.
3187 */ 3197 */
3188 for (i = 0; i < type->num_boxes; i++) { 3198 pmu = &type->pmus[UNCORE_PCI_DEV_IDX(id->driver_data)];
3189 pmu = &type->pmus[i]; 3199 if (pmu->func_id < 0)
3190 if (pmu->func_id == pdev->devfn) 3200 pmu->func_id = pdev->devfn;
3191 break; 3201 else
3192 if (pmu->func_id < 0) { 3202 WARN_ON_ONCE(pmu->func_id != pdev->devfn);
3193 pmu->func_id = pdev->devfn;
3194 break;
3195 }
3196 pmu = NULL;
3197 }
3198
3199 if (!pmu) {
3200 kfree(box);
3201 return -EINVAL;
3202 }
3203 3203
3204 box->phys_id = phys_id; 3204 box->phys_id = phys_id;
3205 box->pci_dev = pdev; 3205 box->pci_dev = pdev;
@@ -3217,9 +3217,22 @@ static int uncore_pci_add(struct intel_uncore_type *type, struct pci_dev *pdev)
3217static void uncore_pci_remove(struct pci_dev *pdev) 3217static void uncore_pci_remove(struct pci_dev *pdev)
3218{ 3218{
3219 struct intel_uncore_box *box = pci_get_drvdata(pdev); 3219 struct intel_uncore_box *box = pci_get_drvdata(pdev);
3220 struct intel_uncore_pmu *pmu = box->pmu; 3220 struct intel_uncore_pmu *pmu;
3221 int cpu, phys_id = pcibus_to_physid[pdev->bus->number]; 3221 int i, cpu, phys_id = pcibus_to_physid[pdev->bus->number];
3222 3222
3223 box = pci_get_drvdata(pdev);
3224 if (!box) {
3225 for (i = 0; i < UNCORE_EXTRA_PCI_DEV_MAX; i++) {
3226 if (extra_pci_dev[phys_id][i] == pdev) {
3227 extra_pci_dev[phys_id][i] = NULL;
3228 break;
3229 }
3230 }
3231 WARN_ON_ONCE(i >= UNCORE_EXTRA_PCI_DEV_MAX);
3232 return;
3233 }
3234
3235 pmu = box->pmu;
3223 if (WARN_ON_ONCE(phys_id != box->phys_id)) 3236 if (WARN_ON_ONCE(phys_id != box->phys_id))
3224 return; 3237 return;
3225 3238
@@ -3240,12 +3253,6 @@ static void uncore_pci_remove(struct pci_dev *pdev)
3240 kfree(box); 3253 kfree(box);
3241} 3254}
3242 3255
3243static int uncore_pci_probe(struct pci_dev *pdev,
3244 const struct pci_device_id *id)
3245{
3246 return uncore_pci_add(pci_uncores[id->driver_data], pdev);
3247}
3248
3249static int __init uncore_pci_init(void) 3256static int __init uncore_pci_init(void)
3250{ 3257{
3251 int ret; 3258 int ret;
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
index 47b3d00c9d89..ede5a8c1d29e 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
@@ -12,6 +12,15 @@
12#define UNCORE_PMC_IDX_FIXED UNCORE_PMC_IDX_MAX_GENERIC 12#define UNCORE_PMC_IDX_FIXED UNCORE_PMC_IDX_MAX_GENERIC
13#define UNCORE_PMC_IDX_MAX (UNCORE_PMC_IDX_FIXED + 1) 13#define UNCORE_PMC_IDX_MAX (UNCORE_PMC_IDX_FIXED + 1)
14 14
15#define UNCORE_PCI_DEV_DATA(type, idx) ((type << 8) | idx)
16#define UNCORE_PCI_DEV_TYPE(data) ((data >> 8) & 0xff)
17#define UNCORE_PCI_DEV_IDX(data) (data & 0xff)
18#define UNCORE_EXTRA_PCI_DEV 0xff
19#define UNCORE_EXTRA_PCI_DEV_MAX 0
20
21/* support up to 8 sockets */
22#define UNCORE_SOCKET_MAX 8
23
15#define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff) 24#define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff)
16 25
17/* SNB event control */ 26/* SNB event control */