VE suffers from serious problem with MMC transfers - low performance, errors when other IO peripherals (especially USB) are used at the same time etc.
It all boils down to the MMC controller short FIFO and - in result - timing constrains. The most problematic case - USB driver hogging CPU and MMC FIFO under/overruns in the result - can be mitigated on SMP system by distributing interrupts handling for these peripherals between cores.
With this, the MMC card clock can be safely (at least it looks like it) increased to 1.5MHz, improving performance.
Signed-off-by: Pawel Moll pawel.moll@arm.com --- arch/arm/mach-vexpress/v2m.c | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 4b5af01..300ac72 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -244,6 +244,7 @@ static unsigned int v2m_mmci_status(struct device *dev) static struct mmci_platform_data v2m_mmci_data = { .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .status = v2m_mmci_status, + .f_max = 1500000, };
static AMBA_DEVICE(aaci, "mb:aaci", V2M_AACI, NULL); @@ -391,6 +392,19 @@ static void __init v2m_init(void) for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++) amba_device_register(v2m_amba_devs[i], &iomem_resource);
+ /* WARNING: HACK HACK HACK! + * + * MMCI cell has very tight timing requirements regarding interrupt + * handling (fractions of millisecond), while the USB host controller + * interrupt handler can hog the CPU for more then 1 millisecond! + * + * To mitigate the problem on SMP systems, we can set CPU affinities + * of these interrupts to different cores... */ + BUG_ON(v2m_usb_resources[1].flags != IORESOURCE_IRQ); + irq_set_affinity(v2m_usb_resources[1].start, cpumask_of(0)); + irq_set_affinity(mmci_device.irq[0], cpumask_of(1)); + irq_set_affinity(mmci_device.irq[1], cpumask_of(1)); + pm_power_off = v2m_power_off; arm_pm_restart = v2m_restart;
Hello.
Pawel Moll wrote:
VE suffers from serious problem with MMC transfers - low performance, errors when other IO peripherals (especially USB) are used at the same time etc.
It all boils down to the MMC controller short FIFO and - in result - timing constrains. The most problematic case - USB driver hogging CPU and MMC FIFO under/overruns in the result - can be mitigated on SMP system by distributing interrupts handling for these peripherals between cores.
With this, the MMC card clock can be safely (at least it looks like it) increased to 1.5MHz, improving performance.
Signed-off-by: Pawel Moll pawel.moll@arm.com
arch/arm/mach-vexpress/v2m.c | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 4b5af01..300ac72 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c
[...]
static AMBA_DEVICE(aaci, "mb:aaci", V2M_AACI, NULL); @@ -391,6 +392,19 @@ static void __init v2m_init(void) for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++) amba_device_register(v2m_amba_devs[i], &iomem_resource);
- /* WARNING: HACK HACK HACK!
*
* MMCI cell has very tight timing requirements regarding interrupt
* handling (fractions of millisecond), while the USB host controller
* interrupt handler can hog the CPU for more then 1 millisecond!
*
* To mitigate the problem on SMP systems, we can set CPU affinities
* of these interrupts to different cores... */
The preferred style for the mutli-line comments is this:
/* * bla * bla */
You were close. :-)
- BUG_ON(v2m_usb_resources[1].flags != IORESOURCE_IRQ);
- irq_set_affinity(v2m_usb_resources[1].start, cpumask_of(0));
- irq_set_affinity(mmci_device.irq[0], cpumask_of(1));
- irq_set_affinity(mmci_device.irq[1], cpumask_of(1));
- pm_power_off = v2m_power_off; arm_pm_restart = v2m_restart;
WBR, Sergei
A word of comment...
At least some of the Linaro file system images are running irqbalance daemon, which will most likely play with MMC and USB interrupts affiliation in runtime. To prevent it from doing so, /etc/default/irqbalance should contain this line:
export IRQBALANCE_BANNED_INTERRUPTS="41 42 48"
Sounds like a job for the VE hwpack, I guess?
Cheers!
Paweł
On Fri, 21 Jan 2011, Pawel Moll wrote:
VE suffers from serious problem with MMC transfers - low performance, errors when other IO peripherals (especially USB) are used at the same time etc.
It all boils down to the MMC controller short FIFO and - in result - timing constrains. The most problematic case - USB driver hogging CPU and MMC FIFO under/overruns in the result - can be mitigated on SMP system by distributing interrupts handling for these peripherals between cores.
Wouldn't the ultimate solution be to simply use FIQs to service the MMC FIFO?
Nicolas
On Fri, Jan 21, 2011 at 02:59:35PM -0500, Nicolas Pitre wrote:
On Fri, 21 Jan 2011, Pawel Moll wrote:
VE suffers from serious problem with MMC transfers - low performance, errors when other IO peripherals (especially USB) are used at the same time etc.
It all boils down to the MMC controller short FIFO and - in result - timing constrains. The most problematic case - USB driver hogging CPU and MMC FIFO under/overruns in the result - can be mitigated on SMP system by distributing interrupts handling for these peripherals between cores.
Wouldn't the ultimate solution be to simply use FIQs to service the MMC FIFO?
Could you suggest how to route an arbitary interrupt to the FIQ using the GIC?
On systems which implement security extensions, the non-secure world can only use IRQs and not FIQs. The secure world can use FIQs - in which case interrupts marked as secure interrupts can go to FIQ.
On systems without security extensions, the GIC only supports IRQ, and you need a second GIC implemented for FIQs. I'm not aware of any system doing that.
On Fri, 21 Jan 2011, Russell King - ARM Linux wrote:
On Fri, Jan 21, 2011 at 02:59:35PM -0500, Nicolas Pitre wrote:
On Fri, 21 Jan 2011, Pawel Moll wrote:
VE suffers from serious problem with MMC transfers - low performance, errors when other IO peripherals (especially USB) are used at the same time etc.
It all boils down to the MMC controller short FIFO and - in result - timing constrains. The most problematic case - USB driver hogging CPU and MMC FIFO under/overruns in the result - can be mitigated on SMP system by distributing interrupts handling for these peripherals between cores.
Wouldn't the ultimate solution be to simply use FIQs to service the MMC FIFO?
Could you suggest how to route an arbitary interrupt to the FIQ using the GIC?
No I can't, hence my question.
On systems which implement security extensions, the non-secure world can only use IRQs and not FIQs. The secure world can use FIQs - in which case interrupts marked as secure interrupts can go to FIQ.
In that case, in theory, the secure world could provide some kind of software based DMA engine facility to the non-secure world for this FIFO servicing purpose.
On systems without security extensions, the GIC only supports IRQ, and you need a second GIC implemented for FIQs. I'm not aware of any system doing that.
The only solution in that case is to give top priority to the FIFO IRQ and never disable IRQs when in interrupt context, except for that FIFO servicing handler which should keep IRQs masked out throughout. In any case this would certainly be only a hack for badly misdesigned hardware.
Nicolas
On Fri, Jan 21, 2011 at 05:20:57PM -0500, Nicolas Pitre wrote:
The only solution in that case is to give top priority to the FIFO IRQ and never disable IRQs when in interrupt context, except for that FIFO servicing handler which should keep IRQs masked out throughout. In any case this would certainly be only a hack for badly misdesigned hardware.
Not possible anymore. The kernel's IRQ handling has changed such that generic code now ensures that IRQs are disabled irrespective of the IRQF_DISABLED flag. All IRQ handlers are called with IRQs disabled, and they remain that way until they call local_irq_enable().
2011/1/21 Russell King - ARM Linux linux@arm.linux.org.uk:
On Fri, Jan 21, 2011 at 05:20:57PM -0500, Nicolas Pitre wrote:
The only solution in that case is to give top priority to the FIFO IRQ and never disable IRQs when in interrupt context, except for that FIFO servicing handler which should keep IRQs masked out throughout. In any case this would certainly be only a hack for badly misdesigned hardware.
Not possible anymore. The kernel's IRQ handling has changed such that generic code now ensures that IRQs are disabled irrespective of the IRQF_DISABLED flag. All IRQ handlers are called with IRQs disabled, and they remain that way until they call local_irq_enable().
Then the only way of assuring low latency on this one IRQ would be to convert the IRQ handlers for all the *other* hardware in the Vexpress to request_threaded_irq(), and that's what the RealTime folks do all the time I believe.
[Pawel Moll]
(...) so far the only time when problem happens is the timeout caused by ISP1761 handler.
Have you considered switching the ISP1761 handler to request_threaded_irq() with IRQF_ONESHOT | IRQF_NO_SUSPEND so it runs in process context with that IRQ masked off, until completion?
Linus Walleij
Have you considered switching the ISP1761 handler to request_threaded_irq() with IRQF_ONESHOT | IRQF_NO_SUSPEND so it runs in process context with that IRQ masked off, until completion?
That's something that Will suggested, but no - I didn't try it. This may be worth discussing with the ISP1761 driver maintainer...
Cheers!
Paweł
Wouldn't the ultimate solution be to simply use FIQs to service the MMC FIFO?
The ultimate solution is to super-size FIFO ;-) It's not impossible (as the motherboard peripherals live in a FPGA), but according to our board people may be tricky due to the MMCI design (it's just ancient, that's all).
Now, the first thing I did was bumping the MMCI interrupts priorities, then I was considering use of FIQ. But - as Russell pointed out - it's simply not so simple...
the secure world could provide some kind of software based DMA engine facility to the non-secure world for this FIFO servicing purpose.
It's very, very unrealistic to expect any secure stack implementation (say, Visa or MasterCard authorization software) to provide such feature for anyone.
So - we'll try to enlarge FIFO. For the moment - playing with interrupts affinity seem to be a viable workaround.
Cheers!
Paweł