On Wed, Jul 15, 2026 at 02:31:17AM +0200, Ilya Maximets wrote:
> On 6/8/26 10:54 AM, Adrian Moreno via dev wrote:
> > This series refactors netdev-linux to make more use use of event-driven
> > netlink notifications instead of polling for device state update, 
> > significantly
> > improving performance under RTNL lock contention.
> >
> > ## Background
> >
> > The RTNL mutex is used to serialize rtnetlink requests in the Linux kernel.
> > It's widespread use in many network configuration paths make it a problem 
> > which
> > the kernel community is well aware of.
> >
> > When there is a lot of network configuration activity, like when lots of
> > interfaces are being created or deleted, specially interfaces that interact
> > with HW resources such as SR-IOV VFs, contention on the RTNL mutex can make
> > rtnetlink requests be quite slow.
> >
> > The impact of RTNL contention on OVS's main thread can be high, making the
> > entire loop take several seconds (even minutes!) to complete, affecting 
> > other
> > periodic tasks such as OVSDB updates, OpenFlow flow programming, etc.
> >
> > After analyzing what requests were being sent by OVS, it was observed that 
> > most
> > of them came from netdev-linux state checking mechanisms. While some state 
> > is
> > cached (such as the MTU or MAC address), the netdev's flags are not, and 
> > they
> > are checked very often.
> >
> > On the other hand, Netlink provides a reliable notification mechanism via
> > multicast groups that allows userspace to receive asynchronouse updates when
> > device state changes, and OVS already has some infrastructure for that
> > purpose.
> >
> > ## Approach
> >
> > The series aims to change two aspects of netdev-linux operations:
> > A - Cache the netdev's flags
> > B - Reuse existing rtnetlink event infrastructure in netdev-linux's main
> > loop run to avoid races.
> >
> > In order to accomplish A (commit 2) some refactoring is done first (commit 
> > 1).
> > In roder to accomplish B (commit 5) some refactoring is done to enhance 
> > existing
> > rtnetlink notifier infrastructure (commits 3-4).
> >
> > Finally, there are some extra consolidation and cleanups (commits 6-8).
> >
> > The following diagram represents the resulting infrastructure:
> >
> >             +---------------------------------+
> >             | bridge.c                        |
> >             |                                 |
> >             |   to call bridge_reconfigure()  |
> >             |     if ifaces changed           |
> >             +--------------------+------------+
> >                                  |
> >                            +-----v-------+
> >                            | if-notifier |
> >                            +-----+-------+
> >                                  |
> >          +-----------------------+
> >          | 
> > +------------------------------------------------------------------------------+
> >    +-----+ | route_table                                                    
> >               |
> >    |       |                                
> > +-------------------------------------------+ |
> >    |       |  +---------------------------+ | for route change detection    
> >             | |
> >    |       |  |                           | |                               
> >             | |
> >    |    +--+--+  for link change detection| |      family: NETLINK_ROUTE    
> >             +-+--+
> >    |    |  |  |                           | |      mcast: 
> > RTNLGRP_IPV{4,6}_{ROUTE,RULE} | |  |
> >    |    |  |  +---------------------------+ |      all_ns:  false           
> >             | |  |
> >    |    |  |                                
> > +-------------------------------------------+ |  |
> >    |    |  
> > +------------------------------------------------------------------------------+
> >   |
> >    |    |                                                                   
> >                  |
> >    |    |    
> > +----------------------------------------------------------------------------+
> >   |
> >    |    |    | netdev_linux                                                 
> >               |  |
> >    |    |    |                                
> > +----------------------------------------+  |  |
> >    |    |    | +-----------------------------+|for address change detection 
> >            |  |  |
> >    |    |    | |   to update netdev          ||                             
> >            |  |  |
> >    |    | +--+-+   internal (cached) state   ||   family: NETLINK_ROUTE     
> >            |  |  |
> >    |    | |  | +-----------------------------+|   mcast: 
> > RTNLGRP_IPV4_IFADDR,          |  |  |
> >    |    | |  |                                |          
> > RTNLGRP_IPV6_{IFADDR,IFINFO}  |  |  |
> >    |    | |  |                                |   all_ns: true              
> >            |  |  |
> >    |    | |  |                                
> > +-----------+----------------------------+  |  |
> >    |    | |  
> > +--------------------------------------------+-------------------------------+
> >   |
> >    |    | |                                               |                 
> >                  |
> >  +-v----v-v-------------------+                           |                 
> >                  |
> >  | rtnetlink_notifier.{c,h}   |                           |                 
> >                  |
> >  |                            |                           |                 
> >                  |
> >  |    family: NETLINK_ROUTE   |                           |                 
> >                  |
> >  |    mcast: RTNLGRP_LINK     |                           |                 
> >                  |
> >  |    all_ns: true            |                           |                 
> >                  |
> >  +----------------------------+                           |                 
> >                  |
> >                |                                          |                 
> >                  |
> >                |                                          |                 
> >                  |
> >         
> > +------v------------------------------------------v----------------------------------v--+
> >         |                                                                   
> >                     |
> >         |                            nln     (netlink_notifier.{h,c})       
> >                     |
> >         |                                                                   
> >                     |
> >         
> > +---------------------------------------------------------------------------------------+
> >
> >
> > ## Testing and results
> >
> > In order to test this series, I have written a small script that chruns
> > (deletes and recreates) some ovs ports (veths) in a way an SDN would do.
> > I increased the number of interfaces to churn from 10 to 100
> >
> > In order to simulate RTNL mutex contention I used delay-kfunc [1] to
> > introduce latency to 'rtnl_lock'. The following table shows the time it
> > takes to complete the test:
> >
> > ==============================================================================
> > N ifaces   RTNL Delay(μs)  Main (s)             Series (s)          Delta 
> > (%)
> > ------------------------------------------------------------------------------
> > 10         0               0.275(0.008)         0.234(0.014)        -14.9%
> > 10         50              0.269(0.009)         0.249(0.012)        -7.3%
> > 10         100             0.278(0.011)         0.266(0.007)        -4.6%
> > 10         500             0.423(0.039)         0.395(0.046)        -6.7%
> > 10         1000            0.695(0.060)         0.586(0.045)        -15.6%
> > 10         5000            1.855(0.099)         1.818(0.041)        -2.0%
> > 10         10000           4.361(0.074)         3.106(0.111)        -28.8%
> > 20         0               0.485(0.014)         0.424(0.019)        -12.6%
> > 20         50              0.478(0.018)         0.472(0.015)        -1.3%
> > 20         100             0.504(0.018)         0.493(0.020)        -2.3%
> > 20         500             0.716(0.022)         0.678(0.031)        -5.3%
> > 20         1000            0.994(0.026)         0.926(0.083)        -6.9%
> > 20         5000            3.313(0.133)         2.851(0.039)        -13.9%
> > 20         10000           6.803(0.093)         4.875(0.117)        -28.3%
> > 30         0               0.716(0.024)         0.645(0.033)        -10.0%
> > 30         50              0.723(0.018)         0.692(0.019)        -4.2%
> > 30         100             0.744(0.024)         0.745(0.031)        +0.1%
> > 30         500             0.981(0.031)         0.997(0.034)        +1.6%
> > 30         1000            1.328(0.046)         1.222(0.040)        -8.0%
> > 30         5000            4.838(0.059)         3.865(0.079)        -20.1%
> > 30         10000           9.146(0.110)         6.653(0.110)        -27.3%
> > 40         0               0.974(0.042)         0.864(0.065)        -11.3%
> > 40         50              0.963(0.032)         0.961(0.044)        -0.2%
> > 40         100             0.997(0.040)         1.004(0.043)        +0.7%
> > 40         500             1.397(0.105)         1.359(0.035)        -2.7%
> > 40         1000            1.990(0.107)         1.805(0.096)        -9.3%
> > 40         5000            7.240(1.751)         4.967(0.587)        -31.4%
> > 40         10000           11.657(0.131)        8.289(0.308)        -28.9%
> > 50         0               1.340(0.111)         1.253(0.167)        -6.5%
> > 50         50              1.410(0.196)         1.274(0.059)        -9.7%
> > 50         100             1.411(0.108)         1.329(0.111)        -5.8%
> > 50         500             1.788(0.060)         1.779(0.079)        -0.5%
> > 50         1000            2.656(0.220)         2.446(0.097)        -7.9%
> > 50         5000            11.532(0.132)        8.216(0.094)        -28.8%
> > 50         10000           22.685(1.157)        14.098(0.186)       -37.8%
> > 60         0               1.760(0.249)         1.738(0.333)        -1.3%
> > 60         50              1.945(0.283)         1.851(0.305)        -4.8%
> > 60         100             1.777(0.340)         1.613(0.116)        -9.2%
> > 60         500             2.525(0.184)         2.330(0.125)        -7.7%
> > 60         1000            3.497(0.327)         3.247(0.174)        -7.2%
> > 60         5000            14.390(0.172)        10.093(0.138)       -29.9%
> > 60         10000           27.980(0.545)        17.383(0.211)       -37.9%
> > 80         0               3.977(0.767)         3.632(0.651)        -8.7%
> > 80         50              3.550(0.667)         3.294(0.645)        -7.2%
> > 80         100             3.854(0.679)         3.182(0.763)        -17.4%
> > 80         500             4.571(0.685)         3.998(0.619)        -12.5%
> > 80         1000            6.445(0.490)         4.955(0.281)        -23.1%
> > 80         5000            27.107(0.331)        17.348(0.197)       -36.0%
> > 80         10000           54.738(0.971)        31.525(1.116)       -42.4%
> > 100        0               8.509(2.392)         7.452(0.138)        -12.4%
> > 100        50              7.730(0.552)         7.278(1.877)        -5.8%
> > 100        100             8.084(2.648)         7.342(1.124)        -9.2%
> > 100        500             7.543(0.551)         6.851(0.997)        -9.2%
> > 100        1000            10.784(0.782)        7.990(0.651)        -25.9%
> > 100        5000            36.393(0.626)        25.800(0.363)       -29.1%
> > 100        10000           72.916(2.488)        45.648(1.929)       -37.4%
> > ==============================================================================
> >
> > Notes about the above results:
> > - Values are shown as "{mean}({std})".
> > - I did not perform any kind of tuning or cpu isolation the test server.
> > - delay-kfunc does not always introduce the exact same delay so there is 
> > some
> > source of variance there as well.
> > - Beyond 200 interfaces, limitations of the test script itself make the 
> > results
> > rather unreliable.
> >
> > All in all, a pretty consistent improvement is observed which increases 
> > with the
> > number of interfaces that we churn and with the amount of external RTNL
> > pressure we add.
> >
> > ## Future work
> >
> > This is part of a larger effort to improve robustness against RTNL 
> > contention.
> > I plan to work on more optimizations in future series.
> >
> >
> > [1] https://github.com/xdp-project/bpf-examples/tree/main/delay-kfunc
> >
> > --
> > v2->v3
> > - ensure carrier_resets counter are preserved by refactoring also flag
> >   setting and state changing routines (Mike)
> > - rename update_flags_local to netdev_linux_update_via_ioctl (Mike)
> > - keep order of miimon and rtnl monitoring
> >
> > Adrian Moreno (8):
> >   netdev_linux: Refactor netdev flag update.
> >   netdev-linux: Cache netdev flags.
> >   netlink-notifier: Drain socket on overflow.
> >   netlink-notifier: Include nsid in callbacks.
> >   netdev-linux: Use rtnetlink to update state.
> >   netdev-linux: Consolidate RTM_GETLINK parsing.
> >   linux-netdev: Check status when reading stats.
> >   netdev-linux: Consolidate netlink updates.
> >
> >  lib/if-notifier.c              |   3 +-
> >  lib/netdev-afxdp.c             |   2 +-
> >  lib/netdev-linux-private.h     |   5 +-
> >  lib/netdev-linux.c             | 452 ++++++++++++++++-----------------
> >  lib/netdev-linux.h             |   1 +
> >  lib/netlink-notifier.c         |  15 +-
> >  lib/netlink-notifier.h         |   9 +-
> >  lib/netnsid.h                  |   1 +
> >  lib/route-table.c              |  12 +-
> >  lib/route-table.h              |   2 +-
> >  lib/rtnetlink.c                |  40 ++-
> >  lib/rtnetlink.h                |  56 +++-
> >  lib/tnl-ports.c                |   2 +-
> >  tests/system-interface.at      |   2 +
> >  tests/system-tap.at            |   5 +-
> >  tests/system-traffic.at        |   3 +-
> >  tests/test-lib-route-table.c   |   9 +-
> >  tests/test-netlink-conntrack.c |   9 +-
> >  18 files changed, 362 insertions(+), 266 deletions(-)
> >
>
>
> Hi, Adrian.  Thanks for working on this and sorry for dealys.
>
> I marked the set as changes-requested for now.  I replied to a couple
> of patches with issues that should be addressed before we can accept
> this set.  I also see that Mike posted some comments to other patches
> as well.
>
> Process-wise, we don't have a lot of time before branching and I'm not
> sure how much time you're willing to spend on this set, but in case
> you have time to try and address the comments and post the updated
> version before Thursday morning, we can try to get it in, I think,
> assuming nothing major comes up in the process.
>

Unfortunately, I don't think I'll have time to respin this series before
Thursday morning.

--
Adrián

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to