{"id":329302,"date":"2023-07-24T07:00:00","date_gmt":"2023-07-24T07:00:00","guid":{"rendered":"http:\/\/itteacheritfreelance.hk\/wordpress\/?guid=8ddc98fba6949fe9324f4a4b85a576d6"},"modified":"2023-07-24T07:00:00","modified_gmt":"2023-07-24T07:00:00","slug":"troubleshooting-open-vswitch-is-the-kernel-to-blame","status":"publish","type":"post","link":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/2023\/07\/24\/troubleshooting-open-vswitch-is-the-kernel-to-blame\/","title":{"rendered":"Troubleshooting Open vSwitch: Is the kernel to blame?"},"content":{"rendered":"<p class=\"syndicated-attribution\"><meta name= \\\"keywords \\\" content= \\\"\u96fb\u5b50\u8a08\u7b97\u6a5f, \u6559\u80b2, IT \u96fb\u8166\u73ed,\u96fb\u8166\u88dc\u7fd2\uff0c \u96fb\u8166\u73ed\uff0c \u5bb6\u6559\uff0c \u79c1\u4eba\u8001\u5e2b\uff0c \u8cc7\u8a0a\u6280\u8853\uff0c \u7a0b\u5e8f\u8a2d\u8a08\uff0c \u96fb\u5b50\u8a08\u7b97\u6a5f\uff0c \u904a\u6232\uff0c \u860b\u679c\uff0c \u96fb\u5f71\uff0c \u8a08\u7b97\u6a5f\uff0c\u7de8\u78bc\uff0c Java\uff0c C\/C++\uff0c JavaScript\uff0c PHP\uff0c HTML\uff0c CSS\uff0c MySQL\uff0c mobile\uff0c Android\uff0c \u52d5\u6f2b\uff0c Python\uff0c teacher\uff0c \u88dc\u7fd2\uff0c \u96fb\u8166\u88dc\u7fd2 \u8cc7\u8a0a, \u7535\u5b50\u8ba1\u7b97\u673a, IT ,Game, apple, movie, Computer,student,Java,\u6559\u80b2, ,\u5b66\u751f, \u5b66\u4e60, learn, \u6559\u5b66,  Android, apple,anime, animation, \u4fe1\u606f\u6280\u672f, \u7a0b\u5e8f\u8bbe\u8ba1, \u79fb\u52a8\u7535\u8bdd, \u8cc7\u8a0a\u79d1\u6280,Game, Jeu, Juego,Call Of Duty ,\u4f7f\u547d\u53ec\u559a , \u6e38\u620f, \u7535\u5b50\u6e38\u620f,, \u591a\u4eba\u7535\u5b50\u6e38\u620f, \u7f51\u7edc\u6e38\u620f\uff0conline\uff0conline game, \u624b\u673a\u6e38\u620f, mobile \\\"><\/p>\n<p><span>Troubleshooting Open vSwitch: Is the kernel to blame?<\/span><\/p>\n<p>Often, when troubleshooting Open vSwitch (OVS) in the field, you might be left wondering if the issue is really OVS-related, or if it&#8217;s a problem with the kernel being overloaded. The <a href=\"https:\/\/github.com\/chaudron\/ovs\/blob\/dev\/kernel_delay\/utilities\/usdt-scripts\/kernel_delay.py\">kernel_delay.py<\/a> tool can help you quickly identify if the focus of your investigation should be OVS or the <a href=\"https:\/\/developers.redhat.com\/topics\/linux\/\">Linux<\/a> kernel.<\/p>\n<h2 id=\"introduction\">About\u00a0kernel_delay.py<\/h2>\n<p>kernel_delay.py\u00a0consists of a <a href=\"https:\/\/developers.redhat.com\/topics\/python\">Python<\/a> script that uses the <a href=\"https:\/\/github.com\/iovisor\/bcc\">BCC<span> <\/span>framework<\/a> to install eBPF probes. \u00a0The data the eBPF probes collect will be analyzed and presented to the user by the Python script. Some of the presented data can also be captured by the individual scripts included in the BBC\u00a0framework.<\/p>\n<p>kernel_delay.py\u00a0has two modes of operation:<\/p>\n<ul>\n<li>In<strong> time mode<\/strong>, the tool runs for a specific time and collects the information.<\/li>\n<li>In <strong>trigger mode<\/strong>, event collection can be started and\/or stopped based on a specific eBPF probe. Currently, we support the following probes:\n<ul>\n<li>USDT probes<\/li>\n<li>Kernel tracepoints<\/li>\n<li>kprobe<\/li>\n<li>kretprobe<\/li>\n<li>uprobe<\/li>\n<li>uretprobe<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>In addition, the option <code>--sample-count<\/code> exists to specify how many iterations you would like to do. When using triggers, you can also ignore samples if they are less than a number of nanoseconds with the <code>--trigger-delta<\/code> option. The latter might be useful when debugging Linux syscalls that take a long time to complete. (More on this later.) Finally, you can configure the delay between two sample runs with the <code>--sample-interval<\/code> option.<\/p>\n<p>Before getting into more details, let&#8217;s just run the tool without any options to see what the output looks like. Notice that it will try to automatically get the process ID of the running <code>ovs-vsdwitchd<\/code>. You can overwrite this with the <code>--pid<\/code> option.<\/p>\n<pre class=\"console\">\n<code>$ sudo .\/kernel_delay.py\n# Start sampling @2023-06-08T12:17:22.725127 (10:17:22 UTC)\n# Stop sampling @2023-06-08T12:17:23.224781 (10:17:23 UTC)\n# Sample dump @2023-06-08T12:17:23.224855 (10:17:23 UTC)\nTID        THREAD           <RESOURCE SPECIFIC>\n---------- ---------------- ----------------------------------------------------------------------------\n     27090 ovs-vswitchd     [SYSCALL STATISTICS]\n                <EDIT: REMOVED DATA FOR ovs-vswitchd THREAD>\n\n     31741 revalidator122   [SYSCALL STATISTICS]\n                NAME                 NUMBER       COUNT          TOTAL ns            MAX ns\n                poll                      7           5       184,193,176       184,191,520\n                recvmsg                  47         494       125,208,756           310,331\n                futex                   202           8        18,768,758         4,023,039\n                sendto                   44          10           375,861           266,867\n                sendmsg                  46           4            43,294            11,213\n                write                     1           1             5,949             5,949\n                getrusage                98           1             1,424             1,424\n                read                      0           1             1,292             1,292\n                TOTAL( - poll):                     519       144,405,334\n\n                [THREAD RUN STATISTICS]\n                SCHED_CNT           TOTAL ns            MIN ns            MAX ns\n                     6       136,764,071             1,480       115,146,424\n\n                [THREAD READY STATISTICS]\n                SCHED_CNT           TOTAL ns            MAX ns\n                     7            11,334             6,636\n\n                [HARD IRQ STATISTICS]\n                NAME                       COUNT          TOTAL ns            MAX ns\n                eno8303-rx-1                   1             3,586             3,586\n                TOTAL:                         1             3,586\n\n                [SOFT IRQ STATISTICS]\n                NAME                 VECT_NR       COUNT          TOTAL ns            MAX ns\n                net_rx                     3           1            17,699            17,699\n                sched                      7           6            13,820             3,226\n                rcu                        9          16            13,586             1,554\n                timer                      1           3            10,259             3,815\n                TOTAL:                                26            55,364<\/code><\/pre>\n<p>By default, the tool will run for half a second in <span class=\"title-ref\">time mode<\/span>. To extend this, you can use the <code>--sample-time<\/code> option.<\/p>\n<h2 id=\"what-will-it-report\">What will it report?<\/h2>\n<p>The above sample output separates the captured data on a per-thread basis. For this, it displays the thread&#8217;s id (<code>TID<\/code>) and name (<code>THREAD<\/code>), followed by resource-specific data. Which are:<\/p>\n<ul>\n<li><code>SYSCALL STATISTICS<\/code><\/li>\n<li><code>THREAD RUN STATISTICS<\/code><\/li>\n<li><code>THREAD READY STATISTICS<\/code><\/li>\n<li><code>HARD IRQ STATISTICS<\/code><\/li>\n<li><code>SOFT IRQ STATISTICS<\/code><\/li>\n<\/ul>\n<p>The following sections will describe in detail what statistics they report.<\/p>\n<h3 id=\"syscall-statistics\">SYSCALL STATISTICS<\/h3>\n<p><code>SYSCALL STATISTICS<\/code>\u00a0tell you which Linux system calls got executed during the measurement interval. This includes the number of times the syscall was called (<code>COUNT<\/code>), the total time spent in the system calls (<code>TOTAL ns<\/code>), and the worst-case duration of a single call (<code>MAX ns<\/code>).<\/p>\n<p>It also shows the total of all system calls, but it excludes the poll system call, as the purpose of this call is to wait for activity on a set of sockets, and usually, the thread gets swapped out.<\/p>\n<p>Note that it only counts calls that started and stopped during the measurement interval!<\/p>\n<h3 id=\"thread-run-statistics\">THREAD RUN STATISTICS<\/h3>\n<p><code>THREAD RUN STATISTICS<\/code>\u00a0tell you how long the thread was running on a CPU during the measurement interval.<\/p>\n<p>Note that these statistics only count events where the thread started and stopped running on a CPU during the measurement interval. For example, if this was a PMD thread, you should see zero <code>SCHED_CNT<\/code> and <code>TOTAL_ns<\/code>. If not, there might be a misconfiguration.<\/p>\n<h3 id=\"thread-ready-statistics\">THREAD READY STATISTICS<\/h3>\n<p><code>THREAD READY STATISTICS<\/code> tell you the time between the thread being ready to run and it actually running on the CPU.<\/p>\n<p>Note that these statistics only count events where the thread was getting ready to run and started running during the measurement interval.<\/p>\n<h3 id=\"hard-irq-statistics\">HARD IRQ STATISTICS<\/h3>\n<p><code>HARD IRQ STATISTICS<\/code> tell you how much time was spent servicing hard interrupts during the threads run time.<\/p>\n<p>It shows the interrupt name (<code>NAME<\/code>), the number of interrupts (<code>COUNT<\/code>), the total time spent in the interrupt handler (<code>TOTAL ns<\/code>), and the worst-case duration (<code>MAX ns<\/code>).<\/p>\n<h3 id=\"soft-irq-statistics\">SOFT IRQ STATISTICS<\/h3>\n<p><code>SOFT IRQ STATISTICS<\/code> tell you how much time was spent servicing soft interrupts during the threads run time.<\/p>\n<p>It shows the interrupt name (<code>NAME<\/code>), vector number (<code>VECT_NR<\/code>), the number of interrupts (<code>COUNT<\/code>), the total time spent in the interrupt handler (<code>TOTAL ns<\/code>), and the worst-case duration (<code>MAX ns<\/code>).<\/p>\n<h1 id=\"the---syscall-events-option\">The\u00a0&#8211;syscall-events\u00a0option<\/h1>\n<p>In addition to reporting global syscall statistics in <code>SYSCALL_STATISTICS<\/code>, the tool can also report each individual syscall. This can be a useful second step if the <code>SYSCALL_STATISTICS<\/code> show high latency numbers.<\/p>\n<p>All you need to do is add the <code>--syscall-events<\/code> option, with or without the additional <code>DURATION_NS<\/code> parameter. The <code>DUTATION_NS<\/code> parameter allows you to exclude events that take less than the supplied time.<\/p>\n<p>The <code>--skip-syscall-poll-events<\/code> option allows you to exclude poll syscalls from the report.<\/p>\n<p>Below is an example run; note that I have removed the resource-specific data to highlight the syscall events:<\/p>\n<pre class=\"console\">\n<code>$ sudo .\/kernel_delay.py  --syscall-events 50000 --skip-syscall-poll-events\n# Start sampling @2023-06-13T17:10:46.460874 (15:10:46 UTC)\n# Stop sampling @2023-06-13T17:10:46.960727 (15:10:46 UTC)\n# Sample dump @2023-06-13T17:10:46.961033 (15:10:46 UTC)\nTID        THREAD           <RESOURCE SPECIFIC>\n---------- ---------------- ----------------------------------------------------------------------------\n   3359686 ipf_clean2       [SYSCALL STATISTICS]\n   ...\n   3359635 ovs-vswitchd     [SYSCALL STATISTICS]\n   ...\n   3359697 revalidator12    [SYSCALL STATISTICS]\n   ...\n   3359698 revalidator13    [SYSCALL STATISTICS]\n   ...\n   3359699 revalidator14    [SYSCALL STATISTICS]\n   ...\n   3359700 revalidator15    [SYSCALL STATISTICS]\n   ...\n\n# SYSCALL EVENTS:\n       ENTRY (ns)           EXIT (ns)        TID COMM             DELTA (us)  SYSCALL\n  ------------------- ------------------- ---------- ---------------- ----------  ----------------\n     2161821694935486    2161821695031201    3359699 revalidator14            95  futex\n      syscall_exit_to_user_mode_prepare+0x161 [kernel]\n      syscall_exit_to_user_mode_prepare+0x161 [kernel]\n      syscall_exit_to_user_mode+0x9 [kernel]\n      do_syscall_64+0x68 [kernel]\n      entry_SYSCALL_64_after_hwframe+0x72 [kernel]\n      __GI___lll_lock_wait+0x30 [libc.so.6]\n      ovs_mutex_lock_at+0x18 [ovs-vswitchd]\n      [unknown] 0x696c003936313a63\n     2161821695276882    2161821695333687    3359698 revalidator13            56  futex\n      syscall_exit_to_user_mode_prepare+0x161 [kernel]\n      syscall_exit_to_user_mode_prepare+0x161 [kernel]\n      syscall_exit_to_user_mode+0x9 [kernel]\n      do_syscall_64+0x68 [kernel]\n      entry_SYSCALL_64_after_hwframe+0x72 [kernel]\n      __GI___lll_lock_wait+0x30 [libc.so.6]\n      ovs_mutex_lock_at+0x18 [ovs-vswitchd]\n      [unknown] 0x696c003134313a63\n     2161821695275820    2161821695405733    3359700 revalidator15           129  futex\n      syscall_exit_to_user_mode_prepare+0x161 [kernel]\n      syscall_exit_to_user_mode_prepare+0x161 [kernel]\n      syscall_exit_to_user_mode+0x9 [kernel]\n      do_syscall_64+0x68 [kernel]\n      entry_SYSCALL_64_after_hwframe+0x72 [kernel]\n      __GI___lll_lock_wait+0x30 [libc.so.6]\n      ovs_mutex_lock_at+0x18 [ovs-vswitchd]\n      [unknown] 0x696c003936313a63\n     2161821695964969    2161821696052021    3359635 ovs-vswitchd             87  accept\n      syscall_exit_to_user_mode_prepare+0x161 [kernel]\n      syscall_exit_to_user_mode_prepare+0x161 [kernel]\n      syscall_exit_to_user_mode+0x9 [kernel]\n      do_syscall_64+0x68 [kernel]\n      entry_SYSCALL_64_after_hwframe+0x72 [kernel]\n      __GI_accept+0x4d [libc.so.6]\n      pfd_accept+0x3a [ovs-vswitchd]\n      [unknown] 0x7fff19f2bd00\n      [unknown] 0xe4b8001f0f<\/code><\/pre>\n<p>As you can see above, the output also shows the stackback trace. You can disable this using the <code>--stack-trace-size 0<\/code> option.<\/p>\n<p>As you can see above, the backtrace does not show a lot of useful information due to the BCC<span> <\/span>toolkit not supporting dwarf decoding. To further analyze system call backtraces, you could use perf. The following perf script can do this for you (refer to the embedded instructions):\u00a0<a href=\"https:\/\/github.com\/chaudron\/perf_scripts\/blob\/master\/analyze_perf_pmd_syscall.py\">https:\/\/github.com\/chaudron\/perf_scripts\/blob\/master\/analyze_perf_pmd_syscall.py<\/a><\/p>\n<h2 id=\"using-triggers\">Using triggers<\/h2>\n<p>The tool supports both start and stop triggers. This will allow you to capture statistics triggered by a specific event. First, let&#8217;s look at what combinations of stop-and-start triggers we can use.<\/p>\n<p>If you only use <code>--start-trigger<\/code>, the inspection start when the trigger happens and runs until the <code>--sample-time<\/code> number of seconds has passed. The example below shows all the supported options in this scenario.<\/p>\n<pre class=\"console\">\n<code>$ sudo .\/kernel_delay.py --start-trigger up:bridge_run --sample-time 4 \\\n                         --sample-count 4 --sample-interval 1<\/code><\/pre>\n<p>If you only use <code>--stop-trigger<\/code>, the inspection starts immediately and stops when the trigger happens. The example below shows all the supported options in this scenario.<\/p>\n<pre class=\"console\">\n<code>$ sudo .\/kernel_delay.py --stop-trigger upr:bridge_run \\\n                         --sample-count 4 --sample-interval 1<\/code><\/pre>\n<p>If you use both <code>--start-trigger<\/code> and <code>--stop-trigger<\/code> triggers, the statistics are captured between the two first occurrences of these events. The example below shows all the supported options in this scenario.<\/p>\n<pre class=\"console\">\n<code>$ sudo .\/kernel_delay.py --start-trigger up:bridge_run \\\n                         --stop-trigger upr:bridge_run \\\n                         --sample-count 4 --sample-interval 1 \\\n                         --trigger-delta 50000<\/code><\/pre>\n<p>Now that we know how these triggers can be used, let&#8217;s investigate what triggers are supported. What we call triggers, BCC\u00a0calls events; these are eBPF tracepoints you can attach to. For more details on the supported tracepoints, check out the <a href=\"https:\/\/github.com\/iovisor\/bcc\/blob\/master\/docs\/reference_guide.md#events--arguments\">BCC documentation<\/a>.<\/p>\n<p>The list below shows the supported triggers and their argument format:<\/p>\n<dl>\n<dt><strong>USDT probes:<\/strong><\/dt>\n<dd>\n<p><code>[u]:{provider}:{probe}<\/code><\/p>\n<\/dd>\n<dt><strong>Kernel tracepoint:<\/strong><\/dt>\n<dd>\n<p><code>[t:trace]:{system}:{event}<\/code><\/p>\n<\/dd>\n<dt><strong>kprobe:<\/strong><\/dt>\n<dd>\n<p><code>[k:kprobe]:{kernel_function}<\/code><\/p>\n<\/dd>\n<dt><strong>kretprobe:<\/strong><\/dt>\n<dd>\n<p><code>[kr:kretprobe]:{kernel_function}<\/code><\/p>\n<\/dd>\n<dt><strong>uprobe:<\/strong><\/dt>\n<dd>\n<p><code>[up:uprobe]:{function}<\/code><\/p>\n<\/dd>\n<dt><strong>uretprobe:<\/strong><\/dt>\n<dd>\n<p><code>[upr:uretprobe]:{function}<\/code><\/p>\n<\/dd>\n<\/dl>\n<p>Here are a couple of trigger examples (more use case-specific examples can be found in the next\u00a0section):<\/p>\n<pre class=\"console\">\n<code>--start|stop-trigger u:udpif_revalidator:start_dump\n--start|stop-trigger t:openvswitch:ovs_dp_upcall\n--start|stop-trigger k:ovs_dp_process_packet\n--start|stop-trigger kr:ovs_dp_process_packet\n--start|stop-trigger up:bridge_run\n--start|stop-trigger upr:bridge_run<\/code><\/pre>\n<h2 id=\"examples\">Examples<\/h2>\n<p>This section will give some examples of how to use this tool in real-world scenarios. Let&#8217;s start with the issue where Open vSwitch reports <code>Unreasonably long XXXXms poll interval<\/code> on your revalidator threads. Note that there is a blog available explaining <a href=\"https:\/\/developers.redhat.com\/articles\/2022\/10\/19\/open-vswitch-revalidator-process-explained\">how the revalidator process works in OVS<\/a>.<\/p>\n<p>First, let me explain this log message. It gets logged if the time delta between two <code>poll_block()<\/code> calls is more than 1 second. In other words, the process was spending a lot of time processing stuff that was made available by the return of the <code>poll_block()<\/code>.<\/p>\n<p>Do a run with the tool using the existing USDT revalidator probes as a start and stop trigger (note that I removed the resource-specific data from the none revalidator threads):<\/p>\n<pre class=\"console\">\n<code>$ sudo .\/kernel_delay.py --start-trigger u:udpif_revalidator:start_dump --stop-trigger u:udpif_revalidator:sweep_done\n# Start sampling (trigger@791777093512008) @2023-06-14T14:52:00.110303 (12:52:00 UTC)\n# Stop sampling (trigger@791778281498462) @2023-06-14T14:52:01.297975 (12:52:01 UTC)\n# Triggered sample dump, stop-start delta 1,187,986,454 ns @2023-06-14T14:52:01.298021 (12:52:01 UTC)\nTID        THREAD           <RESOURCE SPECIFIC>\n---------- ---------------- ----------------------------------------------------------------------------\n   1457761 handler24        [SYSCALL STATISTICS]\n                            NAME                 NUMBER       COUNT          TOTAL ns            MAX ns\n                            sendmsg                  46        6110       123,274,761            41,776\n                            recvmsg                  47      136299        99,397,508            49,896\n                            futex                   202          51         7,655,832         7,536,776\n                            poll                      7        4068         1,202,883             2,907\n                            getrusage                98        2034           586,602             1,398\n                            sendto                   44           9           213,682            27,417\n                            TOTAL( - poll):                  144503       231,128,385\n\n                            [THREAD RUN STATISTICS]\n                            SCHED_CNT           TOTAL ns            MIN ns            MAX ns\n\n                            [THREAD READY STATISTICS]\n                            SCHED_CNT           TOTAL ns            MAX ns\n                                     1             1,438             1,438\n\n                            [SOFT IRQ STATISTICS]\n                            NAME                 VECT_NR       COUNT          TOTAL ns            MAX ns\n                            sched                      7          21            59,145             3,769\n                            rcu                        9          50            42,917             2,234\n                            TOTAL:                                71           102,062\n   1457733 ovs-vswitchd     [SYSCALL STATISTICS]\n   ...\n   1457792 revalidator55    [SYSCALL STATISTICS]\n                            NAME                 NUMBER       COUNT          TOTAL ns            MAX ns\n                            futex                   202          73       572,576,329        19,621,600\n                            recvmsg                  47         815       296,697,618           405,338\n                            sendto                   44           3            78,302            26,837\n                            sendmsg                  46           3            38,712            13,250\n                            write                     1           1             5,073             5,073\n                            TOTAL( - poll):                     895       869,396,034\n\n                            [THREAD RUN STATISTICS]\n                            SCHED_CNT           TOTAL ns            MIN ns            MAX ns\n                                    48       394,350,393             1,729       140,455,796\n\n                            [THREAD READY STATISTICS]\n                            SCHED_CNT           TOTAL ns            MAX ns\n                                    49            23,650             1,559\n\n                            [SOFT IRQ STATISTICS]\n                            NAME                 VECT_NR       COUNT          TOTAL ns            MAX ns\n                            sched                      7          14            26,889             3,041\n                            rcu                        9          28            23,024             1,600\n                            TOTAL:                                42            49,913<\/code><\/pre>\n<p>You can see from the start of the output that the trigger took more than a second (1,187,986,454 nanoseconds), which we would already know by looking at the output of the <code>ovs-vsctl upcall\/show<\/code> command.<\/p>\n<p>From the revalidator55&#8217;s <code>SYSCALL STATISTICS<\/code> statistics, we can see it spent almost 870 milliseconds handling syscalls, and there were no <code>poll()<\/code> calls being executed. The <code>THREAD RUN STATISTICS<\/code> statistics here are a bit misleading, as it looks like we only spent 394 milliseconds on the CPU. But earlier, we learned that this time does not include the time being on the CPU at the start or stop of an event. What is exactly the case here because we are using USDT probes.<\/p>\n<p>From the above data and maybe some <code>top<\/code> output, we can determine that the revalidator55 thread is taking a lot of CPU time, probably because it has to do a lot of revalidator work by itself. The solution is to increase the number of revalidator threads, so more work could be done in parallel.<\/p>\n<p>Let&#8217;s do another run of the same command in another scenario:<\/p>\n<pre class=\"console\">\n<code>$ sudo .\/kernel_delay.py --start-trigger u:udpif_revalidator:start_dump --stop-trigger u:udpif_revalidator:sweep_done\n# Start sampling (trigger@795160501758971) @2023-06-14T15:48:23.518512 (13:48:23 UTC)\n# Stop sampling (trigger@795160764940201) @2023-06-14T15:48:23.781381 (13:48:23 UTC)\n# Triggered sample dump, stop-start delta 263,181,230 ns @2023-06-14T15:48:23.781414 (13:48:23 UTC)\nTID        THREAD           <RESOURCE SPECIFIC>\n---------- ---------------- ----------------------------------------------------------------------------\n   1457733 ovs-vswitchd     [SYSCALL STATISTICS]\n                            ...\n   1457792 revalidator55    [SYSCALL STATISTICS]\n                            NAME                 NUMBER       COUNT          TOTAL ns            MAX ns\n                            recvmsg                  47         284       193,422,110        46,248,418\n                            sendto                   44           2            46,685            23,665\n                            sendmsg                  46           2            24,916            12,703\n                            write                     1           1             6,534             6,534\n                            TOTAL( - poll):                     289       193,500,245\n\n                            [THREAD RUN STATISTICS]\n                            SCHED_CNT           TOTAL ns            MIN ns            MAX ns\n                                     2        47,333,558           331,516        47,002,042\n\n                            [THREAD READY STATISTICS]\n                            SCHED_CNT           TOTAL ns            MAX ns\n                                     3        87,000,403        45,999,712\n\n                            [SOFT IRQ STATISTICS]\n                            NAME                 VECT_NR       COUNT          TOTAL ns            MAX ns\n                            sched                      7           2             9,504             5,109\n                            TOTAL:                                 2             9,504<\/code><\/pre>\n<p>Here you can see the revalidator run took about 263 milliseconds, which does not look odd; however, the <code>THREAD READY STATISTICS<\/code> information shows us we were waiting 87 milliseconds for a CPU to be run on. This means the revalidator process could have finished 87 milliseconds faster. Looking at the <code>MAX ns<\/code> value, we see a worst-case delay of almost 46 milliseconds, which hints at an overloaded system.<\/p>\n<p>The following is one final example where we use a <code>uprobe<\/code> to get some statistics on a <code>bridge_run()<\/code> execution that takes more than 1 \u00a0millisecond:<\/p>\n<pre class=\"console\">\n<code>$ sudo .\/kernel_delay.py --start-trigger up:bridge_run --stop-trigger ur:bridge_run --trigger-delta 1000000\n# Start sampling (trigger@2245245432101270) @2023-06-14T16:21:10.467919 (14:21:10 UTC)\n# Stop sampling (trigger@2245245432414656) @2023-06-14T16:21:10.468296 (14:21:10 UTC)\n# Sample dump skipped, delta 313,386 ns @2023-06-14T16:21:10.468419 (14:21:10 UTC)\n# Start sampling (trigger@2245245505301745) @2023-06-14T16:21:10.540970 (14:21:10 UTC)\n# Stop sampling (trigger@2245245506911119) @2023-06-14T16:21:10.542499 (14:21:10 UTC)\n# Triggered sample dump, stop-start delta 1,609,374 ns @2023-06-14T16:21:10.542565 (14:21:10 UTC)\nTID        THREAD           <RESOURCE SPECIFIC>\n---------- ---------------- ----------------------------------------------------------------------------\n   3371035 <unknown:3366258\/3371035> [SYSCALL STATISTICS]\n   ... <REMOVED 7 MORE unknown THREADS>\n   3371102 handler66        [SYSCALL STATISTICS]\n   ... <REMOVED 7 MORE HANDLER THREADS>\n   3366258 ovs-vswitchd     [SYSCALL STATISTICS]\n                            NAME                 NUMBER       COUNT          TOTAL ns            MAX ns\n                            futex                   202          43           403,469           199,312\n                            clone3                  435          13           174,394            30,731\n                            munmap                   11           8           115,774            21,861\n                            poll                      7           5            92,969            38,307\n                            unlink                   87           2            49,918            35,741\n                            mprotect                 10           8            47,618            13,201\n                            accept                   43          10            31,360             6,976\n                            mmap                      9           8            30,279             5,776\n                            write                     1           6            27,720            11,774\n                            rt_sigprocmask           14          28            12,281               970\n                            read                      0           6             9,478             2,318\n                            recvfrom                 45           3             7,024             4,024\n                            sendto                   44           1             4,684             4,684\n                            getrusage                98           5             4,594             1,342\n                            close                     3           2             2,918             1,627\n                            recvmsg                  47           1             2,722             2,722\n                            TOTAL( - poll):                     144           924,233\n\n                            [THREAD RUN STATISTICS]\n                            SCHED_CNT           TOTAL ns            MIN ns            MAX ns\n                                    13           817,605             5,433           524,376\n\n                            [THREAD READY STATISTICS]\n                            SCHED_CNT           TOTAL ns            MAX ns\n                                    14            28,646            11,566\n\n                            [SOFT IRQ STATISTICS]\n                            NAME                 VECT_NR       COUNT          TOTAL ns            MAX ns\n                            rcu                        9           1             2,838             2,838\n                            TOTAL:                                 1             2,838\n\n   3371110 revalidator74    [SYSCALL STATISTICS]\n   ... <REMOVED 7 MORE NEW revalidator THREADS>\n   3366311 urcu3            [SYSCALL STATISTICS]\n   ...<\/code><\/pre>\n<p>We removed some of the threads and their resource-specific data, but based on the <code><unknown:3366258\/3371035><\/code> thread name, you can see that some threads no longer exist. In the <code>ovs-vswitchd<\/code> thread, you can see some <code>clone3<\/code> syscalls, indicating threads were created. In this example, it was due to the deletion of a bridge, which resulted in the recreation of the revalidator and handler threads.<\/p>\n<h2 id=\"use_with_openshift\">Using kernel_delay.py with OpenShift<\/h2>\n<p>This section describes how you would use the tool on a node in an OpenShift cluster. It assumes you have console access to the node, either directly or through a debug container.<\/p>\n<p>We will use a base Fedora Linux 38 container through Podman, as this will allow us to install some additional tools and packages we need.<\/p>\n<p>The first thing we need to do is to start the container:<\/p>\n<pre class=\"console\">\n<code>[core@sno-master ~]$ sudo podman run -it --rm \\\n   -e PS1='[(DEBUG)\\u@\\h \\W]\\$ ' \\\n   --privileged --network=host --pid=host \\\n   -v \/lib\/modules:\/lib\/modules:ro \\\n   -v \/sys\/kernel\/debug:\/sys\/kernel\/debug \\\n   -v \/proc:\/proc \\\n   -v \/:\/mnt\/rootdir \\\n   quay.io\/fedora\/fedora:38-x86_64\n\n[(DEBUG)root@sno-master \/]#<\/code><\/pre>\n<p>Next, add the <code>linux_delay.py<\/code> dependencies:<\/p>\n<pre class=\"console\">\n<code>[(DEBUG)root@sno-master \/]# dnf install -y bcc-tools perl-interpreter \\\n     python3-pytz  python3-psutil<\/code><\/pre>\n<p>You need to install Devel, debug, and source RPMs for your OVS and kernel version:<\/p>\n<pre class=\"console\">\n<code>[(DEBUG)root@sno-master home]# rpm -i \\\n    openvswitch2.17-debuginfo-2.17.0-67.el8fdp.x86_64.rpm \\\n    openvswitch2.17-debugsource-2.17.0-67.el8fdp.x86_64.rpm \\\n    kernel-devel-4.18.0-372.41.1.el8_6.x86_64.rpm<\/code><\/pre>\n<p>Now we can run the tool. Here we use the above <code>bridge_run()<\/code> example:<\/p>\n<pre class=\"console\">\n<code>[(DEBUG)root@sno-master home]# .\/kernel_delay.py --start-trigger up:bridge_run --stop-trigger ur:bridge_run\n# Start sampling (trigger@75279117343513) @2023-06-15T11:44:07.628372 (11:44:07 UTC)\n# Stop sampling (trigger@75279117443980) @2023-06-15T11:44:07.628529 (11:44:07 UTC)\n# Triggered sample dump, stop-start delta 100,467 ns @2023-06-15T11:44:07.628569 (11:44:07 UTC)\nTID        THREAD           <RESOURCE SPECIFIC>\n---------- ---------------- ----------------------------------------------------------------------------\n      1246 ovs-vswitchd     [SYSCALL STATISTICS]\n                            NAME                 NUMBER       COUNT          TOTAL ns            MAX ns\n                            getdents64              217           2             8,560             8,162\n                            openat                  257           1             6,951             6,951\n                            accept                   43           4             6,942             3,763\n                            recvfrom                 45           1             3,726             3,726\n                            recvmsg                  47           2             2,880             2,188\n                            stat                      4           2             1,946             1,384\n                            close                     3           1             1,393             1,393\n                            fstat                     5           1             1,324             1,324\n                            TOTAL( - poll):                      14            33,722\n\n                            [THREAD RUN STATISTICS]\n                            SCHED_CNT           TOTAL ns            MIN ns            MAX ns\n\n                            [THREAD READY STATISTICS]\n                            SCHED_CNT           TOTAL ns            MAX ns<\/code><\/pre>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>By incorporating the\u00a0kernel_delay.py utility into your development toolkit, you can swiftly pinpoint the problem&#8217;s source and initiate focused debugging efforts.<\/p>\n<p><span><span lang=\"\" about=\"https:\/\/developers.redhat.com\/user\/673121\" typeof=\"schema:Person\" property=\"schema:name\" datatype=\"\" xml:lang=\"\">echaudro@redhat.com<\/span><\/span><br \/>\n<span>Mon, 07\/24\/2023 &#8211; 07:00<\/span><br \/>\n<a href=\"https:\/\/developers.redhat.com\/author\/echaudron\" hreflang=\"en\">Eelco Chaudron<\/a><\/p>\n\n<p class=\"syndicated-attribution\"><figure class= \\\"wp-block-image alignnone \\\"><img src= \\\"http:\/\/itteacheritfreelance.hk\/test\/wordpress\/wp-content\/uploads\/2016\/05\/logo2-2.png\\\" alt=\\\"IT\u96fb\u8166\u88dc\u7fd2 java\u88dc\u7fd2 \u70ba\u5927\u5bb6\u914d\u5c0d\u96fb\u8166\u88dc\u7fd2,IT freelance, \u79c1\u4eba\u8001\u5e2b, PHP\u88dc\u7fd2,CSS\u88dc\u7fd2,XML,Java\u88dc\u7fd2,MySQL\u88dc\u7fd2,graphic design\u88dc\u7fd2,\u4e2d\u5c0f\u5b78ICT\u88dc\u7fd2,\u4e00\u5c0d\u4e00\u79c1\u4eba\u88dc\u7fd2\u548cFreelance\u81ea\u7531\u5de5\u4f5c\u914d\u5c0d\u3002\\\"\/><figcaption>\u7acb\u523b\u8a3b\u518a\u53ca\u5831\u540d\u96fb\u8166\u88dc\u7fd2\u8ab2\u7a0b\u5427!<\/figcaption><\/figure>\r\n<\/br>Find A Teacher Form:\r\n<\/br>https:\/\/docs.google.com\/forms\/d\/1vREBnX5n262umf4wU5U2pyTwvk9O-JrAgblA-wH9GFQ\/viewform?edit_requested=true#responses\r\n<\/br><\/br>Email:\r\n<\/br>public1989two@gmail.com<br><br><br><br><br><br><br>\r\n<a href=www.itsec.hk style=color:#FFFFFF;>www.itsec.hk<\/a><br>\r\n<a href=\\\"www.itsec.vip\\\" style=color:#FFFFFF;>www.itsec.vip<\/a><br>\r\n<a href=\\\"www.itseceu.uk\\\" style=color:#FFFFFF;>www.itseceu.uk<\/a><br><\/p>","protected":false},"excerpt":{"rendered":"<div class=\"mh-excerpt\"><p><span>Troubleshooting Open vSwitch: Is the kernel to blame?<\/span><\/p>\n<p>Often, when troubleshooting Open vSwitch (OVS) in the field, you might be left wondering if the issue is really OVS-related, or if it&#8217;s a problem with the kernel being overloaded. The <a href=\"https:\/\/github.com\/chaudron\/ovs\/blob\/dev\/kernel_delay\/utilities\/usdt-scripts\/kernel_delay.py\">kernel_delay.py<\/a> tool can help you quickly identify if the focus of your investigation should be OVS or the <a href=\"https:\/\/developers.redhat.com\/topics\/linux\/\">Linux<\/a> kernel.<\/p>\n<h2>About\u00a0kernel_delay.py<\/h2>\n<p>kernel_delay.py\u00a0consists of a <a href=\"https:\/\/developers.redhat.com\/topics\/python\">Python<\/a> script that uses the <a href=\"https:\/\/github.com\/iovisor\/bcc\">BCC<span> <\/span>framework<\/a> to install eBPF probes. \u00a0The data the eBPF probes collect will be analyzed and presented to the user by the Python script. Some of the presented data can also be captured by the individual scripts included in the BBC\u00a0framework.<\/p>\n<p>kernel_delay.py\u00a0has two modes of operation:<\/p>\n<ul>\n<li>In<strong> time mode<\/strong>, the tool runs for a specific time and collects the information.<\/li>\n<li>In <strong>trigger mode<\/strong>, event collection can be started and\/or stopped based on a specific eBPF probe. Currently, we support the following probes:\n<ul>\n<li>USDT probes<\/li>\n<li>Kernel tracepoints<\/li>\n<li>kprobe<\/li>\n<li>kretprobe<\/li>\n<li>uprobe<\/li>\n<li>uretprobe<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>In addition, the option <code>--sample-count<\/code> exists to specify how many iterations you would like to do. When using triggers, you can also ignore samples if they are less than a number of nanoseconds with the <code>--trigger-delta<\/code> option. The latter might be useful when debugging Linux syscalls that take a long time to complete. (More on this later.) Finally, you can configure the delay between two sample runs with the <code>--sample-interval<\/code> option.<\/p>\n<p>Before getting into more details, let&#8217;s just run the tool without any options to see what the output looks like. Notice that it will try to automatically get the process ID of the running <code>ovs-vsdwitchd<\/code>. You can overwrite this with the <code>--pid<\/code> option.<\/p>\n<pre class=\"console\">\n<code>$ sudo .\/kernel_delay.py\n# Start sampling @2023-06-08T12:17:22.725127 (10:17:22 UTC)\n# Stop sampling @2023-06-08T12:17:23.224781 (10:17:23 UTC)\n# Sample dump @2023-06-08T12:17:23.224855 (10:17:23 UTC)\nTID        THREAD           <resource specific>\n---------- ---------------- ----------------------------------------------------------------------------\n     27090 ovs-vswitchd     [SYSCALL STATISTICS]\n                <edit: removed data for ovs-vswitchd thread>\n\n     31741 revalidator122   [SYSCALL STATISTICS]\n                NAME                 NUMBER       COUNT          TOTAL ns            MAX ns\n                poll                      7           5       184,193,176       184,191,520\n                recvmsg                  47         494       125,208,756           310,331\n                futex                   202           8        18,768,758         4,023,039\n                sendto                   44          10           375,861           266,867\n                sendmsg                  46           4            43,294            11,213\n                write                     1           1             5,949             5,949\n                getrusage                98           1             1,424             1,424\n                read                      0           1             1,292             1,292\n                TOTAL( - poll):                     519       144,405,334\n\n                [THREAD RUN STATISTICS]\n                SCHED_CNT           TOTAL ns            MIN ns            MAX ns\n                     6       136,764,071             1,480       115,146,424\n\n                [THREAD READY STATISTICS]\n                SCHED_CNT           TOTAL ns            MAX ns\n                     7            11,334             6,636\n\n                [HARD IRQ STATISTICS]\n                NAME                       COUNT          TOTAL ns            MAX ns\n                eno8303-rx-1                   1             3,586             3,586\n                TOTAL:                         1             3,586\n\n                [SOFT IRQ STATISTICS]\n                NAME                 VECT_NR       COUNT          TOTAL ns            MAX ns\n                net_rx                     3           1            17,699            17,699\n                sched                      7           6            13,820             3,226\n                rcu                        9          16            13,586             1,554\n                timer                      1           3            10,259             3,815\n                TOTAL:                                26            55,364<\/edit:><\/resource><\/code><\/pre>\n<p>By default, the tool will run for half a second in <span class=\"title-ref\">time mode<\/span>. To extend this, you can use the <code>--sample-time<\/code> option.<\/p>\n<h2>What will it report?<\/h2>\n<p>The above sample output separates the captured data on a per-thread basis. For this, it displays the thread&#8217;s id (<code>TID<\/code>) and name (<code>THREAD<\/code>), followed by resource-specific data. Which are:<\/p>\n<ul>\n<li><code>SYSCALL STATISTICS<\/code><\/li>\n<li><code>THREAD RUN STATISTICS<\/code><\/li>\n<li><code>THREAD READY STATISTICS<\/code><\/li>\n<li><code>HARD IRQ STATISTICS<\/code><\/li>\n<li><code>SOFT IRQ STATISTICS<\/code><\/li>\n<\/ul>\n<p>The following sections will describe in detail what statistics they report.<\/p>\n<h3>SYSCALL STATISTICS<\/h3>\n<p><code>SYSCALL STATISTICS<\/code>\u00a0tell you which Linux system calls got executed during the measurement interval. This includes the number of times the syscall was called (<code>COUNT<\/code>), the total time spent in the system calls (<code>TOTAL ns<\/code>), and the worst-case duration of a single call (<code>MAX ns<\/code>).<\/p>\n<p>It also shows the total of all system calls, but it excludes the poll system call, as the purpose of this call is to wait for activity on a set of sockets, and usually, the thread gets swapped out.<\/p>\n<p>Note that it only counts calls that started and stopped during the measurement interval!<\/p>\n<h3>THREAD RUN STATISTICS<\/h3>\n<p><code>THREAD RUN STATISTICS<\/code>\u00a0tell you how long the thread was running on a CPU during the measurement interval.<\/p>\n<p>Note that these statistics only count events where the thread started and stopped running on a CPU during the measurement interval. For example, if this was a PMD thread, you should see zero <code>SCHED_CNT<\/code> and <code>TOTAL_ns<\/code>. If not, there might be a misconfiguration.<\/p>\n<h3>THREAD READY STATISTICS<\/h3>\n<p><code>THREAD READY STATISTICS<\/code> tell you the time between the thread being ready to run and it actually running on the CPU.<\/p>\n<p>Note that these statistics only count events where the thread was getting ready to run and started running during the measurement interval.<\/p>\n<h3>HARD IRQ STATISTICS<\/h3>\n<p><code>HARD IRQ STATISTICS<\/code> tell you how much time was spent servicing hard interrupts during the threads run time.<\/p>\n<p>It shows the interrupt name (<code>NAME<\/code>), the number of interrupts (<code>COUNT<\/code>), the total time spent in the interrupt handler (<code>TOTAL ns<\/code>), and the worst-case duration (<code>MAX ns<\/code>).<\/p>\n<h3>SOFT IRQ STATISTICS<\/h3>\n<p><code>SOFT IRQ STATISTICS<\/code> tell you how much time was spent servicing soft interrupts during the threads run time.<\/p>\n<p>It shows the interrupt name (<code>NAME<\/code>), vector number (<code>VECT_NR<\/code>), the number of interrupts (<code>COUNT<\/code>), the total time spent in the interrupt handler (<code>TOTAL ns<\/code>), and the worst-case duration (<code>MAX ns<\/code>).<\/p>\n<h1>The\u00a0&#8211;syscall-events\u00a0option<\/h1>\n<p>In addition to reporting global syscall statistics in <code>SYSCALL_STATISTICS<\/code>, the tool can also report each individual syscall. This can be a useful second step if the <code>SYSCALL_STATISTICS<\/code> show high latency numbers.<\/p>\n<p>All you need to do is add the <code>--syscall-events<\/code> option, with or without the additional <code>DURATION_NS<\/code> parameter. The <code>DUTATION_NS<\/code> parameter allows you to exclude events that take less than the supplied time.<\/p>\n<p>The <code>--skip-syscall-poll-events<\/code> option allows you to exclude poll syscalls from the report.<\/p>\n<p>Below is an example run; note that I have removed the resource-specific data to highlight the syscall events:<\/p>\n<pre class=\"console\">\n<code>$ sudo .\/kernel_delay.py  --syscall-events 50000 --skip-syscall-poll-events\n# Start sampling @2023-06-13T17:10:46.460874 (15:10:46 UTC)\n# Stop sampling @2023-06-13T17:10:46.960727 (15:10:46 UTC)\n# Sample dump @2023-06-13T17:10:46.961033 (15:10:46 UTC)\nTID        THREAD           <resource specific>\n---------- ---------------- ----------------------------------------------------------------------------\n   3359686 ipf_clean2       [SYSCALL STATISTICS]\n   ...\n   3359635 ovs-vswitchd     [SYSCALL STATISTICS]\n   ...\n   3359697 revalidator12    [SYSCALL STATISTICS]\n   ...\n   3359698 revalidator13    [SYSCALL STATISTICS]\n   ...\n   3359699 revalidator14    [SYSCALL STATISTICS]\n   ...\n   3359700 revalidator15    [SYSCALL STATISTICS]\n   ...\n\n# SYSCALL EVENTS:\n       ENTRY (ns)           EXIT (ns)        TID COMM             DELTA (us)  SYSCALL\n  ------------------- ------------------- ---------- ---------------- ----------  ----------------\n     2161821694935486    2161821695031201    3359699 revalidator14            95  futex\n      syscall_exit_to_user_mode_prepare+0x161 [kernel]\n      syscall_exit_to_user_mode_prepare+0x161 [kernel]\n      syscall_exit_to_user_mode+0x9 [kernel]\n      do_syscall_64+0x68 [kernel]\n      entry_SYSCALL_64_after_hwframe+0x72 [kernel]\n      __GI___lll_lock_wait+0x30 [libc.so.6]\n      ovs_mutex_lock_at+0x18 [ovs-vswitchd]\n      [unknown] 0x696c003936313a63\n     2161821695276882    2161821695333687    3359698 revalidator13            56  futex\n      syscall_exit_to_user_mode_prepare+0x161 [kernel]\n      syscall_exit_to_user_mode_prepare+0x161 [kernel]\n      syscall_exit_to_user_mode+0x9 [kernel]\n      do_syscall_64+0x68 [kernel]\n      entry_SYSCALL_64_after_hwframe+0x72 [kernel]\n      __GI___lll_lock_wait+0x30 [libc.so.6]\n      ovs_mutex_lock_at+0x18 [ovs-vswitchd]\n      [unknown] 0x696c003134313a63\n     2161821695275820    2161821695405733    3359700 revalidator15           129  futex\n      syscall_exit_to_user_mode_prepare+0x161 [kernel]\n      syscall_exit_to_user_mode_prepare+0x161 [kernel]\n      syscall_exit_to_user_mode+0x9 [kernel]\n      do_syscall_64+0x68 [kernel]\n      entry_SYSCALL_64_after_hwframe+0x72 [kernel]\n      __GI___lll_lock_wait+0x30 [libc.so.6]\n      ovs_mutex_lock_at+0x18 [ovs-vswitchd]\n      [unknown] 0x696c003936313a63\n     2161821695964969    2161821696052021    3359635 ovs-vswitchd             87  accept\n      syscall_exit_to_user_mode_prepare+0x161 [kernel]\n      syscall_exit_to_user_mode_prepare+0x161 [kernel]\n      syscall_exit_to_user_mode+0x9 [kernel]\n      do_syscall_64+0x68 [kernel]\n      entry_SYSCALL_64_after_hwframe+0x72 [kernel]\n      __GI_accept+0x4d [libc.so.6]\n      pfd_accept+0x3a [ovs-vswitchd]\n      [unknown] 0x7fff19f2bd00\n      [unknown] 0xe4b8001f0f<\/resource><\/code><\/pre>\n<p>As you can see above, the output also shows the stackback trace. You can disable this using the <code>--stack-trace-size 0<\/code> option.<\/p>\n<p>As you can see above, the backtrace does not show a lot of useful information due to the BCC<span> <\/span>toolkit not supporting dwarf decoding. To further analyze system call backtraces, you could use perf. The following perf script can do this for you (refer to the embedded instructions):\u00a0<a href=\"https:\/\/github.com\/chaudron\/perf_scripts\/blob\/master\/analyze_perf_pmd_syscall.py\">https:\/\/github.com\/chaudron\/perf_scripts\/blob\/master\/analyze_perf_pmd_syscall.py<\/a><\/p>\n<h2>Using triggers<\/h2>\n<p>The tool supports both start and stop triggers. This will allow you to capture statistics triggered by a specific event. First, let&#8217;s look at what combinations of stop-and-start triggers we can use.<\/p>\n<p>If you only use <code>--start-trigger<\/code>, the inspection start when the trigger happens and runs until the <code>--sample-time<\/code> number of seconds has passed. The example below shows all the supported options in this scenario.<\/p>\n<pre class=\"console\">\n<code>$ sudo .\/kernel_delay.py --start-trigger up:bridge_run --sample-time 4 \\\n                         --sample-count 4 --sample-interval 1<\/code><\/pre>\n<p>If you only use <code>--stop-trigger<\/code>, the inspection starts immediately and stops when the trigger happens. The example below shows all the supported options in this scenario.<\/p>\n<pre class=\"console\">\n<code>$ sudo .\/kernel_delay.py --stop-trigger upr:bridge_run \\\n                         --sample-count 4 --sample-interval 1<\/code><\/pre>\n<p>If you use both <code>--start-trigger<\/code> and <code>--stop-trigger<\/code> triggers, the statistics are captured between the two first occurrences of these events. The example below shows all the supported options in this scenario.<\/p>\n<pre class=\"console\">\n<code>$ sudo .\/kernel_delay.py --start-trigger up:bridge_run \\\n                         --stop-trigger upr:bridge_run \\\n                         --sample-count 4 --sample-interval 1 \\\n                         --trigger-delta 50000<\/code><\/pre>\n<p>Now that we know how these triggers can be used, let&#8217;s investigate what triggers are supported. What we call triggers, BCC\u00a0calls events; these are eBPF tracepoints you can attach to. For more details on the supported tracepoints, check out the <a href=\"https:\/\/github.com\/iovisor\/bcc\/blob\/master\/docs\/reference_guide.md#events--arguments\">BCC documentation<\/a>.<\/p>\n<p>The list below shows the supported triggers and their argument format:<\/p>\n<dl>\n<dt><strong>USDT probes:<\/strong><\/dt>\n<dd>\n<p><code>[u]:{provider}:{probe}<\/code><\/p>\n<\/dd>\n<dt><strong>Kernel tracepoint:<\/strong><\/dt>\n<dd>\n<p><code>[t:trace]:{system}:{event}<\/code><\/p>\n<\/dd>\n<dt><strong>kprobe:<\/strong><\/dt>\n<dd>\n<p><code>[k:kprobe]:{kernel_function}<\/code><\/p>\n<\/dd>\n<dt><strong>kretprobe:<\/strong><\/dt>\n<dd>\n<p><code>[kr:kretprobe]:{kernel_function}<\/code><\/p>\n<\/dd>\n<dt><strong>uprobe:<\/strong><\/dt>\n<dd>\n<p><code>[up:uprobe]:{function}<\/code><\/p>\n<\/dd>\n<dt><strong>uretprobe:<\/strong><\/dt>\n<dd>\n<p><code>[upr:uretprobe]:{function}<\/code><\/p>\n<\/dd>\n<\/dl>\n<p>Here are a couple of trigger examples (more use case-specific examples can be found in the next\u00a0section):<\/p>\n<pre class=\"console\">\n<code>--start|stop-trigger u:udpif_revalidator:start_dump\n--start|stop-trigger t:openvswitch:ovs_dp_upcall\n--start|stop-trigger k:ovs_dp_process_packet\n--start|stop-trigger kr:ovs_dp_process_packet\n--start|stop-trigger up:bridge_run\n--start|stop-trigger upr:bridge_run<\/code><\/pre>\n<h2>Examples<\/h2>\n<p>This section will give some examples of how to use this tool in real-world scenarios. Let&#8217;s start with the issue where Open vSwitch reports <code>Unreasonably long XXXXms poll interval<\/code> on your revalidator threads. Note that there is a blog available explaining <a href=\"https:\/\/developers.redhat.com\/articles\/2022\/10\/19\/open-vswitch-revalidator-process-explained\">how the revalidator process works in OVS<\/a>.<\/p>\n<p>First, let me explain this log message. It gets logged if the time delta between two <code>poll_block()<\/code> calls is more than 1 second. In other words, the process was spending a lot of time processing stuff that was made available by the return of the <code>poll_block()<\/code>.<\/p>\n<p>Do a run with the tool using the existing USDT revalidator probes as a start and stop trigger (note that I removed the resource-specific data from the none revalidator threads):<\/p>\n<pre class=\"console\">\n<code>$ sudo .\/kernel_delay.py --start-trigger u:udpif_revalidator:start_dump --stop-trigger u:udpif_revalidator:sweep_done\n# Start sampling (trigger@791777093512008) @2023-06-14T14:52:00.110303 (12:52:00 UTC)\n# Stop sampling (trigger@791778281498462) @2023-06-14T14:52:01.297975 (12:52:01 UTC)\n# Triggered sample dump, stop-start delta 1,187,986,454 ns @2023-06-14T14:52:01.298021 (12:52:01 UTC)\nTID        THREAD           <resource specific>\n---------- ---------------- ----------------------------------------------------------------------------\n   1457761 handler24        [SYSCALL STATISTICS]\n                            NAME                 NUMBER       COUNT          TOTAL ns            MAX ns\n                            sendmsg                  46        6110       123,274,761            41,776\n                            recvmsg                  47      136299        99,397,508            49,896\n                            futex                   202          51         7,655,832         7,536,776\n                            poll                      7        4068         1,202,883             2,907\n                            getrusage                98        2034           586,602             1,398\n                            sendto                   44           9           213,682            27,417\n                            TOTAL( - poll):                  144503       231,128,385\n\n                            [THREAD RUN STATISTICS]\n                            SCHED_CNT           TOTAL ns            MIN ns            MAX ns\n\n                            [THREAD READY STATISTICS]\n                            SCHED_CNT           TOTAL ns            MAX ns\n                                     1             1,438             1,438\n\n                            [SOFT IRQ STATISTICS]\n                            NAME                 VECT_NR       COUNT          TOTAL ns            MAX ns\n                            sched                      7          21            59,145             3,769\n                            rcu                        9          50            42,917             2,234\n                            TOTAL:                                71           102,062\n   1457733 ovs-vswitchd     [SYSCALL STATISTICS]\n   ...\n   1457792 revalidator55    [SYSCALL STATISTICS]\n                            NAME                 NUMBER       COUNT          TOTAL ns            MAX ns\n                            futex                   202          73       572,576,329        19,621,600\n                            recvmsg                  47         815       296,697,618           405,338\n                            sendto                   44           3            78,302            26,837\n                            sendmsg                  46           3            38,712            13,250\n                            write                     1           1             5,073             5,073\n                            TOTAL( - poll):                     895       869,396,034\n\n                            [THREAD RUN STATISTICS]\n                            SCHED_CNT           TOTAL ns            MIN ns            MAX ns\n                                    48       394,350,393             1,729       140,455,796\n\n                            [THREAD READY STATISTICS]\n                            SCHED_CNT           TOTAL ns            MAX ns\n                                    49            23,650             1,559\n\n                            [SOFT IRQ STATISTICS]\n                            NAME                 VECT_NR       COUNT          TOTAL ns            MAX ns\n                            sched                      7          14            26,889             3,041\n                            rcu                        9          28            23,024             1,600\n                            TOTAL:                                42            49,913<\/resource><\/code><\/pre>\n<p>You can see from the start of the output that the trigger took more than a second (1,187,986,454 nanoseconds), which we would already know by looking at the output of the <code>ovs-vsctl upcall\/show<\/code> command.<\/p>\n<p>From the revalidator55&#8217;s <code>SYSCALL STATISTICS<\/code> statistics, we can see it spent almost 870 milliseconds handling syscalls, and there were no <code>poll()<\/code> calls being executed. The <code>THREAD RUN STATISTICS<\/code> statistics here are a bit misleading, as it looks like we only spent 394 milliseconds on the CPU. But earlier, we learned that this time does not include the time being on the CPU at the start or stop of an event. What is exactly the case here because we are using USDT probes.<\/p>\n<p>From the above data and maybe some <code>top<\/code> output, we can determine that the revalidator55 thread is taking a lot of CPU time, probably because it has to do a lot of revalidator work by itself. The solution is to increase the number of revalidator threads, so more work could be done in parallel.<\/p>\n<p>Let&#8217;s do another run of the same command in another scenario:<\/p>\n<pre class=\"console\">\n<code>$ sudo .\/kernel_delay.py --start-trigger u:udpif_revalidator:start_dump --stop-trigger u:udpif_revalidator:sweep_done\n# Start sampling (trigger@795160501758971) @2023-06-14T15:48:23.518512 (13:48:23 UTC)\n# Stop sampling (trigger@795160764940201) @2023-06-14T15:48:23.781381 (13:48:23 UTC)\n# Triggered sample dump, stop-start delta 263,181,230 ns @2023-06-14T15:48:23.781414 (13:48:23 UTC)\nTID        THREAD           <resource specific>\n---------- ---------------- ----------------------------------------------------------------------------\n   1457733 ovs-vswitchd     [SYSCALL STATISTICS]\n                            ...\n   1457792 revalidator55    [SYSCALL STATISTICS]\n                            NAME                 NUMBER       COUNT          TOTAL ns            MAX ns\n                            recvmsg                  47         284       193,422,110        46,248,418\n                            sendto                   44           2            46,685            23,665\n                            sendmsg                  46           2            24,916            12,703\n                            write                     1           1             6,534             6,534\n                            TOTAL( - poll):                     289       193,500,245\n\n                            [THREAD RUN STATISTICS]\n                            SCHED_CNT           TOTAL ns            MIN ns            MAX ns\n                                     2        47,333,558           331,516        47,002,042\n\n                            [THREAD READY STATISTICS]\n                            SCHED_CNT           TOTAL ns            MAX ns\n                                     3        87,000,403        45,999,712\n\n                            [SOFT IRQ STATISTICS]\n                            NAME                 VECT_NR       COUNT          TOTAL ns            MAX ns\n                            sched                      7           2             9,504             5,109\n                            TOTAL:                                 2             9,504<\/resource><\/code><\/pre>\n<p>Here you can see the revalidator run took about 263 milliseconds, which does not look odd; however, the <code>THREAD READY STATISTICS<\/code> information shows us we were waiting 87 milliseconds for a CPU to be run on. This means the revalidator process could have finished 87 milliseconds faster. Looking at the <code>MAX ns<\/code> value, we see a worst-case delay of almost 46 milliseconds, which hints at an overloaded system.<\/p>\n<p>The following is one final example where we use a <code>uprobe<\/code> to get some statistics on a <code>bridge_run()<\/code> execution that takes more than 1 \u00a0millisecond:<\/p>\n<pre class=\"console\">\n<code>$ sudo .\/kernel_delay.py --start-trigger up:bridge_run --stop-trigger ur:bridge_run --trigger-delta 1000000\n# Start sampling (trigger@2245245432101270) @2023-06-14T16:21:10.467919 (14:21:10 UTC)\n# Stop sampling (trigger@2245245432414656) @2023-06-14T16:21:10.468296 (14:21:10 UTC)\n# Sample dump skipped, delta 313,386 ns @2023-06-14T16:21:10.468419 (14:21:10 UTC)\n# Start sampling (trigger@2245245505301745) @2023-06-14T16:21:10.540970 (14:21:10 UTC)\n# Stop sampling (trigger@2245245506911119) @2023-06-14T16:21:10.542499 (14:21:10 UTC)\n# Triggered sample dump, stop-start delta 1,609,374 ns @2023-06-14T16:21:10.542565 (14:21:10 UTC)\nTID        THREAD           <resource specific>\n---------- ---------------- ----------------------------------------------------------------------------\n   3371035 <3366258><removed more unknown threads><removed more handler threads><removed more new revalidator threads><\/removed><\/removed><\/removed><\/3366258><\/resource><\/code><\/pre>\n<p><code><3366258><\/3366258><\/code><code><\/code><code><\/code><\/p>\n<h2><\/h2>\n<\/p>\n<\/p>\n<pre class=\"console\"><code><\/code><\/pre>\n<p><code><\/code><\/p>\n<pre class=\"console\"><code><\/code><\/pre>\n<\/p>\n<pre class=\"console\"><code><\/code><\/pre>\n<p><code><\/code><\/p>\n<pre class=\"console\"><code><resource specific><\/resource><\/code><\/pre>\n<h2><\/h2>\n<\/p>\n<p><span><span lang=\"\" about=\"https:\/\/developers.redhat.com\/user\/673121\" typeof=\"schema:Person\" property=\"schema:name\" datatype=\"\" xml:lang=\"\"><\/span><\/span><span><\/span><a href=\"https:\/\/developers.redhat.com\/author\/echaudron\" hreflang=\"en\"><\/a><\/p>\n<\/div>","protected":false},"author":2029,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"slim_seo":{"title":"Troubleshooting Open vSwitch: Is the kernel to blame? - ITTeacherITFreelance.hk","description":"Troubleshooting Open vSwitch: Is the kernel to blame? Often, when troubleshooting Open vSwitch (OVS) in the field, you might be left wondering if the issue is r"},"footnotes":""},"categories":[10700],"tags":[],"_links":{"self":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/329302"}],"collection":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/2029"}],"replies":[{"embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=329302"}],"version-history":[{"count":1,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/329302\/revisions"}],"predecessor-version":[{"id":329303,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/329302\/revisions\/329303"}],"wp:attachment":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=329302"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=329302"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=329302"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}