From dd9a8ea1406e37531bd92dd08223d2813560a6f6 Mon Sep 17 00:00:00 2001 From: zhenggen-xu Date: Thu, 13 Dec 2018 10:32:39 -0800 Subject: [PATCH] Fix snmp mac polling performance issue. (#95) When SONiC system get a few hundreds MACs learnt on vlans, snmp-subagent started to see below errors: INFO supervisord: snmp-subagent socket.send() raised exception. ERR snmp-subagent [ax_interface] ERROR: [Errno 32] Broken pipe This was due to the snmpd getting timeout from subagent and closed the socket. It was root caused to be the mac polling algorithm inefficiency. The redis-server was taking average > 60% CPU cycles (peak to 85~90%) of one core. After the fix in this commit, the redis-server load is average to ~3% (peak to ~6%) of one core. --- src/sonic_ax_impl/mibs/ietf/rfc4363.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/sonic_ax_impl/mibs/ietf/rfc4363.py b/src/sonic_ax_impl/mibs/ietf/rfc4363.py index 2104f65c30b3..864fcd992c3c 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc4363.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc4363.py @@ -7,13 +7,6 @@ from ax_interface.util import mac_decimals from bisect import bisect_right -def fdb_vlanmac(db_conn, fdb): - if 'vlan' in fdb: - vlan_id = fdb["vlan"] - elif 'bvid' in fdb: - vlan_id = port_util.get_vlan_id_from_bvid(db_conn, fdb["bvid"]) - return (int(vlan_id),) + mac_decimals(fdb["mac"]) - class FdbUpdater(MIBUpdater): def __init__(self): super().__init__() @@ -27,7 +20,19 @@ def __init__(self): self.vlanmac_ifindex_map = {} self.vlanmac_ifindex_list = [] self.if_bpid_map = {} - + self.bvid_vlan_map = {} + + def fdb_vlanmac(self, fdb): + if 'vlan' in fdb: + vlan_id = fdb["vlan"] + elif 'bvid' in fdb: + if fdb["bvid"] in self.bvid_vlan_map: + vlan_id = self.bvid_vlan_map[fdb["bvid"]] + else: + vlan_id = port_util.get_vlan_id_from_bvid(self.db_conn, fdb["bvid"]) + self.bvid_vlan_map[fdb["bvid"]] = vlan_id + return (int(vlan_id),) + mac_decimals(fdb["mac"]) + def reinit_data(self): """ Subclass update interface information @@ -39,7 +44,7 @@ def reinit_data(self): self.oid_name_map = mibs.init_sync_d_interface_tables(self.db_conn) self.if_bpid_map = port_util.get_bridge_port_map(self.db_conn) - + self.bvid_vlan_map.clear() def update_data(self): """ @@ -69,7 +74,7 @@ def update_data(self): continue port_id = self.if_bpid_map[bridge_port_id] - vlanmac = fdb_vlanmac(self.db_conn, fdb) + vlanmac = self.fdb_vlanmac(fdb) self.vlanmac_ifindex_map[vlanmac] = mibs.get_index(self.if_id_map[port_id]) self.vlanmac_ifindex_list.append(vlanmac) self.vlanmac_ifindex_list.sort()