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::sync::Arc;
use kernel::workqueue::{self, impl_has_work, new_work, Work, WorkItem};
#[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"),
}), GFP_KERNEL)
}
}
impl WorkItem for MyStruct {
type Pointer = Arc<MyStruct>;
fn run(this: Arc<MyStruct>) {
pr_info!("The value is: {}\n", 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::sync::Arc;
use kernel::workqueue::{self, impl_has_work, new_work, Work, WorkItem};
#[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"),
}), GFP_KERNEL)
}
}
impl WorkItem<1> for MyStruct {
type Pointer = Arc<MyStruct>;
fn run(this: Arc<MyStruct>) {
pr_info!("The value is: {}\n", this.value_1);
}
}
impl WorkItem<2> for MyStruct {
type Pointer = Arc<MyStruct>;
fn run(this: Arc<MyStruct>) {
pr_info!("The second value is: {}\n", 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
Macros§
- impl_
has_ work - Used to safely implement the
HasWork<T, ID>trait. - new_
work - Creates a
Workinitialiser with the given name and a newly-created lock class.
Structs§
Traits§
- HasWork
- Declares that a type has a
Work<T, ID>field. - RawWork
Item - A raw work item.
- Work
Item - Defines the method that should be called when this work item is executed.
- Work
Item Pointer - Defines the method that should be called directly when a work item is executed.
Functions§
- system
- Returns the system work queue (
system_wq). - system_
bh - Returns the system bottom halves work queue (
system_bh_wq). - system_
bh_ highpri - Returns the system bottom halves high-priority work queue (
system_bh_highpri_wq). - system_
freezable - Returns the system freezable work queue (
system_freezable_wq). - system_
freezable_ power_ efficient - Returns the system freezable power-efficient work queue (
system_freezable_power_efficient_wq). - system_
highpri - Returns the system high-priority work queue (
system_highpri_wq). - system_
long - Returns the system work queue for potentially long-running work items (
system_long_wq). - system_
power_ efficient - Returns the system power-efficient work queue (
system_power_efficient_wq). - system_
unbound - Returns the system unbound work queue (
system_unbound_wq).