public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Jason Gunthorpe <jgg@nvidia.com>
To: Michael Shavit <mshavit@google.com>
Cc: iommu@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, will@kernel.org,
	robin.murphy@arm.com, nicolinc@nvidia.com,
	jean-philippe@linaro.org
Subject: Re: [PATCH v2 6/8] iommu/arm-smmu-v3: Refactor write_ctx_desc
Date: Tue, 1 Aug 2023 11:18:21 -0300	[thread overview]
Message-ID: <ZMkULTvwIIE3zo5+@nvidia.com> (raw)
In-Reply-To: <20230731184817.v2.6.I219054a6cf538df5bb22f4ada2d9933155d6058c@changeid>

On Mon, Jul 31, 2023 at 06:48:16PM +0800, Michael Shavit wrote:
> Update arm_smmu_write_ctx_desc and downstream functions to operate on
> a master instead of an smmu domain. We expect arm_smmu_write_ctx_desc()
> to only be called to write a CD entry into a CD table owned by the
> master. Under the hood, arm_smmu_write_ctx_desc still fetches the CD
> table from the domain that is attached to the master, but a subsequent
> commit will move that table's ownership to the master.
> 
> Note that this change isn't a nop refactor since SVA will call
> arm_smmu_write_ctx_desc in a loop for every master the domain is
> attached to despite the fact that they all share the same CD table. This
> loop may look weird but becomes necessary when the CD table becomes
> per-master in a subsequent commit.
> 
> Signed-off-by: Michael Shavit <mshavit@google.com>
> ---
> 
> Changes in v2:
> - minor style fixes
> 
> Changes in v1:
> - arm_smmu_write_ctx_desc now get's the CD table to write to from the
>   master parameter instead of a distinct parameter. This works well
>   because the CD table being written to should always be owned by the
>   master by the end of this series. This version no longer allows master
>   to be NULL.
> 
>  .../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c   | 33 +++++++++--
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 59 ++++++++-----------
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  2 +-
>  3 files changed, 53 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> index 968559d625c40..8242ee3405f2d 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> @@ -45,9 +45,11 @@ static struct arm_smmu_ctx_desc *
>  arm_smmu_share_asid(struct mm_struct *mm, u16 asid)
>  {
>  	int ret;
> +	unsigned long flags;
>  	u32 new_asid;
>  	struct arm_smmu_ctx_desc *cd;
>  	struct arm_smmu_device *smmu;
> +	struct arm_smmu_master *master;
>  	struct arm_smmu_domain *smmu_domain;
>  
>  	cd = xa_load(&arm_smmu_asid_xa, asid);
> @@ -80,7 +82,11 @@ arm_smmu_share_asid(struct mm_struct *mm, u16 asid)
>  	 * be some overlap between use of both ASIDs, until we invalidate the
>  	 * TLB.
>  	 */
> -	arm_smmu_write_ctx_desc(smmu_domain, 0, cd);
> +	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
> +	list_for_each_entry(master, &smmu_domain->devices, domain_head) {
> +		arm_smmu_write_ctx_desc(master, 0, cd);
> +	}

I think it is typical kernel style to not include the single statement
{}

> +	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
>  
>  	/* Invalidate TLB entries previously associated with that context */
>  	arm_smmu_tlb_inv_asid(smmu, asid);
> @@ -211,6 +217,8 @@ static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
>  {
>  	struct arm_smmu_mmu_notifier *smmu_mn = mn_to_smmu(mn);
>  	struct arm_smmu_domain *smmu_domain = smmu_mn->domain;
> +	struct arm_smmu_master *master;
> +	unsigned long flags;
>  
>  	mutex_lock(&sva_lock);
>  	if (smmu_mn->cleared) {
> @@ -222,7 +230,11 @@ static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
>  	 * DMA may still be running. Keep the cd valid to avoid C_BAD_CD events,
>  	 * but disable translation.
>  	 */
> -	arm_smmu_write_ctx_desc(smmu_domain, mm->pasid, &quiet_cd);
> +	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
> +	list_for_each_entry(master, &smmu_domain->devices, domain_head) {
> +		arm_smmu_write_ctx_desc(master, mm->pasid, &quiet_cd);
> +	}
> +	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);

And here

>  	arm_smmu_tlb_inv_asid(smmu_domain->smmu, smmu_mn->cd->asid);
>  	arm_smmu_atc_inv_domain(smmu_domain, mm->pasid, 0, 0);
> @@ -248,7 +260,9 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
>  			  struct mm_struct *mm)
>  {
>  	int ret;
> +	unsigned long flags;
>  	struct arm_smmu_ctx_desc *cd;
> +	struct arm_smmu_master *master;
>  	struct arm_smmu_mmu_notifier *smmu_mn;
>  
>  	list_for_each_entry(smmu_mn, &smmu_domain->mmu_notifiers, list) {
> @@ -279,7 +293,11 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
>  		goto err_free_cd;
>  	}
>  
> -	ret = arm_smmu_write_ctx_desc(smmu_domain, mm->pasid, cd);
> +	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
> +	list_for_each_entry(master, &smmu_domain->devices, domain_head) {
> +		ret = arm_smmu_write_ctx_desc(master, mm->pasid, cd);
> +	}
> +	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);

And here..

>  	if (ret)
>  		goto err_put_notifier;
>  
> @@ -296,6 +314,8 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
>  
>  static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn)
>  {
> +	unsigned long flags;
> +	struct arm_smmu_master *master;
>  	struct mm_struct *mm = smmu_mn->mn.mm;
>  	struct arm_smmu_ctx_desc *cd = smmu_mn->cd;
>  	struct arm_smmu_domain *smmu_domain = smmu_mn->domain;
> @@ -304,7 +324,12 @@ static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn)
>  		return;
>  
>  	list_del(&smmu_mn->list);
> -	arm_smmu_write_ctx_desc(smmu_domain, mm->pasid, NULL);
> +
> +	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
> +	list_for_each_entry(master, &smmu_domain->devices, domain_head) {
> +		arm_smmu_write_ctx_desc(master, mm->pasid, NULL);
> +	}
> +	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
  

