Comment 1 for bug 2038573

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".