From: Yijing Wang <wangyijing@huawei.com> To: Arnd Bergmann <arnd@arndb.de>, linux-arm-kernel@lists.infradead.org Cc: linux-arch@vger.kernel.org, Wuyun <wuyun.wu@huawei.com>, Russell King <linux@arm.linux.org.uk>, Paul.Mundt@huawei.com, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, "James E.J. Bottomley" <jejb@parisc-linux.org>, Xinwei Hu <huxinwei@huawei.com>, Hanjun Guo <guohanjun@huawei.com>, Bjorn Helgaas <bhelgaas@google.com>, virtualization@lists.linux-foundation.org Subject: Re: [RFC PATCH 00/11] Refactor MSI to support Non-PCI device Date: Wed, 30 Jul 2014 10:45:02 +0800 [thread overview] Message-ID: <53D85C2E.3060205@huawei.com> (raw) In-Reply-To: <1748052.OMBQJiOLYT@wuerfel> On 2014/7/29 22:08, Arnd Bergmann wrote: > On Saturday 26 July 2014 11:08:37 Yijing Wang wrote: >> The series is a draft of generic MSI driver that supports PCI >> and Non-PCI device which have MSI capability. If you're not interested >> it, sorry for the noise. > > I've finally managed to take some time to look at the series. Overall, > the concept looks good to me, and the patches look very well implemented. > > The part I'm not sure about is the interface we want to end up with > at the end of the series. More on that below Hi Arnd, Thanks for your review and comments very much! Please refer the inline comments. > >> The series is based on Linux-3.16-rc1. >> >> MSI was introduced in PCI Spec 2.2. Currently, kernel MSI >> driver codes are bonding with PCI device. Because MSI has a lot >> advantages in design. More and more non-PCI devices want to >> use MSI as their default interrupt. The existing MSI device >> include HPET. HPET driver provide its own MSI code to initialize >> and process MSI interrupts. In the latest GIC v3 spec, legacy device >> can deliver MSI by the help of a relay device named consolidator. >> Consolidator can translate the legacy interrupts connected to it >> to MSI/MSI-X. And new non-PCI device will be designed to >> support MSI in future. So make the MSI driver code be generic will >> help the non-PCI device use MSI more simply. >> >> The new data struct for generic MSI driver. >> struct msi_irqs { >> u8 msi_enabled:1; /* Enable flag */ >> u8 msix_enabled:1; >> struct list_head msi_list; /* MSI desc list */ >> void *data; /* help to find the MSI device */ >> struct msi_ops *ops; /* MSI device specific hook */ >> }; >> struct msi_irqs is used to manage MSI related informations. Every device supports >> MSI should contain this data struct and allocate it. > > I think you should have a stronger association with the 'struct > device' here. Can you replace the 'void *data' with 'struct device *dev'? Actually, I used the struct device *dev in my first draft, finally, I replaced it with void *data, because some MSI devices don't have a struct device *dev, like the existing hpet device, dmar msi device, and OF device, like the ARM consolidator. Of course, we can make the MSI devices have their own struct device, and register to device tree, eg, add a class device named MSI_DEV. But I'm not sure whether it is appropriate. > > The other part I'm not completely sure about is how you want to > have MSIs map into normal IRQ descriptors. At the moment, all > MSI users are based on IRQ numbers, but this has known scalability problems. Hmmm, I still use the IRQ number to map the MSIs to IRQ description. I'm sorry, I don't understand you meaning. What are the scalability problems you mentioned ? For device drivers, they always process interrupt in two steps. If irq is the legacy interrupt, drivers will first use the irq_of_parse_and_map() or pci_enable_device() to parse and get the IRQ number. Then drivers will call the request_irq() to register the interrupt handler. If irq is MSIs, first call pci_enable_msi/x() to get the IRQ number and then call request_irq() to register interrupt handler. > I wonder if we can do the interface in a way that > hides the interrupt number from generic device drivers and just > passes a 'struct irq_desc'. Note that there are long-term plans to > get rid of IRQ numbers entirely, but those plans have existed for > a long time already without anybody seriously addressing the device > driver interfaces so far, so it might never really happen. > Maybe this is a huge work, now hundreds drivers use the IRQ number, so maybe we can consider this in a separate title. >> struct msi_ops { >> struct msi_desc *(*msi_setup_entry)(struct msi_irqs *msi, struct msi_desc *entry); >> int msix_setup_entries(struct msi_irqs *msi, struct msix_entry *entries); >> u32 (*msi_mask_irq)(struct msi_desc *desc, u32 mask, u32 flag); >> u32 (*msix_mask_irq)(struct msi_desc *desc, u32 flag); >> void (*msi_read_message)(struct msi_desc *desc, struct msi_msg *msg); >> void (*msi_write_message)(struct msi_desc *desc, struct msi_msg *msg); >> void (*msi_set_intx)(struct msi_irqs *msi, int enable); >> }; >> struct msi_ops provides several hook functions, generic MSI driver will call >> the hook functions to access device specific registers. PCI devices will share >> the same msi_ops, because they have the same way to access MSI hardware registers. >> >> Generic MSI layer export msi_capability_init() and msix_capability_init() functions >> to drivers. msi/x_capability_init() will initialize MSI capability data struct msi_desc >> and alloc the irq, then write the msi address/data value to hardware registers. >> >> This series only did compile test, we will test it in x86 and arm platform later. > > For the generic drivers, I don't see much point in differentiating between > MSI and MSI-X, as I believe the difference is something internal to the PCI > implementation. Yes, we can integrate them, and use a generic ops, add a type in hook function to differentiate them. > > With the other operations, I think they should all take a 'struct device *' > as the first argument for convenience and consistency. I don't think you actually > need msi_read_message(), and we could avoid msi_write_message() by doing it > the other way round. > There only two functions use the read_msi_msg(), because every msi_desc has a struct msi_msg, and it caches the msi address and data. I will consider to retrieve the msg from cached msi_msg, then we can avoid the msi_read_message(). But msi_write_message() maybe necessary, some xxx_set_affinity() functions and restore functions need the msi_write_message() to rewrite the address and data. > What I'd envision as the API from the device driver perspective is something > as simple like this: > > struct msi_desc *msi_request(struct msi_chip *chip, irq_handler_t handler, > unsigned long flags, const char *name, struct device *dev); > > which would get an msi descriptor that is valid for this device (dev) > connected to a particular msi_chip, and associate a handler function > with it. The device driver can call that function and retrieve the > address/message pair from the msi_desc in order to store it in its own > device specific registers. The request_irq() can be handled internally > to msi_request(). This is a huge change for device drivers, and some device drivers don't know which msi_chip their MSI irq deliver to. I'm reworking the msi_chip, and try to use msi_chip to eliminate all arch_msi_xxx() under every arch in kernel. And the important point is how to create the binding for the MSI device to the target msi_chip. For PCI device, some arm platform already bound the msi_chip to the pci hostbridge, then all pci devices under the pci hostbridge deliver their MSI irqs to the target msi_chip. And other platform create the binding in DTS file, then the MSI device can find their msi_chip by device_node. I don't know whether there are other situations, we should provide a generic interface that every MSI device under every platform can use it to find its msi_chip exactly. Thanks! Yijing. > > . > -- Thanks! Yijing
WARNING: multiple messages have this Message-ID (diff)
From: Yijing Wang <wangyijing@huawei.com> To: Arnd Bergmann <arnd@arndb.de>, linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, Russell King <linux@arm.linux.org.uk>, Paul.Mundt@huawei.com, Marc Zyngier <marc.zyngier@arm.com>, linux-pci@vger.kernel.org, "James E.J. Bottomley" <jejb@parisc-linux.org>, virtualization@lists.linux-foundation.org, Xinwei Hu <huxinwei@huawei.com>, Hanjun Guo <guohanjun@huawei.com>, Bjorn Helgaas <bhelgaas@google.com>, Wuyun <wuyun.wu@huawei.com> Subject: Re: [RFC PATCH 00/11] Refactor MSI to support Non-PCI device Date: Wed, 30 Jul 2014 10:45:02 +0800 [thread overview] Message-ID: <53D85C2E.3060205@huawei.com> (raw) Message-ID: <20140730024502.RgFFL6e4kPdUQ6BnWdYRoDuQVtqs6f1Wk6QExQCpCo4@z> (raw) In-Reply-To: <1748052.OMBQJiOLYT@wuerfel> On 2014/7/29 22:08, Arnd Bergmann wrote: > On Saturday 26 July 2014 11:08:37 Yijing Wang wrote: >> The series is a draft of generic MSI driver that supports PCI >> and Non-PCI device which have MSI capability. If you're not interested >> it, sorry for the noise. > > I've finally managed to take some time to look at the series. Overall, > the concept looks good to me, and the patches look very well implemented. > > The part I'm not sure about is the interface we want to end up with > at the end of the series. More on that below Hi Arnd, Thanks for your review and comments very much! Please refer the inline comments. > >> The series is based on Linux-3.16-rc1. >> >> MSI was introduced in PCI Spec 2.2. Currently, kernel MSI >> driver codes are bonding with PCI device. Because MSI has a lot >> advantages in design. More and more non-PCI devices want to >> use MSI as their default interrupt. The existing MSI device >> include HPET. HPET driver provide its own MSI code to initialize >> and process MSI interrupts. In the latest GIC v3 spec, legacy device >> can deliver MSI by the help of a relay device named consolidator. >> Consolidator can translate the legacy interrupts connected to it >> to MSI/MSI-X. And new non-PCI device will be designed to >> support MSI in future. So make the MSI driver code be generic will >> help the non-PCI device use MSI more simply. >> >> The new data struct for generic MSI driver. >> struct msi_irqs { >> u8 msi_enabled:1; /* Enable flag */ >> u8 msix_enabled:1; >> struct list_head msi_list; /* MSI desc list */ >> void *data; /* help to find the MSI device */ >> struct msi_ops *ops; /* MSI device specific hook */ >> }; >> struct msi_irqs is used to manage MSI related informations. Every device supports >> MSI should contain this data struct and allocate it. > > I think you should have a stronger association with the 'struct > device' here. Can you replace the 'void *data' with 'struct device *dev'? Actually, I used the struct device *dev in my first draft, finally, I replaced it with void *data, because some MSI devices don't have a struct device *dev, like the existing hpet device, dmar msi device, and OF device, like the ARM consolidator. Of course, we can make the MSI devices have their own struct device, and register to device tree, eg, add a class device named MSI_DEV. But I'm not sure whether it is appropriate. > > The other part I'm not completely sure about is how you want to > have MSIs map into normal IRQ descriptors. At the moment, all > MSI users are based on IRQ numbers, but this has known scalability problems. Hmmm, I still use the IRQ number to map the MSIs to IRQ description. I'm sorry, I don't understand you meaning. What are the scalability problems you mentioned ? For device drivers, they always process interrupt in two steps. If irq is the legacy interrupt, drivers will first use the irq_of_parse_and_map() or pci_enable_device() to parse and get the IRQ number. Then drivers will call the request_irq() to register the interrupt handler. If irq is MSIs, first call pci_enable_msi/x() to get the IRQ number and then call request_irq() to register interrupt handler. > I wonder if we can do the interface in a way that > hides the interrupt number from generic device drivers and just > passes a 'struct irq_desc'. Note that there are long-term plans to > get rid of IRQ numbers entirely, but those plans have existed for > a long time already without anybody seriously addressing the device > driver interfaces so far, so it might never really happen. > Maybe this is a huge work, now hundreds drivers use the IRQ number, so maybe we can consider this in a separate title. >> struct msi_ops { >> struct msi_desc *(*msi_setup_entry)(struct msi_irqs *msi, struct msi_desc *entry); >> int msix_setup_entries(struct msi_irqs *msi, struct msix_entry *entries); >> u32 (*msi_mask_irq)(struct msi_desc *desc, u32 mask, u32 flag); >> u32 (*msix_mask_irq)(struct msi_desc *desc, u32 flag); >> void (*msi_read_message)(struct msi_desc *desc, struct msi_msg *msg); >> void (*msi_write_message)(struct msi_desc *desc, struct msi_msg *msg); >> void (*msi_set_intx)(struct msi_irqs *msi, int enable); >> }; >> struct msi_ops provides several hook functions, generic MSI driver will call >> the hook functions to access device specific registers. PCI devices will share >> the same msi_ops, because they have the same way to access MSI hardware registers. >> >> Generic MSI layer export msi_capability_init() and msix_capability_init() functions >> to drivers. msi/x_capability_init() will initialize MSI capability data struct msi_desc >> and alloc the irq, then write the msi address/data value to hardware registers. >> >> This series only did compile test, we will test it in x86 and arm platform later. > > For the generic drivers, I don't see much point in differentiating between > MSI and MSI-X, as I believe the difference is something internal to the PCI > implementation. Yes, we can integrate them, and use a generic ops, add a type in hook function to differentiate them. > > With the other operations, I think they should all take a 'struct device *' > as the first argument for convenience and consistency. I don't think you actually > need msi_read_message(), and we could avoid msi_write_message() by doing it > the other way round. > There only two functions use the read_msi_msg(), because every msi_desc has a struct msi_msg, and it caches the msi address and data. I will consider to retrieve the msg from cached msi_msg, then we can avoid the msi_read_message(). But msi_write_message() maybe necessary, some xxx_set_affinity() functions and restore functions need the msi_write_message() to rewrite the address and data. > What I'd envision as the API from the device driver perspective is something > as simple like this: > > struct msi_desc *msi_request(struct msi_chip *chip, irq_handler_t handler, > unsigned long flags, const char *name, struct device *dev); > > which would get an msi descriptor that is valid for this device (dev) > connected to a particular msi_chip, and associate a handler function > with it. The device driver can call that function and retrieve the > address/message pair from the msi_desc in order to store it in its own > device specific registers. The request_irq() can be handled internally > to msi_request(). This is a huge change for device drivers, and some device drivers don't know which msi_chip their MSI irq deliver to. I'm reworking the msi_chip, and try to use msi_chip to eliminate all arch_msi_xxx() under every arch in kernel. And the important point is how to create the binding for the MSI device to the target msi_chip. For PCI device, some arm platform already bound the msi_chip to the pci hostbridge, then all pci devices under the pci hostbridge deliver their MSI irqs to the target msi_chip. And other platform create the binding in DTS file, then the MSI device can find their msi_chip by device_node. I don't know whether there are other situations, we should provide a generic interface that every MSI device under every platform can use it to find its msi_chip exactly. Thanks! Yijing. > > . > -- Thanks! Yijing
next prev parent reply other threads:[~2014-07-30 2:45 UTC|newest] Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top 2014-07-26 3:08 [RFC PATCH 00/11] Refactor MSI to support Non-PCI device Yijing Wang 2014-07-26 3:08 ` [RFC PATCH 01/11] PCI/MSI: Use pci_dev->msi_cap instead of msi_desc->msi_attrib.pos Yijing Wang 2014-07-26 3:08 ` Yijing Wang 2014-07-26 3:08 ` [RFC PATCH 02/11] PCI/MSI: Use new MSI type macro instead of PCI MSI flags Yijing Wang 2014-07-26 3:08 ` Yijing Wang 2014-07-26 3:08 ` [RFC PATCH 03/11] PCI/MSI: Refactor pci_dev_msi_enabled() Yijing Wang 2014-07-26 3:08 ` Yijing Wang 2014-08-05 22:35 ` Stuart Yoder 2014-08-05 22:35 ` Stuart Yoder 2014-08-06 1:23 ` Yijing Wang 2014-08-06 1:23 ` Yijing Wang 2014-08-20 5:57 ` Bharat.Bhushan 2014-08-20 5:57 ` Bharat.Bhushan 2014-08-20 6:30 ` Yijing Wang 2014-08-20 6:30 ` Yijing Wang 2014-07-26 3:08 ` [RFC PATCH 04/11] PCI/MSI: Move MSIX table address mapping out of msix_capability_init Yijing Wang 2014-07-26 3:08 ` Yijing Wang 2014-07-26 3:08 ` [RFC PATCH 05/11] PCI/MSI: Move populate_msi_sysfs() out of msi_capability_init() Yijing Wang 2014-07-26 3:08 ` Yijing Wang 2014-07-26 3:08 ` [RFC PATCH 06/11] PCI/MSI: Save MSI irq in PCI MSI layer Yijing Wang 2014-07-26 3:08 ` Yijing Wang 2014-07-26 3:08 ` [RFC PATCH 07/11] PCI/MSI: Mask MSI-X entry in msix_setup_entries() Yijing Wang 2014-07-26 3:08 ` Yijing Wang 2014-07-26 3:08 ` [RFC PATCH 08/11] PCI/MSI: Introduce new struct msi_irqs and struct msi_ops Yijing Wang 2014-07-26 3:08 ` Yijing Wang 2014-07-26 3:08 ` [RFC PATCH 09/11] PCI/MSI: refactor PCI MSI driver Yijing Wang 2014-07-26 3:08 ` Yijing Wang 2014-08-20 6:06 ` Bharat.Bhushan 2014-08-20 6:06 ` Bharat.Bhushan 2014-08-20 6:34 ` Yijing Wang 2014-08-20 6:34 ` Yijing Wang 2014-07-26 3:08 ` [RFC PATCH 10/11] PCI/MSI: Split the generic MSI code into new file Yijing Wang 2014-07-26 3:08 ` Yijing Wang 2014-08-20 6:18 ` Bharat.Bhushan 2014-08-20 6:18 ` Bharat.Bhushan 2014-08-20 6:43 ` Yijing Wang 2014-08-20 6:43 ` Yijing Wang 2014-07-26 3:08 ` [RFC PATCH 11/11] x86/MSI: Refactor x86 MSI code Yijing Wang 2014-07-26 3:08 ` Yijing Wang 2014-08-20 6:20 ` Bharat.Bhushan 2014-08-20 6:20 ` Bharat.Bhushan 2014-08-20 7:01 ` Yijing Wang 2014-07-29 14:08 ` [RFC PATCH 00/11] Refactor MSI to support Non-PCI device Arnd Bergmann 2014-07-29 14:08 ` Arnd Bergmann 2014-07-30 2:45 ` Yijing Wang [this message] 2014-07-30 2:45 ` Yijing Wang 2014-07-30 6:47 ` Jiang Liu 2014-07-30 6:47 ` Jiang Liu 2014-07-30 7:20 ` Yijing Wang 2014-08-01 13:16 ` Arnd Bergmann 2014-08-01 13:16 ` Arnd Bergmann 2014-08-04 3:32 ` Yijing Wang 2014-08-04 3:32 ` Yijing Wang 2014-08-04 14:45 ` Arnd Bergmann 2014-08-05 2:20 ` Yijing Wang 2014-08-05 2:20 ` Yijing Wang 2014-08-01 13:52 ` Arnd Bergmann 2014-08-01 13:52 ` Arnd Bergmann 2014-08-04 6:43 ` Yijing Wang 2014-08-04 6:43 ` Yijing Wang 2014-08-04 14:59 ` Arnd Bergmann 2014-08-04 14:59 ` Arnd Bergmann 2014-08-05 2:12 ` Yijing Wang 2014-08-05 2:12 ` Yijing Wang 2014-08-01 10:27 ` arnab.basu 2014-08-04 3:03 ` Yijing Wang 2014-08-04 3:03 ` Yijing Wang 2014-08-20 5:44 ` Bharat.Bhushan 2014-08-20 5:44 ` Bharat.Bhushan 2014-08-20 6:28 ` Yijing Wang 2014-08-20 6:28 ` Yijing Wang 2014-08-20 7:41 ` Bharat.Bhushan 2014-08-20 7:41 ` Bharat.Bhushan 2014-08-20 7:55 ` Yijing Wang 2014-09-03 7:15 ` Yijing Wang
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=53D85C2E.3060205@huawei.com \ --to=wangyijing@huawei.com \ --cc=Paul.Mundt@huawei.com \ --cc=arnd@arndb.de \ --cc=bhelgaas@google.com \ --cc=guohanjun@huawei.com \ --cc=huxinwei@huawei.com \ --cc=jejb@parisc-linux.org \ --cc=linux-arch@vger.kernel.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-pci@vger.kernel.org \ --cc=linux@arm.linux.org.uk \ --cc=virtualization@lists.linux-foundation.org \ --cc=wuyun.wu@huawei.com \ /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: linkBe 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; as well as URLs for NNTP newsgroup(s).