From: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
To: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
punit.agrawal-5wv7dgnIgG8@public.gmane.org,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
thunder.leizhen-hv44wF8Li93QT0dZR+AlfA@public.gmane.org
Subject: Re: [PATCH v5 11/19] iommu/arm-smmu: Refactor mmu-masters handling
Date: Thu, 1 Sep 2016 19:47:23 +0100 [thread overview]
Message-ID: <20160901184723.GV6721@arm.com> (raw)
In-Reply-To: <00301aa60323bb94588d078f2962feea0cb45c72.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
On Tue, Aug 23, 2016 at 08:05:22PM +0100, Robin Murphy wrote:
> To be able to support the generic bindings and handle of_xlate() calls,
> we need to be able to associate SMMUs and stream IDs directly with
> devices *before* allocating IOMMU groups. Furthermore, to support real
> default domains with multi-device groups we also have to handle domain
> attach on a per-device basis, as the "whole group at a time" assumption
> fails to properly handle subsequent devices added to a group after the
> first has already triggered default domain creation and attachment.
>
> To that end, use the now-vacant dev->archdata.iommu field for easy
> config and SMMU instance lookup, and unify config management by chopping
> down the platform-device-specific tree and probing the "mmu-masters"
> property on-demand instead. This may add a bit of one-off overhead to
> initially adding a new device, but we're about to deprecate that binding
> in favour of the inherently-more-efficient generic ones anyway.
>
> For the sake of simplicity, this patch does temporarily regress the case
> of aliasing PCI devices by losing the duplicate stream ID detection that
> the previous per-group config had. Stay tuned, because we'll be back to
> fix that in a better and more general way momentarily...
>
> Signed-off-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
> ---
> drivers/iommu/arm-smmu.c | 382 +++++++++++++----------------------------------
> 1 file changed, 107 insertions(+), 275 deletions(-)
>
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index 22c093030322..9066fd1399d4 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -317,18 +317,13 @@ struct arm_smmu_smr {
> };
>
> struct arm_smmu_master_cfg {
> + struct arm_smmu_device *smmu;
> int num_streamids;
> u16 streamids[MAX_MASTER_STREAMIDS];
> s16 smendx[MAX_MASTER_STREAMIDS];
> };
> #define INVALID_SMENDX -1
>
> -struct arm_smmu_master {
> - struct device_node *of_node;
> - struct rb_node node;
> - struct arm_smmu_master_cfg cfg;
> -};
> -
> struct arm_smmu_device {
> struct device *dev;
>
> @@ -376,7 +371,6 @@ struct arm_smmu_device {
> unsigned int *irqs;
>
> struct list_head list;
> - struct rb_root masters;
>
> u32 cavium_id_base; /* Specific to Cavium */
> };
> @@ -415,12 +409,6 @@ struct arm_smmu_domain {
> struct iommu_domain domain;
> };
>
> -struct arm_smmu_phandle_args {
> - struct device_node *np;
> - int args_count;
> - uint32_t args[MAX_MASTER_STREAMIDS];
> -};
> -
> static DEFINE_SPINLOCK(arm_smmu_devices_lock);
> static LIST_HEAD(arm_smmu_devices);
>
> @@ -462,132 +450,89 @@ static struct device_node *dev_get_dev_node(struct device *dev)
>
> while (!pci_is_root_bus(bus))
> bus = bus->parent;
> - return bus->bridge->parent->of_node;
> + return of_node_get(bus->bridge->parent->of_node);
> }
>
> - return dev->of_node;
> + return of_node_get(dev->of_node);
> }
>
> -static struct arm_smmu_master *find_smmu_master(struct arm_smmu_device *smmu,
> - struct device_node *dev_node)
> +static int __arm_smmu_get_pci_sid(struct pci_dev *pdev, u16 alias, void *data)
> {
> - struct rb_node *node = smmu->masters.rb_node;
> -
> - while (node) {
> - struct arm_smmu_master *master;
> -
> - master = container_of(node, struct arm_smmu_master, node);
> -
> - if (dev_node < master->of_node)
> - node = node->rb_left;
> - else if (dev_node > master->of_node)
> - node = node->rb_right;
> - else
> - return master;
> - }
> -
> - return NULL;
> + *((__be32 *)data) = cpu_to_be32(alias);
> + return 0; /* Continue walking */
> }
>
> -static struct arm_smmu_master_cfg *
> -find_smmu_master_cfg(struct device *dev)
> +static int __find_legacy_master_phandle(struct device *dev, void *data)
> {
> - struct arm_smmu_master_cfg *cfg = NULL;
> - struct iommu_group *group = iommu_group_get(dev);
> + struct of_phandle_iterator *it = *(void **)data;
> + struct device_node *np = it->node;
> + int err;
>
> - if (group) {
> - cfg = iommu_group_get_iommudata(group);
> - iommu_group_put(group);
> - }
> -
> - return cfg;
> -}
> -
> -static int insert_smmu_master(struct arm_smmu_device *smmu,
> - struct arm_smmu_master *master)
> -{
> - struct rb_node **new, *parent;
> -
> - new = &smmu->masters.rb_node;
> - parent = NULL;
> - while (*new) {
> - struct arm_smmu_master *this
> - = container_of(*new, struct arm_smmu_master, node);
> -
> - parent = *new;
> - if (master->of_node < this->of_node)
> - new = &((*new)->rb_left);
> - else if (master->of_node > this->of_node)
> - new = &((*new)->rb_right);
> - else
> - return -EEXIST;
> - }
> -
> - rb_link_node(&master->node, parent, new);
> - rb_insert_color(&master->node, &smmu->masters);
> - return 0;
> -}
> -
> -static int register_smmu_master(struct arm_smmu_device *smmu,
> - struct device *dev,
> - struct arm_smmu_phandle_args *masterspec)
> -{
> - int i;
> - struct arm_smmu_master *master;
> -
> - master = find_smmu_master(smmu, masterspec->np);
> - if (master) {
> - dev_err(dev,
> - "rejecting multiple registrations for master device %s\n",
> - masterspec->np->name);
> - return -EBUSY;
> - }
> -
> - if (masterspec->args_count > MAX_MASTER_STREAMIDS) {
> - dev_err(dev,
> - "reached maximum number (%d) of stream IDs for master device %s\n",
> - MAX_MASTER_STREAMIDS, masterspec->np->name);
> - return -ENOSPC;
> - }
> -
> - master = devm_kzalloc(dev, sizeof(*master), GFP_KERNEL);
> - if (!master)
> - return -ENOMEM;
> -
> - master->of_node = masterspec->np;
> - master->cfg.num_streamids = masterspec->args_count;
> -
> - for (i = 0; i < master->cfg.num_streamids; ++i) {
> - u16 streamid = masterspec->args[i];
> -
> - if (!(smmu->features & ARM_SMMU_FEAT_STREAM_MATCH) &&
> - (streamid >= smmu->num_mapping_groups)) {
> - dev_err(dev,
> - "stream ID for master device %s greater than maximum allowed (%d)\n",
> - masterspec->np->name, smmu->num_mapping_groups);
> - return -ERANGE;
> + of_for_each_phandle(it, err, dev->of_node, "mmu-masters",
> + "#stream-id-cells", 0)
> + if (it->node == np) {
> + *(void **)data = dev;
> + return 1;
> }
> - master->cfg.streamids[i] = streamid;
> - master->cfg.smendx[i] = INVALID_SMENDX;
> - }
> - return insert_smmu_master(smmu, master);
> + it->node = np;
> + return err;
> }
>
> -static struct arm_smmu_device *find_smmu_for_device(struct device *dev)
> +static int arm_smmu_register_legacy_master(struct device *dev)
> {
> struct arm_smmu_device *smmu;
> - struct arm_smmu_master *master = NULL;
> - struct device_node *dev_node = dev_get_dev_node(dev);
> + struct arm_smmu_master_cfg *cfg;
> + struct device_node *np;
> + struct of_phandle_iterator it;
> + void *data = ⁢
> + __be32 pci_sid;
> + int err;
>
> + np = dev_get_dev_node(dev);
> + if (!np || !of_find_property(np, "#stream-id-cells", NULL)) {
> + of_node_put(np);
> + return -ENODEV;
> + }
> +
> + it.node = np;
> spin_lock(&arm_smmu_devices_lock);
> list_for_each_entry(smmu, &arm_smmu_devices, list) {
> - master = find_smmu_master(smmu, dev_node);
> - if (master)
> + err = __find_legacy_master_phandle(smmu->dev, &data);
> + if (err)
> break;
> }
> spin_unlock(&arm_smmu_devices_lock);
> + of_node_put(np);
> + if (err == 0)
> + return -ENODEV;
> + if (err < 0)
> + return err;
>
> - return master ? smmu : NULL;
> + if (it.cur_count > MAX_MASTER_STREAMIDS) {
> + dev_err(smmu->dev,
> + "reached maximum number (%d) of stream IDs for master device %s\n",
> + MAX_MASTER_STREAMIDS, dev_name(dev));
> + return -ENOSPC;
> + }
> + if (dev_is_pci(dev)) {
> + /* "mmu-masters" assumes Stream ID == Requester ID */
> + pci_for_each_dma_alias(to_pci_dev(dev), __arm_smmu_get_pci_sid,
> + &pci_sid);
> + it.cur = &pci_sid;
> + it.cur_count = 1;
> + }
> +
> + cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
> + if (!cfg)
> + return -ENOMEM;
> +
> + cfg->smmu = smmu;
> + dev->archdata.iommu = cfg;
> +
> + while (it.cur_count--)
> + cfg->streamids[cfg->num_streamids++] = be32_to_cpup(it.cur++);
I pronounce this construct, the "Murphy Device"! At least it didn't survive
until the end of the series :p
Will
next prev parent reply other threads:[~2016-09-01 18:47 UTC|newest]
Thread overview: 61+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-23 19:05 [PATCH v5 00/19] Generic DT bindings for PCI IOMMUs and ARM SMMU Robin Murphy
[not found] ` <cover.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2016-08-23 19:05 ` [PATCH v5 01/19] Docs: dt: add PCI IOMMU map bindings Robin Murphy
2016-08-23 19:05 ` [PATCH v5 02/19] of/irq: Break out msi-map lookup (again) Robin Murphy
2016-08-23 19:05 ` [PATCH v5 03/19] iommu/of: Handle iommu-map property for PCI Robin Murphy
[not found] ` <93909648835867008b21cb688a1d7db238d3641a.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2016-08-31 15:43 ` Will Deacon
2016-08-23 19:05 ` [PATCH v5 04/19] iommu/of: Introduce iommu_fwspec Robin Murphy
[not found] ` <3e8eaf4fd65833fecc62828214aee81f6ca6c190.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2016-08-31 17:28 ` Will Deacon
[not found] ` <20160831172856.GI29505-5wv7dgnIgG8@public.gmane.org>
2016-09-01 12:07 ` Robin Murphy
[not found] ` <900f3dcb-217c-4fb3-2f7d-15572f31a0c0-5wv7dgnIgG8@public.gmane.org>
2016-09-01 12:31 ` Will Deacon
[not found] ` <20160901123158.GE6721-5wv7dgnIgG8@public.gmane.org>
2016-09-01 13:25 ` Robin Murphy
2016-08-23 19:05 ` [PATCH v5 05/19] iommu/arm-smmu: Implement of_xlate() for SMMUv3 Robin Murphy
[not found] ` <6088007f60a24b36a3bf965b62521f99cd908019.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2016-09-01 17:06 ` Will Deacon
[not found] ` <20160901170604.GP6721-5wv7dgnIgG8@public.gmane.org>
2016-09-01 17:40 ` Robin Murphy
2016-08-23 19:05 ` [PATCH v5 06/19] iommu/arm-smmu: Support non-PCI devices with SMMUv3 Robin Murphy
[not found] ` <207d0ae38c5b01b7cf7e48231a4d01bac453b57c.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2016-09-01 17:08 ` Will Deacon
2016-08-23 19:05 ` [PATCH v5 07/19] iommu/arm-smmu: Set PRIVCFG in stage 1 STEs Robin Murphy
[not found] ` <1cda9861ce3ede6c2de9c6c4f2294549808b421b.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2016-09-01 17:19 ` Will Deacon
2016-08-23 19:05 ` [PATCH v5 08/19] iommu/arm-smmu: Handle stream IDs more dynamically Robin Murphy
[not found] ` <36f71a07fbc6037ca664bdcc540650f893081dd1.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2016-09-01 18:17 ` Will Deacon
2016-08-23 19:05 ` [PATCH v5 09/19] iommu/arm-smmu: Consolidate stream map entry state Robin Murphy
[not found] ` <26fcf7d3138816b9546a3dcc2bbbc2f229f34c91.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2016-09-01 18:32 ` Will Deacon
[not found] ` <20160901183257.GT6721-5wv7dgnIgG8@public.gmane.org>
2016-09-01 18:45 ` Robin Murphy
[not found] ` <6d3209ff-51ad-30ca-867b-ce62105e6699-5wv7dgnIgG8@public.gmane.org>
2016-09-01 18:54 ` Will Deacon
2016-08-23 19:05 ` [PATCH v5 10/19] iommu/arm-smmu: Keep track of S2CR state Robin Murphy
[not found] ` <e086741acfd0959671d184203ef758c824c8d7da.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2016-09-01 18:42 ` Will Deacon
[not found] ` <20160901184259.GU6721-5wv7dgnIgG8@public.gmane.org>
2016-09-01 19:00 ` Robin Murphy
2016-08-23 19:05 ` [PATCH v5 11/19] iommu/arm-smmu: Refactor mmu-masters handling Robin Murphy
[not found] ` <00301aa60323bb94588d078f2962feea0cb45c72.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2016-09-01 18:47 ` Will Deacon [this message]
2016-08-23 19:05 ` [PATCH v5 12/19] iommu/arm-smmu: Streamline SMMU data lookups Robin Murphy
2016-08-23 19:05 ` [PATCH v5 13/19] iommu/arm-smmu: Add a stream map entry iterator Robin Murphy
2016-08-23 19:05 ` [PATCH v5 14/19] iommu/arm-smmu: Intelligent SMR allocation Robin Murphy
[not found] ` <693b7fdd58be254297eb43ac8f5e035beb5226b2.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2016-09-01 15:17 ` Lorenzo Pieralisi
2016-09-01 17:59 ` Robin Murphy
2016-08-23 19:05 ` [PATCH v5 15/19] iommu/arm-smmu: Convert to iommu_fwspec Robin Murphy
[not found] ` <221f668d606abdfb4d6ee6da2c5f568c57ceccdd.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2016-09-01 18:53 ` Will Deacon
2016-08-23 19:05 ` [PATCH v5 16/19] Docs: dt: document ARM SMMU generic binding usage Robin Murphy
[not found] ` <b4f0eca93ac944c3430297b97c703e1bc54846d7.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2016-08-29 15:44 ` Rob Herring
2016-08-23 19:05 ` [PATCH v5 17/19] iommu/arm-smmu: Wire up generic configuration support Robin Murphy
[not found] ` <4439250e01ac071bae8f03a5ccf107ed7ddc0b49.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2016-09-01 19:02 ` Will Deacon
2016-08-23 19:05 ` [PATCH v5 18/19] iommu/arm-smmu: Set domain geometry Robin Murphy
[not found] ` <d6cedec16fe96a081ea2f9f27378dd1a6f406c72.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2016-08-31 21:00 ` Auger Eric
2016-08-23 19:05 ` [PATCH v5 19/19] iommu/dma: Add support for mapping MSIs Robin Murphy
2016-08-23 19:05 ` Robin Murphy
[not found] ` <4c901ff0f6355039de55b0bc0df283065f02efa1.1471975357.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2016-08-24 8:16 ` Thomas Gleixner
2016-08-24 8:16 ` Thomas Gleixner
2016-08-24 10:06 ` Robin Murphy
2016-08-24 10:06 ` Robin Murphy
2016-08-25 22:25 ` Auger Eric
2016-08-25 22:25 ` Auger Eric
[not found] ` <5d8d4ae0-846a-2499-eb46-6f215b87ebd4-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-08-26 1:17 ` Robin Murphy
2016-08-26 1:17 ` Robin Murphy
[not found] ` <20160826021736.571a732f-h2/QxWiDqNo@public.gmane.org>
2016-08-31 20:51 ` Auger Eric
2016-08-31 20:51 ` Auger Eric
2016-08-23 19:15 ` [PATCH v5 00/19] Generic DT bindings for PCI IOMMUs and ARM SMMU Robin Murphy
2016-08-23 19:15 ` Robin Murphy
[not found] ` <3a9a9369-d8cd-66f4-9344-965c80894bb6-5wv7dgnIgG8@public.gmane.org>
2016-09-01 3:49 ` Anup Patel
2016-09-01 3:49 ` Anup Patel
[not found] ` <CAALAos-OzPG=+aU8eKEZtx6EFXytPXq09k3QweHvtYCD=mN0mQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-09-01 10:10 ` Robin Murphy
2016-09-01 10:10 ` Robin Murphy
2016-09-01 15:22 ` Lorenzo Pieralisi
2016-09-01 19:05 ` Will Deacon
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=20160901184723.GV6721@arm.com \
--to=will.deacon-5wv7dgnigg8@public.gmane.org \
--cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
--cc=punit.agrawal-5wv7dgnIgG8@public.gmane.org \
--cc=robin.murphy-5wv7dgnIgG8@public.gmane.org \
--cc=thunder.leizhen-hv44wF8Li93QT0dZR+AlfA@public.gmane.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.