And here..

You know, you should try to keep the function instead of duplicating
these

arm_smmu_write_ctx_desc_devices()

And put the four lines in there?

> @@ -987,19 +985,14 @@ static void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain,
>  		},
>  	};
>  
> -	if (!smmu_domain->cd_table.installed)
> +	if (!master->domain->cd_table.installed)
>  		return;

BTW, do you have locking for this? I didn't check carefully

Jason

  reply	other threads:[~2023-08-01 14:18 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-31 10:48 [PATCH v2 0/8] Refactor the SMMU's CD table ownership Michael Shavit
2023-07-31 10:48 ` [PATCH v2 1/8] iommu/arm-smmu-v3: Move ctx_desc out of s1_cfg Michael Shavit
2023-08-01 14:08   ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 2/8] iommu/arm-smmu-v3: Replace s1_cfg with cdtab_cfg Michael Shavit
2023-08-01  4:14   ` Nicolin Chen
2023-08-01  8:00     ` Michael Shavit
2023-08-01 13:43   ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 3/8] iommu/arm-smmu-v3: Encapsulate ctx_desc_cfg init in alloc_cd_tables Michael Shavit
2023-08-01 14:09   ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 4/8] iommu/arm-smmu-v3: move stall_enabled to the cd table Michael Shavit
2023-08-01  4:28   ` Nicolin Chen
2023-08-01  4:52     ` Nicolin Chen
2023-08-01  8:09       ` Michael Shavit
2023-08-01 13:31         ` Jason Gunthorpe
2023-08-01 14:12   ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 5/8] iommu/arm-smmu-v3: Skip cd sync if CD table isn't active Michael Shavit
2023-08-01 14:13   ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 6/8] iommu/arm-smmu-v3: Refactor write_ctx_desc Michael Shavit
2023-08-01 14:18   ` Jason Gunthorpe [this message]
2023-08-01 17:03     ` Michael Shavit
2023-07-31 10:48 ` [PATCH v2 7/8] iommu/arm-smmu-v3: Move CD table to arm_smmu_master Michael Shavit
2023-08-01 14:42   ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 8/8] iommu/arm-smmu-v3: Rename cdcfg to cd_table Michael Shavit
2023-08-01 14:44   ` Jason Gunthorpe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZMkULTvwIIE3zo5+@nvidia.com \
    --to=jgg@nvidia.com \
    --cc=iommu@lists.linux.dev \
    --cc=jean-philippe@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mshavit@google.com \
    --cc=nicolinc@nvidia.com \
    --cc=robin.murphy@arm.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox