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
Work
struct is the Rust wrapper for the Cwork_struct
type. - The
WorkItem
trait is implemented for structs that can be enqueued to a workqueue. - The
WorkItemPointer
trait 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
).