[SRU] irqbalance stops balancing Mellanox VF IRQs due to unsigned integer overflow

Bug #2038573 reported by Mauricio Faria de Oliveira
10
This bug affects 1 person
Affects Status Importance Assigned to Milestone
irqbalance (Ubuntu)
Fix Released
Undecided
Unassigned
Jammy
Fix Released
High
Mauricio Faria de Oliveira

Bug Description

[Impact]

 * irqbalance in Jammy might stop rebalancing IRQs
   due to an unsigned integer overflow bug.

 * This impacts the key functionality of irqbalance,
   and impacts high-performance networking traffic
   (eg, network IRQs remain unbalanced in same CPUs).

 * Only Jammy is impacted:
   - Kinetic and later have the fix.
   - Focal and earlier do not have the bug.

 * There are no fix-up commits upstream (the fix is
   the last commit in the file since August, 2021).

 * The fix just uses an equivalent comparison:
   - Before: A - B < C (ie, overflows if A < B)
   - After: A < C + B

[Test Case]

 * Scenario described by the original reporter:

   - VM with 4 vCPUs and VF from Mellanox NIC.
     (comment #6)
     It reproduces with virtio-net multiqueue too.
     (comment #7)

   - Detach the VF (some maintenance, for example)
   - Attach the VF back.
   - VF IRQs are mapped to 4 vCPUs during attach.
   - VF IRQs are mapped to 1 vCPU by irqbalance.
   - VF network receive (RX) traffic is increased.

   Now:

   - Without the fix: that 1 vCPU keeps at high
     CPU utilization in ksoftirqd (network RX),
     and the VF IRQs are not rebalanced to vCPUs.

     The total network RX speed is reduced
     (limited to the performance of 1 vCPU).

   - With the fix: the VF IRQs are rebalanced to
     other vCPUs eventually, and CPU util is not
     too high on any vCPUs.

     The total network RX speed is not reduced
     (limited to other factors, but not 1 vCPU).

 * The original reporter verified a test package
   in ppa:mfo/sf00370397, and confirmed it works
   as expected.

[Regression Potential]

 * Theoretically, the updated condition might hit
   other issues, but it should not regress existing
   cases since it's mathematically equivalent to the
   original condition.

 * If an issue were to occur, it might prevent again
   irqbalance from balancing IRQs, as this if-block
   has `else return;` before calling `migrate_irq()`
   (which is the issue hit by this bug, actually).

 * Fortunately, not only the condition is equivalent,
   but this change has been in place upstream since
   Aug 2021, and in Ubuntu since Kinetic, and has not
   received additional fix-ups or reverts in either.

[Other Info]

 * More details about the fix and scope in comment #1.

Revision history for this message
Mauricio Faria de Oliveira (mfo) wrote :

The fix commit, dated Aug 2021:

 $ git show --no-patch 2a66a666d3e20
 commit 2a66a666d3e202dec5b1a4309447e32d5f292871
 Author: liuchao173 <email address hidden>
 Date: Tue Aug 24 20:50:18 2021 +0800

     fix unsigned integer subtraction sign overflow

     Min_load, adjustment_load and load are unsigned integers, so it overflows when (lb_info->min_load + info->load) < (lb_info->adjustment_load - info->load). The result will be greater than zero. Therefore the irq cannot be selected to rebalanced.

- No fixups upstream; it's the last commit in the file (since Aug 2021):

 $ git log --oneline -1 origin/master -- irqlist.c
 2a66a666d3e2 fix unsigned integer subtraction sign overflow

Only needed in Ubuntu Jammy (v1.8.0-based):

- Introduced upstream for v1.9.0:

 $ git describe --contains 2a66a666d3e20
 v1.9.0~7^2

- Present in Ubuntu Lunar (1.9.2) and later:

 $ rmadison -a source irqbalance
  irqbalance | 1.0.6-2 | trusty | source
  irqbalance | 1.0.6-2ubuntu0.14.04.4 | trusty-updates | source
  irqbalance | 1.1.0-2ubuntu1 | xenial | source
  irqbalance | 1.3.0-0.1 | bionic | source
  irqbalance | 1.3.0-0.1ubuntu0.18.04.1 | bionic-updates | source
  irqbalance | 1.6.0-3ubuntu1 | focal | source
  irqbalance | 1.8.0-1build1 | jammy | source
  irqbalance | 1.9.2-1 | lunar | source
  irqbalance | 1.9.2-1 | mantic | source

- First introduced in Ubuntu Kinetic (1.9.0-1), so it's been tested since.
 https://launchpad.net/ubuntu/+source/irqbalance/1.9.0-1

- Focal (v1.6.0-based) and earlier do not it, because it fixes commit
e9e28114036a ("improve irq migrate rule to avoid high irq load") that
was introduced upstream for v1.7.0.

The code change is relatively simple math, for an equivalent comparison:

- if ((lb_info->min_load + info->load) - (lb_info->adjustment_load - info->load) < delta_load) {
+ if ((lb_info->min_load + info->load) < delta_load + (lb_info->adjustment_load - info->load)) {

i.e.,

- if ((A) - (B) < C) {
+ if ((A) < C + (B)) {

And, indeed, for unsigned integer math, if "A is less than B", then "A - B" (above) is not negative (as it's unsigned), but actually overflows to a very large positive integer, which does not meet the condition "< delta_load".

description: updated
Changed in irqbalance (Ubuntu):
status: New → Invalid
Changed in irqbalance (Ubuntu Jammy):
status: New → Triaged
importance: Undecided → Medium
importance: Medium → High
assignee: nobody → Mauricio Faria de Oliveira (mfo)
Revision history for this message
Mauricio Faria de Oliveira (mfo) wrote :
Revision history for this message
Mauricio Faria de Oliveira (mfo) wrote :

(Re)built successfully in ppa:mfo/lp2038573 in all supported architectures (riscv64 not available).
Uploaded to jammy.

Revision history for this message
Timo Aaltonen (tjaalton) wrote :

best to mark this being fixed in the devel series

Changed in irqbalance (Ubuntu):
status: Invalid → Fix Released
Changed in irqbalance (Ubuntu Jammy):
status: Triaged → Fix Committed
tags: added: verification-needed verification-needed-jammy
Revision history for this message
Timo Aaltonen (tjaalton) wrote : Please test proposed package

Hello Mauricio, or anyone else affected,

Accepted irqbalance into jammy-proposed. The package will build now and be available at https://launchpad.net/ubuntu/+source/irqbalance/1.8.0-1ubuntu0.1 in a few hours, and then in the -proposed repository.

Please help us by testing this new package. See https://wiki.ubuntu.com/Testing/EnableProposed for documentation on how to enable and use -proposed. Your feedback will aid us getting this update out to other Ubuntu users.

If this package fixes the bug for you, please add a comment to this bug, mentioning the version of the package you tested, what testing has been performed on the package and change the tag from verification-needed-jammy to verification-done-jammy. If it does not fix the bug for you, please add a comment stating that, and change the tag to verification-failed-jammy. In either case, without details of your testing we will not be able to proceed.

Further information regarding the verification process can be found at https://wiki.ubuntu.com/QATeam/PerformingSRUVerification . Thank you in advance for helping!

N.B. The updated package will be released to -updates after the bug(s) fixed by this package have been verified and the package has been in -proposed for a minimum of 7 days.

Revision history for this message
Mauricio Faria de Oliveira (mfo) wrote :
Download full text (9.1 KiB)

Verification done on jammy-proposed.

Environment:
---

There are 4x completion IRQs (network receive traffic / RX) plus 1x IRQ, for the Mellanox network VF.

  24: ... mlx5_comp0@pci:0b9d:00:02.0
  25: ... mlx5_comp1@pci:0b9d:00:02.0
  26: ... mlx5_comp2@pci:0b9d:00:02.0
  27: ... mlx5_comp3@pci:0b9d:00:02.0
  28: ... mlx5_async4@pci:0b9d:00:02.0

irqbalance is configured with `--debug` in /etc/default/irqbalance, and restarted.

 $ journalctl -b -u irqbalance.service
 ...
 Oct 06 16:48:40 jammy irqbalance[1388]: Adding IRQ 25 to database
 Oct 06 16:48:40 jammy irqbalance[1388]: Adding IRQ 28 to database
 Oct 06 16:48:40 jammy irqbalance[1388]: Adding IRQ 26 to database
 Oct 06 16:48:40 jammy irqbalance[1388]: Adding IRQ 24 to database
 Oct 06 16:48:40 jammy irqbalance[1388]: Adding IRQ 27 to database
 ...

With package from jammy-release:
----

The interrupts are initially balanced:

 Oct 06 16:48:40 jammy irqbalance[1388]: CPU number 3 numa_node is 0 (load 0)
 Oct 06 16:48:40 jammy irqbalance[1388]: Interrupt 27 node_num is 0 (ethernet/0:39)
 Oct 06 16:48:40 jammy irqbalance[1388]: Interrupt 25 node_num is 0 (ethernet/0:3)
 Oct 06 16:48:40 jammy irqbalance[1388]: CPU number 2 numa_node is 0 (load 0)
 Oct 06 16:48:40 jammy irqbalance[1388]: Interrupt 26 node_num is 0 (ethernet/0:22)
 ...
 Oct 06 16:48:40 jammy irqbalance[1388]: CPU number 1 numa_node is 0 (load 0)
 Oct 06 16:48:40 jammy irqbalance[1388]: Interrupt 24 node_num is 0 (ethernet/0:13)
 Oct 06 16:48:40 jammy irqbalance[1388]: CPU number 0 numa_node is 0 (load 0)
 Oct 06 16:48:40 jammy irqbalance[1388]: Interrupt 28 node_num is 0 (ethernet/0:1)

Then VF is removed/re-added due to module remove/add of `mlx5_ib mlx5_core` modules.

 Oct 06 16:51:40 jammy irqbalance[1388]: IRQ 25 is removed from interrupts_db.
 Oct 06 16:51:40 jammy irqbalance[1388]: IRQ 28 is removed from interrupts_db.
 Oct 06 16:51:40 jammy irqbalance[1388]: IRQ 26 is removed from interrupts_db.
 Oct 06 16:51:40 jammy irqbalance[1388]: IRQ 24 is removed from interrupts_db.
 Oct 06 16:51:40 jammy irqbalance[1388]: IRQ 27 is removed from interrupts_db.
 ...
 Oct 06 16:52:20 jammy irqbalance[1388]: Adding IRQ 24 to database
 Oct 06 16:52:20 jammy irqbalance[1388]: Hotplug dev irq: 24 finished.
 Oct 06 16:52:20 jammy irqbalance[1388]: Adding IRQ 25 to database
 Oct 06 16:52:20 jammy irqbalance[1388]: Hotplug dev irq: 25 finished.
 Oct 06 16:52:20 jammy irqbalance[1388]: Adding IRQ 26 to database
 Oct 06 16:52:20 jammy irqbalance[1388]: Hotplug dev irq: 26 finished.
 Oct 06 16:52:20 jammy irqbalance[1388]: Adding IRQ 27 to database
 Oct 06 16:52:20 jammy irqbalance[1388]: Hotplug dev irq: 27 finished.
 Oct 06 16:52:20 jammy irqbalance[1388]: Adding IRQ 28 to database
 Oct 06 16:52:20 jammy irqbalance[1388]: Hotplug dev irq: 28 finished.

Then all get into CPU2:

 Oct 06 16:52:20 jammy irqbalance[1388]: CPU number 2 numa_node is 0 (load 3900000000)
 Oct 06 16:52:20 jammy irqbalance[1388]: Interrupt 28 node_num is 0 (ethernet/0:341...

Read more...

tags: added: verification-done verification-done-jammy
removed: verification-needed verification-needed-jammy
Revision history for this message
Mauricio Faria de Oliveira (mfo) wrote :
Download full text (18.6 KiB)

Verified with jammy-proposed with a
local VM with virtio-net multiqueue.

Host: lunar, 4 pCPUs
Guest: jammy, 4 vCPUs (1 socket/die, 2 cores, 2 threads/core) with 1 virtio-net interface with 4 queues

Setup:
---

 $ uvt-simplestreams-libvirt sync release=jammy arch=amd64
 $ uvt-kvm create --no-start irqjammy release=jammy

 $ virsh edit irqjamy
 ...
   <vcpu placement='static'>4</vcpu>
 ...
   <cpu ...>
     <topology sockets='1' dies='1' cores='2' threads='2'/>
   </cpu>
 ...
     <interface type='network'>
 ...
       <model type='virtio'/>
       <driver queues='4'/>
 ...

Start VM:

 $ virsh start irqjammy
 $ uvt-kvm wait irqjammy
 $ uvt-kvm ssh irqjammy

Configure irqbalance:

 $ echo "IRQBALANCE_ARGS='--debug --interval 5'" | sudo tee -a /etc/default/irqbalance
 $ sudo systemctl restart irqbalance.service
 $ systemctl status irqbalance.service | grep debug
       └─1561 /usr/sbin/irqbalance --foreground --debug --interval 5

Test with jammy-release:
---

Run in tmux (keep running across connection drops)

 $ tmux

Start iperf server in the VM

 $ sudo apt update && sudo apt install -y iperf

 $ iperf -s >/dev/null &

(*) Start iperf client in the HOST

 $ iperf -c $(uvt-kvm ip irqjammy) -t 0 -P4 -i 5 | grep SUM
 ...
 <let it run for a few 5-second intervals/reports and...>

Remove/add virtio-net modules:

 $ date; sudo modprobe -r virtio-net && sleep 5 && sudo modprobe virtio-net; date
 Sat Oct 7 06:40:39 PM UTC 2023
 Sat Oct 7 06:40:45 PM UTC 2023

Notice the connection drop in the client.
Let the client run for another minute and stop it.

 $ iperf -c $(uvt-kvm ip irqjammy) -t 0 -P4 -i 5 | grep SUM
 WARNING: client will send traffic forever or until an external signal (e.g. SIGINT or SIGTERM) occurs to stop it
 [SUM] 0.0000-5.0000 sec 8.27 GBytes 14.2 Gbits/sec
 [SUM] 5.0000-10.0000 sec 8.78 GBytes 15.1 Gbits/sec
 [SUM] 10.0000-15.0000 sec 9.19 GBytes 15.8 Gbits/sec
 [SUM] 15.0000-20.0000 sec 9.13 GBytes 15.7 Gbits/sec
 [SUM] 20.0000-25.0000 sec 8.05 GBytes 13.8 Gbits/sec
 [SUM] 25.0000-30.0000 sec 8.60 GBytes 14.8 Gbits/sec
 [SUM] 30.0000-35.0000 sec 1.53 GBytes 2.64 Gbits/sec <<< DROP
 [SUM] 35.0000-40.0000 sec 4.79 GBytes 8.23 Gbits/sec <<< DROP
 [SUM] 40.0000-45.0000 sec 9.00 GBytes 15.5 Gbits/sec
 [SUM] 45.0000-50.0000 sec 7.93 GBytes 13.6 Gbits/sec
 [SUM] 50.0000-55.0000 sec 9.15 GBytes 15.7 Gbits/sec
 [SUM] 55.0000-60.0000 sec 9.00 GBytes 15.5 Gbits/sec
 [SUM] 60.0000-65.0000 sec 9.05 GBytes 15.5 Gbits/sec
 [SUM] 65.0000-70.0000 sec 8.89 GBytes 15.3 Gbits/sec
 [SUM] 70.0000-75.0000 sec 9.30 GBytes 16.0 Gbits/sec
 [SUM] 75.0000-80.0000 sec 9.14 GBytes 15.7 Gbits/sec
 [SUM] 80.0000-85.0000 sec 9.17 GBytes 15.8 Gbits/sec
 [SUM] 85.0000-90.0000 sec 8.48 GBytes 14.6 Gbits/sec
 [SUM] 90.0000-95.0000 sec 9.11 GBytes 15.6 Gbits/sec
 [SUM] 95.0000-100.0000 sec 9.12 GBytes 15.7 Gbits/sec
 [SUM] 100.0000-105.0000 sec 8.34 GBytes 14.3 Gbits/sec
^C

Check the irqbalance logs for the network receive queues IRQs:

 $ grep virtio.-input /proc/interrupts
  50: 3401 39990 0 0 PCI-MSI 524289-edge virtio0-input.0
  52: 0 142952 0 1 PCI-M...

description: updated
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package irqbalance - 1.8.0-1ubuntu0.1

---------------
irqbalance (1.8.0-1ubuntu0.1) jammy; urgency=medium

  * d/p/lp2038573-fix-unsigned-integer-subtraction-sign-overflow.patch:
    Do not stop balancing IRQs due to unsigned int issue. (LP: #2038573)

 -- Mauricio Faria de Oliveira <email address hidden> Wed, 04 Oct 2023 12:54:18 -0300

Changed in irqbalance (Ubuntu Jammy):
status: Fix Committed → Fix Released
Revision history for this message
Brian Murray (brian-murray) wrote : Update Released

The verification of the Stable Release Update for irqbalance has completed successfully and the package is now being released to -updates. Subsequently, the Ubuntu Stable Release Updates Team is being unsubscribed and will not receive messages about this bug report. In the event that you encounter a regression using the package from -updates please report a new bug using ubuntu-bug and tag the bug report regression-update so we can easily find any regressions.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.