Skip to content

Use zero-cost method to construct Errors - #335

Closed
TheSven73 wants to merge 3 commits into
Rust-for-Linux:rustfrom
TheSven73:rust-for-linux-error-invariant
Closed

Use zero-cost method to construct Errors#335
TheSven73 wants to merge 3 commits into
Rust-for-Linux:rustfrom
TheSven73:rust-for-linux-error-invariant

Conversation

@TheSven73

Copy link
Copy Markdown
Collaborator

When constructing an Error, avoid the runtime check which verifies the errno invariant, by:

  • trusting that negative return values from certain kernel C functions always satisfy the invariant, and
  • using pre-constructed constErrors if an error return is needed in Rust code.

For the time being, no explicit Error invariant runtime checks are used or required anywhere, so we can eliminate the function which carries out the check.

@ksquirrel

This comment has been minimized.

@TheSven73
TheSven73force-pushed the rust-for-linux-error-invariant branch from 4f424b2 to c23f634CompareJune 3, 2021 16:39
@ksquirrel

This comment has been minimized.

@TheSven73
TheSven73force-pushed the rust-for-linux-error-invariant branch from c23f634 to 2f2c5efCompareJune 3, 2021 16:46
@ksquirrel

This comment has been minimized.

@ojeda

ojeda commented Jun 3, 2021

Copy link
Copy Markdown
Member

The first two commits have the same title and mostly the same message, which is a bit confusing: perhaps: "rust: introduce zero-cost from_kernel_int_result_uint" or something like that to see the difference between them?

(I noted to add a @ksquirrel check for this)

@ojeda

ojeda commented Jun 3, 2021

Copy link
Copy Markdown
Member

The third commit is related to #324 (comment) and #283 -- so not sure what to do. Also, I think @foxhlchen was going to send a PR to discuss moving it to return Result<Error> (i.e. Result<Error, Error>).

I think this is a good candidate for discussion this Saturday (and likely also in a technical meeting next week or so).

@TheSven73

Copy link
Copy Markdown
CollaboratorAuthor

so not sure what to do. Also, I think @foxhlchen was going to send a PR to discuss moving it to return Result<Error> (i.e. Result<Error, Error>).

Perhaps we can bypass this whole discussion by not removing the runtime check function? That will of course generate a warning, as the function is now unused. I can add a dead-code marker. How does that sound?

