Skip to content
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

Implement more ergonomic CPU-local storage #1012

Merged
merged 13 commits into from
Jul 27, 2023

Conversation

tsoutsman
Copy link
Member

@tsoutsman tsoutsman commented Jul 21, 2023

MVP of a cpu_local attribute.

Limitations that will be addressed in a future PR:

  • Only integer types supported
  • CLS section offsets must be manually specified

Draft PR because the macro needs to be implemented for aarch64.

Signed-off-by: Klimenty Tsoutsman <[email protected]>
Signed-off-by: Klimenty Tsoutsman <[email protected]>
@tsoutsman tsoutsman marked this pull request as draft July 21, 2023 05:53
Signed-off-by: Klimenty Tsoutsman <[email protected]>
Signed-off-by: Klimenty Tsoutsman <[email protected]>
@tsoutsman tsoutsman marked this pull request as ready for review July 23, 2023 10:43
@tsoutsman tsoutsman requested a review from kevinaboos July 23, 2023 22:21
Signed-off-by: Klimenty Tsoutsman <[email protected]>
Signed-off-by: Klimenty Tsoutsman <[email protected]>
Copy link
Member

@kevinaboos kevinaboos left a comment

Choose a reason for hiding this comment

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

Generally looks good, i left a few questions

Cargo.toml Outdated Show resolved Hide resolved
kernel/cls/cls_macros/src/lib.rs Outdated Show resolved Hide resolved
kernel/cls/cls_macros/src/lib.rs Show resolved Hide resolved
kernel/cls/cls_macros/src/lib.rs Outdated Show resolved Hide resolved
kernel/cls/cls_macros/src/lib.rs Outdated Show resolved Hide resolved
kernel/cls/cls_macros/src/lib.rs Outdated Show resolved Hide resolved
Signed-off-by: Klimenty Tsoutsman <[email protected]>
@tsoutsman tsoutsman requested a review from kevinaboos July 26, 2023 23:32
Copy link
Member

@kevinaboos kevinaboos left a comment

Choose a reason for hiding this comment

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

Left one major question about the atomicity of increment+load and load+decrement.

Also, can you add (or restore) typical things like crate-level docs, authorship/description fields in the toml, etc? thanks.

Everything else looks good.

kernel/preemption/src/lib.rs Show resolved Hide resolved
kernel/preemption/src/lib.rs Outdated Show resolved Hide resolved
kernel/preemption/src/lib.rs Outdated Show resolved Hide resolved
Signed-off-by: Klimenty Tsoutsman <[email protected]>
Signed-off-by: Klimenty Tsoutsman <[email protected]>
Signed-off-by: Klimenty Tsoutsman <[email protected]>
Copy link
Member

@kevinaboos kevinaboos left a comment

Choose a reason for hiding this comment

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

left one comment as a suggestion to try out in #1015

use crate::cpu_local::{CpuLocal, CpuLocalField, PerCpuField};
use no_drop::NoDrop;
#![no_std]
#![feature(negative_impls, thread_local)]
Copy link
Member

Choose a reason for hiding this comment

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

note for next PR: i think we can avoid the need for every user of cls_macro to declare #![feature(thread_local)] by using the #[allow_internal_unstable(...)] attribute in the cls_macro crate, either on the proc macro definition or as a crate-level attribute. I recall using that attribute in the thread_local_macro crate, based on std's thread_local!() macro trickery.

This isn't a blocker to merging/approving this PR, but we should try to improve that rough edge, especially once we have dozens of CPU local vars everywhere.

Copy link
Member

Choose a reason for hiding this comment

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

(i just realized this is intended for regular macros, not procedural macros, but you should try it anyway)

