All of lore.kernel.org
 help / color / mirror / Atom feed
From: Robin Murphy <robin.murphy@arm.com>
To: Lu Baolu <baolu.lu@linux.intel.com>,
	Joerg Roedel <joro@8bytes.org>, Jason Gunthorpe <jgg@nvidia.com>,
	Christoph Hellwig <hch@infradead.org>,
	Ben Skeggs <bskeggs@redhat.com>,
	Kevin Tian <kevin.tian@intel.com>,
	Ashok Raj <ashok.raj@intel.com>, Will Deacon <will@kernel.org>
Cc: David Airlie <airlied@linux.ie>,
	Alex Williamson <alex.williamson@redhat.com>,
	linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org,
	Thierry Reding <thierry.reding@gmail.com>,
	Jacob jun Pan <jacob.jun.pan@intel.com>,
	Daniel Vetter <daniel@ffwll.ch>,
	Jonathan Hunter <jonathanh@nvidia.com>
Subject: Re: [PATCH 6/7] iommu: Use right way to retrieve iommu_ops
Date: Tue, 25 Jan 2022 00:20:26 +0000	[thread overview]
Message-ID: <363b8f7d-5459-0d19-c1ac-a2c6bce9d26f@arm.com> (raw)
In-Reply-To: <20220124071103.2097118-7-baolu.lu@linux.intel.com>

On 2022-01-24 07:11, Lu Baolu wrote:
> The common iommu_ops is hooked to both device and domain. When a helper
> has both device and domain pointer, the way to get the iommu_ops looks
> messy in iommu core. This sorts out the way to get iommu_ops. The device
> related helpers go through device pointer, while the domain related ones
> go through domain pointer.
> 
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> ---
>   include/linux/iommu.h |  8 ++++++++
>   drivers/iommu/iommu.c | 25 ++++++++++++++-----------
>   2 files changed, 22 insertions(+), 11 deletions(-)
> 
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index aa5486243892..111b3e9c79bb 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -385,6 +385,14 @@ static inline void iommu_iotlb_gather_init(struct iommu_iotlb_gather *gather)
>   	};
>   }
>   
> +static inline const struct iommu_ops *dev_iommu_ops_get(struct device *dev)
> +{
> +	if (dev && dev->iommu && dev->iommu->iommu_dev)
> +		return dev->iommu->iommu_dev->ops;
> +
> +	return NULL;

This probably warrants at least a WARN, but it's arguable to just assume 
that valid ops must be installed if iommu_probe_device() has succeeded. 
The device ops are essentially for internal use within the IOMMU 
subsystem itself, so we should be able to trust ourselves not to misuse 
the helper.

> +}
> +
>   #define IOMMU_BUS_NOTIFY_PRIORITY		0
>   #define IOMMU_GROUP_NOTIFY_ADD_DEVICE		1 /* Device added */
>   #define IOMMU_GROUP_NOTIFY_DEL_DEVICE		2 /* Pre Device removed */
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 5230c6d90ece..6631e2ea44df 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -764,6 +764,7 @@ EXPORT_SYMBOL_GPL(iommu_group_set_name);
>   static int iommu_create_device_direct_mappings(struct iommu_group *group,
>   					       struct device *dev)
>   {
> +	const struct iommu_ops *ops = dev_iommu_ops_get(dev);
>   	struct iommu_domain *domain = group->default_domain;
>   	struct iommu_resv_region *entry;
>   	struct list_head mappings;
> @@ -785,8 +786,8 @@ static int iommu_create_device_direct_mappings(struct iommu_group *group,
>   		dma_addr_t start, end, addr;
>   		size_t map_size = 0;
>   
> -		if (domain->ops->apply_resv_region)
> -			domain->ops->apply_resv_region(dev, domain, entry);
> +		if (ops->apply_resv_region)
> +			ops->apply_resv_region(dev, domain, entry);

Strictly I think this was a domain op, as it was about reserving the 
IOVA range in the given DMA domain. Also taking the domain as an 
argument is a bit of a giveaway. However it's now just dead code either 
way since there are no remaining implementations, and no reason for any 
new ones.

>   
>   		start = ALIGN(entry->start, pg_size);
>   		end   = ALIGN(entry->start + entry->length, pg_size);
> @@ -831,8 +832,10 @@ static int iommu_create_device_direct_mappings(struct iommu_group *group,
>   static bool iommu_is_attach_deferred(struct iommu_domain *domain,
>   				     struct device *dev)
>   {
> -	if (domain->ops->is_attach_deferred)
> -		return domain->ops->is_attach_deferred(domain, dev);
> +	const struct iommu_ops *ops = dev_iommu_ops_get(dev);
> +
> +	if (ops->is_attach_deferred)
> +		return ops->is_attach_deferred(domain, dev);

Similarly if this takes a domain as its first argument then it's de 
facto a domain method. However, I'd concur that logically it *is* a 
device op, so let's drop that (unused) domain argument if we're cleaning up.

Maybe there's even an argument for factoring this out to a standard flag 
in dev_iommu rather than an op at all?

The others covered here look OK - we can blame PCI for page response 
being weirdly device-centric - however could we also convert all the 
feasible instances of dev->bus->iommu_ops to dev_iommu_ops() as well? 
(Subtly implying that I'm also not a fan of having "_get" in the name 
for a non-refcounted lookup...) Obviously iommu_probe_device() and 
iommmu_domain_alloc() still need bus ops at this point, but I'm working 
on that... :)

Thanks,
Robin.

>   	return false;
>   }
> @@ -1251,10 +1254,10 @@ int iommu_page_response(struct device *dev,
>   	struct iommu_fault_event *evt;
>   	struct iommu_fault_page_request *prm;
>   	struct dev_iommu *param = dev->iommu;
> +	const struct iommu_ops *ops = dev_iommu_ops_get(dev);
>   	bool has_pasid = msg->flags & IOMMU_PAGE_RESP_PASID_VALID;
> -	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
>   
> -	if (!domain || !domain->ops->page_response)
> +	if (!ops || !ops->page_response)
>   		return -ENODEV;
>   
>   	if (!param || !param->fault_param)
> @@ -1295,7 +1298,7 @@ int iommu_page_response(struct device *dev,
>   			msg->pasid = 0;
>   		}
>   
> -		ret = domain->ops->page_response(dev, evt, msg);
> +		ret = ops->page_response(dev, evt, msg);
>   		list_del(&evt->list);
>   		kfree(evt);
>   		break;
> @@ -1758,10 +1761,10 @@ static int __iommu_group_dma_attach(struct iommu_group *group)
>   
>   static int iommu_group_do_probe_finalize(struct device *dev, void *data)
>   {
> -	struct iommu_domain *domain = data;
> +	const struct iommu_ops *ops = dev_iommu_ops_get(dev);
>   
> -	if (domain->ops->probe_finalize)
> -		domain->ops->probe_finalize(dev);
> +	if (ops->probe_finalize)
> +		ops->probe_finalize(dev);
>   
>   	return 0;
>   }
> @@ -2020,7 +2023,7 @@ EXPORT_SYMBOL_GPL(iommu_attach_device);
>   
>   int iommu_deferred_attach(struct device *dev, struct iommu_domain *domain)
>   {
> -	const struct iommu_ops *ops = domain->ops;
> +	const struct iommu_ops *ops = dev_iommu_ops_get(dev);
>   
>   	if (ops->is_attach_deferred && ops->is_attach_deferred(domain, dev))
>   		return __iommu_attach_device(domain, dev);
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

WARNING: multiple messages have this Message-ID (diff)
From: Robin Murphy <robin.murphy@arm.com>
To: Lu Baolu <baolu.lu@linux.intel.com>,
	Joerg Roedel <joro@8bytes.org>, Jason Gunthorpe <jgg@nvidia.com>,
	Christoph Hellwig <hch@infradead.org>,
	Ben Skeggs <bskeggs@redhat.com>,
	Kevin Tian <kevin.tian@intel.com>,
	Ashok Raj <ashok.raj@intel.com>, Will Deacon <will@kernel.org>
Cc: David Airlie <airlied@linux.ie>,
	linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org,
	Jonathan Hunter <jonathanh@nvidia.com>,
	Alex Williamson <alex.williamson@redhat.com>,
	Thierry Reding <thierry.reding@gmail.com>,
	Jacob jun Pan <jacob.jun.pan@intel.com>,
	Daniel Vetter <daniel@ffwll.ch>
Subject: Re: [PATCH 6/7] iommu: Use right way to retrieve iommu_ops
Date: Tue, 25 Jan 2022 00:20:26 +0000	[thread overview]
Message-ID: <363b8f7d-5459-0d19-c1ac-a2c6bce9d26f@arm.com> (raw)
In-Reply-To: <20220124071103.2097118-7-baolu.lu@linux.intel.com>

On 2022-01-24 07:11, Lu Baolu wrote:
> The common iommu_ops is hooked to both device and domain. When a helper
> has both device and domain pointer, the way to get the iommu_ops looks
> messy in iommu core. This sorts out the way to get iommu_ops. The device
> related helpers go through device pointer, while the domain related ones
> go through domain pointer.
> 
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> ---
>   include/linux/iommu.h |  8 ++++++++
>   drivers/iommu/iommu.c | 25 ++++++++++++++-----------
>   2 files changed, 22 insertions(+), 11 deletions(-)
> 
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index aa5486243892..111b3e9c79bb 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -385,6 +385,14 @@ static inline void iommu_iotlb_gather_init(struct iommu_iotlb_gather *gather)
>   	};
>   }
>   
> +static inline const struct iommu_ops *dev_iommu_ops_get(struct device *dev)
> +{
> +	if (dev && dev->iommu && dev->iommu->iommu_dev)
> +		return dev->iommu->iommu_dev->ops;
> +
> +	return NULL;

This probably warrants at least a WARN, but it's arguable to just assume 
that valid ops must be installed if iommu_probe_device() has succeeded. 
The device ops are essentially for internal use within the IOMMU 
subsystem itself, so we should be able to trust ourselves not to misuse 
the helper.

> +}
> +
>   #define IOMMU_BUS_NOTIFY_PRIORITY		0
>   #define IOMMU_GROUP_NOTIFY_ADD_DEVICE		1 /* Device added */
>   #define IOMMU_GROUP_NOTIFY_DEL_DEVICE		2 /* Pre Device removed */
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 5230c6d90ece..6631e2ea44df 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -764,6 +764,7 @@ EXPORT_SYMBOL_GPL(iommu_group_set_name);
>   static int iommu_create_device_direct_mappings(struct iommu_group *group,
>   					       struct device *dev)
>   {
> +	const struct iommu_ops *ops = dev_iommu_ops_get(dev);
>   	struct iommu_domain *domain = group->default_domain;
>   	struct iommu_resv_region *entry;
>   	struct list_head mappings;
> @@ -785,8 +786,8 @@ static int iommu_create_device_direct_mappings(struct iommu_group *group,
>   		dma_addr_t start, end, addr;
>   		size_t map_size = 0;
>   
> -		if (domain->ops->apply_resv_region)
> -			domain->ops->apply_resv_region(dev, domain, entry);
> +		if (ops->apply_resv_region)
> +			ops->apply_resv_region(dev, domain, entry);

Strictly I think this was a domain op, as it was about reserving the 
IOVA range in the given DMA domain. Also taking the domain as an 
argument is a bit of a giveaway. However it's now just dead code either 
way since there are no remaining implementations, and no reason for any 
new ones.

>   
>   		start = ALIGN(entry->start, pg_size);
>   		end   = ALIGN(entry->start + entry->length, pg_size);
> @@ -831,8 +832,10 @@ static int iommu_create_device_direct_mappings(struct iommu_group *group,
>   static bool iommu_is_attach_deferred(struct iommu_domain *domain,
>   				     struct device *dev)
>   {
> -	if (domain->ops->is_attach_deferred)
> -		return domain->ops->is_attach_deferred(domain, dev);
> +	const struct iommu_ops *ops = dev_iommu_ops_get(dev);
> +
> +	if (ops->is_attach_deferred)
> +		return ops->is_attach_deferred(domain, dev);

Similarly if this takes a domain as its first argument then it's de 
facto a domain method. However, I'd concur that logically it *is* a 
device op, so let's drop that (unused) domain argument if we're cleaning up.

Maybe there's even an argument for factoring this out to a standard flag 
in dev_iommu rather than an op at all?

The others covered here look OK - we can blame PCI for page response 
being weirdly device-centric - however could we also convert all the 
feasible instances of dev->bus->iommu_ops to dev_iommu_ops() as well? 
(Subtly implying that I'm also not a fan of having "_get" in the name 
for a non-refcounted lookup...) Obviously iommu_probe_device() and 
iommmu_domain_alloc() still need bus ops at this point, but I'm working 
on that... :)

Thanks,
Robin.

>   	return false;
>   }
> @@ -1251,10 +1254,10 @@ int iommu_page_response(struct device *dev,
>   	struct iommu_fault_event *evt;
>   	struct iommu_fault_page_request *prm;
>   	struct dev_iommu *param = dev->iommu;
> +	const struct iommu_ops *ops = dev_iommu_ops_get(dev);
>   	bool has_pasid = msg->flags & IOMMU_PAGE_RESP_PASID_VALID;
> -	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
>   
> -	if (!domain || !domain->ops->page_response)
> +	if (!ops || !ops->page_response)
>   		return -ENODEV;
>   
>   	if (!param || !param->fault_param)
> @@ -1295,7 +1298,7 @@ int iommu_page_response(struct device *dev,
>   			msg->pasid = 0;
>   		}
>   
> -		ret = domain->ops->page_response(dev, evt, msg);
> +		ret = ops->page_response(dev, evt, msg);
>   		list_del(&evt->list);
>   		kfree(evt);
>   		break;
> @@ -1758,10 +1761,10 @@ static int __iommu_group_dma_attach(struct iommu_group *group)
>   
>   static int iommu_group_do_probe_finalize(struct device *dev, void *data)
>   {
> -	struct iommu_domain *domain = data;
> +	const struct iommu_ops *ops = dev_iommu_ops_get(dev);
>   
> -	if (domain->ops->probe_finalize)
> -		domain->ops->probe_finalize(dev);
> +	if (ops->probe_finalize)
> +		ops->probe_finalize(dev);
>   
>   	return 0;
>   }
> @@ -2020,7 +2023,7 @@ EXPORT_SYMBOL_GPL(iommu_attach_device);
>   
>   int iommu_deferred_attach(struct device *dev, struct iommu_domain *domain)
>   {
> -	const struct iommu_ops *ops = domain->ops;
> +	const struct iommu_ops *ops = dev_iommu_ops_get(dev);
>   
>   	if (ops->is_attach_deferred && ops->is_attach_deferred(domain, dev))
>   		return __iommu_attach_device(domain, dev);

  parent reply	other threads:[~2022-01-25  0:20 UTC|newest]

Thread overview: 101+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-24  7:10 [PATCH 0/7] iommu cleanup and refactoring Lu Baolu
2022-01-24  7:10 ` Lu Baolu
2022-01-24  7:10 ` [PATCH 1/7] iommu/vt-d: Remove guest pasid related callbacks Lu Baolu
2022-01-24  7:10   ` Lu Baolu
2022-01-24  9:25   ` Christoph Hellwig
2022-01-24  9:25     ` Christoph Hellwig
2022-01-24  7:10 ` [PATCH 2/7] iommu: Remove guest pasid related interfaces and definitions Lu Baolu
2022-01-24  7:10   ` Lu Baolu
2022-01-24  9:26   ` Christoph Hellwig
2022-01-24  9:26     ` Christoph Hellwig
2022-01-24  7:10 ` [PATCH 3/7] iommu/vt-d: Remove aux-domain related callbacks Lu Baolu
2022-01-24  7:10   ` Lu Baolu
2022-01-24  9:26   ` Christoph Hellwig
2022-01-24  9:26     ` Christoph Hellwig
2022-01-24  7:10 ` [PATCH 4/7] iommu: Remove aux-domain related interfaces and iommu_ops Lu Baolu
2022-01-24  7:10   ` Lu Baolu
2022-01-24  9:27   ` Christoph Hellwig
2022-01-24  9:27     ` Christoph Hellwig
2022-01-24  7:11 ` [PATCH 5/7] drm/nouveau/device: Get right pgsize_bitmap of iommu_domain Lu Baolu
2022-01-24  7:11   ` Lu Baolu
2022-01-24  9:29   ` Christoph Hellwig
2022-01-24  9:29     ` Christoph Hellwig
2022-01-25  2:59     ` Lu Baolu
2022-01-25  2:59       ` Lu Baolu
2022-01-24  7:11 ` [PATCH 6/7] iommu: Use right way to retrieve iommu_ops Lu Baolu
2022-01-24  7:11   ` Lu Baolu
2022-01-24  9:32   ` Christoph Hellwig
2022-01-24  9:32     ` Christoph Hellwig
2022-01-25  3:01     ` Lu Baolu
2022-01-25  3:01       ` Lu Baolu
2022-01-24  9:48   ` Tian, Kevin
2022-01-24  9:48     ` Tian, Kevin
2022-01-25  3:04     ` Lu Baolu
2022-01-25  3:04       ` Lu Baolu
2022-01-24 17:36   ` Jason Gunthorpe
2022-01-24 17:36     ` Jason Gunthorpe via iommu
2022-01-25  1:11     ` Tian, Kevin
2022-01-25  1:52       ` Robin Murphy
2022-01-25  2:08         ` Tian, Kevin
2022-01-25  3:31           ` Lu Baolu
2022-01-25  3:18     ` Lu Baolu
2022-01-25  3:18       ` Lu Baolu
2022-01-25  0:20   ` Robin Murphy [this message]
2022-01-25  0:20     ` Robin Murphy
2022-01-25  3:54     ` Lu Baolu
2022-01-25  3:54       ` Lu Baolu
2022-01-24  7:11 ` [PATCH 7/7] iommu: Add iommu_domain::domain_ops Lu Baolu
2022-01-24  7:11   ` Lu Baolu
2022-01-24  9:37   ` Christoph Hellwig
2022-01-24  9:37     ` Christoph Hellwig
2022-01-24 17:24     ` Jason Gunthorpe
2022-01-24 17:24       ` Jason Gunthorpe via iommu
2022-01-25  4:43       ` Lu Baolu
2022-01-25  4:43         ` Lu Baolu
2022-01-25  4:42     ` Lu Baolu
2022-01-25  4:42       ` Lu Baolu
2022-01-24  9:58   ` Tian, Kevin
2022-01-24  9:58     ` Tian, Kevin
2022-01-24 10:16     ` Jean-Philippe Brucker
2022-01-24 10:16       ` Jean-Philippe Brucker
2022-01-24 16:33       ` Jason Gunthorpe
2022-01-24 16:33         ` Jason Gunthorpe via iommu
2022-01-26  9:41         ` Jean-Philippe Brucker
2022-01-26  9:41           ` Jean-Philippe Brucker
2022-01-24 17:17     ` Jason Gunthorpe
2022-01-24 17:17       ` Jason Gunthorpe via iommu
2022-01-25  0:58       ` Tian, Kevin
2022-01-25  4:59     ` Lu Baolu
2022-01-25  4:59       ` Lu Baolu
2022-01-25 12:37       ` Jason Gunthorpe via iommu
2022-01-25 12:37         ` Jason Gunthorpe
2022-01-24 17:55   ` Jason Gunthorpe
2022-01-24 17:55     ` Jason Gunthorpe via iommu
2022-01-25  5:04     ` Lu Baolu
2022-01-25  5:04       ` Lu Baolu
2022-01-25  0:57   ` Robin Murphy
2022-01-25  0:57     ` Robin Murphy
2022-01-25  6:27     ` Lu Baolu
2022-01-25  6:27       ` Lu Baolu
2022-01-25 14:23       ` Robin Murphy
2022-01-25 14:23         ` Robin Murphy
2022-01-25 15:00         ` Jason Gunthorpe via iommu
2022-01-25 15:00           ` Jason Gunthorpe
2022-01-24  9:46 ` [PATCH 0/7] iommu cleanup and refactoring Tian, Kevin
2022-01-24  9:46   ` Tian, Kevin
2022-01-24 17:44   ` Jason Gunthorpe
2022-01-24 17:44     ` Jason Gunthorpe via iommu
2022-01-25  1:11     ` Tian, Kevin
2022-01-25  1:11       ` Tian, Kevin
2022-01-25 14:48     ` Robin Murphy
2022-01-25 14:48       ` Robin Murphy
2022-01-25 15:16       ` Jason Gunthorpe via iommu
2022-01-25 15:16         ` Jason Gunthorpe
2022-01-26  1:51         ` Lu Baolu
2022-01-26  1:51           ` Lu Baolu
2022-01-26 13:27           ` Jason Gunthorpe
2022-01-26 13:27             ` Jason Gunthorpe via iommu
2022-01-26 14:00             ` Robin Murphy
2022-01-26 14:00               ` Robin Murphy
2022-02-08  1:32 ` Lu Baolu
2022-02-08  1:32   ` Lu Baolu

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=363b8f7d-5459-0d19-c1ac-a2c6bce9d26f@arm.com \
    --to=robin.murphy@arm.com \
    --cc=airlied@linux.ie \
    --cc=alex.williamson@redhat.com \
    --cc=ashok.raj@intel.com \
    --cc=baolu.lu@linux.intel.com \
    --cc=bskeggs@redhat.com \
    --cc=daniel@ffwll.ch \
    --cc=hch@infradead.org \
    --cc=iommu@lists.linux-foundation.org \
    --cc=jacob.jun.pan@intel.com \
    --cc=jgg@nvidia.com \
    --cc=jonathanh@nvidia.com \
    --cc=joro@8bytes.org \
    --cc=kevin.tian@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=thierry.reding@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.