Skip to content

Commit daaf51d

Browse files
committed
struct_ops: implement preLoad()
Signed-off-by: shun159 <[email protected]>
1 parent 94d1686 commit daaf51d

File tree

4 files changed

+486
-52
lines changed

4 files changed

+486
-52
lines changed

collection_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -774,16 +774,18 @@ func TestStructOpsMapSpecSimpleLoadAndAssign(t *testing.T) {
774774

775775
spec := &CollectionSpec{
776776
Maps: map[string]*MapSpec{
777+
// TODO: we should use "bpf_testmod_ops" for this case (tentative test case)
777778
"dummy_ops": {
778779
Name: "dummy_ops",
779780
Type: StructOpsMap,
780781
KeySize: 4,
781782
ValueSize: 128,
782783
MaxEntries: 1,
784+
Value: &btf.Struct{Name: "bpf_dummy_ops"},
783785
Contents: []MapKV{
784786
{Key: uint32(0), Value: structOpsMeta{
785-
userTypeName: "bpf_dummy_ops",
786-
kernTypeName: "bpf_struct_ops_bpf_dummy_ops",
787+
data: make([]byte, 128),
788+
funcs: []structOpsFunc{},
787789
}},
788790
},
789791
},

map.go

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -547,60 +547,65 @@ func (spec *MapSpec) createMap(inner *sys.FD) (_ *Map, err error) {
547547
}
548548

549549
if spec.Key != nil || spec.Value != nil {
550-
handle, keyTypeID, valueTypeID, err := btf.MarshalMapKV(spec.Key, spec.Value)
551-
if err != nil && !errors.Is(err, btf.ErrNotSupported) {
552-
return nil, fmt.Errorf("load BTF: %w", err)
553-
}
550+
if spec.Type == StructOpsMap {
551+
// we need drop meta entry here
552+
if len(spec.Contents) > 0 {
553+
spec.Contents = spec.Contents[1:]
554+
}
554555

555-
if handle != nil {
556-
defer handle.Close()
556+
var b btf.Builder
557+
h, err := btf.NewHandle(&b)
558+
if err != nil {
559+
return nil, err
560+
}
561+
defer h.Close()
557562

558-
// Use BTF k/v during map creation.
559-
attr.BtfFd = uint32(handle.FD())
560-
attr.BtfKeyTypeId = keyTypeID
561-
attr.BtfValueTypeId = valueTypeID
562-
}
563-
}
563+
s, err := btf.LoadKernelSpec()
564+
if err != nil {
565+
return nil, fmt.Errorf("open vmlinux BTF: %w", err)
566+
}
564567

565-
if spec.Type == StructOpsMap {
566-
meta, err := extractStructOpsMeta(spec.Contents)
567-
if err != nil {
568-
return nil, err
569-
}
568+
if spec.Value == nil {
569+
return nil, fmt.Errorf("Struct type is not specified as Value")
570+
}
570571

571-
// we need drop meta entry here
572-
if len(spec.Contents) > 0 {
573-
spec.Contents = spec.Contents[1:]
574-
}
572+
userStructTypeName := spec.Value.TypeName()
573+
t, err := s.AnyTypeByName(structOpsValuePrefix + userStructTypeName)
574+
if errors.Is(err, btf.ErrNotFound) {
575+
return nil, fmt.Errorf("struct_ops kernel type %q: %w", userStructTypeName, btf.ErrNotFound)
576+
}
577+
if err != nil {
578+
return nil, fmt.Errorf("lookup kernel type %q: %w", userStructTypeName, err)
579+
}
575580

576-
var b btf.Builder
577-
h, err := btf.NewHandle(&b)
578-
if err != nil {
579-
return nil, err
580-
}
581-
defer h.Close()
581+
userStructType, ok := t.(*btf.Struct)
582+
if !ok {
583+
return nil, fmt.Errorf("Value must be Struct type")
584+
}
582585

583-
s, err := btf.LoadKernelSpec()
584-
if err != nil {
585-
return nil, fmt.Errorf("open vmlinux BTF: %w", err)
586-
}
586+
btfValueTypeId, err := s.TypeID(userStructType)
587+
if err != nil {
588+
return nil, fmt.Errorf("lookup type_id: %w", err)
589+
}
587590

588-
typeSpec, err := s.AnyTypeByName(meta.kernTypeName)
589-
if errors.Is(err, btf.ErrNotFound) {
590-
return nil, fmt.Errorf("struct_ops kernel type %q: %w", meta.kernTypeName, ErrNotSupported)
591-
}
592-
if err != nil {
593-
return nil, fmt.Errorf("lookup kernel type %q: %w", meta.kernTypeName, err)
594-
}
591+
attr.ValueSize = spec.ValueSize
592+
attr.BtfVmlinuxValueTypeId = btfValueTypeId
593+
attr.BtfFd = uint32(h.FD())
594+
} else {
595+
handle, keyTypeID, valueTypeID, err := btf.MarshalMapKV(spec.Key, spec.Value)
596+
if err != nil && !errors.Is(err, btf.ErrNotSupported) {
597+
return nil, fmt.Errorf("load BTF: %w", err)
598+
}
595599

596-
btfValueTypeId, err := s.TypeID(typeSpec)
597-
if err != nil {
598-
return nil, fmt.Errorf("lookup type_id of %s: %w", typeSpec.TypeName(), err)
599-
}
600+
if handle != nil {
601+
defer handle.Close()
600602

601-
attr.ValueSize = spec.ValueSize
602-
attr.BtfVmlinuxValueTypeId = btfValueTypeId
603-
attr.BtfFd = uint32(h.FD())
603+
// Use BTF k/v during map creation.
604+
attr.BtfFd = uint32(handle.FD())
605+
attr.BtfKeyTypeId = keyTypeID
606+
attr.BtfValueTypeId = valueTypeID
607+
}
608+
}
604609
}
605610

606611
fd, err := sys.MapCreate(&attr)

0 commit comments

Comments
 (0)