Skip to content

Commit 9a1aac8

Browse files
spandruvadajwrdegoede
authored andcommitted
platform/x86: ISST: PUNIT device mapping with Sub-NUMA clustering
On a multiple package system using Sub-NUMA clustering, there is an issue in mapping Linux CPU number to PUNIT PCI device when manufacturer decided to reuse the PCI bus number across packages. Bus number can be reused as long as they are in different domain or segment. In this case some CPU will fail to find a PCI device to issue SST requests. When bus numbers are reused across CPU packages, we are using proximity information by matching CPU numa node id to PUNIT PCI device numa node id. But on a package there can be only one PUNIT PCI device, but multiple numa nodes (one for each sub cluster). So, the numa node ID of the PUNIT PCI device can only match with one numa node id of CPUs in a sub cluster in the package. Since there can be only one PUNIT PCI device per package, if we match with numa node id of any sub cluster in that package, we can use that mapping for any CPU in that package. So, store the match information in a per package data structure and return the information when there is no match. While here, use defines for max bus number instead of hardcoding. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Link: https://lore.kernel.org/r/20220629194817.2418240-1-srinivas.pandruvada@linux.intel.com Reviewed-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
1 parent 221756e commit 9a1aac8

File tree

1 file changed

+32
-7
lines changed

1 file changed

+32
-7
lines changed

drivers/platform/x86/intel/speed_select_if/isst_if_common.c

+32-7
Original file line numberDiff line numberDiff line change
@@ -277,29 +277,38 @@ static int isst_if_get_platform_info(void __user *argp)
277277
return 0;
278278
}
279279

280+
#define ISST_MAX_BUS_NUMBER 2
280281

281282
struct isst_if_cpu_info {
282283
/* For BUS 0 and BUS 1 only, which we need for PUNIT interface */
283-
int bus_info[2];
284-
struct pci_dev *pci_dev[2];
284+
int bus_info[ISST_MAX_BUS_NUMBER];
285+
struct pci_dev *pci_dev[ISST_MAX_BUS_NUMBER];
285286
int punit_cpu_id;
286287
int numa_node;
287288
};
288289

290+
struct isst_if_pkg_info {
291+
struct pci_dev *pci_dev[ISST_MAX_BUS_NUMBER];
292+
};
293+
289294
static struct isst_if_cpu_info *isst_cpu_info;
295+
static struct isst_if_pkg_info *isst_pkg_info;
296+
290297
#define ISST_MAX_PCI_DOMAINS 8
291298

292299
static struct pci_dev *_isst_if_get_pci_dev(int cpu, int bus_no, int dev, int fn)
293300
{
294301
struct pci_dev *matched_pci_dev = NULL;
295302
struct pci_dev *pci_dev = NULL;
296-
int no_matches = 0;
303+
int no_matches = 0, pkg_id;
297304
int i, bus_number;
298305

299-
if (bus_no < 0 || bus_no > 1 || cpu < 0 || cpu >= nr_cpu_ids ||
300-
cpu >= num_possible_cpus())
306+
if (bus_no < 0 || bus_no >= ISST_MAX_BUS_NUMBER || cpu < 0 ||
307+
cpu >= nr_cpu_ids || cpu >= num_possible_cpus())
301308
return NULL;
302309

310+
pkg_id = topology_physical_package_id(cpu);
311+
303312
bus_number = isst_cpu_info[cpu].bus_info[bus_no];
304313
if (bus_number < 0)
305314
return NULL;
@@ -324,6 +333,8 @@ static struct pci_dev *_isst_if_get_pci_dev(int cpu, int bus_no, int dev, int fn
324333
}
325334

326335
if (node == isst_cpu_info[cpu].numa_node) {
336+
isst_pkg_info[pkg_id].pci_dev[bus_no] = _pci_dev;
337+
327338
pci_dev = _pci_dev;
328339
break;
329340
}
@@ -342,6 +353,10 @@ static struct pci_dev *_isst_if_get_pci_dev(int cpu, int bus_no, int dev, int fn
342353
if (!pci_dev && no_matches == 1)
343354
pci_dev = matched_pci_dev;
344355

356+
/* Return pci_dev pointer for any matched CPU in the package */
357+
if (!pci_dev)
358+
pci_dev = isst_pkg_info[pkg_id].pci_dev[bus_no];
359+
345360
return pci_dev;
346361
}
347362

@@ -361,8 +376,8 @@ struct pci_dev *isst_if_get_pci_dev(int cpu, int bus_no, int dev, int fn)
361376
{
362377
struct pci_dev *pci_dev;
363378

364-
if (bus_no < 0 || bus_no > 1 || cpu < 0 || cpu >= nr_cpu_ids ||
365-
cpu >= num_possible_cpus())
379+
if (bus_no < 0 || bus_no >= ISST_MAX_BUS_NUMBER || cpu < 0 ||
380+
cpu >= nr_cpu_ids || cpu >= num_possible_cpus())
366381
return NULL;
367382

368383
pci_dev = isst_cpu_info[cpu].pci_dev[bus_no];
@@ -417,10 +432,19 @@ static int isst_if_cpu_info_init(void)
417432
if (!isst_cpu_info)
418433
return -ENOMEM;
419434

435+
isst_pkg_info = kcalloc(topology_max_packages(),
436+
sizeof(*isst_pkg_info),
437+
GFP_KERNEL);
438+
if (!isst_pkg_info) {
439+
kfree(isst_cpu_info);
440+
return -ENOMEM;
441+
}
442+
420443
ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
421444
"platform/x86/isst-if:online",
422445
isst_if_cpu_online, NULL);
423446
if (ret < 0) {
447+
kfree(isst_pkg_info);
424448
kfree(isst_cpu_info);
425449
return ret;
426450
}
@@ -433,6 +457,7 @@ static int isst_if_cpu_info_init(void)
433457
static void isst_if_cpu_info_exit(void)
434458
{
435459
cpuhp_remove_state(isst_if_online_id);
460+
kfree(isst_pkg_info);
436461
kfree(isst_cpu_info);
437462
};
438463

0 commit comments

Comments
 (0)