Performance Tweaks i.MX8MM for USB camera via PCIe

  • Hello,


    we are currently in the process of integrating a USB 3.0 camera (goal = 1920x1080@30fps) into our system, which is powered by a PicoCoreMX8MM.

    As the i.MX8MM does not have native USB 3.0, we use the uDP720202 PCIe to USB 3.0 chip. So far so good, USB 3.0 works with all the right drivers.


    Unfortunately we don't reach 30fps. Everything above 20fps starts to stutter heavily.
    And for some reason only the first stream works, every subsequent stream fails and I see error messages like:

    • "uvcvideo 2-1:1.1: Failed to resubmit video URB (-1)."
    • "uvcvideo 3-2:1.1: Non-zero status (-71) in video completion handler."

    At first I thought that 30fps is just too much data to handle, but in the process of testing/debuging I stumbled upon usbmon.

    Strangely enough while usbmon is actively running in the background, I am able to get a stable 30fps from the camera.

    So I have one session (SSH) dumping the usbmon output and one session (Serial) which starts the GStreamer pipeline to show the camera video on a screen.

    It seems that having usbmon running, the USB performance increases.


    Unfortunately I am not able to replicate that performance without usbmon.

    What I tried so far:

    • Set CPU frequency scaling to performance:
      echo performance > /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
    • Map the IRQs to a isolated core. Unfortunately because the USB 3.0 is connected via PCIe, Message Signaled Interrupts (MSI) are used,
      for which I cannot change the smp_affinity in /proc/irq/<N>/smp_affinity (see NXP-Forum).
      But I see from the output of /proc/interrupts, that CPU0 is handling all the MSIs. And there are a lot of them...


    Is there anything else I can try to improve the USB/PCIe performance?

    Would it be possible to isolate one core to only handle USB/PCIe?


    Thank you and best regards,

    Stefan

  • This is strange. Did you try to have some other process in the background instead of usbmon? For example


    Code
    1. dd if=/dev/zero of=/dev/null &

    If this also works for higher frame rates, it would indicate that there is still something wrong with the frequency scaling. Maybe if all cores have nothing to do and go to idle. Then such a second process would block this, keeping the cores active.


    On the other hand, if such a second process does not have the same effect as usbmon, then we should look more in the direction of USB behaviour and timing.


    Your F&S Support Team

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Hello,


    The uvc driver seems to provide some module parameters.

    https://github.com/torvalds/li…sb/uvc/uvc_driver.c#L2624

    Did you try to set some of them? Maybe the UVC_QUIRK_FIX_BANDWIDTH?

    Code
    1. modprobe uvcvideo quirks=0x80


    I found some commands online to increase the debug output of uvcvideo. Did you try already try to apply them?

    Code
    1. echo 0xffff > /sys/module/uvcvideo/parameters/trace
    2. echo 0 > /sys/module/uvcvideo/parameters/trace



    Your F&S Support Team

  • Hello again,


    it actually seems like an issue with the cpu cores frequency scaling.

    Code
    1. dd if=/dev/zero of=/dev/null &

    has the same effect as usbmon...


    As stated in the original post, setting the scaling_governor to "performance" for every core, does not change anything.


    Do you have any other suggestions to keep the cores active?


    Thank you and best regards,

    Stefan

  • Hello,


    maybe the time between the frames is to long, so the CPU goes into idle mode and maybe it takes to long to recover from idle mode to render the next frame.

    USB and dd may keep the CPU to go into idle mode.


    Could you try to disable the CPU idle mode entirely, and see if it has influence on the performance?


    Go to U-Boot and set the following environment variable and boot:

    Code
    1. setenv extra cpuidle.off=1
    2. boot



    In Linux you could also try to disable the memory bus frequency scaler. Maybe this has also an effect on the performance.

    Code
    1. echo 0 > /sys/bus/platform/drivers/imx_busfreq/busfreq/enable


    Your F&S Support Team

  • Disabling the memory bus frequency scaler did not change anything...


    But passing cpuidle.off=1 to Linux from U-Boot works!

    I am also able to dynamically enable/disable idle states for each CPU core via sysfs /sys/devices/system/cpu/cpu*/cpuidle/state*/disable.

    I think that this should work now, so I can disable the idle states before I start the camera and enable them afterwards.


    Another question regarding IMX GStreamer plugins:

    There are two imx plugins which kind of handle the same things:

    Do you guys have any experience with them or prefer one over the other?


    Stefan

  • Hello,


    the main difference is, that imx-gst1.0-plugin is supported by NXP while gstreamer1.0-plugins-imx is supported by the community. The imx-gst1.0-plugin allocates more buffers in CMA insde the kernel, while gstreamer1.0-plugins-imx does this in a more generic way in user land.

    imx-gst1.0-plugin will only work with NXP specific vendor kernels, while gstreamer1.0-plugins-imx may also work with mainline kernel based releases.


    However, gstreamer1.0-plugins-imx does not work with all newer SoCs yet, as you can see here:

    https://github.com/Freescale/m…include/imx-base.inc#L513

    Support for other boards may be added in the future, i.MX8MM is already supported though,


    We are currently working on basing our releases on the meta-freescale layer, as it tends to be more stable in long time support than the meta-imx layer.

    Also, we are working on supporting the mainline kernel with a few patches on our older boards, including i.MX8MM, so if this is interesting for you, you could test the gstreamer1.0-plugins-imx with your application. However, it is not guaranteed, that it will work out of the box, but we can support you with integrating it.


    Your F&S Support Team