Skip to content

Commit b33f908

Browse files
committed
Merge branch 'for-next/perf' of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux into for-next/core
2 parents 24cf262 + 9bcb929 commit b33f908

File tree

9 files changed

+1018
-47
lines changed

9 files changed

+1018
-47
lines changed

Documentation/arm64/silicon-errata.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ stable kernels.
7878
| Hisilicon | Hip0{5,6,7} | #161010101 | HISILICON_ERRATUM_161010101 |
7979
| Hisilicon | Hip0{6,7} | #161010701 | N/A |
8080
| Hisilicon | Hip07 | #161600802 | HISILICON_ERRATUM_161600802 |
81+
| Hisilicon | Hip08 SMMU PMCG | #162001800 | N/A |
8182
| | | | |
8283
| Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 |
8384
| Qualcomm Tech. | Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009 |

arch/arm64/kernel/perf_event.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ static inline u64 armv8pmu_read_hw_counter(struct perf_event *event)
431431
return val;
432432
}
433433

434-
static inline u64 armv8pmu_read_counter(struct perf_event *event)
434+
static u64 armv8pmu_read_counter(struct perf_event *event)
435435
{
436436
struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
437437
struct hw_perf_event *hwc = &event->hw;
@@ -468,7 +468,7 @@ static inline void armv8pmu_write_hw_counter(struct perf_event *event,
468468
}
469469
}
470470

471-
static inline void armv8pmu_write_counter(struct perf_event *event, u64 value)
471+
static void armv8pmu_write_counter(struct perf_event *event, u64 value)
472472
{
473473
struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
474474
struct hw_perf_event *hwc = &event->hw;

drivers/acpi/arm64/iort.c

Lines changed: 107 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,8 @@ static struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
356356
if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) {
357357
if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
358358
node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX ||
359-
node->type == ACPI_IORT_NODE_SMMU_V3) {
359+
node->type == ACPI_IORT_NODE_SMMU_V3 ||
360+
node->type == ACPI_IORT_NODE_PMCG) {
360361
*id_out = map->output_base;
361362
return parent;
362363
}
@@ -394,6 +395,8 @@ static int iort_get_id_mapping_index(struct acpi_iort_node *node)
394395
}
395396

396397
return smmu->id_mapping_index;
398+
case ACPI_IORT_NODE_PMCG:
399+
return 0;
397400
default:
398401
return -EINVAL;
399402
}
@@ -1218,14 +1221,23 @@ static void __init arm_smmu_v3_init_resources(struct resource *res,
12181221
}
12191222
}
12201223

1221-
static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node)
1224+
static void __init arm_smmu_v3_dma_configure(struct device *dev,
1225+
struct acpi_iort_node *node)
12221226
{
12231227
struct acpi_iort_smmu_v3 *smmu;
1228+
enum dev_dma_attr attr;
12241229

12251230
/* Retrieve SMMUv3 specific data */
12261231
smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
12271232

1228-
return smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE;
1233+
attr = (smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE) ?
1234+
DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT;
1235+
1236+
/* We expect the dma masks to be equivalent for all SMMUv3 set-ups */
1237+
dev->dma_mask = &dev->coherent_dma_mask;
1238+
1239+
/* Configure DMA for the page table walker */
1240+
acpi_dma_configure(dev, attr);
12291241
}
12301242

12311243
#if defined(CONFIG_ACPI_NUMA)
@@ -1307,40 +1319,113 @@ static void __init arm_smmu_init_resources(struct resource *res,
13071319
}
13081320
}
13091321

