mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
Generate parent nodes to spread ShapedDevices.csv entries across CPU cores if ParentNode not defined
This commit is contained in:
parent
7d3212d28a
commit
e60f3f4ffd
@ -13,7 +13,7 @@ import warnings
|
||||
|
||||
from ispConfig import fqOrCAKE, upstreamBandwidthCapacityDownloadMbps, upstreamBandwidthCapacityUploadMbps, \
|
||||
defaultClassCapacityDownloadMbps, defaultClassCapacityUploadMbps, interfaceA, interfaceB, enableActualShellCommands, \
|
||||
runShellCommandsAsSudo
|
||||
runShellCommandsAsSudo, generatedPNDownloadMbps, generatedPNUploadMbps
|
||||
|
||||
|
||||
def shell(command):
|
||||
@ -170,9 +170,10 @@ def refreshShapers():
|
||||
if circuitID in knownCircuitIDs:
|
||||
for circuit in subscriberCircuits:
|
||||
if circuit['circuitID'] == circuitID:
|
||||
if circuit['ParentNode'] != ParentNode:
|
||||
errorMessageString = "Device " + deviceName + " with deviceID " + deviceID + " had different Parent Node from other devices of circuit ID #" + circuitID
|
||||
raise ValueError(errorMessageString)
|
||||
if circuit['ParentNode'] != "none":
|
||||
if circuit['ParentNode'] != ParentNode:
|
||||
errorMessageString = "Device " + deviceName + " with deviceID " + deviceID + " had different Parent Node from other devices of circuit ID #" + circuitID
|
||||
raise ValueError(errorMessageString)
|
||||
if ((circuit['downloadMin'] != round(int(downloadMin)*tcpOverheadFactor))
|
||||
or (circuit['uploadMin'] != round(int(uploadMin)*tcpOverheadFactor))
|
||||
or (circuit['downloadMax'] != round(int(downloadMax)*tcpOverheadFactor))
|
||||
@ -255,6 +256,36 @@ def refreshShapers():
|
||||
with open('network.json', 'r') as j:
|
||||
network = json.loads(j.read())
|
||||
|
||||
# Find queues and CPU cores available. Use min between those two as queuesAvailable
|
||||
queuesAvailable = 0
|
||||
path = '/sys/class/net/' + interfaceA + '/queues/'
|
||||
directory_contents = os.listdir(path)
|
||||
for item in directory_contents:
|
||||
if "tx-" in str(item):
|
||||
queuesAvailable += 1
|
||||
|
||||
print("NIC queues:\t" + str(queuesAvailable))
|
||||
cpuCount = multiprocessing.cpu_count()
|
||||
print("CPU cores:\t" + str(cpuCount))
|
||||
queuesAvailable = min(queuesAvailable,cpuCount)
|
||||
|
||||
#Generate Parent Nodes. Spread ShapedDevices.csv which lack defined ParentNode across these (balance across CPUs)
|
||||
generatedPNs = []
|
||||
for x in range(queuesAvailable):
|
||||
genPNname = "Generated_PN_" + str(x+1)
|
||||
network[genPNname] = {
|
||||
"downloadBandwidthMbps":generatedPNDownloadMbps,
|
||||
"uploadBandwidthMbps":generatedPNUploadMbps
|
||||
}
|
||||
generatedPNs.append(genPNname)
|
||||
genPNcounter = 0
|
||||
for circuit in subscriberCircuits:
|
||||
if circuit['ParentNode'] == 'none':
|
||||
circuit['ParentNode'] = generatedPNs[genPNcounter]
|
||||
genPNcounter += 1
|
||||
if genPNcounter >= queuesAvailable:
|
||||
genPNcounter = 0
|
||||
|
||||
#Find the bandwidth minimums for each node by combining mimimums of devices lower in that node's heirarchy
|
||||
def findBandwidthMins(data, depth):
|
||||
tabs = ' ' * depth
|
||||
@ -275,20 +306,7 @@ def refreshShapers():
|
||||
|
||||
minDownload, minUpload = findBandwidthMins(network, 0)
|
||||
|
||||
# Find queues and CPU cores available. Use min between those two as queuesAvailable
|
||||
queuesAvailable = 0
|
||||
path = '/sys/class/net/' + interfaceA + '/queues/'
|
||||
directory_contents = os.listdir(path)
|
||||
for item in directory_contents:
|
||||
if "tx-" in str(item):
|
||||
queuesAvailable += 1
|
||||
|
||||
print("NIC queues:\t" + str(queuesAvailable))
|
||||
cpuCount = multiprocessing.cpu_count()
|
||||
print("CPU cores:\t" + str(cpuCount))
|
||||
queuesAvailable = min(queuesAvailable,cpuCount)
|
||||
|
||||
#Parse network.json. For each tier, create corresponding HTB and leaf classes. Prepare for execution later
|
||||
#Parse network structure. For each tier, create corresponding HTB and leaf classes. Prepare for execution later
|
||||
linuxTCcommands = []
|
||||
xdpCPUmapCommands = []
|
||||
devicesShaped = []
|
||||
@ -296,7 +314,7 @@ def refreshShapers():
|
||||
def traverseNetwork(data, depth, major, minor, queue, parentClassID, parentMaxDL, parentMaxUL):
|
||||
tabs = ' ' * depth
|
||||
for elem in data:
|
||||
print(tabs + elem)
|
||||
#print(tabs + elem)
|
||||
elemClassID = hex(major) + ':' + hex(minor)
|
||||
#Cap based on this node's max bandwidth, or parent node's max bandwidth, whichever is lower
|
||||
elemDownloadMax = min(data[elem]['downloadBandwidthMbps'],parentMaxDL)
|
||||
@ -348,7 +366,7 @@ def refreshShapers():
|
||||
xdpCPUmapCommands.append('./xdp-cpumap-tc/src/xdp_iphash_to_cpu_cmdline --add --ip ' + str(ipv4) + ' --cpu ' + hex(queue-1) + ' --classid ' + flowIDstring)
|
||||
if device['deviceName'] not in devicesShaped:
|
||||
devicesShaped.append(device['deviceName'])
|
||||
print()
|
||||
#print()
|
||||
minor += 1
|
||||
#Recursive call this function for children nodes attached to this node
|
||||
if 'children' in data[elem]:
|
||||
@ -403,11 +421,12 @@ def refreshShapers():
|
||||
# Default class can use up to defaultClassCapacityUploadMbps when that bandwidth isn't used by known hosts.
|
||||
shell('tc class add dev ' + thisInterface + ' parent ' + hex(queue+1) + ':1 classid ' + hex(queue+1) + ':2 htb rate ' + str(defaultClassCapacityUploadMbps/4) + 'mbit ceil ' + str(defaultClassCapacityUploadMbps) + 'mbit prio 5')
|
||||
shell('tc qdisc add dev ' + thisInterface + ' parent ' + hex(queue+1) + ':2 ' + fqOrCAKE)
|
||||
print()
|
||||
#print()
|
||||
|
||||
#Execute actual Linux TC and XDP-CPUMAP-TC filter commands
|
||||
with open('linux_tc.txt', 'w') as f:
|
||||
for line in linuxTCcommands:
|
||||
print(line)
|
||||
f.write(f"{line}\n")
|
||||
|
||||
shell("/sbin/tc -f -b linux_tc.txt")
|
||||
|
Loading…
Reference in New Issue
Block a user