[PATCH v3 1/3] perf/smmuv3: Don't reserve the PMCG register spaces

Robin Murphy robin.murphy at arm.com
Fri Jan 29 10:06:55 EST 2021


On 2021-01-27 11:32, Zhen Lei wrote:
> According to the SMMUv3 specification:
> Each PMCG counter group is represented by one 4KB page (Page 0) with one
> optional additional 4KB page (Page 1), both of which are at IMPLEMENTATION
> DEFINED base addresses.
> 
> This means that the PMCG register spaces may be within the 64KB pages of
> the SMMUv3 register space. When both the SMMU and PMCG drivers reserve
> their own resources, a resource conflict occurs.
> 
> To avoid this conflict, don't reserve the PMCG regions.

I'm still not a fan of this get_and_ioremap notion in general, 
especially when the "helper" function ends up over twice the size of all 
the code it replaces[1], but for the actual functional change here,

Reviewed-by: Robin Murphy <robin.murphy at arm.com>

> Suggested-by: Robin Murphy <robin.murphy at arm.com>
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
> ---
>   drivers/perf/arm_smmuv3_pmu.c | 27 +++++++++++++++++++++++++--
>   1 file changed, 25 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
> index 74474bb322c3f26..e5e505a0804fe53 100644
> --- a/drivers/perf/arm_smmuv3_pmu.c
> +++ b/drivers/perf/arm_smmuv3_pmu.c
> @@ -761,6 +761,29 @@ static void smmu_pmu_get_acpi_options(struct smmu_pmu *smmu_pmu)
>   	dev_notice(smmu_pmu->dev, "option mask 0x%x\n", smmu_pmu->options);
>   }
>   
> +static void __iomem *
> +smmu_pmu_get_and_ioremap_resource(struct platform_device *pdev,
> +				  unsigned int index,
> +				  struct resource **res)
> +{
> +	void __iomem *base;
> +	struct resource *r;
> +
> +	r = platform_get_resource(pdev, IORESOURCE_MEM, index);
> +	if (!r) {
> +		dev_err(&pdev->dev, "invalid resource\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +	if (res)
> +		*res = r;
> +
> +	base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
> +	if (!base)
> +		return ERR_PTR(-ENOMEM);
> +
> +	return base;
> +}
> +
>   static int smmu_pmu_probe(struct platform_device *pdev)
>   {
>   	struct smmu_pmu *smmu_pmu;
> @@ -793,7 +816,7 @@ static int smmu_pmu_probe(struct platform_device *pdev)
>   		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
>   	};
>   
> -	smmu_pmu->reg_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res_0);
> +	smmu_pmu->reg_base = smmu_pmu_get_and_ioremap_resource(pdev, 0, &res_0);
>   	if (IS_ERR(smmu_pmu->reg_base))
>   		return PTR_ERR(smmu_pmu->reg_base);
>   
> @@ -801,7 +824,7 @@ static int smmu_pmu_probe(struct platform_device *pdev)
>   
>   	/* Determine if page 1 is present */
>   	if (cfgr & SMMU_PMCG_CFGR_RELOC_CTRS) {
> -		smmu_pmu->reloc_base = devm_platform_ioremap_resource(pdev, 1);
> +		smmu_pmu->reloc_base = smmu_pmu_get_and_ioremap_resource(pdev, 1, NULL);
>   		if (IS_ERR(smmu_pmu->reloc_base))
>   			return PTR_ERR(smmu_pmu->reloc_base);
>   	} else {
> 

[1]
----->8-----
  drivers/perf/arm_smmuv3_pmu.c | 35 +++++++++--------------------------
  1 file changed, 9 insertions(+), 26 deletions(-)

diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
index e5e505a0804f..c9adbc7b55a1 100644
--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -761,33 +761,10 @@ static void smmu_pmu_get_acpi_options(struct 
smmu_pmu *smmu_pmu)
  	dev_notice(smmu_pmu->dev, "option mask 0x%x\n", smmu_pmu->options);
  }

-static void __iomem *
-smmu_pmu_get_and_ioremap_resource(struct platform_device *pdev,
-				  unsigned int index,
-				  struct resource **res)
-{
-	void __iomem *base;
-	struct resource *r;
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, index);
-	if (!r) {
-		dev_err(&pdev->dev, "invalid resource\n");
-		return ERR_PTR(-EINVAL);
-	}
-	if (res)
-		*res = r;
-
-	base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
-	if (!base)
-		return ERR_PTR(-ENOMEM);
-
-	return base;
-}
-
  static int smmu_pmu_probe(struct platform_device *pdev)
  {
  	struct smmu_pmu *smmu_pmu;
-	struct resource *res_0;
+	struct resource *res_0, *res_1;
  	u32 cfgr, reg_size;
  	u64 ceid_64[2];
  	int irq, err;
@@ -816,7 +793,10 @@ static int smmu_pmu_probe(struct platform_device *pdev)
  		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
  	};

-	smmu_pmu->reg_base = smmu_pmu_get_and_ioremap_resource(pdev, 0, &res_0);
+	res_0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res_0)
+		return ERR_PTR(-EINVAL);
+	smmu_pmu->reg_base = devm_ioremap(dev, res_0->start, 
resource_size(res_0));
  	if (IS_ERR(smmu_pmu->reg_base))
  		return PTR_ERR(smmu_pmu->reg_base);

@@ -824,7 +804,10 @@ static int smmu_pmu_probe(struct platform_device *pdev)

  	/* Determine if page 1 is present */
  	if (cfgr & SMMU_PMCG_CFGR_RELOC_CTRS) {
-		smmu_pmu->reloc_base = smmu_pmu_get_and_ioremap_resource(pdev, 1, NULL);
+		res_1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+		if (!res_1)
+			return -EINVAL;
+		smmu_pmu->reloc_base = devm_ioremap(dev, res_1->start, 
resource_size(res_1));
  		if (IS_ERR(smmu_pmu->reloc_base))
  			return PTR_ERR(smmu_pmu->reloc_base);
  	} else {



More information about the linux-arm-kernel mailing list