Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bcc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
bcc
Commits
64258256
Commit
64258256
authored
Mar 29, 2016
by
Zaafar Ahmed
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
optimised the percpu support patch.
removed kernel checks.
parent
b0e40388
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
90 additions
and
100 deletions
+90
-100
src/cc/frontends/clang/b_frontend_action.cc
src/cc/frontends/clang/b_frontend_action.cc
+2
-4
src/python/bcc/__init__.py
src/python/bcc/__init__.py
+2
-2
src/python/bcc/table.py
src/python/bcc/table.py
+86
-94
No files found.
src/cc/frontends/clang/b_frontend_action.cc
View file @
64258256
...
...
@@ -571,10 +571,8 @@ bool BTypeVisitor::VisitVarDecl(VarDecl *Decl) {
}
else
if
(
A
->
getName
()
==
"maps/array"
)
{
map_type
=
BPF_MAP_TYPE_ARRAY
;
}
else
if
(
A
->
getName
()
==
"maps/pc_hash"
)
{
if
(
KERNEL_VERSION
(
major
,
minor
,
0
)
>=
KERNEL_VERSION
(
4
,
5
,
0
))
map_type
=
BPF_MAP_TYPE_PERCPU_HASH
;
}
else
if
(
A
->
getName
()
==
"maps/pc_array"
)
{
if
(
KERNEL_VERSION
(
major
,
minor
,
0
)
>=
KERNEL_VERSION
(
4
,
5
,
0
))
map_type
=
BPF_MAP_TYPE_PERCPU_ARRAY
;
}
else
if
(
A
->
getName
()
==
"maps/histogram"
)
{
if
(
table
.
key_desc
==
"
\"
int
\"
"
)
...
...
src/python/bcc/__init__.py
View file @
64258256
...
...
@@ -228,7 +228,7 @@ class BPF(object):
cls
=
type
(
str
(
desc
[
0
]),
(
base
,),
dict
(
_fields_
=
fields
))
return
cls
def
get_table
(
self
,
name
,
keytype
=
None
,
leaftype
=
None
,
func_
reducer
=
None
):
def
get_table
(
self
,
name
,
keytype
=
None
,
leaftype
=
None
,
reducer
=
None
):
map_id
=
lib
.
bpf_table_id
(
self
.
module
,
name
.
encode
(
"ascii"
))
map_fd
=
lib
.
bpf_table_fd
(
self
.
module
,
name
.
encode
(
"ascii"
))
if
map_fd
<
0
:
...
...
@@ -243,7 +243,7 @@ class BPF(object):
if
not
leaf_desc
:
raise
Exception
(
"Failed to load BPF Table %s leaf desc"
%
name
)
leaftype
=
BPF
.
_decode_table_type
(
json
.
loads
(
leaf_desc
.
decode
()))
return
Table
(
self
,
map_id
,
map_fd
,
keytype
,
leaftype
,
func_
reducer
)
return
Table
(
self
,
map_id
,
map_fd
,
keytype
,
leaftype
,
reducer
=
reducer
)
def
__getitem__
(
self
,
key
):
if
key
not
in
self
.
tables
:
...
...
src/python/bcc/table.py
View file @
64258256
...
...
@@ -74,8 +74,8 @@ def _print_log2_hist(vals, val_type):
_stars
(
val
,
val_max
,
stars
)))
def
Table
(
bpf
,
map_id
,
map_fd
,
keytype
,
leaftype
,
func_reducer
):
"""Table(bpf, map_id, map_fd, keytype, leaftype,
func_reducer
)
def
Table
(
bpf
,
map_id
,
map_fd
,
keytype
,
leaftype
,
**
kwargs
):
"""Table(bpf, map_id, map_fd, keytype, leaftype,
**kwargs
)
Create a python object out of a reference to a bpf table handle"""
...
...
@@ -90,11 +90,9 @@ def Table(bpf, map_id, map_fd, keytype, leaftype, func_reducer):
elif
ttype
==
BPF_MAP_TYPE_PERF_EVENT_ARRAY
:
t
=
PerfEventArray
(
bpf
,
map_id
,
map_fd
,
keytype
,
leaftype
)
elif
ttype
==
BPF_MAP_TYPE_PERCPU_HASH
:
t
=
PerCpuHash
(
bpf
,
map_id
,
map_fd
,
keytype
,
leaftype
,
func
=
func_reducer
)
t
=
PerCpuHash
(
bpf
,
map_id
,
map_fd
,
keytype
,
leaftype
,
**
kwargs
)
elif
ttype
==
BPF_MAP_TYPE_PERCPU_ARRAY
:
t
=
PerCpuArray
(
bpf
,
map_id
,
map_fd
,
keytype
,
leaftype
,
func
=
func_reducer
)
t
=
PerCpuArray
(
bpf
,
map_id
,
map_fd
,
keytype
,
leaftype
,
**
kwargs
)
elif
ttype
==
BPF_MAP_TYPE_STACK_TRACE
:
t
=
StackTrace
(
bpf
,
map_id
,
map_fd
,
keytype
,
leaftype
)
if
t
==
None
:
...
...
@@ -149,9 +147,9 @@ class TableBase(MutableMapping):
raise
Exception
(
"Could not scanf leaf"
)
return
leaf
def
__getitem__
(
self
,
key
,
leaf
=
None
):
def
__getitem__
(
self
,
key
):
key_p
=
ct
.
pointer
(
key
)
if
not
leaf
:
leaf
=
self
.
Leaf
()
leaf
=
self
.
Leaf
()
leaf_p
=
ct
.
pointer
(
leaf
)
res
=
lib
.
bpf_lookup_elem
(
self
.
map_fd
,
ct
.
cast
(
key_p
,
ct
.
c_void_p
),
...
...
@@ -312,9 +310,9 @@ class ArrayBase(TableBase):
def
__len__
(
self
):
return
self
.
max_entries
def
__getitem__
(
self
,
key
,
leaf
=
None
):
def
__getitem__
(
self
,
key
):
key
=
self
.
_normalize_key
(
key
)
return
super
(
ArrayBase
,
self
).
__getitem__
(
key
,
leaf
)
return
super
(
ArrayBase
,
self
).
__getitem__
(
key
)
def
__setitem__
(
self
,
key
,
leaf
):
key
=
self
.
_normalize_key
(
key
)
...
...
@@ -408,127 +406,121 @@ class PerfEventArray(ArrayBase):
class
PerCpuHash
(
HashTable
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
func_reducer
=
kwargs
[
'func'
]
del
kwargs
[
'func'
]
self
.
total_cpu
=
multiprocessing
.
cpu_count
()
self
.
alignment
=
int
(
check_output
([
"grep"
,
"-m"
,
"1"
,
"cache_alignment"
,
"/proc/cpuinfo"
]).
split
(
' '
,
2
)[
1
])
/
8
self
.
reducer
=
kwargs
[
"reducer"
]
del
kwargs
[
"reducer"
]
super
(
PerCpuHash
,
self
).
__init__
(
*
args
,
**
kwargs
)
self
.
leafsize
=
ct
.
sizeof
(
self
.
Leaf
)
if
isinstance
(
self
.
Leaf
(),
ct
.
Structure
)
and
self
.
leafsize
%
self
.
alignment
is
not
0
:
# Struct that are not aligned to cache.
raise
IndexError
(
"Struct must be aligned to %s, please add some padding"
%
self
.
alignment
)
self
.
sLeaf
=
self
.
Leaf
self
.
total_cpu
=
multiprocessing
.
cpu_count
()
# This needs to be 8 as hard coded into the linux kernel.
self
.
alignment
=
ct
.
sizeof
(
self
.
sLeaf
)
%
8
if
self
.
alignment
is
0
:
self
.
Leaf
=
self
.
sLeaf
*
self
.
total_cpu
else
:
# Currently Float, Char, un-aligned structs are not supported
if
self
.
sLeaf
==
ct
.
c_uint
:
self
.
Leaf
=
ct
.
c_uint64
*
self
.
total_cpu
elif
self
.
sLeaf
==
ct
.
c_int
:
self
.
Leaf
=
ct
.
c_int64
*
self
.
total_cpu
else
:
raise
IndexError
(
"Leaf must be aligned to 8 bytes"
)
def
__getitem__
(
self
,
key
):
if
self
.
leafsize
%
self
.
alignment
is
0
:
# Struct/DataTypes that are aligned to cache
leaf_arr
=
(
self
.
Leaf
*
self
.
total_cpu
)()
result
=
super
(
PerCpuHash
,
self
).
__getitem__
(
key
)
if
self
.
alignment
is
0
:
ret
=
result
else
:
# DataTypes that are not aligned to cache
leaf_arr
=
(
ct
.
c_uint64
*
self
.
total_cpu
)()
if
(
self
.
func_reducer
):
super
(
PerCpuHash
,
self
).
__getitem__
(
key
,
leaf_arr
)
leaf_ret
=
(
self
.
Leaf
*
self
.
total_cpu
)()
ret
=
(
self
.
sLeaf
*
self
.
total_cpu
)()
for
i
in
range
(
0
,
self
.
total_cpu
):
leaf_ret
[
i
]
=
leaf_arr
[
i
]
return
reduce
(
self
.
func_reducer
,
leaf_ret
)
ret
[
i
]
=
result
[
i
]
if
(
self
.
reducer
):
return
reduce
(
self
.
reducer
,
ret
)
else
:
super
(
PerCpuHash
,
self
).
__getitem__
(
key
,
leaf_arr
)
leaf_ret
=
(
self
.
Leaf
*
self
.
total_cpu
)()
for
i
in
range
(
0
,
self
.
total_cpu
):
leaf_ret
[
i
]
=
leaf_arr
[
i
]
return
leaf_ret
return
ret
def
__setitem__
(
self
,
key
,
leaf
):
if
self
.
leafsize
%
self
.
alignment
is
0
:
leaf_arr
=
(
self
.
Leaf
*
self
.
total_cpu
)()
for
i
in
range
(
0
,
self
.
total_cpu
):
leaf_arr
[
i
]
=
leaf
else
:
leaf_arr
=
(
ct
.
c_uint64
*
self
.
total_cpu
)()
for
i
in
range
(
0
,
self
.
total_cpu
):
leaf_arr
[
i
]
=
leaf
.
value
super
(
PerCpuHash
,
self
).
__setitem__
(
key
,
leaf_arr
)
super
(
PerCpuHash
,
self
).
__setitem__
(
key
,
leaf
)
def
sum
(
self
,
key
):
if
isinstance
(
self
.
Leaf
(),
ct
.
Structure
):
raise
IndexError
(
"Leaf must be an integer type for default sum functions"
)
leaf_arr
=
(
ct
.
c_uint64
*
self
.
total_cpu
)()
return
self
.
Leaf
(
reduce
(
lambda
x
,
y
:
x
+
y
,
super
(
PerCpuHash
,
self
).
__getitem__
(
key
,
leaf_arr
)))
temp
=
self
.
reducer
self
.
reducer
=
None
result
=
self
.
__getitem__
(
key
)
self
.
reducer
=
temp
return
self
.
sLeaf
(
reduce
(
lambda
x
,
y
:
x
+
y
,
result
))
def
max
(
self
,
key
):
if
isinstance
(
self
.
Leaf
(),
ct
.
Structure
):
raise
IndexError
(
"Leaf must be an integer type for default sum functions"
)
leaf_arr
=
(
ct
.
c_uint64
*
self
.
total_cpu
)()
return
self
.
Leaf
(
max
(
super
(
PerCpuHash
,
self
).
__getitem__
(
key
,
leaf_arr
)))
raise
IndexError
(
"Leaf must be an integer type for default max functions"
)
temp
=
self
.
reducer
self
.
reducer
=
None
result
=
self
.
__getitem__
(
key
)
self
.
reducer
=
temp
return
self
.
sLeaf
(
max
(
result
))
def
average
(
self
,
key
):
if
isinstance
(
self
.
Leaf
(),
ct
.
Structure
):
raise
IndexError
(
"Leaf must be an integer type for default sum functions"
)
leaf_arr
=
(
ct
.
c_uint64
*
self
.
total_cpu
)()
return
self
.
Leaf
(
reduce
(
lambda
x
,
y
:
x
+
y
,
super
(
PerCpuHash
,
self
).
__getitem__
(
key
,
leaf_arr
))
/
self
.
total_cpu
)
result
=
self
.
sum
(
key
)
result
.
value
/=
self
.
total_cpu
return
result
class
PerCpuArray
(
ArrayBase
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
func_reducer
=
kwargs
[
'func'
]
del
kwargs
[
'func'
]
self
.
total_cpu
=
multiprocessing
.
cpu_count
()
self
.
alignment
=
int
(
check_output
([
"grep"
,
"-m"
,
"1"
,
"cache_alignment"
,
"/proc/cpuinfo"
]).
split
(
' '
,
2
)[
1
])
/
8
self
.
reducer
=
kwargs
[
"reducer"
]
del
kwargs
[
"reducer"
]
super
(
PerCpuArray
,
self
).
__init__
(
*
args
,
**
kwargs
)
self
.
leafsize
=
ct
.
sizeof
(
self
.
Leaf
)
if
isinstance
(
self
.
Leaf
(),
ct
.
Structure
)
and
self
.
leafsize
%
self
.
alignment
is
not
0
:
# Struct that are not aligned to cache.
raise
IndexError
(
"Struct must be aligned to %s, please add some padding"
%
self
.
alignment
)
self
.
sLeaf
=
self
.
Leaf
self
.
total_cpu
=
multiprocessing
.
cpu_count
()
# This needs to be 8 as hard coded into the linux kernel.
self
.
alignment
=
ct
.
sizeof
(
self
.
sLeaf
)
%
8
if
self
.
alignment
is
0
:
self
.
Leaf
=
self
.
sLeaf
*
self
.
total_cpu
else
:
# Currently Float, Char, un-aligned structs are not supported
if
self
.
sLeaf
==
ct
.
c_uint
:
self
.
Leaf
=
ct
.
c_uint64
*
self
.
total_cpu
elif
self
.
sLeaf
==
ct
.
c_int
:
self
.
Leaf
=
ct
.
c_int64
*
self
.
total_cpu
else
:
raise
IndexError
(
"Leaf must be aligned to 8 bytes"
)
def
__getitem__
(
self
,
key
):
if
self
.
leafsize
%
self
.
alignment
is
0
:
# Struct/DataTypes that are aligned to cache
leaf_arr
=
(
self
.
Leaf
*
self
.
total_cpu
)()
result
=
super
(
PerCpuArray
,
self
).
__getitem__
(
key
)
if
self
.
alignment
is
0
:
ret
=
result
else
:
# DataTypes that are not aligned to cache
leaf_arr
=
(
ct
.
c_uint64
*
self
.
total_cpu
)()
if
(
self
.
func_reducer
):
super
(
PerCpuArray
,
self
).
__getitem__
(
key
,
leaf_arr
)
leaf_ret
=
(
self
.
Leaf
*
self
.
total_cpu
)()
ret
=
(
self
.
sLeaf
*
self
.
total_cpu
)()
for
i
in
range
(
0
,
self
.
total_cpu
):
leaf_ret
[
i
]
=
leaf_arr
[
i
]
return
reduce
(
self
.
func_reducer
,
leaf_ret
)
ret
[
i
]
=
result
[
i
]
if
(
self
.
reducer
):
return
reduce
(
self
.
reducer
,
ret
)
else
:
super
(
PerCpuArray
,
self
).
__getitem__
(
key
,
leaf_arr
)
leaf_ret
=
(
self
.
Leaf
*
self
.
total_cpu
)()
for
i
in
range
(
0
,
self
.
total_cpu
):
leaf_ret
[
i
]
=
leaf_arr
[
i
]
return
leaf_ret
return
ret
def
__setitem__
(
self
,
key
,
leaf
):
if
self
.
leafsize
%
self
.
alignment
is
0
:
leaf_arr
=
(
self
.
Leaf
*
self
.
total_cpu
)()
for
i
in
range
(
0
,
self
.
total_cpu
):
leaf_arr
[
i
]
=
leaf
else
:
leaf_arr
=
(
ct
.
c_uint64
*
self
.
total_cpu
)()
for
i
in
range
(
0
,
self
.
total_cpu
):
leaf_arr
[
i
]
=
leaf
.
value
super
(
PerCpuArray
,
self
).
__setitem__
(
key
,
leaf_arr
)
super
(
PerCpuArray
,
self
).
__setitem__
(
key
,
leaf
)
def
sum
(
self
,
key
):
if
isinstance
(
self
.
Leaf
(),
ct
.
Structure
):
raise
IndexError
(
"Leaf must be an integer type for default sum functions"
)
leaf_arr
=
(
ct
.
c_uint64
*
self
.
total_cpu
)()
return
self
.
Leaf
(
reduce
(
lambda
x
,
y
:
x
+
y
,
super
(
PerCpuArray
,
self
).
__getitem__
(
key
,
leaf_arr
)))
temp
=
self
.
reducer
self
.
reducer
=
None
result
=
self
.
__getitem__
(
key
)
self
.
reducer
=
temp
return
self
.
sLeaf
(
reduce
(
lambda
x
,
y
:
x
+
y
,
result
))
def
max
(
self
,
key
):
if
isinstance
(
self
.
Leaf
(),
ct
.
Structure
):
raise
IndexError
(
"Leaf must be an integer type for default sum functions"
)
leaf_arr
=
(
ct
.
c_uint64
*
self
.
total_cpu
)()
return
self
.
Leaf
(
max
(
super
(
PerCpuArray
,
self
).
__getitem__
(
key
,
leaf_arr
)))
raise
IndexError
(
"Leaf must be an integer type for default max functions"
)
temp
=
self
.
reducer
self
.
reducer
=
None
result
=
self
.
__getitem__
(
key
)
self
.
reducer
=
temp
return
self
.
sLeaf
(
max
(
result
))
def
average
(
self
,
key
):
if
isinstance
(
self
.
Leaf
(),
ct
.
Structure
):
raise
IndexError
(
"Leaf must be an integer type for default sum functions"
)
leaf_arr
=
(
ct
.
c_uint64
*
self
.
total_cpu
)()
return
self
.
Leaf
(
reduce
(
lambda
x
,
y
:
x
+
y
,
super
(
PerCpuArray
,
self
).
__getitem__
(
key
,
leaf_arr
))
/
self
.
total_cpu
)
result
=
self
.
sum
(
key
)
result
.
value
/=
self
.
total_cpu
return
result
class
StackTrace
(
TableBase
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment