-
Notifications
You must be signed in to change notification settings - Fork 384
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Memory: Swap probe_read to kernel or user version #2213
base: main
Are you sure you want to change the base?
Changes from 1 commit
31f4c79
5fed43c
7d51904
0cb1f70
e1bcd2e
4a2fe97
9c4d85e
e2f0091
1bc49cd
70a327e
179404a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,8 +30,10 @@ type argPrinter struct { | |
} | ||
|
||
const ( | ||
argReturnCopyBit = 1 << 4 | ||
argMaxDataBit = 1 << 5 | ||
argSizeArgIndexMask = int(0xf) | ||
argReturnCopyBit = 1 << 4 | ||
argMaxDataBit = 1 << 5 | ||
argUserspaceDataBit = 1 << 6 | ||
) | ||
|
||
func argReturnCopy(meta int) bool { | ||
|
@@ -41,37 +43,39 @@ func argReturnCopy(meta int) bool { | |
// meta value format: | ||
// bits | ||
// | ||
// 0-3 : SizeArgIndex | ||
// 4 : ReturnCopy | ||
// 5 : MaxData | ||
func getMetaValue(arg *v1alpha1.KProbeArg) (int, error) { | ||
var meta int | ||
// 0-3 : SizeArgIndex | ||
// 4 : ReturnCopy | ||
// 5 : MaxData | ||
// 6 : UserspaceData | ||
// 7-15 : reserved | ||
// 16-31 : size for const_buf | ||
func getMetaValue(arg *v1alpha1.KProbeArg, userspaceDataDefault bool) (int, error) { | ||
meta := 0 | ||
|
||
if arg.SizeArgIndex > 0 { | ||
if arg.SizeArgIndex > 15 { | ||
return 0, fmt.Errorf("invalid SizeArgIndex value (>15): %v", arg.SizeArgIndex) | ||
} | ||
meta = int(arg.SizeArgIndex) | ||
meta = meta | int(arg.SizeArgIndex) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: |
||
} | ||
if arg.ReturnCopy { | ||
meta = meta | argReturnCopyBit | ||
} | ||
if arg.MaxData { | ||
meta = meta | argMaxDataBit | ||
} | ||
return meta, nil | ||
} | ||
|
||
// getTracepointMetaArg is a temporary helper to find meta values while tracepoint | ||
// converts into new CRD and config formats. | ||
func getTracepointMetaValue(arg *v1alpha1.KProbeArg) int { | ||
if arg.SizeArgIndex > 0 { | ||
return int(arg.SizeArgIndex) | ||
} | ||
if arg.ReturnCopy { | ||
return -1 | ||
if arg.IsUserspaceData == nil { | ||
// If not set in policy, use the default. | ||
if userspaceDataDefault { | ||
meta = meta | argUserspaceDataBit | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: |
||
} | ||
} else { | ||
// Otherwise, use the provided value. | ||
if *arg.IsUserspaceData { | ||
meta = meta | argUserspaceDataBit | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: |
||
} | ||
} | ||
return 0 | ||
return meta, nil | ||
} | ||
|
||
func getArg(r *bytes.Reader, a argPrinter) api.MsgGenericKprobeArg { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -222,10 +222,10 @@ func (out *genericTracepointArg) getGenericTypeId() (int, error) { | |
if err != nil { | ||
return gt.GenericInvalidType, fmt.Errorf("failed to get size of array type %w", err) | ||
} | ||
if out.MetaArg == 0 { | ||
// set MetaArg equal to the number of bytes we need to copy | ||
out.MetaArg = nbytes | ||
} | ||
// set MetaArg's upper half-word equal to the number of bytes we need to copy | ||
out.MetaArg = out.MetaArg & 0xffff | ||
out.MetaArg = out.MetaArg | (nbytes << 16) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's add a check and return an error if nbytes is cannot fit in the number of bits we have. |
||
|
||
return gt.GenericConstBuffer, nil | ||
|
||
case tracepoint.SizeTy: | ||
|
@@ -238,18 +238,24 @@ func (out *genericTracepointArg) getGenericTypeId() (int, error) { | |
func buildGenericTracepointArgs(info *tracepoint.Tracepoint, specArgs []v1alpha1.KProbeArg) ([]genericTracepointArg, error) { | ||
ret := make([]genericTracepointArg, 0, len(specArgs)) | ||
nfields := uint32(len(info.Format.Fields)) | ||
syscall := info.Subsys == "syscalls" || info.Subsys == "raw_syscalls" | ||
|
||
for argIdx := range specArgs { | ||
specArg := &specArgs[argIdx] | ||
if specArg.Index >= nfields { | ||
return nil, fmt.Errorf("tracepoint %s/%s has %d fields but field %d was requested", info.Subsys, info.Event, nfields, specArg.Index) | ||
} | ||
field := info.Format.Fields[specArg.Index] | ||
// Syscall tracepoint arguments are in userspace memory. | ||
metaTp, err := getMetaValue(specArg, syscall) | ||
if err != nil { | ||
return nil, fmt.Errorf("tracepoint %s/%s getMetaValue error: %w", info.Subsys, info.Event, err) | ||
} | ||
ret = append(ret, genericTracepointArg{ | ||
CtxOffset: int(field.Offset), | ||
ArgIdx: uint32(argIdx), | ||
TpIdx: int(specArg.Index), | ||
MetaTp: getTracepointMetaValue(specArg), | ||
MetaTp: metaTp, | ||
nopTy: false, | ||
format: &field, | ||
genericTypeId: gt.GenericInvalidType, | ||
|
@@ -275,12 +281,16 @@ func buildGenericTracepointArgs(info *tracepoint.Tracepoint, specArgs []v1alpha1 | |
} | ||
field := info.Format.Fields[tpIdx] | ||
argIdx := uint32(len(ret)) | ||
metaArg := 0 | ||
if syscall { | ||
metaArg = argUserspaceDataBit | ||
} | ||
ret = append(ret, genericTracepointArg{ | ||
CtxOffset: int(field.Offset), | ||
ArgIdx: argIdx, | ||
TpIdx: tpIdx, | ||
MetaTp: 0, | ||
MetaArg: 0, | ||
MetaArg: metaArg, | ||
nopTy: true, | ||
format: &field, | ||
genericTypeId: gt.GenericInvalidType, | ||
|
@@ -290,15 +300,18 @@ func buildGenericTracepointArgs(info *tracepoint.Tracepoint, specArgs []v1alpha1 | |
|
||
for idx := 0; idx < len(ret); idx++ { | ||
meta := ret[idx].MetaTp | ||
if meta == 0 || meta == -1 { | ||
metaArgIndex := meta & argSizeArgIndexMask | ||
|
||
if metaArgIndex == 0 || (meta&argReturnCopyBit != 0) { | ||
ret[idx].MetaArg = meta | ||
continue | ||
} | ||
a, err := getOrAppendMeta(meta) | ||
a, err := getOrAppendMeta(metaArgIndex) | ||
if err != nil { | ||
return nil, err | ||
} | ||
ret[idx].MetaArg = int(a.ArgIdx) + 1 | ||
meta = meta & ^argSizeArgIndexMask | ||
ret[idx].MetaArg = meta | (int(a.ArgIdx) + 1) | ||
} | ||
return ret, nil | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, just use
argm & ARGM_USERSPACE_DATA
. No need for!= 0