@kevinaboos kevinaboos merged commit 1f620ac into theseus-os:theseus_main Jul 27, 2023
github-actions bot pushed a commit that referenced this pull request Jul 27, 2023
* The new `cls` crate offers a `#[cpu_local]` attribute that can be applied
  to a static variable to declare it as Cpu-Local Storage (CLS),
  much like `#[thread_local]` and Thread-Local Storage (TLS).
  * The `cls_macro` crate provides a procedural macro that implements
    the `#[cpu_local]` attribute. Currently, this only supports basic
    primitive types: `u8`, `u16`, `u32`, `u64`. More coming later.
  * The API for accessing CPU-local primitive types is quite simple:
    only `load`, `fetch_add`, `fetch_sub`. Note that these functions are
    implemented as atomic with respect to ONLY the single current CPU,
    not atomic with respect to all memory accesses across all other CPUs.
    This is intentional as it is more efficient, and CPU-local variables are
    only accessible to a single CPU and not by another "foreign" CPU.
  * Currently this is only used for the preemption counter on each CPU,
    but it will be used for more variables in future PRs.

* This simplifies the implementation of `preemption` management,
  as we can rely on the `#[cpu_local]` API's semantics to be atomic
  with respect to the current CPU.
  * This also avoids a minor latent bug that existed in the old preemption
    implementation which made it theoretically possible for a task migration
    to occur between accessing the CPU-local preemption count and
    modifying that count. This wasn't a problem since Theseus does not yet
    perform task migration, but the new design makes this interleaving
    impossible and is thus future-proof for later task migration support.

* Re-separate `preemption` and `cpu_local` into two different crates,
  as they previously were. This is possible because the preemption count
  now uses the new `#[cpu_local]` attribute, which allows `preemption`
  and `cpu_local` to not have cyclic dependencies on each other.
  * This is responsible for most of the changes in this PR: changing
    `cpu_local_preemption` back to `cpu_local` or `preemption`.

* Another current limitation is that we must use the `#[cpu_local]` attribute
  to _manually_ specify the offset of each CPU-local variable from the start
  of the `PerCpuData` storage type. This will be removed in a future PR.

Signed-off-by: Klimenty Tsoutsman <[email protected]>
Co-authored-by: Kevin Boos <[email protected]> 1f620ac
github-actions bot pushed a commit to tsoutsman/Theseus that referenced this pull request Jul 27, 2023
…us-os#1012)

* The new `cls` crate offers a `#[cpu_local]` attribute that can be applied
  to a static variable to declare it as Cpu-Local Storage (CLS),
  much like `#[thread_local]` and Thread-Local Storage (TLS).
  * The `cls_macro` crate provides a procedural macro that implements
    the `#[cpu_local]` attribute. Currently, this only supports basic
    primitive types: `u8`, `u16`, `u32`, `u64`. More coming later.
  * The API for accessing CPU-local primitive types is quite simple:
    only `load`, `fetch_add`, `fetch_sub`. Note that these functions are
    implemented as atomic with respect to ONLY the single current CPU,
    not atomic with respect to all memory accesses across all other CPUs.
    This is intentional as it is more efficient, and CPU-local variables are
    only accessible to a single CPU and not by another "foreign" CPU.
  * Currently this is only used for the preemption counter on each CPU,
    but it will be used for more variables in future PRs.

* This simplifies the implementation of `preemption` management,
  as we can rely on the `#[cpu_local]` API's semantics to be atomic
  with respect to the current CPU.
  * This also avoids a minor latent bug that existed in the old preemption
    implementation which made it theoretically possible for a task migration
    to occur between accessing the CPU-local preemption count and
    modifying that count. This wasn't a problem since Theseus does not yet
    perform task migration, but the new design makes this interleaving
    impossible and is thus future-proof for later task migration support.

* Re-separate `preemption` and `cpu_local` into two different crates,
  as they previously were. This is possible because the preemption count
  now uses the new `#[cpu_local]` attribute, which allows `preemption`
  and `cpu_local` to not have cyclic dependencies on each other.
  * This is responsible for most of the changes in this PR: changing
    `cpu_local_preemption` back to `cpu_local` or `preemption`.

* Another current limitation is that we must use the `#[cpu_local]` attribute
  to _manually_ specify the offset of each CPU-local variable from the start
  of the `PerCpuData` storage type. This will be removed in a future PR.

Signed-off-by: Klimenty Tsoutsman <[email protected]>
Co-authored-by: Kevin Boos <[email protected]> 1f620ac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants