--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- SPDX-License-Identifier: BSD-3-Clause -->
+
+<!-- Copyright(c) 2022 NVIDIA Corporation & Affiliates -->
+
+<svg
+ width="485"
+ height="535"
+ overflow="hidden"
+ version="1.1"
+ id="svg61"
+ sodipodi:docname="rte_flow_async_init.svg"
+ inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview63"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="1.517757"
+ inkscape:cx="242.79249"
+ inkscape:cy="267.17057"
+ inkscape:window-width="2400"
+ inkscape:window-height="1271"
+ inkscape:window-x="2391"
+ inkscape:window-y="-9"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="g59" />
+ <defs
+ id="defs5">
+ <clipPath
+ id="clip0">
+ <rect
+ x="0"
+ y="0"
+ width="485"
+ height="535"
+ id="rect2" />
+ </clipPath>
+ </defs>
+ <g
+ clip-path="url(#clip0)"
+ id="g59">
+ <rect
+ x="0"
+ y="0"
+ width="485"
+ height="535"
+ fill="#FFFFFF"
+ id="rect7" />
+ <rect
+ x="0.500053"
+ y="79.5001"
+ width="482"
+ height="59"
+ stroke="#000000"
+ stroke-width="1.33333"
+ stroke-miterlimit="8"
+ fill="#A6A6A6"
+ id="rect9" />
+ <text
+ font-family="Calibri,Calibri_MSFontService,sans-serif"
+ font-weight="400"
+ font-size="24"
+ transform="translate(121.6 116)"
+ id="text13">
+ rte_eth_dev_configure
+ <tspan
+ font-size="24"
+ x="224.007"
+ y="0"
+ id="tspan11">()</tspan></text>
+ <rect
+ x="0.500053"
+ y="158.5"
+ width="482"
+ height="59"
+ stroke="#000000"
+ stroke-width="1.33333"
+ stroke-miterlimit="8"
+ fill="#FFFFFF"
+ id="rect15" />
+ <text
+ font-family="Calibri,Calibri_MSFontService,sans-serif"
+ font-weight="400"
+ font-size="24"
+ transform="translate(140.273 195)"
+ id="text17">
+ rte_flow_configure()
+ </text>
+ <rect
+ x="0.500053"
+ y="236.5"
+ width="482"
+ height="60"
+ stroke="#000000"
+ stroke-width="1.33333"
+ stroke-miterlimit="8"
+ fill="#FFFFFF"
+ id="rect19" />
+ <text
+ font-family="Calibri, Calibri_MSFontService, sans-serif"
+ font-weight="400"
+ font-size="24px"
+ id="text21"
+ x="63.425903"
+ y="274">rte_flow_pattern_template_create()</text>
+ <rect
+ x="0.500053"
+ y="316.5"
+ width="482"
+ height="59"
+ stroke="#000000"
+ stroke-width="1.33333"
+ stroke-miterlimit="8"
+ fill="#FFFFFF"
+ id="rect23" />
+ <text
+ font-family="Calibri, Calibri_MSFontService, sans-serif"
+ font-weight="400"
+ font-size="24px"
+ id="text27"
+ x="69.379204"
+ y="353">rte_flow_actions_template_create()</text>
+ <rect
+ x="0.500053"
+ y="0.500053"
+ width="482"
+ height="60"
+ stroke="#000000"
+ stroke-width="1.33333"
+ stroke-miterlimit="8"
+ fill="#A6A6A6"
+ id="rect29" />
+ <text
+ font-family="Calibri, Calibri_MSFontService, sans-serif"
+ font-weight="400"
+ font-size="24px"
+ transform="translate(177.233,37)"
+ id="text33">rte_eal_init()</text>
+ <path
+ d="M2-1.09108e-05 2.00005 9.2445-1.99995 9.24452-2 1.09108e-05ZM6.00004 7.24448 0.000104987 19.2445-5.99996 7.24455Z"
+ transform="matrix(-1 0 0 1 241 60)"
+ id="path35" />
+ <path
+ d="M2-1.08133e-05 2.00005 9.41805-1.99995 9.41807-2 1.08133e-05ZM6.00004 7.41802 0.000104987 19.4181-5.99996 7.41809Z"
+ transform="matrix(-1 0 0 1 241 138)"
+ id="path37" />
+ <path
+ d="M2-1.09108e-05 2.00005 9.2445-1.99995 9.24452-2 1.09108e-05ZM6.00004 7.24448 0.000104987 19.2445-5.99996 7.24455Z"
+ transform="matrix(-1 0 0 1 241 217)"
+ id="path39" />
+ <rect
+ x="0.500053"
+ y="395.5"
+ width="482"
+ height="59"
+ stroke="#000000"
+ stroke-width="1.33333"
+ stroke-miterlimit="8"
+ fill="#FFFFFF"
+ id="rect41" />
+ <text
+ font-family="Calibri, Calibri_MSFontService, sans-serif"
+ font-weight="400"
+ font-size="24px"
+ id="text47"
+ x="76.988998"
+ y="432">rte_flow_template_table_create()</text>
+ <path
+ d="M2-1.05859e-05 2.00005 9.83526-1.99995 9.83529-2 1.05859e-05ZM6.00004 7.83524 0.000104987 19.8353-5.99996 7.83531Z"
+ transform="matrix(-1 0 0 1 241 296)"
+ id="path49" />
+ <path
+ d="M243 375 243 384.191 239 384.191 239 375ZM247 382.191 241 394.191 235 382.191Z"
+ id="path51" />
+ <rect
+ x="0.500053"
+ y="473.5"
+ width="482"
+ height="60"
+ stroke="#000000"
+ stroke-width="1.33333"
+ stroke-miterlimit="8"
+ fill="#A6A6A6"
+ id="rect53" />
+ <text
+ font-family="Calibri, Calibri_MSFontService, sans-serif"
+ font-weight="400"
+ font-size="24px"
+ id="text55"
+ x="149.30299"
+ y="511">rte_eth_dev_start()</text>
+ <path
+ d="M245 454 245 463.191 241 463.191 241 454ZM249 461.191 243 473.191 237 461.191Z"
+ id="path57" />
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- SPDX-License-Identifier: BSD-3-Clause -->
+
+<!-- Copyright(c) 2022 NVIDIA Corporation & Affiliates -->
+
+<svg
+ width="880"
+ height="610"
+ overflow="hidden"
+ version="1.1"
+ id="svg103"
+ sodipodi:docname="rte_flow_async_usage.svg"
+ inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview105"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="1.3311475"
+ inkscape:cx="439.84607"
+ inkscape:cy="305.37563"
+ inkscape:window-width="2400"
+ inkscape:window-height="1271"
+ inkscape:window-x="-9"
+ inkscape:window-y="-9"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="g101" />
+ <defs
+ id="defs5">
+ <clipPath
+ id="clip0">
+ <rect
+ x="0"
+ y="0"
+ width="880"
+ height="610"
+ id="rect2" />
+ </clipPath>
+ </defs>
+ <g
+ clip-path="url(#clip0)"
+ id="g101">
+ <rect
+ x="0"
+ y="0"
+ width="880"
+ height="610"
+ fill="#FFFFFF"
+ id="rect7" />
+ <rect
+ x="333.5"
+ y="0.500053"
+ width="234"
+ height="45"
+ stroke="#000000"
+ stroke-width="1.33333"
+ stroke-miterlimit="8"
+ fill="#A6A6A6"
+ id="rect9" />
+ <text
+ font-family="Consolas, Consolas_MSFontService, sans-serif"
+ font-weight="400"
+ font-size="19px"
+ transform="translate(357.196,29)"
+ id="text11">rte_eth_rx_burst()</text>
+ <rect
+ x="333.5"
+ y="63.5001"
+ width="234"
+ height="45"
+ stroke="#000000"
+ stroke-width="1.33333"
+ stroke-miterlimit="8"
+ fill="#D9D9D9"
+ id="rect13" />
+ <text
+ font-family="Calibri,Calibri_MSFontService,sans-serif"
+ font-weight="400"
+ font-size="19"
+ transform="translate(394.666 91)"
+ id="text17">analyze <tspan
+ font-size="19"
+ x="60.9267"
+ y="0"
+ id="tspan15">packet </tspan></text>
+ <rect
+ x="587.84119"
+ y="279.47534"
+ width="200.65393"
+ height="46.049305"
+ stroke="#000000"
+ stroke-width="1.20888"
+ stroke-miterlimit="8"
+ fill="#ffffff"
+ id="rect19" />
+ <text
+ font-family="Calibri, Calibri_MSFontService, sans-serif"
+ font-weight="400"
+ font-size="19px"
+ id="text21"
+ x="595.42902"
+ y="308">rte_flow_async_create()</text>
+ <path
+ d="M333.5 384 450.5 350.5 567.5 384 450.5 417.5Z"
+ stroke="#000000"
+ stroke-width="1.33333"
+ stroke-miterlimit="8"
+ fill="#D9D9D9"
+ fill-rule="evenodd"
+ id="path23" />
+ <text
+ font-family="Calibri,Calibri_MSFontService,sans-serif"
+ font-weight="400"
+ font-size="19"
+ transform="translate(430.069 378)"
+ id="text27">more <tspan
+ font-size="19"
+ x="-12.94"
+ y="23"
+ id="tspan25">packets?</tspan></text>
+ <path
+ d="M689.249 325.5 689.249 338.402 450.5 338.402 450.833 338.069 450.833 343.971 450.167 343.971 450.167 337.735 688.916 337.735 688.582 338.069 688.582 325.5ZM454.5 342.638 450.5 350.638 446.5 342.638Z"
+ id="path29" />
+ <path
+ d="M450.833 45.5 450.833 56.8197 450.167 56.8197 450.167 45.5001ZM454.5 55.4864 450.5 63.4864 446.5 55.4864Z"
+ id="path31" />
+ <path
+ d="M450.833 108.5 450.833 120.375 450.167 120.375 450.167 108.5ZM454.5 119.041 450.5 127.041 446.5 119.041Z"
+ id="path33" />
+ <path
+ d="M451.833 507.5 451.833 533.61 451.167 533.61 451.167 507.5ZM455.5 532.277 451.5 540.277 447.5 532.277Z"
+ id="path35" />
+ <path
+ d="M0 0.333333-23.9993 0.333333-23.666 0-23.666 141.649-23.9993 141.316 562.966 141.316 562.633 141.649 562.633 124.315 563.299 124.315 563.299 141.983-24.3327 141.983-24.3327-0.333333 0-0.333333ZM558.966 125.649 562.966 117.649 566.966 125.649Z"
+ transform="matrix(-6.12323e-17 -1 -1 6.12323e-17 451.149 585.466)"
+ id="path37" />
+ <path
+ d="M333.5 160.5 450.5 126.5 567.5 160.5 450.5 194.5Z"
+ stroke="#000000"
+ stroke-width="1.33333"
+ stroke-miterlimit="8"
+ fill="#D9D9D9"
+ fill-rule="evenodd"
+ id="path39" />
+ <text
+ font-family="Calibri,Calibri_MSFontService,sans-serif"
+ font-weight="400"
+ font-size="19"
+ transform="translate(417.576 155)"
+ id="text43">add new <tspan
+ font-size="19"
+ x="13.2867"
+ y="23"
+ id="tspan41">rule?</tspan></text>
+ <path
+ d="M567.5 160.167 689.267 160.167 689.267 273.228 688.6 273.228 688.6 160.5 688.933 160.833 567.5 160.833ZM692.933 271.894 688.933 279.894 684.933 271.894Z"
+ id="path45" />
+ <rect
+ x="602.5"
+ y="127.5"
+ width="46"
+ height="30"
+ stroke="#000000"
+ stroke-width="0.666667"
+ stroke-miterlimit="8"
+ fill="#D9D9D9"
+ id="rect47" />
+ <text
+ font-family="Calibri,Calibri_MSFontService,sans-serif"
+ font-weight="400"
+ font-size="19"
+ transform="translate(611.34 148)"
+ id="text49">yes</text>
+ <rect
+ x="254.5"
+ y="126.5"
+ width="46"
+ height="31"
+ stroke="#000000"
+ stroke-width="0.666667"
+ stroke-miterlimit="8"
+ fill="#D9D9D9"
+ id="rect51" />
+ <text
+ font-family="Calibri,Calibri_MSFontService,sans-serif"
+ font-weight="400"
+ font-size="19"
+ transform="translate(267.182 147)"
+ id="text53">no</text>
+ <path
+ d="M0-0.333333 251.563-0.333333 251.563 298.328 8.00002 298.328 8.00002 297.662 251.229 297.662 250.896 297.995 250.896 0 251.229 0.333333 0 0.333333ZM9.33333 301.995 1.33333 297.995 9.33333 293.995Z"
+ transform="matrix(1 0 0 -1 567.5 383.495)"
+ id="path55" />
+ <path
+ d="M86.5001 213.5 203.5 180.5 320.5 213.5 203.5 246.5Z"
+ stroke="#000000"
+ stroke-width="1.33333"
+ stroke-miterlimit="8"
+ fill="#D9D9D9"
+ fill-rule="evenodd"
+ id="path57" />
+ <text
+ font-family="Calibri,Calibri_MSFontService,sans-serif"
+ font-weight="400"
+ font-size="19"
+ transform="translate(159.155 208)"
+ id="text61">destroy the <tspan
+ font-size="19"
+ x="24.0333"
+ y="23"
+ id="tspan59">rule?</tspan></text>
+ <path
+ d="M0-0.333333 131.029-0.333333 131.029 12.9778 130.363 12.9778 130.363 0 130.696 0.333333 0 0.333333ZM134.696 11.6445 130.696 19.6445 126.696 11.6445Z"
+ transform="matrix(-1 1.22465e-16 1.22465e-16 1 334.196 160.5)"
+ id="path63" />
+ <rect
+ x="92.600937"
+ y="280.48242"
+ width="210.14578"
+ height="45.035149"
+ stroke="#000000"
+ stroke-width="1.24464"
+ stroke-miterlimit="8"
+ fill="#ffffff"
+ id="rect65" />
+ <text
+ font-family="Calibri, Calibri_MSFontService, sans-serif"
+ font-weight="400"
+ font-size="19px"
+ id="text67"
+ x="100.2282"
+ y="308">rte_flow_async_destroy()</text>
+ <path
+ d="M0 0.333333-24.0001 0.333333-23.6667 0-23.6667 49.9498-24.0001 49.6165 121.748 49.6165 121.748 59.958 121.082 59.958 121.082 49.9498 121.415 50.2832-24.3334 50.2832-24.3334-0.333333 0-0.333333ZM125.415 58.6247 121.415 66.6247 117.415 58.6247Z"
+ transform="matrix(-1 0 0 1 319.915 213.5)"
+ id="path69" />
+ <path
+ d="M86.5001 213.833 62.5002 213.833 62.8335 213.5 62.8335 383.95 62.5002 383.617 327.511 383.617 327.511 384.283 62.1668 384.283 62.1668 213.167 86.5001 213.167ZM326.178 379.95 334.178 383.95 326.178 387.95Z"
+ id="path71" />
+ <path
+ d="M0-0.333333 12.8273-0.333333 12.8273 252.111 12.494 251.778 18.321 251.778 18.321 252.445 12.1607 252.445 12.1607 0 12.494 0.333333 0 0.333333ZM16.9877 248.111 24.9877 252.111 16.9877 256.111Z"
+ transform="matrix(1.83697e-16 1 1 -1.83697e-16 198.5 325.5)"
+ id="path73" />
+ <rect
+ x="357.15436"
+ y="540.45984"
+ width="183.59026"
+ height="45.08033"
+ stroke="#000000"
+ stroke-width="1.25785"
+ stroke-miterlimit="8"
+ fill="#ffffff"
+ id="rect75" />
+ <text
+ font-family="Calibri, Calibri_MSFontService, sans-serif"
+ font-weight="400"
+ font-size="19px"
+ id="text77"
+ x="393.08301"
+ y="569">rte_flow_pull()</text>
+ <rect
+ x="357.15436"
+ y="462.45984"
+ width="183.59026"
+ height="45.08033"
+ stroke="#000000"
+ stroke-width="1.25785"
+ stroke-miterlimit="8"
+ fill="#ffffff"
+ id="rect79" />
+ <text
+ font-family="Calibri, Calibri_MSFontService, sans-serif"
+ font-weight="400"
+ font-size="19px"
+ id="text81"
+ x="389.19"
+ y="491">rte_flow_push()</text>
+ <path
+ d="M450.833 417.495 451.402 455.999 450.735 456.008 450.167 417.505ZM455.048 454.611 451.167 462.669 447.049 454.729Z"
+ id="path83" />
+ <rect
+ x="0.500053"
+ y="287.5"
+ width="46"
+ height="30"
+ stroke="#000000"
+ stroke-width="0.666667"
+ stroke-miterlimit="8"
+ fill="#D9D9D9"
+ id="rect85" />
+ <text
+ font-family="Calibri,Calibri_MSFontService,sans-serif"
+ font-weight="400"
+ font-size="19"
+ transform="translate(12.8617 308)"
+ id="text87">no</text>
+ <rect
+ x="357.5"
+ y="223.5"
+ width="47"
+ height="31"
+ stroke="#000000"
+ stroke-width="0.666667"
+ stroke-miterlimit="8"
+ fill="#D9D9D9"
+ id="rect89" />
+ <text
+ font-family="Calibri,Calibri_MSFontService,sans-serif"
+ font-weight="400"
+ font-size="19"
+ transform="translate(367.001 244)"
+ id="text91">yes</text>
+ <rect
+ x="469.5"
+ y="421.5"
+ width="46"
+ height="30"
+ stroke="#000000"
+ stroke-width="0.666667"
+ stroke-miterlimit="8"
+ fill="#D9D9D9"
+ id="rect93" />
+ <text
+ font-family="Calibri,Calibri_MSFontService,sans-serif"
+ font-weight="400"
+ font-size="19"
+ transform="translate(481.872 442)"
+ id="text95">no</text>
+ <rect
+ x="832.5"
+ y="223.5"
+ width="46"
+ height="31"
+ stroke="#000000"
+ stroke-width="0.666667"
+ stroke-miterlimit="8"
+ fill="#D9D9D9"
+ id="rect97" />
+ <text
+ font-family="Calibri,Calibri_MSFontService,sans-serif"
+ font-weight="400"
+ font-size="19"
+ transform="translate(841.777 244)"
+ id="text99">yes</text>
+ </g>
+</svg>
and optimize NIC hardware configuration and memory layout in advance.
``rte_flow_configure()`` must be called before any flow rule is created,
but after an Ethernet device is configured.
+It also creates flow queues for asynchronous flow rules operations via
+queue-based API, see `Asynchronous operations`_ section.
.. code-block:: c
int
rte_flow_configure(uint16_t port_id,
const struct rte_flow_port_attr *port_attr,
+ uint16_t nb_queue,
+ const struct rte_flow_queue_attr *queue_attr[],
struct rte_flow_error *error);
Information about the number of available resources can be retrieved via
int
rte_flow_info_get(uint16_t port_id,
struct rte_flow_port_info *port_info,
+ struct rte_flow_queue_info *queue_info,
struct rte_flow_error *error);
Flow templates
&actions_templates, nb_actions_templ,
&error);
+Asynchronous operations
+-----------------------
+
+Flow rules management can be done via special lockless flow management queues.
+- Queue operations are asynchronous and not thread-safe.
+
+- Operations can thus be invoked by the app's datapath,
+ packet processing can continue while queue operations are processed by NIC.
+
+- Number of flow queues is configured at initialization stage.
+
+- Available operation types: rule creation, rule destruction,
+ indirect rule creation, indirect rule destruction, indirect rule update.
+
+- Operations may be reordered within a queue.
+
+- Operations can be postponed and pushed to NIC in batches.
+
+- Results pulling must be done on time to avoid queue overflows.
+
+- User data is returned as part of the result to identify an operation.
+
+- Flow handle is valid once the creation operation is enqueued and must be
+ destroyed even if the operation is not successful and the rule is not inserted.
+
+- Application must wait for the creation operation result before enqueueing
+ the deletion operation to make sure the creation is processed by NIC.
+
+The asynchronous flow rule insertion logic can be broken into two phases.
+
+1. Initialization stage as shown here:
+
+.. _figure_rte_flow_async_init:
+
+.. figure:: img/rte_flow_async_init.*
+
+2. Main loop as presented on a datapath application example:
+
+.. _figure_rte_flow_async_usage:
+
+.. figure:: img/rte_flow_async_usage.*
+
+Enqueue creation operation
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enqueueing a flow rule creation operation is similar to simple creation.
+
+.. code-block:: c
+
+ struct rte_flow *
+ rte_flow_async_create(uint16_t port_id,
+ uint32_t queue_id,
+ const struct rte_flow_op_attr *op_attr,
+ struct rte_flow_template_table *template_table,
+ const struct rte_flow_item pattern[],
+ uint8_t pattern_template_index,
+ const struct rte_flow_action actions[],
+ uint8_t actions_template_index,
+ void *user_data,
+ struct rte_flow_error *error);
+
+A valid handle in case of success is returned. It must be destroyed later
+by calling ``rte_flow_async_destroy()`` even if the rule is rejected by HW.
+
+Enqueue destruction operation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enqueueing a flow rule destruction operation is similar to simple destruction.
+
+.. code-block:: c
+
+ int
+ rte_flow_async_destroy(uint16_t port_id,
+ uint32_t queue_id,
+ const struct rte_flow_op_attr *op_attr,
+ struct rte_flow *flow,
+ void *user_data,
+ struct rte_flow_error *error);
+
+Push enqueued operations
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Pushing all internally stored rules from a queue to the NIC.
+
+.. code-block:: c
+
+ int
+ rte_flow_push(uint16_t port_id,
+ uint32_t queue_id,
+ struct rte_flow_error *error);
+
+There is the postpone attribute in the queue operation attributes.
+When it is set, multiple operations can be bulked together and not sent to HW
+right away to save SW/HW interactions and prioritize throughput over latency.
+The application must invoke this function to actually push all outstanding
+operations to HW in this case.
+
+Pull enqueued operations
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Pulling asynchronous operations results.
+
+The application must invoke this function in order to complete asynchronous
+flow rule operations and to receive flow rule operations statuses.
+
+.. code-block:: c
+
+ int
+ rte_flow_pull(uint16_t port_id,
+ uint32_t queue_id,
+ struct rte_flow_op_result res[],
+ uint16_t n_res,
+ struct rte_flow_error *error);
+
+Multiple outstanding operation results can be pulled simultaneously.
+User data may be provided during a flow creation/destruction in order
+to distinguish between multiple operations. User data is returned as part
+of the result to provide a method to detect which operation is completed.
+
.. _flow_isolated_mode:
Flow isolated mode
``rte_flow_template_table_destroy``, ``rte_flow_pattern_template_destroy``
and ``rte_flow_actions_template_destroy``.
+* **Added functions for asynchronous flow rules creation/destruction.**
+
+ * Added ``rte_flow_async_create`` and ``rte_flow_async_destroy`` API
+ to enqueue flow creaion/destruction operations asynchronously as well as
+ ``rte_flow_pull`` to poll and retrieve results of these operations and
+ ``rte_flow_push`` to push all the in-flight operations to the NIC.
+
* **Added rte_flow support for matching GRE optional fields.**
Added ``gre_option`` item in rte_flow to support checksum/key/sequence
int
rte_flow_info_get(uint16_t port_id,
struct rte_flow_port_info *port_info,
+ struct rte_flow_queue_info *queue_info,
struct rte_flow_error *error)
{
struct rte_eth_dev *dev = &rte_eth_devices[port_id];
}
if (likely(!!ops->info_get)) {
return flow_err(port_id,
- ops->info_get(dev, port_info, error),
+ ops->info_get(dev, port_info, queue_info, error),
error);
}
return rte_flow_error_set(error, ENOTSUP,
int
rte_flow_configure(uint16_t port_id,
const struct rte_flow_port_attr *port_attr,
+ uint16_t nb_queue,
+ const struct rte_flow_queue_attr *queue_attr[],
struct rte_flow_error *error)
{
struct rte_eth_dev *dev = &rte_eth_devices[port_id];
RTE_FLOW_LOG(ERR, "Port %"PRIu16" info is NULL.\n", port_id);
return -EINVAL;
}
+ if (queue_attr == NULL) {
+ RTE_FLOW_LOG(ERR, "Port %"PRIu16" queue info is NULL.\n", port_id);
+ return -EINVAL;
+ }
if (likely(!!ops->configure)) {
- ret = ops->configure(dev, port_attr, error);
+ ret = ops->configure(dev, port_attr, nb_queue, queue_attr, error);
if (ret == 0)
dev->data->flow_configured = 1;
return flow_err(port_id, ret, error);
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL, rte_strerror(ENOTSUP));
}
+
+struct rte_flow *
+rte_flow_async_create(uint16_t port_id,
+ uint32_t queue_id,
+ const struct rte_flow_op_attr *op_attr,
+ struct rte_flow_template_table *template_table,
+ const struct rte_flow_item pattern[],
+ uint8_t pattern_template_index,
+ const struct rte_flow_action actions[],
+ uint8_t actions_template_index,
+ void *user_data,
+ struct rte_flow_error *error)
+{
+ struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+ const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+ struct rte_flow *flow;
+
+ flow = ops->async_create(dev, queue_id,
+ op_attr, template_table,
+ pattern, pattern_template_index,
+ actions, actions_template_index,
+ user_data, error);
+ if (flow == NULL)
+ flow_err(port_id, -rte_errno, error);
+ return flow;
+}
+
+int
+rte_flow_async_destroy(uint16_t port_id,
+ uint32_t queue_id,
+ const struct rte_flow_op_attr *op_attr,
+ struct rte_flow *flow,
+ void *user_data,
+ struct rte_flow_error *error)
+{
+ struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+ const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+
+ return flow_err(port_id,
+ ops->async_destroy(dev, queue_id,
+ op_attr, flow,
+ user_data, error),
+ error);
+}
+
+int
+rte_flow_push(uint16_t port_id,
+ uint32_t queue_id,
+ struct rte_flow_error *error)
+{
+ struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+ const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+
+ return flow_err(port_id,
+ ops->push(dev, queue_id, error),
+ error);
+}
+
+int
+rte_flow_pull(uint16_t port_id,
+ uint32_t queue_id,
+ struct rte_flow_op_result res[],
+ uint16_t n_res,
+ struct rte_flow_error *error)
+{
+ struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+ const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+ int ret;
+
+ ret = ops->pull(dev, queue_id, res, n_res, error);
+ return ret ? ret : flow_err(port_id, ret, error);
+}
*
*/
struct rte_flow_port_info {
+ /**
+ * Maximum number of queues for asynchronous operations.
+ */
+ uint32_t max_nb_queues;
/**
* Maximum number of counters.
* @see RTE_FLOW_ACTION_TYPE_COUNT
uint32_t max_nb_meters;
};
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Information about flow engine asynchronous queues.
+ * The value only valid if @p port_attr.max_nb_queues is not zero.
+ *
+ */
+struct rte_flow_queue_info {
+ /**
+ * Maximum number of operations a queue can hold.
+ */
+ uint32_t max_size;
+};
+
/**
* @warning
* @b EXPERIMENTAL: this API may change without prior notice.
* @param[out] port_info
* A pointer to a structure of type *rte_flow_port_info*
* to be filled with the resources information of the port.
+ * @param[out] queue_info
+ * A pointer to a structure of type *rte_flow_queue_info*
+ * to be filled with the asynchronous queues information.
* @param[out] error
* Perform verbose error reporting if not NULL.
* PMDs initialize this structure in case of error only.
int
rte_flow_info_get(uint16_t port_id,
struct rte_flow_port_info *port_info,
+ struct rte_flow_queue_info *queue_info,
struct rte_flow_error *error);
/**
uint32_t nb_meters;
};
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Flow engine asynchronous queues settings.
+ * The value means default value picked by PMD.
+ *
+ */
+struct rte_flow_queue_attr {
+ /**
+ * Number of flow rule operations a queue can hold.
+ */
+ uint32_t size;
+};
+
/**
* @warning
* @b EXPERIMENTAL: this API may change without prior notice.
* Port identifier of Ethernet device.
* @param[in] port_attr
* Port configuration attributes.
+ * @param[in] nb_queue
+ * Number of flow queues to be configured.
+ * @param[in] queue_attr
+ * Array that holds attributes for each flow queue.
+ * Number of elements is set in @p port_attr.nb_queues.
* @param[out] error
* Perform verbose error reporting if not NULL.
* PMDs initialize this structure in case of error only.
int
rte_flow_configure(uint16_t port_id,
const struct rte_flow_port_attr *port_attr,
+ uint16_t nb_queue,
+ const struct rte_flow_queue_attr *queue_attr[],
struct rte_flow_error *error);
/**
struct rte_flow_template_table *template_table,
struct rte_flow_error *error);
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Asynchronous operation attributes.
+ */
+__extension__
+struct rte_flow_op_attr {
+ /**
+ * When set, the requested action will not be sent to the HW immediately.
+ * The application must call the rte_flow_queue_push to actually send it.
+ */
+ uint32_t postpone:1;
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Enqueue rule creation operation.
+ *
+ * @param port_id
+ * Port identifier of Ethernet device.
+ * @param queue_id
+ * Flow queue used to insert the rule.
+ * @param[in] op_attr
+ * Rule creation operation attributes.
+ * @param[in] template_table
+ * Template table to select templates from.
+ * @param[in] pattern
+ * List of pattern items to be used.
+ * The list order should match the order in the pattern template.
+ * The spec is the only relevant member of the item that is being used.
+ * @param[in] pattern_template_index
+ * Pattern template index in the table.
+ * @param[in] actions
+ * List of actions to be used.
+ * The list order should match the order in the actions template.
+ * @param[in] actions_template_index
+ * Actions template index in the table.
+ * @param[in] user_data
+ * The user data that will be returned on the completion events.
+ * @param[out] error
+ * Perform verbose error reporting if not NULL.
+ * PMDs initialize this structure in case of error only.
+ *
+ * @return
+ * Handle on success, NULL otherwise and rte_errno is set.
+ * The rule handle doesn't mean that the rule has been populated.
+ * Only completion result indicates that if there was success or failure.
+ */
+__rte_experimental
+struct rte_flow *
+rte_flow_async_create(uint16_t port_id,
+ uint32_t queue_id,
+ const struct rte_flow_op_attr *op_attr,
+ struct rte_flow_template_table *template_table,
+ const struct rte_flow_item pattern[],
+ uint8_t pattern_template_index,
+ const struct rte_flow_action actions[],
+ uint8_t actions_template_index,
+ void *user_data,
+ struct rte_flow_error *error);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Enqueue rule destruction operation.
+ *
+ * This function enqueues a destruction operation on the queue.
+ * Application should assume that after calling this function
+ * the rule handle is not valid anymore.
+ * Completion indicates the full removal of the rule from the HW.
+ *
+ * @param port_id
+ * Port identifier of Ethernet device.
+ * @param queue_id
+ * Flow queue which is used to destroy the rule.
+ * This must match the queue on which the rule was created.
+ * @param[in] op_attr
+ * Rule destruction operation attributes.
+ * @param[in] flow
+ * Flow handle to be destroyed.
+ * @param[in] user_data
+ * The user data that will be returned on the completion events.
+ * @param[out] error
+ * Perform verbose error reporting if not NULL.
+ * PMDs initialize this structure in case of error only.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+__rte_experimental
+int
+rte_flow_async_destroy(uint16_t port_id,
+ uint32_t queue_id,
+ const struct rte_flow_op_attr *op_attr,
+ struct rte_flow *flow,
+ void *user_data,
+ struct rte_flow_error *error);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Push all internally stored rules to the HW.
+ * Postponed rules are rules that were inserted with the postpone flag set.
+ * Can be used to notify the HW about batch of rules prepared by the SW to
+ * reduce the number of communications between the HW and SW.
+ *
+ * @param port_id
+ * Port identifier of Ethernet device.
+ * @param queue_id
+ * Flow queue to be pushed.
+ * @param[out] error
+ * Perform verbose error reporting if not NULL.
+ * PMDs initialize this structure in case of error only.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+__rte_experimental
+int
+rte_flow_push(uint16_t port_id,
+ uint32_t queue_id,
+ struct rte_flow_error *error);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Asynchronous operation status.
+ */
+enum rte_flow_op_status {
+ /**
+ * The operation was completed successfully.
+ */
+ RTE_FLOW_OP_SUCCESS,
+ /**
+ * The operation was not completed successfully.
+ */
+ RTE_FLOW_OP_ERROR,
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Asynchronous operation result.
+ */
+__extension__
+struct rte_flow_op_result {
+ /**
+ * Returns the status of the operation that this completion signals.
+ */
+ enum rte_flow_op_status status;
+ /**
+ * The user data that will be returned on the completion events.
+ */
+ void *user_data;
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Pull a rte flow operation.
+ * The application must invoke this function in order to complete
+ * the flow rule offloading and to retrieve the flow rule operation status.
+ *
+ * @param port_id
+ * Port identifier of Ethernet device.
+ * @param queue_id
+ * Flow queue which is used to pull the operation.
+ * @param[out] res
+ * Array of results that will be set.
+ * @param[in] n_res
+ * Maximum number of results that can be returned.
+ * This value is equal to the size of the res array.
+ * @param[out] error
+ * Perform verbose error reporting if not NULL.
+ * PMDs initialize this structure in case of error only.
+ *
+ * @return
+ * Number of results that were pulled,
+ * a negative errno value otherwise and rte_errno is set.
+ */
+__rte_experimental
+int
+rte_flow_pull(uint16_t port_id,
+ uint32_t queue_id,
+ struct rte_flow_op_result res[],
+ uint16_t n_res,
+ struct rte_flow_error *error);
+
#ifdef __cplusplus
}
#endif
int (*info_get)
(struct rte_eth_dev *dev,
struct rte_flow_port_info *port_info,
+ struct rte_flow_queue_info *queue_info,
struct rte_flow_error *err);
/** See rte_flow_configure() */
int (*configure)
(struct rte_eth_dev *dev,
const struct rte_flow_port_attr *port_attr,
+ uint16_t nb_queue,
+ const struct rte_flow_queue_attr *queue_attr[],
struct rte_flow_error *err);
/** See rte_flow_pattern_template_create() */
struct rte_flow_pattern_template *(*pattern_template_create)
(struct rte_eth_dev *dev,
struct rte_flow_template_table *template_table,
struct rte_flow_error *err);
+ /** See rte_flow_async_create() */
+ struct rte_flow *(*async_create)
+ (struct rte_eth_dev *dev,
+ uint32_t queue_id,
+ const struct rte_flow_op_attr *op_attr,
+ struct rte_flow_template_table *template_table,
+ const struct rte_flow_item pattern[],
+ uint8_t pattern_template_index,
+ const struct rte_flow_action actions[],
+ uint8_t actions_template_index,
+ void *user_data,
+ struct rte_flow_error *err);
+ /** See rte_flow_async_destroy() */
+ int (*async_destroy)
+ (struct rte_eth_dev *dev,
+ uint32_t queue_id,
+ const struct rte_flow_op_attr *op_attr,
+ struct rte_flow *flow,
+ void *user_data,
+ struct rte_flow_error *err);
+ /** See rte_flow_push() */
+ int (*push)
+ (struct rte_eth_dev *dev,
+ uint32_t queue_id,
+ struct rte_flow_error *err);
+ /** See rte_flow_pull() */
+ int (*pull)
+ (struct rte_eth_dev *dev,
+ uint32_t queue_id,
+ struct rte_flow_op_result res[],
+ uint16_t n_res,
+ struct rte_flow_error *error);
};
/**
rte_flow_actions_template_destroy;
rte_flow_template_table_create;
rte_flow_template_table_destroy;
+ rte_flow_async_create;
+ rte_flow_async_destroy;
+ rte_flow_push;
+ rte_flow_pull;
};
INTERNAL {