From ea3735f7441e9668d84c3e87cc90bdf89a23b8f5 Mon Sep 17 00:00:00 2001 From: Prabhat Aravind Date: Tue, 10 Sep 2024 18:45:56 +0000 Subject: [PATCH] [image_config]: Enable Receive Packet Steering (RPS) * This patch enables Receive Packet Steering (RPS) which helps to distribute softirq processing for CPU bound packets to all available cores. This will help prevent kernel packet drops when there are bouts of intense CPU bound packets. Ref: https://lwn.net/Articles/362339/ https://docs.kernel.org/networking/scaling.html Signed-off-by: Prabhat Aravind --- .../build_templates/sonic_debian_extension.j2 | 9 ++- files/image_config/rps/rps.py | 58 +++++++++++++++++++ files/image_config/udev/rules.d/99-rps.rules | 1 + 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100755 files/image_config/rps/rps.py create mode 100644 files/image_config/udev/rules.d/99-rps.rules diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 1845f9b8c18e..523a3ebda628 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -505,8 +505,10 @@ sudo cp $IMAGE_CONFIGS/resolv-config/update-containers $FILESYSTEM_ROOT/etc/reso sudo cp $IMAGE_CONFIGS/interfaces/init_interfaces $FILESYSTEM_ROOT/etc/network/interfaces sudo mkdir -p $FILESYSTEM_ROOT/etc/network/interfaces.d -# System'd network udev rules +# Systemd network udev rules sudo cp $IMAGE_CONFIGS/systemd/network/* $FILESYSTEM_ROOT_ETC/systemd/network/ +sudo mkdir -p $FILESYSTEM_ROOT_ETC/udev/rules.d +sudo cp $IMAGE_CONFIGS/udev/rules.d/* $FILESYSTEM_ROOT_ETC/udev/rules.d/ # copy core file uploader files sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM @@ -715,6 +717,11 @@ sudo cp $IMAGE_CONFIGS/backend_acl/backend-acl.service $FILESYSTEM_ROOT_USR_LIB_ sudo cp $IMAGE_CONFIGS/backend_acl/backend_acl.py $FILESYSTEM_ROOT/usr/bin/backend_acl.py echo "backend-acl.service" | sudo tee -a $GENERATED_SERVICE_FILE +# Copy RPS script and service file +sudo cp $IMAGE_CONFIGS/rps/rps.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM/rps.service +sudo cp $IMAGE_CONFIGS/rps/rps.py $FILESYSTEM_ROOT/usr/bin/rps.py +echo "rps.service" | sudo tee -a $GENERATED_SERVICE_FILE + # Copy SNMP configuration files sudo cp $IMAGE_CONFIGS/snmp/snmp.yml $FILESYSTEM_ROOT/etc/sonic/ diff --git a/files/image_config/rps/rps.py b/files/image_config/rps/rps.py new file mode 100755 index 000000000000..70218f941cfc --- /dev/null +++ b/files/image_config/rps/rps.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +import os +import sys + +''' +Script to enable Receive Packet Steering (RPS) +''' +def get_num_cpus(): + ncpus = 0 + cpu_count = os.cpu_count() + if cpu_count is not None: + ncpus = cpu_count + + return ncpus + + +def get_cpumask(ncpus): + return hex(pow(2, ncpus) - 1)[2:] + + +def configure_rps(): + rv = 0 + NET_DIR_PATH = "/sys/class/net" + + num_cpus = get_num_cpus() + if not num_cpus: + rv = -1 + return rv + + cpumask = get_cpumask(num_cpus) + for intf in os.listdir(NET_DIR_PATH): + if "Ethernet" in intf: + queues_path = os.path.join(NET_DIR_PATH, intf, "queues") + queues = os.listdir(queues_path) + num_rx_queues = len([q for q in queues if q.startswith("rx")]) + for q in range(num_rx_queues): + rps_cpus_path = os.path.join(queues_path, "rx-{}", "rps_cpus").format(q) + with open(rps_cpus_path, 'w') as file: + print ("Setting {} to cpu mask {}".format(rps_cpus_path, cpumask)) + file.write(cpumask) + + return rv + + +def main(): + rv = 0 + try: + rv = configure_rps() + except Exception as e: + print ("configure_rps exception occurred: {}".format(str(e))) + + sys.exit(rv) + + +if __name__ == "__main__": + main() + diff --git a/files/image_config/udev/rules.d/99-rps.rules b/files/image_config/udev/rules.d/99-rps.rules new file mode 100644 index 000000000000..3764e29af2a5 --- /dev/null +++ b/files/image_config/udev/rules.d/99-rps.rules @@ -0,0 +1 @@ +ACTION=="add", SUBSYSTEM=="net", KERNEL=="Ethernet*", RUN+="/usr/bin/rps.py"