Comment threadrust/kernel/error.rs Outdated
Comment on lines +268 to +297
match retval {
success if success >= 0 => Ok(()),
// SAFETY: Safety above and match arm guarantee that `errno` is a valid negative `errno`.
errno => Err(Error::from_kernel_errno_unchecked(errno)),
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

match statements are great, but I think for cases like this where it reduces to a single condition it looks easier to read:

Suggested change
match retval {
success if success >= 0 => Ok(()),
// SAFETY: Safety above and match arm guarantee that `errno` is a valid negative `errno`.
errno => Err(Error::from_kernel_errno_unchecked(errno)),
}
if retval < 0{
// SAFETY: Safety above and match arm guarantee that `errno` is a valid negative `errno`.
returnErr(Error::from_kernel_errno_unchecked(errno));
}
Ok(())

Comment threadrust/kernel/error.rs Outdated
pub(crate) unsafe fn from_kernel_int_result(retval: c_types::c_int) -> Result {
match retval {
success if success >= 0 => Ok(()),
// SAFETY: Safety above and match arm guarantee that `errno` is a valid negative `errno`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the comment, perhaps:

Suggested change
// SAFETY: Safety above and match arm guarantee that `errno` is a valid negative `errno`.
// SAFETY: This condition together with the function precondition guarantee
// `errno` is a valid negative `errno`.

Comment threadrust/kernel/error.rs Outdated
Comment threadrust/kernel/error.rs
@ojeda

ojeda commented Jun 3, 2021

Copy link
Copy Markdown
Member

Perhaps we can bypass this whole discussion by not removing the runtime check function? That will of course generate a warning, as the function is now unused. I can add a dead-code marker. How does that sound?

Sure, feel free to split the PR.

Sven Van Asbroeck added 3 commits June 3, 2021 20:04
In a previous PR, the type invariant for `Error` is enforced using
a runtime check. This is non-zero cost.
However we may decide to trust the return value of certain kernel C
functions. In such cases, no runtime check is required to enforce the
type invariant. So we can return to zero-cost.
This patch removes invariant checks from kernel C functions that
return 0 on success, or a non-zero errno on failure.
Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
In a previous PR, the type invariant for `Error` is enforced using
a runtime check. This is non-zero cost.
However we may decide to trust the return value of certain kernel C
functions. In such cases, no runtime check is required to enforce the
type invariant. So we can return to zero-cost.
This patch removes invariant checks from kernel C functions that
return a positive value on success, or a non-zero errno on failure.
Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
It turns out that we don't need an `Error` constructor that
checks the `errno` invariant at runtime. This is because we
trust return values originating from kernel C. And any return
values originating from Rust code can be constucted using
`Error::` constants, which also do not need a runtime check:
```rust
return Err(Error::EBUSY);
```
However, there is still ongoing discussion about the merits and
purpose of this function. To facilitate this discussion, keep the
function for the time being, and remove the "dead code" warning.
Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
@TheSven73
TheSven73force-pushed the rust-for-linux-error-invariant branch from 2f2c5ef to ec1faf3CompareJune 4, 2021 00:06
@ksquirrel

Copy link
Copy Markdown
Member

Review of ec1faf3ac524:

@TheSven73

Copy link
Copy Markdown
CollaboratorAuthor

v1 -> v2:

ojeda:

  • fix commit titles
  • keep function and remove dead code warning instead of removing function
  • use if instead of match to clarify control flow
  • clarify function docs
  • add unsafe blocks inside unsafe functions
  • clarify various comments

@foxhlchen

Copy link
Copy Markdown

The third commit is related to #324 (comment) and #283 -- so not sure what to do. Also, I think @foxhlchen was going to send a PR to discuss moving it to return Result<Error> (i.e. Result<Error, Error>).

I think this is a good candidate for discussion this Saturday (and likely also in a technical meeting next week or so).

You have a call on Saturday?? Can you send me an invitation??

@ojeda

ojeda commented Jun 4, 2021

Copy link
Copy Markdown
Member

Of course! We have informal calls every first Saturday of a month. I will send a remainder to the mailing list.

@foxhlchen

Copy link
Copy Markdown

Of course! We have informal calls every first Saturday of a month. I will send a remainder to the mailing list.

Great, Thank you!

@TheSven73

Copy link
Copy Markdown
CollaboratorAuthor

@ojeda How can I assign a "Prio: low" label to this PR?

@TheSven73
TheSven73 deleted the rust-for-linux-error-invariant branch July 8, 2021 13:01
metaspace pushed a commit to metaspace/linux that referenced this pull request Nov 12, 2025
[ Upstream commit 6fc6167 ]
Current code will validate current plane and previous plane to
confirm they can share a SSPP with multi-rect mode. The SSPP
is already allocated for previous plane, while current plane
is not associated with any SSPP yet. Null pointer is referenced
when validating the SSPP of current plane. Skip SSPP validation
for current plane.
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000020
Mem abort info:
ESR = 0x0000000096000004
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x04: level 0 translation fault
Data abort info:
ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
CM = 0, WnR = 0, TnD = 0, TagAccess = 0
GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
user pgtable: 4k pages, 48-bit VAs, pgdp=0000000888ac3000
[0000000000000020] pgd=0000000000000000, p4d=0000000000000000
Internal error: Oops: 0000000096000004 [#1] SMP
Modules linked in:
CPU: 4 UID: 0 PID: 1891 Comm: modetest Tainted: G S 6.15.0-rc2-g3ee3f6e1202e Rust-for-Linux#335 PREEMPT
Tainted: [S]=CPU_OUT_OF_SPEC
Hardware name: SM8650 EV1 rev1 4slam 2et (DT)
pstate: 63400009 (nZCv daif +PAN -UAO +TCO +DIT -SSBS BTYPE=--)
pc : dpu_plane_is_multirect_capable+0x68/0x90
lr : dpu_assign_plane_resources+0x288/0x410
sp : ffff800093dcb770
x29: ffff800093dcb770 x28: 0000000000002000 x27: ffff000817c6c000
x26: ffff000806b46368 x25: ffff0008013f6080 x24: ffff00080cbf4800
x23: ffff000810842680 x22: ffff0008013f1080 x21: ffff00080cc86080
x20: ffff000806b463b0 x19: ffff00080cbf5a00 x18: 00000000ffffffff
x17: 707a5f657a696c61 x16: 0000000000000003 x15: 0000000000002200
x14: 00000000ffffffff x13: 00aaaaaa00aaaaaa x12: 0000000000000000
x11: ffff000817c6e2b8 x10: 0000000000000000 x9 : ffff80008106a950
x8 : ffff00080cbf48f4 x7 : 0000000000000000 x6 : 0000000000000000
x5 : 0000000000000000 x4 : 0000000000000438 x3 : 0000000000000438
x2 : ffff800082e245e0 x1 : 0000000000000008 x0 : 0000000000000000
Call trace:
dpu_plane_is_multirect_capable+0x68/0x90 (P)
dpu_crtc_atomic_check+0x5bc/0x650
drm_atomic_helper_check_planes+0x13c/0x220
drm_atomic_helper_check+0x58/0xb8
msm_atomic_check+0xd8/0xf0
drm_atomic_check_only+0x4a8/0x968
drm_atomic_commit+0x50/0xd8
drm_atomic_helper_update_plane+0x140/0x188
__setplane_atomic+0xfc/0x148
drm_mode_setplane+0x164/0x378
drm_ioctl_kernel+0xc0/0x140
drm_ioctl+0x20c/0x500
__arm64_sys_ioctl+0xbc/0xf8
invoke_syscall+0x50/0x120
el0_svc_common.constprop.0+0x48/0xf8
do_el0_svc+0x28/0x40
el0_svc+0x30/0xd0
el0t_64_sync_handler+0x144/0x168
el0t_64_sync+0x198/0x1a0
Code: b9402021 370fffc1 f9401441 3707ff81 (f94010a1)
---[ end trace 0000000000000000 ]---
Fixes: 3ed12a3 ("drm/msm/dpu: allow sharing SSPP between planes")
Signed-off-by: Jun Nie <jun.nie@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/669224/
Link: https://lore.kernel.org/r/20250819-v6-16-rc2-quad-pipe-upstream-v15-1-2c7a85089db8@linaro.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@TheSven73@ksquirrel@ojeda@foxhlchen