diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index e439478b9eb6..bb0e495f6e33 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -3517,6 +3517,9 @@ Topics: File: cnf-understanding-low-latency - Name: Tuning nodes for low latency with the performance profile File: cnf-tuning-low-latency-nodes-with-perf-profile +- Name: Reserve CPUs for OVS-DPDK + File: cnf-reserving-cpus-for-ovs-dpdk + Distros: openshift-origin,openshift-enterprise - Name: Tuning hosted control planes for low latency with the performance profile File: cnf-tuning-low-latency-hosted-cp-nodes-with-perf-profile - Name: Provisioning real-time and low latency workloads diff --git a/modules/cnf-configuring-ovs-dpdk-cpus.adoc b/modules/cnf-configuring-ovs-dpdk-cpus.adoc new file mode 100644 index 000000000000..3aa4f55ed37c --- /dev/null +++ b/modules/cnf-configuring-ovs-dpdk-cpus.adoc @@ -0,0 +1,91 @@ +// Module included in the following assemblies: +// +// * scalability_and_performance/cnf-reserving-cpus-for-ovs-dpdk.adoc + +:_mod-docs-content-type: PROCEDURE +[id="cnf-configuring-ovs-dpdk-cpus_{context}"] += Reserve OVS-DPDK CPUs with a performance profile + +[role="_abstract"] +Create or update a `PerformanceProfile` custom resource (CR) that reserves CPUs for OVS-DPDK by setting `spec.cpu.ovsDpdk`. You can optionally add the load-balancing annotation in the same CR; see _Disable load balancing on OVS-DPDK CPUs_ for when that extra hardening is useful. + +.Prerequisites + +* You have access to the cluster as a user with the `cluster-admin` role. +* You have installed the OpenShift CLI (`oc`). +* You have identified the CPU topology and NUMA locality of the OVS-DPDK NICs on the target nodes. +* Workload partitioning is enabled, or the `kubelet` CPU Manager `strict-cpu-reservation` policy option is configured on the target nodes. +* You understand that this feature is Technology Preview. + +.Procedure + +. Optional: Inspect CPU and NUMA topology on a target node: ++ +[source,terminal] +---- +$ oc debug node/ -- chroot /host lscpu +---- + +. Plan the CPU budget so that the `reserved`, `ovsDpdk`, and `isolated` sets do not overlap, cover the online CPUs that you intend to use, and leave enough reserved capacity for platform components. On single-node {product-title}, ensure that `reserved` can host both system daemons and control plane workloads. + +. Create a `PerformanceProfile` CR that includes `spec.cpu.ovsDpdk`. ++ +.Example performance profile with OVS-DPDK CPUs +[source,yaml] +---- +apiVersion: performance.openshift.io/v2 +kind: PerformanceProfile +metadata: + name: ovs-dpdk-isolation + annotations: + performance.openshift.io/cpu-load-balancing-ovs-dpdk: "disable" +spec: + cpu: + reserved: "0-1" + ovsDpdk: "2-3" + isolated: "4-7" + nodeSelector: + node-role.kubernetes.io/worker: "" +---- ++ +where: + +* `performance.openshift.io/cpu-load-balancing-ovs-dpdk: "disable"` is optional. Set it only when you need stronger scheduler isolation for PMD threads. Omit the annotation for the base reservation. For why and when to use this annotation, see _Disable load balancing on OVS-DPDK CPUs_. +* `spec.cpu.reserved` lists CPUs for operating system and platform components. +* `spec.cpu.ovsDpdk` lists CPUs reserved for OVS-DPDK PMD threads. Do not reuse this set for unrelated DPDK applications. +* `spec.cpu.isolated` lists CPUs for `Guaranteed` application pods. ++ +[IMPORTANT] +==== +The Performance Profile Creator (PPC) tool does not currently generate the `ovsDpdk` field. Create or edit the performance profile YAML manually. +==== + +. Apply the performance profile: ++ +[source,terminal] +---- +$ oc apply -f performance-profile-ovs-dpdk.yaml +---- + +. Wait for the Machine Config Operator to apply the configuration and for the target nodes to reboot. Confirm that the relevant machine config pool has finished updating: ++ +[source,terminal] +---- +$ oc get mcp +---- ++ +The pool that matches your profile selector must show `UPDATED=True` and `UPDATING=False`. + +. Verify that the performance profile is available: ++ +[source,terminal] +---- +$ oc get performanceprofile ovs-dpdk-isolation -o yaml +---- ++ +Confirm that the `Available` condition is `True`. If the profile is `Degraded` with reason `OvsDpdkCPUsPrerequisiteNotMet`, enable workload partitioning or `strict-cpu-reservation` and reapply the profile. + +.Verification + +* Confirm that the `PerformanceProfile` status shows `Available=True`. +* Complete the checks in _Verify OVS-DPDK CPU isolation_ to confirm node-level configuration. diff --git a/modules/cnf-performance-profile-ovs-dpdk-reference.adoc b/modules/cnf-performance-profile-ovs-dpdk-reference.adoc new file mode 100644 index 000000000000..6db8edc9fed7 --- /dev/null +++ b/modules/cnf-performance-profile-ovs-dpdk-reference.adoc @@ -0,0 +1,62 @@ +// Module included in the following assemblies: +// +// * scalability_and_performance/cnf-reserving-cpus-for-ovs-dpdk.adoc + +:_mod-docs-content-type: REFERENCE +[id="cnf-performance-profile-ovs-dpdk-reference_{context}"] += OVS-DPDK performance profile fields + +[role="_abstract"] +Use the following reference when you reserve OVS-DPDK CPUs in a `PerformanceProfile` custom resource (CR). + +== API fields and annotations + +[cols="2,1,3"] +|=== +|Field or annotation |Type |Description + +|`spec.cpu.ovsDpdk` +|string (CPU set) +|Optional. CPUs reserved for OVS-DPDK PMD threads. Example value: `"2-3,8-9"`. Must not overlap `reserved`, `isolated`, or `offlined`. + +|`metadata.annotations["performance.openshift.io/cpu-load-balancing-ovs-dpdk"]` +|string +|Optional. Set to `disable` to exclude `ovsDpdk` CPUs from kernel scheduler load balancing and scheduling domains, and to set the OVS-DPDK cgroup partition to `isolated`. Omit the annotation or set `enable` to keep the default `member` partition. +|=== + +== Validation and status + +* The `ovsDpdk` CPU set must not overlap the `reserved`, `isolated`, or `offlined` CPU sets. +* Workload partitioning or `kubelet` `strict-cpu-reservation` is required. If the prerequisite is missing, the profile becomes `Degraded` with reason `OvsDpdkCPUsPrerequisiteNotMet`. +* The Node Tuning Operator adds `ovsDpdk` CPUs to `kubelet` `reservedSystemCPUs` together with `reserved`, and to TuneD `isolated_cores` together with `isolated`. + +== Day-2 changes + +* When you change `spec.cpu.ovsDpdk`, keep all CPU sets disjoint, wait for the MCO and node reboot, and re-verify isolation for the new set. CPUs that leave `ovsDpdk` must return to their new role without leftover IRQ bans or exclusive cgroup assignment. +* When you remove `spec.cpu.ovsDpdk` and the optional annotation, expect full cleanup of OVS-DPDK isolation artifacts, including `ovsdpdk.slice`. See _Update or remove OVS-DPDK CPU reservation_. + +== Example configuration + +[source,yaml] +---- +apiVersion: performance.openshift.io/v2 +kind: PerformanceProfile +metadata: + name: ovs-dpdk-isolation + annotations: + performance.openshift.io/cpu-load-balancing-ovs-dpdk: "disable" +spec: + cpu: + reserved: "0-1" + ovsDpdk: "2-3" + isolated: "4-7" + nodeSelector: + node-role.kubernetes.io/worker: "" +---- + +== Limitations + +* Technology Preview support only. +* Specific to OVS-DPDK. Not a generic dedicated-CPU pool for other DPDK applications. +* The Performance Profile Creator (PPC) tool does not generate `spec.cpu.ovsDpdk` in this release. Edit the performance profile manually. +* Full effect of `performance.openshift.io/cpu-load-balancing-ovs-dpdk: "disable"` depends on matching OVS-side support. \ No newline at end of file diff --git a/modules/cnf-understanding-ovs-dpdk-cpu-isolation.adoc b/modules/cnf-understanding-ovs-dpdk-cpu-isolation.adoc new file mode 100644 index 000000000000..489b5d967bda --- /dev/null +++ b/modules/cnf-understanding-ovs-dpdk-cpu-isolation.adoc @@ -0,0 +1,63 @@ +// Module included in the following assemblies: +// +// * scalability_and_performance/cnf-reserving-cpus-for-ovs-dpdk.adoc + +:_mod-docs-content-type: CONCEPT +[id="cnf-understanding-ovs-dpdk-cpu-isolation_{context}"] += OVS-DPDK CPU isolation + +[role="_abstract"] +OVS-DPDK poll mode driver (PMD) threads busy-poll the NIC on the host and need exclusive CPUs. Use `spec.cpu.ovsDpdk` in a `PerformanceProfile` custom resource (CR) when `reserved` and `isolated` alone cannot protect those threads from jitter. + +OVS-DPDK PMD threads run as host processes outside the pod scheduling path. Interruption from the kernel, system daemons, or other workloads can introduce jitter and reduce throughput. A performance profile already defines the following CPU sets, which do not fully cover that case: + +* `reserved`:: CPUs for operating system daemons and Kubernetes infrastructure. Without additional controls, `Burstable` and `BestEffort` pods can still run on reserved CPUs. +* `isolated`:: CPUs for `Guaranteed` application pods that the `kubelet` schedules. Isolated CPUs are not intended for host processes such as OVS-DPDK. + +Because OVS-DPDK is not a `Guaranteed` pod workload, the profile needs a third CPU set that is excluded from `kubelet` scheduling and from host interference sources. + +When you set `spec.cpu.ovsDpdk`, the Node Tuning Operator configures the following CPU roles on matching nodes: + +[cols="1,2,2"] +|=== +|CPU set |Typical use |Isolation behavior + +|`reserved` +|System daemons and platform components +|`Guaranteed` application pods are not placed on these CPUs. Workload partitioning or related policies can further protect them. + +|`ovsDpdk` +|OVS-DPDK PMD threads on the host +|Pods of any QoS class are not placed on these CPUs. The Node Tuning Operator also bans them from `irqbalance`, removes them from systemd CPU affinity, adds them to kernel isolation parameters, and places them under the OVS cgroup hierarchy. + +|`isolated` +|`Guaranteed` latency-sensitive pods +|The `kubelet` can place `Guaranteed` workloads that request exclusive CPUs on this set. +|=== + +[IMPORTANT] +==== +The `ovsDpdk` CPU set is specific to OVS-DPDK. Do not use it as a generic pool for other DPDK applications. The Node Tuning Operator places these CPUs under the existing `ovs.slice` hierarchy for `ovs-vswitchd`. +==== + +== What the Node Tuning Operator configures + +For CPUs listed in `spec.cpu.ovsDpdk`, the Node Tuning Operator applies configuration across several layers, including the following: + +* Adds the CPUs to the `kubelet` `reservedSystemCPUs` set together with `spec.cpu.reserved`. +* Adds the CPUs to TuneD `isolated_cores` together with `spec.cpu.isolated`. +* Includes the CPUs in kernel boot parameters such as `isolcpus`, `nohz_full`, and `rcu_nocbs`. +* Excludes the CPUs from `systemd.cpu_affinity`. +* Updates `IRQBALANCE_BANNED_CPUS` so that hardware IRQs are not balanced onto those CPUs. +* Creates and configures `ovsdpdk.slice` under `ovs.slice/ovs-vswitchd.service`, including exclusive CPU assignment for OVS-DPDK. + +== Prerequisites for isolation + +Workload partitioning (`CPUPartitioningAllNodes`) or the `kubelet` CPU Manager `strict-cpu-reservation` policy option is required. If neither is enabled, the Node Tuning Operator marks the performance profile as `Degraded` with the reason `OvsDpdkCPUsPrerequisiteNotMet` and does not complete the configuration. + +Without one of those prerequisites, `Burstable` and `BestEffort` pods can still be scheduled on the OVS-DPDK CPUs and break isolation. + +[NOTE] +==== +You must choose NUMA-aligned CPUs for your OVS-DPDK NICs. The Operator does not automatically assign CPUs based on NIC locality. +==== diff --git a/modules/cnf-understanding-ovs-dpdk-cpu-load-balancing.adoc b/modules/cnf-understanding-ovs-dpdk-cpu-load-balancing.adoc new file mode 100644 index 000000000000..aec4c7714d58 --- /dev/null +++ b/modules/cnf-understanding-ovs-dpdk-cpu-load-balancing.adoc @@ -0,0 +1,47 @@ +// Module included in the following assemblies: +// +// * scalability_and_performance/cnf-reserving-cpus-for-ovs-dpdk.adoc + +:_mod-docs-content-type: CONCEPT +[id="cnf-understanding-ovs-dpdk-cpu-load-balancing_{context}"] += Disable load balancing on OVS-DPDK CPUs + +[role="_abstract"] +After you reserve CPUs with `spec.cpu.ovsDpdk`, you can optionally disable kernel CPU load balancing on the same set. Use this when PMD threads still risk scheduler interference and your OVS-DPDK stack supports the matching OVS-side configuration. + +== Why disable load balancing on OVS-DPDK CPUs + +OVS-DPDK PMD threads typically pin to specific CPUs and busy-poll the NIC. Latency and packet loss increase when anything else runs on those CPUs, even briefly. + +The `spec.cpu.ovsDpdk` field applies multi-layer reservation: `kubelet` does not schedule pods on the CPUs, IRQ balancing excludes them, and the Node Tuning Operator places them under the OVS cgroup hierarchy. By default, those CPUs can still remain in the kernel scheduler load-balancing pool (`cpuset.cpus.partition=member`). + +Disabling load balancing removes the CPUs from that shared scheduler pool (`cpuset.cpus.partition=isolated`). Those CPUs are also removed from kernel scheduling domains. The exclusion is persistent for the `ovsDpdk` set: it does not depend on `Guaranteed` pod lifecycle the way the pod annotation `cpu-load-balancing.crio.io=disable` does. + +The advantage is stronger exclusive ownership for PMD threads: the kernel is less likely to migrate or run unrelated tasks on the same CPUs, which helps keep poll-loop timing stable. + +Use the annotation when you need that extra scheduler isolation and your OVS-DPDK stack supports the matching OVS-side configuration. If you only need the base reservation, set `spec.cpu.ovsDpdk` and omit the annotation. + +== Annotation behavior + +Set the following annotation on the `PerformanceProfile` custom resource (CR): + +[source,yaml] +---- +metadata: + annotations: + performance.openshift.io/cpu-load-balancing-ovs-dpdk: "disable" +---- + +Valid values are as follows: + +* `disable`:: Exclude `ovsDpdk` CPUs from the kernel scheduler load-balancing pool and from kernel scheduling domains. The Operator configures the OVS-DPDK cgroup partition as `isolated`. +* `enable`, or omit the annotation:: Keep the default behavior. The Operator configures the OVS-DPDK cgroup partition as `member`. The CPUs remain reserved for OVS-DPDK, but they are not removed from scheduling domains by this annotation. + +== Why the control is an annotation + +Full effect of disabling load balancing depends on matching support in the OVS process. The Node Tuning Operator exposes the control as an optional annotation so that base CPU reservation with `spec.cpu.ovsDpdk` stays independent of this extra hardening step. + +[NOTE] +==== +This annotation controls kernel CPU load balancing for the `ovsDpdk` CPU set. It is not the same as the pod annotation `cpu-load-balancing.crio.io`, and it is not the same as OVN-Kubernetes dynamic CPU affinity management for OVS services. +==== diff --git a/modules/cnf-updating-or-removing-ovs-dpdk-cpus.adoc b/modules/cnf-updating-or-removing-ovs-dpdk-cpus.adoc new file mode 100644 index 000000000000..337d86f70e53 --- /dev/null +++ b/modules/cnf-updating-or-removing-ovs-dpdk-cpus.adoc @@ -0,0 +1,64 @@ +// Module included in the following assemblies: +// +// * scalability_and_performance/cnf-reserving-cpus-for-ovs-dpdk.adoc + +:_mod-docs-content-type: PROCEDURE +[id="cnf-updating-or-removing-ovs-dpdk-cpus_{context}"] += Update or remove OVS-DPDK CPU reservation + +[role="_abstract"] +Change the `spec.cpu.ovsDpdk` CPU set on a day-2 retune, or remove the field when you no longer need OVS-DPDK CPU isolation. Keep CPU sets disjoint, wait for the Machine Config Operator (MCO) to apply changes, and re-verify isolation or cleanup on the node. + +.Prerequisites + +* You have access to the cluster as a user with the `cluster-admin` role. +* You have installed the OpenShift CLI (`oc`). +* A `PerformanceProfile` custom resource (CR) with `spec.cpu.ovsDpdk` is already applied. +* Workload partitioning is enabled, or the `kubelet` CPU Manager `strict-cpu-reservation` policy option is configured on the target nodes. + +.Procedure + +. To change the OVS-DPDK CPU set, edit the performance profile and replace `spec.cpu.ovsDpdk` with the new CPU list. Adjust `spec.cpu.isolated` and `spec.cpu.reserved` so that the sets do not overlap. ++ +.Example expand of the OVS-DPDK set +[source,yaml] +---- +spec: + cpu: + reserved: "0-1" + ovsDpdk: "2-3" + isolated: "4-7" +---- ++ +After the MCO applies the change and the node reboots, confirm that isolation reflects the new set: + +* Kernel parameters, `reservedSystemCPUs`, `IRQBALANCE_BANNED_CPUS`, and `ovsdpdk.slice` `cpuset.cpus.exclusive` include the new `ovsDpdk` CPUs. +* CPUs that left the `ovsDpdk` set are no longer banned or exclusively assigned for OVS-DPDK, and they match their new role in `isolated` or `reserved`. + +. To remove OVS-DPDK CPU reservation, edit the performance profile, delete `spec.cpu.ovsDpdk`, remove the `performance.openshift.io/cpu-load-balancing-ovs-dpdk` annotation if present, and move the former OVS-DPDK CPUs into `isolated` or another appropriate set so that your CPU layout remains valid. ++ +After the MCO applies the change and the node reboots, confirm cleanup: + +* `reservedSystemCPUs` no longer includes the former `ovsDpdk` CPUs (unless those CPUs were moved into `reserved`). +* `IRQBALANCE_BANNED_CPUS` and `default_smp_affinity` no longer isolate those CPUs for OVS-DPDK. +* The `ovsdpdk.slice` directory under `ovs.slice/ovs-vswitchd.service/` is gone. +* Former `ovsDpdk` CPUs behave according to their new role in the performance profile. + +. Apply the updated performance profile by running the following command ++ +[source,terminal] +---- +$ oc apply -f performance-profile-ovs-dpdk.yaml +---- + +. Run the following command to check on the progress of the machine config updating and node reboot. Wait until the `MCP` is `Updated` and the node is `Ready` before proceeding: ++ +[source,terminal] +---- +$ oc get mcp -w +---- + +.Verification + +* For an updated `ovsDpdk` set, complete the checks in _Verify OVS-DPDK CPU isolation_ against the new CPU list. +* For a removed `ovsDpdk` field, confirm that no OVS-DPDK isolation artifacts remain for the former CPU set. diff --git a/modules/cnf-verifying-ovs-dpdk-cpu-isolation.adoc b/modules/cnf-verifying-ovs-dpdk-cpu-isolation.adoc new file mode 100644 index 000000000000..9a2e7f297556 --- /dev/null +++ b/modules/cnf-verifying-ovs-dpdk-cpu-isolation.adoc @@ -0,0 +1,99 @@ +// Module included in the following assemblies: +// +// * scalability_and_performance/cnf-reserving-cpus-for-ovs-dpdk.adoc + +:_mod-docs-content-type: REFERENCE +[id="cnf-verifying-ovs-dpdk-cpu-isolation_{context}"] += Verify OVS-DPDK CPU isolation + +[role="_abstract"] +After the performance profile is applied and the node has rebooted, verify that the Node Tuning Operator configured kernel parameters, `kubelet` reserved CPUs, IRQ affinity, and the OVS-DPDK cgroup hierarchy as expected. + +.Prerequisites + +* You configured a `PerformanceProfile` CR with `spec.cpu.ovsDpdk`. +* The target node has rebooted and the machine config pool update is complete. +* You have access to the cluster as a user with the `cluster-admin` role. + +.Procedure + +. Start a debug session on a node that matches the performance profile: ++ +[source,terminal] +---- +$ oc debug node/ +---- + +. Set `/host` as the root directory for the debug shell: ++ +[source,terminal] +---- +# chroot /host +---- + +. Verify that kernel boot parameters include the OVS-DPDK CPUs: ++ +[source,terminal] +---- +# cat /proc/cmdline +---- ++ +Confirm the following: + +* `isolcpus` includes the union of `isolated` and `ovsDpdk` CPUs. +* `nohz_full` and `rcu_nocbs` include the `ovsDpdk` CPUs. +* `systemd.cpu_affinity` does not include the `ovsDpdk` CPUs. + +. Verify that `kubelet` reserved system CPUs are the union of `reserved` and `ovsDpdk`: ++ +[source,terminal] +---- +# cat /etc/kubernetes/kubelet.conf | grep reservedSystemCPUs +---- ++ +The reported set must equal `reserved` ∪ `ovsDpdk`. + +. Verify that IRQ balancing excludes the OVS-DPDK CPUs: ++ +[source,terminal] +---- +# cat /etc/sysconfig/irqbalance +---- ++ +Confirm that `IRQBALANCE_BANNED_CPUS` includes a mask that covers the `ovsDpdk` CPUs. + +. Verify that the default SMP affinity mask excludes the OVS-DPDK CPUs: ++ +[source,terminal] +---- +# cat /proc/irq/default_smp_affinity +---- + +. Verify that the OVS-DPDK configuration script is present: ++ +[source,terminal] +---- +# stat /usr/local/bin/ovs-dpdk-cpus-configure.sh +---- + +. Verify the OVS-DPDK cgroup hierarchy and CPU assignment: ++ +[source,terminal] +---- +# cat /sys/fs/cgroup/ovs.slice/ovs-vswitchd.service/ovsdpdk.slice/cgroup.type +# cat /sys/fs/cgroup/ovs.slice/ovs-vswitchd.service/ovsdpdk.slice/cpuset.cpus.exclusive +# cat /sys/fs/cgroup/ovs.slice/ovs-vswitchd.service/ovsdpdk.slice/cpuset.cpus.partition +---- ++ +Confirm the following: + +* `cgroup.type` is `threaded`. +* `cpuset.cpus.exclusive` matches the `spec.cpu.ovsDpdk` value. +* `cpuset.cpus.partition` is `isolated` when `performance.openshift.io/cpu-load-balancing-ovs-dpdk` is set to `disable`, or `member` when the annotation is omitted or set to `enable`. ++ +When the annotation is set to `disable`, the `ovsDpdk` CPUs are also excluded from kernel scheduling domains. That exclusion must remain in place for the life of the reservation and must not change when unrelated `Guaranteed` pods start or stop on the node. + +[NOTE] +==== +These checks confirm that the platform configuration for OVS-DPDK CPU isolation is in place. Measuring OVS-DPDK dataplane throughput and packet loss requires your OVS-DPDK application test environment. +==== diff --git a/scalability_and_performance/cnf-reserving-cpus-for-ovs-dpdk.adoc b/scalability_and_performance/cnf-reserving-cpus-for-ovs-dpdk.adoc new file mode 100644 index 000000000000..a1f7362a55bd --- /dev/null +++ b/scalability_and_performance/cnf-reserving-cpus-for-ovs-dpdk.adoc @@ -0,0 +1,34 @@ +:_mod-docs-content-type: ASSEMBLY +[id="cnf-reserving-cpus-for-ovs-dpdk"] += Reserve CPUs for OVS-DPDK +include::_attributes/common-attributes.adoc[] +:context: cnf-reserving-cpus-for-ovs-dpdk + +toc::[] + +[role="_abstract"] +Reserve CPUs for Open vSwitch Data Plane Development Kit (OVS-DPDK) poll mode driver (PMD) threads by using a `PerformanceProfile` custom resource (CR). The Node Tuning Operator applies multi-layer CPU isolation so that those host-side threads can run with reduced interference from the operating system and Kubernetes scheduling. + +:FeatureName: OVS-DPDK CPU reservation +include::snippets/technology-preview.adoc[] + +include::modules/cnf-understanding-ovs-dpdk-cpu-isolation.adoc[leveloffset=+1] + +include::modules/cnf-configuring-ovs-dpdk-cpus.adoc[leveloffset=+1] + +include::modules/cnf-verifying-ovs-dpdk-cpu-isolation.adoc[leveloffset=+1] + +include::modules/cnf-understanding-ovs-dpdk-cpu-load-balancing.adoc[leveloffset=+1] + +include::modules/cnf-updating-or-removing-ovs-dpdk-cpus.adoc[leveloffset=+1] + +include::modules/cnf-performance-profile-ovs-dpdk-reference.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* xref:../scalability_and_performance/cnf-tuning-low-latency-nodes-with-perf-profile.adoc#cnf-create-performance-profiles_cnf-tuning-low-latency-nodes-with-perf-profile[Creating a performance profile] + +* xref:../scalability_and_performance/enabling-workload-partitioning.adoc#enabling-workload-partitioning[Workload partitioning] + +* xref:../scalability_and_performance/using-node-tuning-operator.adoc#using-node-tuning-operator[Using the Node Tuning Operator]