Bug 2002762

Summary: [RFE] ovsdb-server: Optimize json parser
Product: Red Hat Enterprise Linux Fast Datapath Reporter: Ilya Maximets <i.maximets>
Component: openvswitch3.1Assignee: Timothy Redaelli <tredaelli>
Status: CLOSED ERRATA QA Contact: ovs-qe
Severity: high Docs Contact:
Priority: high    
Version: RHEL 8.0CC: ctrautma, dcbw, fleitner, jhsiao, qding, ralongi
Target Milestone: ---Keywords: FutureFeature
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: openvswitch3.0-3.0.0-1.el9fdp Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2023-07-06 19:17:49 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Ilya Maximets 2021-09-09 16:11:57 UTC
OVSDB uses json objects for RPC and storing the data.  Current implementation
of JSON parsing from string is fairly slow, because it copies the data multiple
times and also does that symbol by symbol.  Optimization of this process should
positively affect performance of all the communications in OVS/OVN.

Functions in question are json_parser_feed() and json_lex_input().

Ideas:
- Try to eliminate 'buffer' as an intermediate place to store the token by
  using a pointer to the position in the original string + current size.
- Simplify the branch-heavy logic to help CPU's branch predictor.

Comment 1 Ilya Maximets 2022-01-10 13:49:14 UTC
Helper patch with a parser benchmark posted:
  https://patchwork.ozlabs.org/project/openvswitch/patch/20220110125410.3099055-1-i.maximets@ovn.org/
Should be useful to measure improvements for this BZ.

Comment 2 Dan Williams 2022-04-29 14:52:13 UTC
Committed upstream to OVS master (after 2.17).
http://patchwork.ozlabs.org/project/openvswitch/patch/20220329165111.19157-1-roriorden@redhat.com/

commit 2f16123c1bf0793381683ede3d63ae6da379d9b7
Author:     Rosemarie O'Riorden <roriorden>
AuthorDate: Tue Mar 29 12:51:11 2022 -0400
Commit:     Ilya Maximets <i.maximets>
CommitDate: Mon Apr 4 22:52:12 2022 +0200

    json: Improve string parsing.
    
    To parse a json string prior to this change, json_lex_input is called
    with each character of the string. If the character needs to be copied
    to the buffer, it is copied individually. This is an expensive
    operation, as often there are multiple characters in a row
    that need to be copied, and copying memory in blocks is more efficient
    than byte by byte. To improve this, the string is now copied
    in blocks with an offset counter. A copy is performed when the parser
    state equals done.
    
    Functions that are called for each character use a lot of CPU cycles.
    Making these functions inline greatly reduces the cycles used and
    improves overall performance. Since json_lex_input was only needed in
    one place, it doesn't have to be its own function.
    
    There is also a conditional that checks if the current character is a
    new line, which is quite unlikely. When this was examined with perf, the
    comparison had a very high CPU cycle usage. To improve this, the
    OVS_UNLIKELY macro was used, which forces the compiler to switch the
    order of the instructions.
    
    Here is the improvement seen in the json-string-benchmark test:
    
      SIZE      Q  S         BEFORE       AFTER      CHANGE
    --------------------------------------------------------
    100000      0  0 :      0.842 ms     0.489 ms   -41.9 %
    100000      2  1 :      0.917 ms     0.535 ms   -41.7 %
    100000      10 1 :      1.063 ms     0.656 ms   -38.3 %
    10000000    0  0 :     85.328 ms    49.878 ms   -41.5 %
    10000000    2  1 :     92.555 ms    54.778 ms   -40.8 %
    10000000    10 1 :    106.728 ms    66.735 ms   -37.5 %
    100000000   0  0 :    955.375 ms   621.950 ms   -34.9 %
    100000000   2  1 :   1031.700 ms   665.200 ms   -35.5 %
    100000000   10 1 :   1189.300 ms   796.050 ms   -33.0 %
    
    Here Q is probability (%) for a character to be a '\"' and
    S is probability (%) to be a special character ( < 32).
    
    Signed-off-by: Rosemarie O'Riorden <roriorden>
    Acked-by: Dumitru Ceara <dceara>
    Signed-off-by: Ilya Maximets <i.maximets>

Comment 9 Christian Trautman 2023-07-06 13:09:12 UTC
No test to verify.  We have completed all regression tests and no blockers were found.

Comment 11 errata-xmlrpc 2023-07-06 19:17:49 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (openvswitch3.1 bug fix and enhancement update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2023:3989