1310-
static bool __init arm_smmu_is_coherent(struct acpi_iort_node *node)
1322+
static void __init arm_smmu_dma_configure(struct device *dev,
1323+
struct acpi_iort_node *node)
13111324
{
13121325
struct acpi_iort_smmu *smmu;
1326+
enum dev_dma_attr attr;
13131327

13141328
/* Retrieve SMMU specific data */
13151329
smmu = (struct acpi_iort_smmu *)node->node_data;
13161330

1317-
return smmu->flags & ACPI_IORT_SMMU_COHERENT_WALK;
1331+
attr = (smmu->flags & ACPI_IORT_SMMU_COHERENT_WALK) ?
1332+
DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT;
1333+
1334+
/* We expect the dma masks to be equivalent for SMMU set-ups */
1335+
dev->dma_mask = &dev->coherent_dma_mask;
1336+
1337+
/* Configure DMA for the page table walker */
1338+
acpi_dma_configure(dev, attr);
1339+
}
1340+
1341+
static int __init arm_smmu_v3_pmcg_count_resources(struct acpi_iort_node *node)
1342+
{
1343+
struct acpi_iort_pmcg *pmcg;
1344+
1345+
/* Retrieve PMCG specific data */
1346+
pmcg = (struct acpi_iort_pmcg *)node->node_data;
1347+
1348+
/*
1349+
* There are always 2 memory resources.
1350+
* If the overflow_gsiv is present then add that for a total of 3.
1351+
*/
1352+
return pmcg->overflow_gsiv ? 3 : 2;
1353+
}
1354+
1355+
static void __init arm_smmu_v3_pmcg_init_resources(struct resource *res,
1356+
struct acpi_iort_node *node)
1357+
{
1358+
struct acpi_iort_pmcg *pmcg;
1359+
1360+
/* Retrieve PMCG specific data */
1361+
pmcg = (struct acpi_iort_pmcg *)node->node_data;
1362+
1363+
res[0].start = pmcg->page0_base_address;
1364+
res[0].end = pmcg->page0_base_address + SZ_4K - 1;
1365+
res[0].flags = IORESOURCE_MEM;
1366+
res[1].start = pmcg->page1_base_address;
1367+
res[1].end = pmcg->page1_base_address + SZ_4K - 1;
1368+
res[1].flags = IORESOURCE_MEM;
1369+
1370+
if (pmcg->overflow_gsiv)
1371+
acpi_iort_register_irq(pmcg->overflow_gsiv, "overflow",
1372+
ACPI_EDGE_SENSITIVE, &res[2]);
1373+
}
1374+
1375+
static struct acpi_platform_list pmcg_plat_info[] __initdata = {
1376+
/* HiSilicon Hip08 Platform */
1377+
{"HISI ", "HIP08 ", 0, ACPI_SIG_IORT, greater_than_or_equal,
1378+
"Erratum #162001800", IORT_SMMU_V3_PMCG_HISI_HIP08},
1379+
{ }
1380+
};
1381+
1382+
static int __init arm_smmu_v3_pmcg_add_platdata(struct platform_device *pdev)
1383+
{
1384+
u32 model;
1385+
int idx;
1386+
1387+
idx = acpi_match_platform_list(pmcg_plat_info);
1388+
if (idx >= 0)
1389+
model = pmcg_plat_info[idx].data;
1390+
else
1391+
model = IORT_SMMU_V3_PMCG_GENERIC;
1392+
1393+
return platform_device_add_data(pdev, &model, sizeof(model));
13181394
}
13191395

13201396
struct iort_dev_config {
13211397
const char *name;
13221398
int (*dev_init)(struct acpi_iort_node *node);
1323-
bool (*dev_is_coherent)(struct acpi_iort_node *node);
1399+
void (*dev_dma_configure)(struct device *dev,
1400+
struct acpi_iort_node *node);
13241401
int (*dev_count_resources)(struct acpi_iort_node *node);
13251402
void (*dev_init_resources)(struct resource *res,
13261403
struct acpi_iort_node *node);
13271404
int (*dev_set_proximity)(struct device *dev,
13281405
struct acpi_iort_node *node);
1406+
int (*dev_add_platdata)(struct platform_device *pdev);
13291407
};
13301408

13311409
static const struct iort_dev_config iort_arm_smmu_v3_cfg __initconst = {
13321410
.name = "arm-smmu-v3",
1333-
.dev_is_coherent = arm_smmu_v3_is_coherent,
1411+
.dev_dma_configure = arm_smmu_v3_dma_configure,
13341412
.dev_count_resources = arm_smmu_v3_count_resources,
13351413
.dev_init_resources = arm_smmu_v3_init_resources,
13361414
.dev_set_proximity = arm_smmu_v3_set_proximity,
13371415
};
13381416

13391417
static const struct iort_dev_config iort_arm_smmu_cfg __initconst = {
13401418
.name = "arm-smmu",
1341-
.dev_is_coherent = arm_smmu_is_coherent,
1419+
.dev_dma_configure = arm_smmu_dma_configure,
13421420
.dev_count_resources = arm_smmu_count_resources,
1343-
.dev_init_resources = arm_smmu_init_resources
1421+
.dev_init_resources = arm_smmu_init_resources,
1422+
};
1423+
1424+
static const struct iort_dev_config iort_arm_smmu_v3_pmcg_cfg __initconst = {
1425+
.name = "arm-smmu-v3-pmcg",
1426+
.dev_count_resources = arm_smmu_v3_pmcg_count_resources,
1427+
.dev_init_resources = arm_smmu_v3_pmcg_init_resources,
1428+
.dev_add_platdata = arm_smmu_v3_pmcg_add_platdata,
13441429
};
13451430

13461431
static __init const struct iort_dev_config *iort_get_dev_cfg(
@@ -1351,6 +1436,8 @@ static __init const struct iort_dev_config *iort_get_dev_cfg(
13511436
return &iort_arm_smmu_v3_cfg;
13521437
case ACPI_IORT_NODE_SMMU:
13531438
return &iort_arm_smmu_cfg;
1439+
case ACPI_IORT_NODE_PMCG:
1440+
return &iort_arm_smmu_v3_pmcg_cfg;
13541441
default:
13551442
return NULL;
13561443
}
@@ -1368,7 +1455,6 @@ static int __init iort_add_platform_device(struct acpi_iort_node *node,
13681455
struct fwnode_handle *fwnode;
13691456
struct platform_device *pdev;
13701457
struct resource *r;
1371-
enum dev_dma_attr attr;
13721458
int ret, count;
13731459

13741460
pdev = platform_device_alloc(ops->name, PLATFORM_DEVID_AUTO);
@@ -1402,19 +1488,19 @@ static int __init iort_add_platform_device(struct acpi_iort_node *node,
14021488
goto dev_put;
14031489

14041490
/*
1405-
* Add a copy of IORT node pointer to platform_data to
1406-
* be used to retrieve IORT data information.
1491+
* Platform devices based on PMCG nodes uses platform_data to
1492+
* pass the hardware model info to the driver. For others, add
1493+
* a copy of IORT node pointer to platform_data to be used to
1494+
* retrieve IORT data information.
14071495
*/
1408-
ret = platform_device_add_data(pdev, &node, sizeof(node));
1496+
if (ops->dev_add_platdata)
1497+
ret = ops->dev_add_platdata(pdev);
1498+
else
1499+
ret = platform_device_add_data(pdev, &node, sizeof(node));
1500+
14091501
if (ret)
14101502
goto dev_put;
14111503

1412-
/*
1413-
* We expect the dma masks to be equivalent for
1414-
* all SMMUs set-ups
1415-
*/
1416-
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
1417-
14181504
fwnode = iort_get_fwnode(node);
14191505

14201506
if (!fwnode) {
@@ -1424,11 +1510,8 @@ static int __init iort_add_platform_device(struct acpi_iort_node *node,
14241510

14251511
pdev->dev.fwnode = fwnode;
14261512

1427-
attr = ops->dev_is_coherent && ops->dev_is_coherent(node) ?
1428-
DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT;
1429-
1430-
/* Configure DMA for the page table walker */
1431-
acpi_dma_configure(&pdev->dev, attr);
1513+
if (ops->dev_dma_configure)
1514+
ops->dev_dma_configure(&pdev->dev, node);
14321515

14331516
iort_set_device_domain(&pdev->dev, node);
14341517

drivers/perf/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ config ARM_PMU_ACPI
5252
depends on ARM_PMU && ACPI
5353
def_bool y
5454

55+
config ARM_SMMU_V3_PMU
56+
tristate "ARM SMMUv3 Performance Monitors Extension"
57+
depends on ARM64 && ACPI && ARM_SMMU_V3
58+
help
59+
Provides support for the ARM SMMUv3 Performance Monitor Counter
60+
Groups (PMCG), which provide monitoring of transactions passing
61+
through the SMMU and allow the resulting information to be filtered
62+
based on the Stream ID of the corresponding master.
63+
5564
config ARM_DSU_PMU
5665
tristate "ARM DynamIQ Shared Unit (DSU) PMU"
5766
depends on ARM64

drivers/perf/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ obj-$(CONFIG_ARM_CCN) += arm-ccn.o
44
obj-$(CONFIG_ARM_DSU_PMU) += arm_dsu_pmu.o
55
obj-$(CONFIG_ARM_PMU) += arm_pmu.o arm_pmu_platform.o
66
obj-$(CONFIG_ARM_PMU_ACPI) += arm_pmu_acpi.o
7+
obj-$(CONFIG_ARM_SMMU_V3_PMU) += arm_smmuv3_pmu.o
78
obj-$(CONFIG_HISI_PMU) += hisilicon/
89
obj-$(CONFIG_QCOM_L2_PMU) += qcom_l2_pmu.o
910
obj-$(CONFIG_QCOM_L3_PMU) += qcom_l3_pmu.o

drivers/perf/arm-cci.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,21 +1684,24 @@ static int cci_pmu_probe(struct platform_device *pdev)
16841684
raw_spin_lock_init(&cci_pmu->hw_events.pmu_lock);
16851685
mutex_init(&cci_pmu->reserve_mutex);
16861686
atomic_set(&cci_pmu->active_events, 0);
1687-
cci_pmu->cpu = get_cpu();
1688-
1689-
ret = cci_pmu_init(cci_pmu, pdev);
1690-
if (ret) {
1691-
put_cpu();
1692-
return ret;
1693-
}
16941687

1688+
cci_pmu->cpu = raw_smp_processor_id();
1689+
g_cci_pmu = cci_pmu;
16951690
cpuhp_setup_state_nocalls(CPUHP_AP_PERF_ARM_CCI_ONLINE,
16961691
"perf/arm/cci:online", NULL,
16971692
cci_pmu_offline_cpu);
1698-
put_cpu();
1699-
g_cci_pmu = cci_pmu;
1693+
1694+
ret = cci_pmu_init(cci_pmu, pdev);
1695+
if (ret)
1696+
goto error_pmu_init;
1697+
17001698
pr_info("ARM %s PMU driver probed", cci_pmu->model->name);
17011699
return 0;
1700+
1701+
error_pmu_init:
1702+
cpuhp_remove_state(CPUHP_AP_PERF_ARM_CCI_ONLINE);
1703+
g_cci_pmu = NULL;
1704+
return ret;
17021705
}
17031706

17041707
static int cci_pmu_remove(struct platform_device *pdev)

drivers/perf/arm-ccn.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ struct arm_ccn_dt {
167167

168168
struct hrtimer hrtimer;
169169

170-
cpumask_t cpu;
170+
unsigned int cpu;
171171
struct hlist_node node;
172172

173173
struct pmu pmu;
@@ -559,7 +559,7 @@ static ssize_t arm_ccn_pmu_cpumask_show(struct device *dev,
559559
{
560560
struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev));
561561

562-
return cpumap_print_to_pagebuf(true, buf, &ccn->dt.cpu);
562+
return cpumap_print_to_pagebuf(true, buf, cpumask_of(ccn->dt.cpu));
563563
}
564564

565565
static struct device_attribute arm_ccn_pmu_cpumask_attr =
@@ -759,7 +759,7 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
759759
* mitigate this, we enforce CPU assignment to one, selected
760760
* processor (the one described in the "cpumask" attribute).
761761
*/
762-
event->cpu = cpumask_first(&ccn->dt.cpu);
762+
event->cpu = ccn->dt.cpu;
763763

764764
node_xp = CCN_CONFIG_NODE(event->attr.config);
765765
type = CCN_CONFIG_TYPE(event->attr.config);
@@ -1215,15 +1215,15 @@ static int arm_ccn_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
12151215
struct arm_ccn *ccn = container_of(dt, struct arm_ccn, dt);
12161216
unsigned int target;
12171217

1218-
if (!cpumask_test_and_clear_cpu(cpu, &dt->cpu))
1218+
if (cpu != dt->cpu)
12191219
return 0;
12201220
target = cpumask_any_but(cpu_online_mask, cpu);
12211221
if (target >= nr_cpu_ids)
12221222
return 0;
12231223
perf_pmu_migrate_context(&dt->pmu, cpu, target);
1224-
cpumask_set_cpu(target, &dt->cpu);
1224+
dt->cpu = target;
12251225
if (ccn->irq)
1226-
WARN_ON(irq_set_affinity_hint(ccn->irq, &dt->cpu) != 0);
1226+
WARN_ON(irq_set_affinity_hint(ccn->irq, cpumask_of(dt->cpu)));
12271227
return 0;
12281228
}
12291229

@@ -1299,29 +1299,30 @@ static int arm_ccn_pmu_init(struct arm_ccn *ccn)
12991299
}
13001300

13011301
/* Pick one CPU which we will use to collect data from CCN... */
1302-
cpumask_set_cpu(get_cpu(), &ccn->dt.cpu);
1302+
ccn->dt.cpu = raw_smp_processor_id();
13031303

13041304
/* Also make sure that the overflow interrupt is handled by this CPU */
13051305
if (ccn->irq) {
1306-
err = irq_set_affinity_hint(ccn->irq, &ccn->dt.cpu);
1306+
err = irq_set_affinity_hint(ccn->irq, cpumask_of(ccn->dt.cpu));
13071307
if (err) {
13081308
dev_err(ccn->dev, "Failed to set interrupt affinity!\n");
13091309
goto error_set_affinity;
13101310
}
13111311
}
13121312

1313+
cpuhp_state_add_instance_nocalls(CPUHP_AP_PERF_ARM_CCN_ONLINE,
1314+
&ccn->dt.node);
1315+
13131316
err = perf_pmu_register(&ccn->dt.pmu, name, -1);
13141317
if (err)
13151318
goto error_pmu_register;
13161319

1317-
cpuhp_state_add_instance_nocalls(CPUHP_AP_PERF_ARM_CCN_ONLINE,
1318-
&ccn->dt.node);
1319-
put_cpu();
13201320
return 0;
13211321

13221322
error_pmu_register:
1323+
cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_CCN_ONLINE,
1324+
&ccn->dt.node);
13231325
error_set_affinity:
1324-
put_cpu();
13251326
error_choose_name:
13261327
ida_simple_remove(&arm_ccn_pmu_ida, ccn->dt.id);
13271328
for (i = 0; i < ccn->num_xps; i++)

0 commit comments

Comments
 (0)