-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
add direction per-field support in struct #2008
Conversation
pkg/compiler/check.go
Outdated
// into two different structs: one is in and second is out. | ||
// But that will require attaching dir to individual fields. | ||
if dir != prog.DirIn { | ||
if dir == prog.DirOut { |
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.
Don't do this is past of this change. If you sure this is the right thing to do, send a separate PR for this. I don't want to think of all potential implications of this additional change in the context of this PR.
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.
Okay, I took this change back (here).
The errors rise after doing this change seem very useful to pinpoint the locations where we can utilize per field directions.
I will think more about other implications of this change, and send another PR to further discuss as you suggested.
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.
The errors rise after doing this change seem very useful to pinpoint the locations where we can utilize per field directions.
That's interesting. If you can find more places to apply per-field attributes, that's definitely useful.
I suspect it may also be possible to find some places to apply the attribute by searching for [opt] resources.
I try to avoid push forces to make reviewing easier. I will simplify the commit history possibly by squashing later when the PR is ready to merge. |
Do we want to mark a non-resource field with direction attributes? I did for some in the newly added changes but I can see no use for it, will possibly remove. On the contrary, it might be even better to let the parent node indicate the direction for the unmarked fields since a struct can be used for different purposes on different syscalls. By the way, I can move the changes on the descriptions to another PR as it seems to complicate the reviews for the other parts. |
Direction is still useful for ints b/c output integers are not generated/mutated and input integers are generated/mutated. |
23eb051
to
f3980a9
Compare
This should be ready for review. Some changes were done on the existing descriptions to utilize per-field directions. To ease the review, I will keep doing that in a seperate PR. |
Codecov Report
|
@@ -181,6 +187,22 @@ test_struct { | |||
} | |||
``` | |||
|
|||
For more complex producer/consumer scenarios, field attributes can be utilized. |
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.
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.
pkg/compiler/check.go
Outdated
@@ -614,7 +632,12 @@ func (comp *compiler) checkTypeCtors(t *ast.Type, dir prog.Dir, isArg bool, | |||
} | |||
checked[key] = true | |||
for _, fld := range s.Fields { | |||
comp.checkTypeCtors(fld.Type, dir, false, ctors, inputs, checked) | |||
// If the field has direction, it overrides any upper levels. | |||
if fldDir, fldHasDir := comp.genFieldDir(fld); fldHasDir { |
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.
Will be less logic duplication with:
fldDir, fldHasDir := comp.genFieldDir(fld)
if !fldHasDir {
fldDir = dir
}
comp.checkTypeCtors(fld.Type, fldDir, false, ctors, inputs, checked)
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.
This is right, done.
pkg/compiler/gen.go
Outdated
Name: f.Name.Name, | ||
Type: comp.genType(f.Type, argSize), | ||
HasDirection: hasDir, | ||
Direction: dir} |
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.
Please format it as:
Direction: dir,
}
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.
sys/linux/bpf.txt
Outdated
len len[info, int32] | ||
btf fd_btf (in) | ||
len len[info, int32] (in) | ||
# TODO: What is "in" about info? |
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.
I don't fully understand what this TODO is about. Either extend it or remove.
Note: that pointers are always "in" because we need to generate the actual address, even if the pointee is out.
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.
The pointee needed some changes. This is now solved (here).
fd_type const[0, int32] | ||
probe_offset const[0, int64] | ||
probe_addr const[0, int64] | ||
pid pid (in) |
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.
Looking at this I am thinking what practice of using the direction we should establish.
There are basic primitives and capabilities, but I think we also need some practice and patterns of how to use the direction in typical situations.
We still have the direction on the pointer, in this case: ptr[inout, bpf_task_fd_query]
. If we specify directions on all fields, what direction do we use on the pointer? Or do we use the pointer direction as "default" and don't specify direction for all fields?
Also I think instead of const[0, int32] (out)
, we should say int32 (out)
because if it's out
there is no point in adding more details wrt const/0.
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.
If we specify directions on all fields, what direction do we use on the pointer? Or do we use the pointer direction as "default" and don't specify direction for all fields?
If we have a mix of directions in the struct, I just used inout
at the ptr level but this isn't necessarily intiuitive to keep as a convention. One other approach might be (which requires some changes in the core code) to omit ptr direction for structs with all fields marked with directions. This would be easier on the eye and allow us to have additional checks at the compile time for such descriptions.
If we have a mix of directions and don't reuse a struct by changing the direction of the pointer, it seemed better to push all the directions to the per-field level for better readability. If the fields of different directions are close in count, which direction do we choose for the ptr, and what could be a good reason for choosing this direction anyway?
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.
Thinking of this more I can't come up with any scheme right now. Let's proceed with your changes. I guess we need to use directions more to gather more experience.
handle drm_dumb_handle[opt] | ||
pitch const[0, int32] | ||
size const[0, int64] | ||
flags const[0, int32] |
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.
This looks unrelated. Are you use it's always 0?
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.
The flags field is currently unused and must be zeroed. Different flags to modify the behavior may be added in the future.
source: https://manpages.debian.org/testing/libdrm-dev/drm-gem.7.en.html
The handling of the flags is driver dependent. I didn't see any driver code checking the flags fields though. Thus, converting it back to int32 cause any trouble in the current situation. Let me do that.
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.
If it's not used, it's good to declare it as const[0, int32]
. Maybe clarify with a comment:
# Does not seem to be used by any driver.
flags const[0, int32]
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.
sys/linux/dev_dri.txt
Outdated
size const[0, intptr] | ||
type const[0, int32] | ||
flags const[0, int32] | ||
handle vma (in) |
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.
This structure is already passed as in
:
ioctl$DRM_IOCTL_RM_MAP(fd fd_dri, cmd const[DRM_IOCTL_RM_MAP], arg ptr[in, drm_map$DRM_IOCTL_RM_MAP])
so it seems there is something wrong here.
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.
Only the handle
field is used, which is in
.
I just wanted to use per-field direction here to indicate this and to keep it consistent with the other options for drm_map
. Removing it shouldn't make any difference since as you said the struct itself is passed as in
already.
To avoid confusions, maybe it is best to remove the per-field directions for places where the upper-level ptr direction is enough to cover overall direction.
Another question (for here and other places): if some field is unused (e.g., flags
is not used in this drm_map
, it is neither checked so any value is valid), it is preferred to make it const[0, T]
to avoid having fuzzer mutate values for this, right?
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.
I just wanted to use per-field direction here to indicate this and to keep it consistent with the other options for drm_map.
I see.
To avoid confusions, maybe it is best to remove the per-field directions for places where the upper-level ptr direction is enough to cover overall direction.
Hard to say.
Using ptr direction for the whole struct when it's all in or out is what have in 99% of cases, so I assumed that an explicit direction is used to override the ptr direction.
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.
it is preferred to make it const[0, T]
Yes.
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.
Now the per-field direction is removed and the ptr direction is used as before (and as how it is used all over the descriptions). (here)
sys/linux/dev_dri.txt
Outdated
|
||
drm_agp_buffer$DRM_IOCTL_AGP_FREE { | ||
size const[0, intptr] | ||
handle drm_agp_handle (in) |
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.
Again, this whole struct is already in
:
ioctl$DRM_IOCTL_AGP_FREE(fd fd_dri, cmd const[DRM_IOCTL_AGP_FREE], arg ptr[in, drm_agp_buffer$DRM_IOCTL_AGP_FREE])
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.
As above, this change is now taken back. (here)
sys/linux/io_uring.txt
Outdated
flags flags[io_uring_setup_flags, int32] (in) | ||
sq_thread_cpu int32[0:3] (in) | ||
sq_thread_idle int32[0:1000] (in) | ||
features const[0, int32] (out) |
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.
Does this need to be 0? If not, use int32 (out)
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.
f3980a9
to
444600d
Compare
All (the pull request submitter and all commit authors) CLAs are signed, but one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that by leaving a comment that contains only Note to project maintainer: There may be cases where the author cannot leave a comment, or the comment is not properly detected as consent. In those cases, you can manually confirm consent of the commit author(s), and set the ℹ️ Googlers: Go here for more info. |
444600d
to
30adf4a
Compare
After rebasing this with master, I was trying to drop a few unrelated commits to avoid needing to get the latest kernel and build it. |
30adf4a
to
ddf9079
Compare
opt
fields (sublist is obtained grepping[opt]
in sys/linux)dev_dri, dev_infiniband_rdma, filesystem, fs_ioctl_fscrypt, io_uring, key, perf, sys
bpf, dev_video4linux, socket_can, socket_netlink_generic_batadv, socket_netlink_generic_team, socket_netlink_generic_wireguard, socket_netlink_route, socket_netlink_sock_diag, socket_netlink_xfrm, socket, socket_vnet, socket_xdp
@dvyukov @xairy
Update #245