Consolidate iommu_ops->add/remove_device() calls
Subsystems (3)
Joerg Roedel
maintainerv2 cover Consolidate iommu_ops->add/remove_device() calls
Hi,
here is the second version of the patch-set to wrap the invocation of iommu_ops->add/remove_device() into functions. The functions will do more setup stuff later when the the iommu-related pointers in 'struct device' are consolidated.
Since version one this patch-set was rebased to v4.20-rc6 and I removed the pointer checks for the function pointers, as suggested by Robin. I checked all 16 drivers and all of them implement the add/remove_device call-backs.
Please review, if there are no objections I plan to queue these patches in the IOMMU tree.
Thanks,
Joerg
Joerg Roedel (4):
iommu/sysfs: Rename iommu_release_device()
iommu: Consolitate ->add/remove_device() calls iommu/of: Don't call iommu_ops->add_device directly ACPI/IORT: Don't call iommu_ops->add_device directly
drivers/acpi/arm64/iort.c | 4 +-- drivers/iommu/iommu-sysfs.c | 12 ++++----- drivers/iommu/iommu.c | 51 ++++++++++++++++++------------------- drivers/iommu/of_iommu.c | 6 ++--- include/linux/iommu.h | 3 +++ 5 files changed, 39 insertions(+), 37 deletions(-)
Signature · 1 line
2.17.1
Joerg Roedel
maintainerPATCH v2 1/4 iommu/sysfs: Rename iommu_release_device()
From: Joerg Roedel <[email protected]>
Remove the iommu_ prefix from the function and a few other static data structures so that the iommu_release_device name can be re-used in iommu core code.
--- drivers/iommu/iommu-sysfs.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/iommu/iommu-sysfs.c +6 -6
@@ -22,25 +22,25 @@ static struct attribute *devices_attr[] = { NULL, }; -static const struct attribute_group iommu_devices_attr_group = { +static const struct attribute_group devices_attr_group = { .name ="devices" , .attrs = devices_attr, }; -static const struct attribute_group *iommu_dev_groups[] = { - &iommu_devices_attr_group, +static const struct attribute_group *dev_groups[] = { + &devices_attr_group,NULL , }; -static void iommu_release_device (struct device *dev) +static void release_device (struct device *dev) {kfree (dev); }static struct class iommu_class = { .name ="iommu" , - .dev_release = iommu_release_device, - .dev_groups = iommu_dev_groups, + .dev_release = release_device, + .dev_groups = dev_groups, };static int __init iommu_dev_init (void )
Signature · 1 line
2.17.1
Joerg Roedel
maintainerPATCH v2 2/4 iommu: Consolitate ->add/remove_device() calls
In reply to Joerg RoedelFrom: Joerg Roedel <[email protected]>
Put them into separate functions and call those where the plain ops have been called before.
--- drivers/iommu/iommu.c | 51 +++++++++++++++++++++---------------------- include/linux/iommu.h | 3 +++ 2 files changed, 28 insertions(+), 26 deletions(-)
drivers/iommu/iommu.c +25 -26
@@ -110,6 +110,23 @@ void iommu_device_unregister(struct iommu_device *iommu)spin_unlock (&iommu_device_lock); } +int iommu_probe_device (struct device *dev) +{ +const struct iommu_ops *ops = dev->bus->iommu_ops; + +WARN_ON (dev->iommu_group); + +return ops->add_device (dev); +} + +void iommu_release_device (struct device *dev) +{ +const struct iommu_ops *ops = dev->bus->iommu_ops; + +if (dev->iommu_group) + ops->remove_device (dev); +} +static struct iommu_domain *__iommu_domain_alloc (struct bus_type *bus,unsigned type); static int __iommu_attach_device(struct iommu_domain *domain,
@@ -1117,16 +1134,7 @@ struct iommu_domain *iommu_group_default_domain(struct iommu_group *group)static int add_iommu_group (struct device *dev,void *data) { -struct iommu_callback_data *cb = data; -const struct iommu_ops *ops = cb->ops; -int ret; - -if (!ops->add_device) -return 0 ; - -WARN_ON (dev->iommu_group); - - ret = ops->add_device (dev); +int ret =iommu_probe_device (dev);/* * We ignore -ENODEV errors for now, as they just mean that the
@@ -1141,11 +1149,7 @@ static int add_iommu_group(struct device *dev, void *data)static int remove_iommu_group (struct device *dev,void *data) { -struct iommu_callback_data *cb = data; -const struct iommu_ops *ops = cb->ops; - -if (ops->remove_device && dev->iommu_group) - ops->remove_device (dev); +iommu_release_device (dev);return 0 ; }
@@ -1153,27 +1157,22 @@ static int remove_iommu_group(struct device *dev, void *data)static int iommu_bus_notifier (struct notifier_block *nb,unsigned long action,void *data) { +unsigned long group_action =0 ;struct device *dev = data; -const struct iommu_ops *ops = dev->bus->iommu_ops;struct iommu_group *group; -unsigned long group_action =0 ;/* * ADD/DEL call into iommu driver ops if provided, which may * result in ADD/DEL notifiers to group->notifier */ if (action ==BUS_NOTIFY_ADD_DEVICE ) { -if (ops->add_device) { -int ret; +int ret; - ret = ops->add_device (dev); -return (ret) ?NOTIFY_DONE :NOTIFY_OK ; - } + ret =iommu_probe_device (dev); +return (ret) ?NOTIFY_DONE :NOTIFY_OK ; }else if (action ==BUS_NOTIFY_REMOVED_DEVICE ) { -if (ops->remove_device && dev->iommu_group) { - ops->remove_device (dev); -return 0 ; - } +iommu_release_device (dev); +return NOTIFY_OK ; }/*
include/linux/iommu.h +3 -0
@@ -398,6 +398,9 @@ void iommu_fwspec_free(struct device *dev);int iommu_fwspec_add_ids (struct device *dev,u32 *ids,int num_ids);const struct iommu_ops *iommu_ops_from_fwnode (struct fwnode_handle *fwnode); +int iommu_probe_device (struct device *dev); +void iommu_release_device (struct device *dev); +#else /* CONFIG_IOMMU_API */ struct iommu_ops {};
Signature · 1 line
2.17.1
Joerg Roedel
maintainerPATCH v2 3/4 iommu/of: Don't call iommu_ops->add_device directly
In reply to Joerg RoedelFrom: Joerg Roedel <[email protected]>
Make sure to invoke this call-back through the proper function of the IOMMU-API.
--- drivers/iommu/of_iommu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/iommu/of_iommu.c +3 -3
@@ -218,10 +218,10 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, ops = dev->iommu_fwspec->ops;/* * If we have reason to believe the IOMMU driver missed the initial -* add_device callback for dev, replay it to get things in order. +* probe for dev, replay it to get things in order. */ -if (ops && ops->add_device && dev->bus && !dev->iommu_group) - err = ops->add_device (dev); +if (dev->bus && !dev->iommu_group) + err =iommu_probe_device (dev);/* Ignore all other errors apart from EPROBE_DEFER */ if (err == -EPROBE_DEFER ) {
Signature · 1 line
2.17.1
Re: [PATCH 3/4] iommu/of: Don't call iommu_ops->add_device directly
Hi Joerg,
This patch landed in today's linux-next and causes a regression.
Quoted 15 lines · Joerg Roedel
From: Joerg Roedel <[email protected]>
Make sure to invoke this call-back through the proper function of the IOMMU-API.
Signed-off-by Joerg Roedel <[email protected]>--- drivers/iommu/of_iommu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)drivers/iommu/of_iommu.c +0
-0
drivers/iommu/of_iommu.c const struct iommu_ops *of_iommu_configure(struct device *dev, · line 224
Quoted 10 lines
drivers/iommu/of_iommu.c +3
-3@@ -218,10 +218,10 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, ops = dev->iommu_fwspec->ops;/* * If we have reason to believe the IOMMU driver missed the initial -* add_device callback for dev, replay it to get things in order. +* probe for dev, replay it to get things in order. */ -if (ops && ops->add_device && dev->bus && !dev->iommu_group) - err = ops->add_device (dev); +if (dev->bus && !dev->iommu_group) + err =iommu_probe_device (dev);
This change removes a check for NULL ops, what causes NULL pointer exception on first device without IOMMU.
I'm also not sure if this is a good idea to call iommu_probe_device(), which comes from dev->bus->iommu_ops, which might be different from ops from local variable.
drivers/iommu/of_iommu.c const struct iommu_ops *of_iommu_configure(struct device *dev, · line 227
Quoted 3 lines
drivers/iommu/of_iommu.c +0
-0/* Ignore all other errors apart from EPROBE_DEFER */ if (err == -EPROBE_DEFER ) {
Best regards
Signature · 2 lines
Marek Szyprowski, PhD Samsung R&D Institute Poland
Joerg Roedel
maintainerRe: [PATCH 3/4] iommu/of: Don't call iommu_ops->add_device directly
Hi Marek,
thanks for the report!
Quoted 21 lines · Marek Szyprowski
Quoted 20 lines · Joerg Roedel
From: Joerg Roedel <[email protected]>
Make sure to invoke this call-back through the proper function of the IOMMU-API.
Signed-off-by Joerg Roedel <[email protected]>--- drivers/iommu/of_iommu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)drivers/iommu/of_iommu.c +1
-1@@ -218,10 +218,10 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, ops = dev->iommu_fwspec->ops;/* * If we have reason to believe the IOMMU driver missed the initial -* add_device callback for dev, replay it to get things in order. +* probe for dev, replay it to get things in order.
Quoted 8 lines
drivers/iommu/of_iommu.c const struct iommu_ops *of_iommu_configure(struct device *dev, · line 224
Quoted 5 lines
drivers/iommu/of_iommu.c +2
-2*/ -if (ops && ops->add_device && dev->bus && !dev->iommu_group) - err = ops->add_device (dev); +if (dev->bus && !dev->iommu_group) + err =iommu_probe_device (dev);This change removes a check for NULL ops, what causes NULL pointer exception on first device without IOMMU.
Bummer, this check was supposed to be in iommu_probe_device(), but apparently it got lost. Does the attached patch fix it?
Quoted 3 lines
I'm also not sure if this is a good idea to call
iommu_probe_device(), which comes fromdev->bus->iommu_ops, which might be different from ops from local variable.
The local variable comes from dev->iommu_fwspec->ops, which should be exactly the same as dev->bus->iommu_ops. I'll leave that for now until it turns out to be a problem (which I don't expect).
Regards,
Joerg
drivers/iommu/iommu.c +5 -1
@@ -114,10 +114,14 @@ void iommu_device_unregister(struct iommu_device *iommu)int iommu_probe_device (struct device *dev) {const struct iommu_ops *ops = dev->bus->iommu_ops; +int ret = -EINVAL ;WARN_ON (dev->iommu_group); -return ops->add_device (dev); +if (ops) + ret = ops->add_device (dev); + +return ret; }void iommu_release_device (struct device *dev)
Re: [PATCH 3/4] iommu/of: Don't call iommu_ops->add_device directly
Hi Joerg,
Quoted 33 lines · Joerg Roedel
Hi Marek,
thanks for the report!
Quoted 20 lines · Marek Szyprowski
Quoted 19 lines · Joerg Roedel
From: Joerg Roedel <[email protected]>
Make sure to invoke this call-back through the proper function of the IOMMU-API.
Signed-off-by Joerg Roedel <[email protected]>--- drivers/iommu/of_iommu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)drivers/iommu/of_iommu.c +0
-1@@ -218,10 +218,10 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, ops = dev->iommu_fwspec->ops;/* * If we have reason to believe the IOMMU driver missed the initial -* add_device callback for dev, replay it to get things in order. Quoted 8 lines
drivers/iommu/of_iommu.c const struct iommu_ops *of_iommu_configure(struct device *dev, · line 224
Quoted 6 lines
drivers/iommu/of_iommu.c +3
-2+* probe for dev, replay it to get things in order. */ -if (ops && ops->add_device && dev->bus && !dev->iommu_group) - err = ops->add_device (dev); +if (dev->bus && !dev->iommu_group) + err =iommu_probe_device (dev);This change removes a check for NULL ops, what causes NULL pointer exception on first device without IOMMU.
Quoted 2 lines
Bummer, this check was supposed to be in
iommu_probe_device(), but apparently it got lost. Does the attached patch fix it?
Yes, it fixes this issue.
Quoted 24 lines
Quoted 3 lines
I'm also not sure if this is a good idea to call
iommu_probe_device(), which comes fromdev->bus->iommu_ops, which might be different from ops from local variable.The local variable comes from
dev->iommu_fwspec->ops, which should be exactly the same asdev->bus->iommu_ops. I'll leave that for now until it turns out to be a problem (which I don't expect).Regards,
Joerg
drivers/iommu/iommu.c +1
-0@@ -114,10 +114,14 @@ void iommu_device_unregister(struct iommu_device *iommu)int iommu_probe_device (struct device *dev) {const struct iommu_ops *ops = dev->bus->iommu_ops; +int ret = -EINVAL ;
drivers/iommu/iommu.c void iommu_device_unregister(struct iommu_device *iommu) · line 127
Quoted 10 lines
drivers/iommu/iommu.c +4
-1WARN_ON (dev->iommu_group); -return ops->add_device (dev); +if (ops) + ret = ops->add_device (dev); + +return ret; }void iommu_release_device (struct device *dev)
Best regards
Signature · 2 lines
Marek Szyprowski, PhD Samsung R&D Institute Poland
Joerg Roedel
maintainerRe: [PATCH 3/4] iommu/of: Don't call iommu_ops->add_device directly
Hi Marek,
Quoted 1 line · Marek Szyprowski
Yes, it fixes this issue.
Thanks a lot, patch is sent out and in iommu tree.
Regards,
Joerg
Re: [PATCH 3/4] iommu/of: Don't call iommu_ops->add_device directly
In reply to Joerg RoedelHi Jörg,
Quoted 52 lines · Joerg Roedel
Quoted 21 lines · Marek Szyprowski
Quoted 20 lines · Joerg Roedel
From: Joerg Roedel <[email protected]>
Make sure to invoke this call-back through the proper function of the IOMMU-API.
Signed-off-by Joerg Roedel <[email protected]>--- drivers/iommu/of_iommu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)drivers/iommu/of_iommu.c +1
-1@@ -218,10 +218,10 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, ops = dev->iommu_fwspec->ops;/* * If we have reason to believe the IOMMU driver missed the initial -* add_device callback for dev, replay it to get things in order. +* probe for dev, replay it to get things in order. Quoted 8 lines
drivers/iommu/of_iommu.c const struct iommu_ops *of_iommu_configure(struct device *dev, · line 224
Quoted 5 lines
drivers/iommu/of_iommu.c +2
-2*/ -if (ops && ops->add_device && dev->bus && !dev->iommu_group) - err = ops->add_device (dev); +if (dev->bus && !dev->iommu_group) + err =iommu_probe_device (dev);This change removes a check for NULL ops, what causes NULL pointer exception on first device without IOMMU.
Bummer, this check was supposed to be in
iommu_probe_device(), but apparently it got lost. Does the attached patch fix it?Quoted 3 lines
I'm also not sure if this is a good idea to call
iommu_probe_device(), which comes fromdev->bus->iommu_ops, which might be different from ops from local variable.The local variable comes from
dev->iommu_fwspec->ops, which should be exactly the same asdev->bus->iommu_ops. I'll leave that for now until it turns out to be a problem (which I don't expect).Regards,
Joerg
drivers/iommu/iommu.c +0
-0
drivers/iommu/iommu.c void iommu_device_unregister(struct iommu_device *iommu) · line 121
Quoted 9 lines
drivers/iommu/iommu.c +2
-1@@ -114,10 +114,14 @@ void iommu_device_unregister(struct iommu_device *iommu)int iommu_probe_device (struct device *dev) {const struct iommu_ops *ops = dev->bus->iommu_ops; +int ret = -EINVAL ;WARN_ON (dev->iommu_group); -return ops->add_device (dev); +if (ops)
Is this sufficient? The old code checked for ops->add_device != NULL, too.
drivers/iommu/iommu.c void iommu_device_unregister(struct iommu_device *iommu) · line 127
Quoted 6 lines
drivers/iommu/iommu.c +3
-0+ ret = ops->add_device (dev); + +return ret; }void iommu_release_device (struct device *dev)
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Joerg Roedel
maintainerRe: [PATCH 3/4] iommu/of: Don't call iommu_ops->add_device directly
Hi Geert,
Quoted 5 lines · Geert Uytterhoeven
drivers/iommu/iommu.c void iommu_device_unregister(struct iommu_device *iommu) · line 121
Quoted 2 lines
drivers/iommu/iommu.c +1
-1-return ops->add_device (dev); +if (ops)Is this sufficient? The old code checked for
ops->add_device!= NULL, too.
Robin brought up that all iommu-ops implementations support the add_device call-back, so we can remove that check and make the call-back mandatory for new implementations too.
Regards,
Joerg
Joerg Roedel
maintainerPATCH v2 4/4 ACPI/IORT: Don't call iommu_ops->add_device directly
In reply to Joerg RoedelFrom: Joerg Roedel <[email protected]>
Make sure to invoke this call-back through the proper function of the IOMMU-API.
--- drivers/acpi/arm64/iort.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/acpi/arm64/iort.c +2 -2
@@ -805,8 +805,8 @@ static inline int iort_add_device_replay(const struct iommu_ops *ops, {int err =0 ; -if (ops->add_device && dev->bus && !dev->iommu_group) - err = ops->add_device (dev); +if (dev->bus && !dev->iommu_group) + err =iommu_probe_device (dev);return err; }
Signature · 1 line
2.17.1
Re: [PATCH 4/4] ACPI/IORT: Don't call iommu_ops->add_device directly
Quoted 9 lines · Joerg Roedel
From: Joerg Roedel <[email protected]>
Make sure to invoke this call-back through the proper function of the IOMMU-API.
Signed-off-by Joerg Roedel <[email protected]>--- drivers/acpi/arm64/iort.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Robin and Lorenzo know this better than me, but it's pretty straight forward to me,
Thanks
Hanjun