Expand description
Work queues.
This file has two components: The raw work item API, and the safe work item API.
One pattern that is used in both APIs is the ID const generic, which exists to allow a single
type to define multiple work_struct fields. This is done by choosing an id for each field,
and using that id to specify which field you wish to use. (The actual value doesn’t matter, as
long as you use different values for different fields of the same struct.) Since these IDs are
generic, they are used only at compile-time, so they shouldn’t exist in the final binary.
The raw API
The raw API consists of the RawWorkItem trait, where the work item needs to provide an
arbitrary function that knows how to enqueue the work item. It should usually not be used
directly, but if you want to, you can use it without using the pieces from the safe API.
The safe API
The safe API is used via the Work struct and WorkItem traits. Furthermore, it also includes
a trait called WorkItemPointer, which is usually not used directly by the user.
- The
Workstruct is the Rust wrapper for the Cwork_structtype. - The
WorkItemtrait is implemented for structs that can be enqueued to a workqueue. - The
WorkItemPointertrait is implemented for the pointer type that points at a something that implementsWorkItem.
Example
This example defines a struct that holds an integer and can be scheduled on the workqueue. When
the struct is executed, it will print the integer. Since there is only one work_struct field,
we do not need to specify ids for the fields.
use kernel::prelude::*;
use kernel::sync::Arc;
use kernel::workqueue::{self, Work, WorkItem};
use kernel::{impl_has_work, new_work};
#[pin_data]
struct MyStruct {
value: i32,
#[pin]
work: Work<MyStruct>,
}
impl_has_work! {
impl HasWork<Self> for MyStruct { self.work }
}
impl MyStruct {
fn new(value: i32) -> Result<Arc<Self>> {
Arc::pin_init(pin_init!(MyStruct {
value,
work <- new_work!("MyStruct::work"),
}))
}
}
impl WorkItem for MyStruct {
type Pointer = Arc<MyStruct>;
fn run(this: Arc<MyStruct>) {
pr_info!("The value is: {}", this.value);
}
}
/// This method will enqueue the struct for execution on the system workqueue, where its value
/// will be printed.
fn print_later(val: Arc<MyStruct>) {
let _ = workqueue::system().enqueue(val);
}The following example shows how multiple work_struct fields can be used:
use kernel::prelude::*;
use kernel::sync::Arc;
use kernel::workqueue::{self, Work, WorkItem};
use kernel::{impl_has_work, new_work};
#[pin_data]
struct MyStruct {
value_1: i32,
value_2: i32,
#[pin]
work_1: Work<MyStruct, 1>,
#[pin]
work_2: Work<MyStruct, 2>,
}
impl_has_work! {
impl HasWork<Self, 1> for MyStruct { self.work_1 }
impl HasWork<Self, 2> for MyStruct { self.work_2 }
}
impl MyStruct {
fn new(value_1: i32, value_2: i32) -> Result<Arc<Self>> {
Arc::pin_init(pin_init!(MyStruct {
value_1,
value_2,
work_1 <- new_work!("MyStruct::work_1"),
work_2 <- new_work!("MyStruct::work_2"),
}))
}
}
impl WorkItem<1> for MyStruct {
type Pointer = Arc<MyStruct>;
fn run(this: Arc<MyStruct>) {
pr_info!("The value is: {}", this.value_1);
}
}
impl WorkItem<2> for MyStruct {
type Pointer = Arc<MyStruct>;
fn run(this: Arc<MyStruct>) {
pr_info!("The second value is: {}", this.value_2);
}
}
fn print_1_later(val: Arc<MyStruct>) {
let _ = workqueue::system().enqueue::<Arc<MyStruct>, 1>(val);
}
fn print_2_later(val: Arc<MyStruct>) {
let _ = workqueue::system().enqueue::<Arc<MyStruct>, 2>(val);
}C header: include/linux/workqueue.h
Structs
- A kernel work queue.
- Links for a work item.
Traits
- Declares that a type has a
Work<T, ID>field. - A raw work item.
- Defines the method that should be called when this work item is executed.
- Defines the method that should be called directly when a work item is executed.
Functions
- Returns the system work queue (
system_wq). - Returns the system freezable work queue (
system_freezable_wq). - Returns the system freezable power-efficient work queue (
system_freezable_power_efficient_wq). - Returns the system high-priority work queue (
system_highpri_wq). - Returns the system work queue for potentially long-running work items (
system_long_wq). - Returns the system power-efficient work queue (
system_power_efficient_wq). - Returns the system unbound work queue (
system_unbound_wq).