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

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>

authored by

Yan, Zheng and committed by
Ingo Molnar
899396cf 894e8d08

+68 -52
+59 -52
arch/x86/kernel/cpu/perf_event_intel_uncore.c
··· 6 6 /* pci bus to socket mapping */ 7 7 static int pcibus_to_physid[256] = { [0 ... 255] = -1, }; 8 8 9 + static struct pci_dev *extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX]; 10 + 9 11 static DEFINE_RAW_SPINLOCK(uncore_box_lock); 10 12 11 13 /* mask of cpus that collect uncore events */ ··· 809 807 static DEFINE_PCI_DEVICE_TABLE(snbep_uncore_pci_ids) = { 810 808 { /* Home Agent */ 811 809 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA), 812 - .driver_data = SNBEP_PCI_UNCORE_HA, 810 + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_HA, 0), 813 811 }, 814 812 { /* MC Channel 0 */ 815 813 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0), 816 - .driver_data = SNBEP_PCI_UNCORE_IMC, 814 + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 0), 817 815 }, 818 816 { /* MC Channel 1 */ 819 817 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1), 820 - .driver_data = SNBEP_PCI_UNCORE_IMC, 818 + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 1), 821 819 }, 822 820 { /* MC Channel 2 */ 823 821 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2), 824 - .driver_data = SNBEP_PCI_UNCORE_IMC, 822 + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 2), 825 823 }, 826 824 { /* MC Channel 3 */ 827 825 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3), 828 - .driver_data = SNBEP_PCI_UNCORE_IMC, 826 + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 3), 829 827 }, 830 828 { /* QPI Port 0 */ 831 829 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0), 832 - .driver_data = SNBEP_PCI_UNCORE_QPI, 830 + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 0), 833 831 }, 834 832 { /* QPI Port 1 */ 835 833 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1), 836 - .driver_data = SNBEP_PCI_UNCORE_QPI, 834 + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 1), 837 835 }, 838 836 { /* R2PCIe */ 839 837 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE), 840 - .driver_data = SNBEP_PCI_UNCORE_R2PCIE, 838 + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R2PCIE, 0), 841 839 }, 842 840 { /* R3QPI Link 0 */ 843 841 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0), 844 - .driver_data = SNBEP_PCI_UNCORE_R3QPI, 842 + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 0), 845 843 }, 846 844 { /* R3QPI Link 1 */ 847 845 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1), 848 - .driver_data = SNBEP_PCI_UNCORE_R3QPI, 846 + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 1), 849 847 }, 850 848 { /* end: all zeroes */ } 851 849 }; ··· 1258 1256 static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = { 1259 1257 { /* Home Agent 0 */ 1260 1258 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30), 1261 - .driver_data = IVT_PCI_UNCORE_HA, 1259 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_HA, 0), 1262 1260 }, 1263 1261 { /* Home Agent 1 */ 1264 1262 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38), 1265 - .driver_data = IVT_PCI_UNCORE_HA, 1263 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_HA, 1), 1266 1264 }, 1267 1265 { /* MC0 Channel 0 */ 1268 1266 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4), 1269 - .driver_data = IVT_PCI_UNCORE_IMC, 1267 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 0), 1270 1268 }, 1271 1269 { /* MC0 Channel 1 */ 1272 1270 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5), 1273 - .driver_data = IVT_PCI_UNCORE_IMC, 1271 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 1), 1274 1272 }, 1275 1273 { /* MC0 Channel 3 */ 1276 1274 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0), 1277 - .driver_data = IVT_PCI_UNCORE_IMC, 1275 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 2), 1278 1276 }, 1279 1277 { /* MC0 Channel 4 */ 1280 1278 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1), 1281 - .driver_data = IVT_PCI_UNCORE_IMC, 1279 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 3), 1282 1280 }, 1283 1281 { /* MC1 Channel 0 */ 1284 1282 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4), 1285 - .driver_data = IVT_PCI_UNCORE_IMC, 1283 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 4), 1286 1284 }, 1287 1285 { /* MC1 Channel 1 */ 1288 1286 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5), 1289 - .driver_data = IVT_PCI_UNCORE_IMC, 1287 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 5), 1290 1288 }, 1291 1289 { /* MC1 Channel 3 */ 1292 1290 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0), 1293 - .driver_data = IVT_PCI_UNCORE_IMC, 1291 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 6), 1294 1292 }, 1295 1293 { /* MC1 Channel 4 */ 1296 1294 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1), 1297 - .driver_data = IVT_PCI_UNCORE_IMC, 1295 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 7), 1298 1296 }, 1299 1297 { /* QPI0 Port 0 */ 1300 1298 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32), 1301 - .driver_data = IVT_PCI_UNCORE_QPI, 1299 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 0), 1302 1300 }, 1303 1301 { /* QPI0 Port 1 */ 1304 1302 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33), 1305 - .driver_data = IVT_PCI_UNCORE_QPI, 1303 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 1), 1306 1304 }, 1307 1305 { /* QPI1 Port 2 */ 1308 1306 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a), 1309 - .driver_data = IVT_PCI_UNCORE_QPI, 1307 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 2), 1310 1308 }, 1311 1309 { /* R2PCIe */ 1312 1310 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34), 1313 - .driver_data = IVT_PCI_UNCORE_R2PCIE, 1311 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R2PCIE, 0), 1314 1312 }, 1315 1313 { /* R3QPI0 Link 0 */ 1316 1314 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36), 1317 - .driver_data = IVT_PCI_UNCORE_R3QPI, 1315 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 0), 1318 1316 }, 1319 1317 { /* R3QPI0 Link 1 */ 1320 1318 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37), 1321 - .driver_data = IVT_PCI_UNCORE_R3QPI, 1319 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 1), 1322 1320 }, 1323 1321 { /* R3QPI1 Link 2 */ 1324 1322 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e), 1325 - .driver_data = IVT_PCI_UNCORE_R3QPI, 1323 + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 2), 1326 1324 }, 1327 1325 { /* end: all zeroes */ } 1328 1326 }; ··· 3169 3167 /* 3170 3168 * add a pci uncore device 3171 3169 */ 3172 - static int uncore_pci_add(struct intel_uncore_type *type, struct pci_dev *pdev) 3170 + static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 3173 3171 { 3174 3172 struct intel_uncore_pmu *pmu; 3175 3173 struct intel_uncore_box *box; 3176 - int i, phys_id; 3174 + struct intel_uncore_type *type; 3175 + int phys_id; 3177 3176 3178 3177 phys_id = pcibus_to_physid[pdev->bus->number]; 3179 3178 if (phys_id < 0) 3180 3179 return -ENODEV; 3181 3180 3181 + if (UNCORE_PCI_DEV_TYPE(id->driver_data) == UNCORE_EXTRA_PCI_DEV) { 3182 + extra_pci_dev[phys_id][UNCORE_PCI_DEV_IDX(id->driver_data)] = pdev; 3183 + pci_set_drvdata(pdev, NULL); 3184 + return 0; 3185 + } 3186 + 3187 + type = pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)]; 3182 3188 box = uncore_alloc_box(type, 0); 3183 3189 if (!box) 3184 3190 return -ENOMEM; ··· 3195 3185 * for performance monitoring unit with multiple boxes, 3196 3186 * each box has a different function id. 3197 3187 */ 3198 - for (i = 0; i < type->num_boxes; i++) { 3199 - pmu = &type->pmus[i]; 3200 - if (pmu->func_id == pdev->devfn) 3201 - break; 3202 - if (pmu->func_id < 0) { 3203 - pmu->func_id = pdev->devfn; 3204 - break; 3205 - } 3206 - pmu = NULL; 3207 - } 3208 - 3209 - if (!pmu) { 3210 - kfree(box); 3211 - return -EINVAL; 3212 - } 3188 + pmu = &type->pmus[UNCORE_PCI_DEV_IDX(id->driver_data)]; 3189 + if (pmu->func_id < 0) 3190 + pmu->func_id = pdev->devfn; 3191 + else 3192 + WARN_ON_ONCE(pmu->func_id != pdev->devfn); 3213 3193 3214 3194 box->phys_id = phys_id; 3215 3195 box->pci_dev = pdev; ··· 3217 3217 static void uncore_pci_remove(struct pci_dev *pdev) 3218 3218 { 3219 3219 struct intel_uncore_box *box = pci_get_drvdata(pdev); 3220 - struct intel_uncore_pmu *pmu = box->pmu; 3221 - int cpu, phys_id = pcibus_to_physid[pdev->bus->number]; 3220 + struct intel_uncore_pmu *pmu; 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 3236 if (WARN_ON_ONCE(phys_id != box->phys_id)) 3224 3237 return; 3225 3238 ··· 3251 3238 3252 3239 WARN_ON_ONCE(atomic_read(&box->refcnt) != 1); 3253 3240 kfree(box); 3254 - } 3255 - 3256 - static int uncore_pci_probe(struct pci_dev *pdev, 3257 - const struct pci_device_id *id) 3258 - { 3259 - return uncore_pci_add(pci_uncores[id->driver_data], pdev); 3260 3241 } 3261 3242 3262 3243 static int __init uncore_pci_init(void)
+9
arch/x86/kernel/cpu/perf_event_intel_uncore.h
··· 12 12 #define UNCORE_PMC_IDX_FIXED UNCORE_PMC_IDX_MAX_GENERIC 13 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 24 #define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff) 16 25 17 26 /* SNB event control */