Commit f8228364 authored by Zaafar Ahmed's avatar Zaafar Ahmed

b_frontend_action.cc

changed pc_hash/array to percpu_hash/array

table.py
optimised/fixup table.py code based on Brenden feedback

test_percpu.py
Now tests are processor aware and doesn't use sleep
added new line at the EOF
parent 8bd6fba5
...@@ -570,9 +570,9 @@ bool BTypeVisitor::VisitVarDecl(VarDecl *Decl) { ...@@ -570,9 +570,9 @@ bool BTypeVisitor::VisitVarDecl(VarDecl *Decl) {
map_type = BPF_MAP_TYPE_HASH; map_type = BPF_MAP_TYPE_HASH;
} else if (A->getName() == "maps/array") { } else if (A->getName() == "maps/array") {
map_type = BPF_MAP_TYPE_ARRAY; map_type = BPF_MAP_TYPE_ARRAY;
} else if (A->getName() == "maps/pc_hash") { } else if (A->getName() == "maps/percpu_hash") {
map_type = BPF_MAP_TYPE_PERCPU_HASH; map_type = BPF_MAP_TYPE_PERCPU_HASH;
} else if (A->getName() == "maps/pc_array") { } else if (A->getName() == "maps/percpu_array") {
map_type = BPF_MAP_TYPE_PERCPU_ARRAY; map_type = BPF_MAP_TYPE_PERCPU_ARRAY;
} else if (A->getName() == "maps/histogram") { } else if (A->getName() == "maps/histogram") {
if (table.key_desc == "\"int\"") if (table.key_desc == "\"int\"")
......
...@@ -406,8 +406,7 @@ class PerfEventArray(ArrayBase): ...@@ -406,8 +406,7 @@ class PerfEventArray(ArrayBase):
class PerCpuHash(HashTable): class PerCpuHash(HashTable):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.reducer = kwargs["reducer"] self.reducer = kwargs.pop("reducer", None)
del kwargs["reducer"]
super(PerCpuHash, self).__init__(*args, **kwargs) super(PerCpuHash, self).__init__(*args, **kwargs)
self.sLeaf = self.Leaf self.sLeaf = self.Leaf
self.total_cpu = multiprocessing.cpu_count() self.total_cpu = multiprocessing.cpu_count()
...@@ -424,7 +423,7 @@ class PerCpuHash(HashTable): ...@@ -424,7 +423,7 @@ class PerCpuHash(HashTable):
else: else:
raise IndexError("Leaf must be aligned to 8 bytes") raise IndexError("Leaf must be aligned to 8 bytes")
def __getitem__(self, key): def getvalue(self, key):
result = super(PerCpuHash, self).__getitem__(key) result = super(PerCpuHash, self).__getitem__(key)
if self.alignment is 0: if self.alignment is 0:
ret = result ret = result
...@@ -432,31 +431,26 @@ class PerCpuHash(HashTable): ...@@ -432,31 +431,26 @@ class PerCpuHash(HashTable):
ret = (self.sLeaf * self.total_cpu)() ret = (self.sLeaf * self.total_cpu)()
for i in range(0, self.total_cpu): for i in range(0, self.total_cpu):
ret[i] = result[i] ret[i] = result[i]
if (self.reducer):
return reduce(self.reducer, ret)
else:
return ret return ret
def __getitem__(self, key):
if self.reducer:
return reduce(self.reducer, self.getvalue(key))
else:
return self.getvalue(key)
def __setitem__(self, key, leaf): def __setitem__(self, key, leaf):
super(PerCpuHash, self).__setitem__(key, leaf) super(PerCpuHash, self).__setitem__(key, leaf)
def sum(self, key): def sum(self, key):
if isinstance(self.Leaf(), ct.Structure): if isinstance(self.Leaf(), ct.Structure):
raise IndexError("Leaf must be an integer type for default sum functions") raise IndexError("Leaf must be an integer type for default sum functions")
temp = self.reducer return self.sLeaf(reduce(lambda x,y: x+y, self.getvalue(key)))
self.reducer = None
result = self.__getitem__(key)
self.reducer = temp
return self.sLeaf(reduce(lambda x,y: x+y, result))
def max(self, key): def max(self, key):
if isinstance(self.Leaf(), ct.Structure): if isinstance(self.Leaf(), ct.Structure):
raise IndexError("Leaf must be an integer type for default max functions") raise IndexError("Leaf must be an integer type for default max functions")
temp = self.reducer return self.sLeaf(max(self.getvalue(key)))
self.reducer = None
result = self.__getitem__(key)
self.reducer = temp
return self.sLeaf(max(result))
def average(self, key): def average(self, key):
result = self.sum(key) result = self.sum(key)
...@@ -465,8 +459,7 @@ class PerCpuHash(HashTable): ...@@ -465,8 +459,7 @@ class PerCpuHash(HashTable):
class PerCpuArray(ArrayBase): class PerCpuArray(ArrayBase):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.reducer = kwargs["reducer"] self.reducer = kwargs.pop("reducer", None)
del kwargs["reducer"]
super(PerCpuArray, self).__init__(*args, **kwargs) super(PerCpuArray, self).__init__(*args, **kwargs)
self.sLeaf = self.Leaf self.sLeaf = self.Leaf
self.total_cpu = multiprocessing.cpu_count() self.total_cpu = multiprocessing.cpu_count()
...@@ -483,7 +476,7 @@ class PerCpuArray(ArrayBase): ...@@ -483,7 +476,7 @@ class PerCpuArray(ArrayBase):
else: else:
raise IndexError("Leaf must be aligned to 8 bytes") raise IndexError("Leaf must be aligned to 8 bytes")
def __getitem__(self, key): def getvalue(self, key):
result = super(PerCpuArray, self).__getitem__(key) result = super(PerCpuArray, self).__getitem__(key)
if self.alignment is 0: if self.alignment is 0:
ret = result ret = result
...@@ -491,10 +484,13 @@ class PerCpuArray(ArrayBase): ...@@ -491,10 +484,13 @@ class PerCpuArray(ArrayBase):
ret = (self.sLeaf * self.total_cpu)() ret = (self.sLeaf * self.total_cpu)()
for i in range(0, self.total_cpu): for i in range(0, self.total_cpu):
ret[i] = result[i] ret[i] = result[i]
return ret
def __getitem__(self, key):
if (self.reducer): if (self.reducer):
return reduce(self.reducer, ret) return reduce(self.reducer, self.getvalue(key))
else: else:
return ret return self.getvalue(key)
def __setitem__(self, key, leaf): def __setitem__(self, key, leaf):
super(PerCpuArray, self).__setitem__(key, leaf) super(PerCpuArray, self).__setitem__(key, leaf)
...@@ -502,20 +498,12 @@ class PerCpuArray(ArrayBase): ...@@ -502,20 +498,12 @@ class PerCpuArray(ArrayBase):
def sum(self, key): def sum(self, key):
if isinstance(self.Leaf(), ct.Structure): if isinstance(self.Leaf(), ct.Structure):
raise IndexError("Leaf must be an integer type for default sum functions") raise IndexError("Leaf must be an integer type for default sum functions")
temp = self.reducer return self.sLeaf(reduce(lambda x,y: x+y, self.getvalue(key)))
self.reducer = None
result = self.__getitem__(key)
self.reducer = temp
return self.sLeaf(reduce(lambda x,y: x+y, result))
def max(self, key): def max(self, key):
if isinstance(self.Leaf(), ct.Structure): if isinstance(self.Leaf(), ct.Structure):
raise IndexError("Leaf must be an integer type for default max functions") raise IndexError("Leaf must be an integer type for default max functions")
temp = self.reducer return self.sLeaf(max(self.getvalue(key)))
self.reducer = None
result = self.__getitem__(key)
self.reducer = temp
return self.sLeaf(max(result))
def average(self, key): def average(self, key):
result = self.sum(key) result = self.sum(key)
......
...@@ -2,15 +2,16 @@ ...@@ -2,15 +2,16 @@
# Copyright (c) PLUMgrid, Inc. # Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License") # Licensed under the Apache License, Version 2.0 (the "License")
import os
import unittest
from bcc import BPF from bcc import BPF
from time import sleep import multiprocessing
import unittest as ut
class TestPercpu(ut.TestCase): class TestPercpu(unittest.TestCase):
def test_u64(self): def test_u64(self):
test_prog1 = """ test_prog1 = """
BPF_TABLE("pc_hash", u32, u64, stats, 1); BPF_TABLE("percpu_hash", u32, u64, stats, 1);
int hello_world(void *ctx) { int hello_world(void *ctx) {
u32 key=0; u32 key=0;
u64 value = 0, *val; u64 value = 0, *val;
...@@ -23,23 +24,23 @@ class TestPercpu(ut.TestCase): ...@@ -23,23 +24,23 @@ class TestPercpu(ut.TestCase):
bpf_code = BPF(text=test_prog1) bpf_code = BPF(text=test_prog1)
stats_map = bpf_code.get_table("stats") stats_map = bpf_code.get_table("stats")
bpf_code.attach_kprobe(event="sys_clone", fn_name="hello_world") bpf_code.attach_kprobe(event="sys_clone", fn_name="hello_world")
sleep(1) ini = stats_map.Leaf()
self.assertEqual(len(stats_map),1) for i in range(0, multiprocessing.cpu_count()):
for x in range(0, 10): ini[i] = 0
ini = stats_map.Leaf(0,0,0,0,0,0,0,0)
stats_map[ stats_map.Key(0) ] = ini stats_map[ stats_map.Key(0) ] = ini
sleep(1) f = os.popen("hostname")
k = stats_map[ stats_map.Key(0) ] f.close()
x = stats_map.sum(stats_map.Key(0)) self.assertEqual(len(stats_map),1)
y = stats_map.average(stats_map.Key(0)) val = stats_map[ stats_map.Key(0) ]
z = stats_map.max(stats_map.Key(0)) sum = stats_map.sum(stats_map.Key(0))
print (x.value) avg = stats_map.average(stats_map.Key(0))
self.assertGreater(x.value, 1L) max = stats_map.max(stats_map.Key(0))
self.assertGreater(z.value, 1L) self.assertGreater(sum.value, 0L)
self.assertGreater(max.value, 0L)
def test_u32(self): def test_u32(self):
test_prog1 = """ test_prog1 = """
BPF_TABLE("pc_array", u32, u32, stats, 1); BPF_TABLE("percpu_array", u32, u32, stats, 1);
int hello_world(void *ctx) { int hello_world(void *ctx) {
u32 key=0; u32 key=0;
u32 value = 0, *val; u32 value = 0, *val;
...@@ -52,18 +53,19 @@ class TestPercpu(ut.TestCase): ...@@ -52,18 +53,19 @@ class TestPercpu(ut.TestCase):
bpf_code = BPF(text=test_prog1) bpf_code = BPF(text=test_prog1)
stats_map = bpf_code.get_table("stats") stats_map = bpf_code.get_table("stats")
bpf_code.attach_kprobe(event="sys_clone", fn_name="hello_world") bpf_code.attach_kprobe(event="sys_clone", fn_name="hello_world")
sleep(1) ini = stats_map.Leaf()
self.assertEqual(len(stats_map),1) for i in range(0, multiprocessing.cpu_count()):
for x in range(0, 10): ini[i] = 0
ini = stats_map.Leaf(0,0,0,0,0,0,0,0)
stats_map[ stats_map.Key(0) ] = ini stats_map[ stats_map.Key(0) ] = ini
sleep(1) f = os.popen("hostname")
k = stats_map[ stats_map.Key(0) ] f.close()
x = stats_map.sum(stats_map.Key(0)) self.assertEqual(len(stats_map),1)
y = stats_map.average(stats_map.Key(0)) val = stats_map[ stats_map.Key(0) ]
z = stats_map.max(stats_map.Key(0)) sum = stats_map.sum(stats_map.Key(0))
self.assertGreater(x.value, 1L) avg = stats_map.average(stats_map.Key(0))
self.assertGreater(z.value, 1L) max = stats_map.max(stats_map.Key(0))
self.assertGreater(sum.value, 0L)
self.assertGreater(max.value, 0L)
def test_struct_custom_func(self): def test_struct_custom_func(self):
test_prog2 = """ test_prog2 = """
...@@ -71,7 +73,7 @@ class TestPercpu(ut.TestCase): ...@@ -71,7 +73,7 @@ class TestPercpu(ut.TestCase):
u32 c1; u32 c1;
u32 c2; u32 c2;
} counter; } counter;
BPF_TABLE("pc_hash", u32, counter, stats, 1); BPF_TABLE("percpu_hash", u32, counter, stats, 1);
int hello_world(void *ctx) { int hello_world(void *ctx) {
u32 key=0; u32 key=0;
counter value = {0,0}, *val; counter value = {0,0}, *val;
...@@ -86,20 +88,19 @@ class TestPercpu(ut.TestCase): ...@@ -86,20 +88,19 @@ class TestPercpu(ut.TestCase):
stats_map = bpf_code.get_table("stats", stats_map = bpf_code.get_table("stats",
reducer=lambda x,y: stats_map.sLeaf(x.c1+y.c1)) reducer=lambda x,y: stats_map.sLeaf(x.c1+y.c1))
bpf_code.attach_kprobe(event="sys_clone", fn_name="hello_world") bpf_code.attach_kprobe(event="sys_clone", fn_name="hello_world")
sleep(1)
self.assertEqual(len(stats_map),1)
for x in range(0, 10):
ini = stats_map.Leaf() ini = stats_map.Leaf()
for i in ini: for i in ini:
i = stats_map.sLeaf(0,0) i = stats_map.sLeaf(0,0)
stats_map[ stats_map.Key(0) ] = ini stats_map[ stats_map.Key(0) ] = ini
sleep(1) f = os.popen("hostname")
f.close()
self.assertEqual(len(stats_map),1)
k = stats_map[ stats_map.Key(0) ] k = stats_map[ stats_map.Key(0) ]
self.assertGreater(k.c1, 1L) self.assertGreater(k.c1, 0L)
def cleanup(self): def cleanup(self):
BPF.detach_kprobe("sys_clone") BPF.detach_kprobe("sys_clone")
if __name__ == "__main__": if __name__ == "__main__":
ut.main() unittest.main()
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment