xref: /linux/rust/kernel/task.rs (revision 70d7f7dbd98a4d499b46ec9ef2bd1f2698facf2b)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Tasks (threads and processes).
4 //!
5 //! C header: [`include/linux/sched.h`](srctree/include/linux/sched.h).
6 
7 use crate::{
8     bindings,
9     types::{NotThreadSafe, Opaque},
10 };
11 use core::{
12     cmp::{Eq, PartialEq},
13     ffi::{c_int, c_long, c_uint},
14     ops::Deref,
15     ptr,
16 };
17 
18 /// A sentinel value used for infinite timeouts.
19 pub const MAX_SCHEDULE_TIMEOUT: c_long = c_long::MAX;
20 
21 /// Bitmask for tasks that are sleeping in an interruptible state.
22 pub const TASK_INTERRUPTIBLE: c_int = bindings::TASK_INTERRUPTIBLE as c_int;
23 /// Bitmask for tasks that are sleeping in an uninterruptible state.
24 pub const TASK_UNINTERRUPTIBLE: c_int = bindings::TASK_UNINTERRUPTIBLE as c_int;
25 /// Convenience constant for waking up tasks regardless of whether they are in interruptible or
26 /// uninterruptible sleep.
27 pub const TASK_NORMAL: c_uint = bindings::TASK_NORMAL as c_uint;
28 
29 /// Returns the currently running task.
30 #[macro_export]
31 macro_rules! current {
32     () => {
33         // SAFETY: Deref + addr-of below create a temporary `TaskRef` that cannot outlive the
34         // caller.
35         unsafe { &*$crate::task::Task::current() }
36     };
37 }
38 
39 /// Wraps the kernel's `struct task_struct`.
40 ///
41 /// # Invariants
42 ///
43 /// All instances are valid tasks created by the C portion of the kernel.
44 ///
45 /// Instances of this type are always refcounted, that is, a call to `get_task_struct` ensures
46 /// that the allocation remains valid at least until the matching call to `put_task_struct`.
47 ///
48 /// # Examples
49 ///
50 /// The following is an example of getting the PID of the current thread with zero additional cost
51 /// when compared to the C version:
52 ///
53 /// ```
54 /// let pid = current!().pid();
55 /// ```
56 ///
57 /// Getting the PID of the current process, also zero additional cost:
58 ///
59 /// ```
60 /// let pid = current!().group_leader().pid();
61 /// ```
62 ///
63 /// Getting the current task and storing it in some struct. The reference count is automatically
64 /// incremented when creating `State` and decremented when it is dropped:
65 ///
66 /// ```
67 /// use kernel::{task::Task, types::ARef};
68 ///
69 /// struct State {
70 ///     creator: ARef<Task>,
71 ///     index: u32,
72 /// }
73 ///
74 /// impl State {
75 ///     fn new() -> Self {
76 ///         Self {
77 ///             creator: current!().into(),
78 ///             index: 0,
79 ///         }
80 ///     }
81 /// }
82 /// ```
83 #[repr(transparent)]
84 pub struct Task(pub(crate) Opaque<bindings::task_struct>);
85 
86 // SAFETY: By design, the only way to access a `Task` is via the `current` function or via an
87 // `ARef<Task>` obtained through the `AlwaysRefCounted` impl. This means that the only situation in
88 // which a `Task` can be accessed mutably is when the refcount drops to zero and the destructor
89 // runs. It is safe for that to happen on any thread, so it is ok for this type to be `Send`.
90 unsafe impl Send for Task {}
91 
92 // SAFETY: It's OK to access `Task` through shared references from other threads because we're
93 // either accessing properties that don't change (e.g., `pid`, `group_leader`) or that are properly
94 // synchronised by C code (e.g., `signal_pending`).
95 unsafe impl Sync for Task {}
96 
97 /// The type of process identifiers (PIDs).
98 type Pid = bindings::pid_t;
99 
100 /// The type of user identifiers (UIDs).
101 #[derive(Copy, Clone)]
102 pub struct Kuid {
103     kuid: bindings::kuid_t,
104 }
105 
106 impl Task {
107     /// Returns a raw pointer to the current task.
108     ///
109     /// It is up to the user to use the pointer correctly.
110     #[inline]
111     pub fn current_raw() -> *mut bindings::task_struct {
112         // SAFETY: Getting the current pointer is always safe.
113         unsafe { bindings::get_current() }
114     }
115 
116     /// Returns a task reference for the currently executing task/thread.
117     ///
118     /// The recommended way to get the current task/thread is to use the
119     /// [`current`] macro because it is safe.
120     ///
121     /// # Safety
122     ///
123     /// Callers must ensure that the returned object doesn't outlive the current task/thread.
124     pub unsafe fn current() -> impl Deref<Target = Task> {
125         struct TaskRef<'a> {
126             task: &'a Task,
127             _not_send: NotThreadSafe,
128         }
129 
130         impl Deref for TaskRef<'_> {
131             type Target = Task;
132 
133             fn deref(&self) -> &Self::Target {
134                 self.task
135             }
136         }
137 
138         let current = Task::current_raw();
139         TaskRef {
140             // SAFETY: If the current thread is still running, the current task is valid. Given
141             // that `TaskRef` is not `Send`, we know it cannot be transferred to another thread
142             // (where it could potentially outlive the caller).
143             task: unsafe { &*current.cast() },
144             _not_send: NotThreadSafe,
145         }
146     }
147 
148     /// Returns the group leader of the given task.
149     pub fn group_leader(&self) -> &Task {
150         // SAFETY: By the type invariant, we know that `self.0` is a valid task. Valid tasks always
151         // have a valid `group_leader`.
152         let ptr = unsafe { *ptr::addr_of!((*self.0.get()).group_leader) };
153 
154         // SAFETY: The lifetime of the returned task reference is tied to the lifetime of `self`,
155         // and given that a task has a reference to its group leader, we know it must be valid for
156         // the lifetime of the returned task reference.
157         unsafe { &*ptr.cast() }
158     }
159 
160     /// Returns the PID of the given task.
161     pub fn pid(&self) -> Pid {
162         // SAFETY: By the type invariant, we know that `self.0` is a valid task. Valid tasks always
163         // have a valid pid.
164         unsafe { *ptr::addr_of!((*self.0.get()).pid) }
165     }
166 
167     /// Returns the UID of the given task.
168     pub fn uid(&self) -> Kuid {
169         // SAFETY: By the type invariant, we know that `self.0` is valid.
170         Kuid::from_raw(unsafe { bindings::task_uid(self.0.get()) })
171     }
172 
173     /// Returns the effective UID of the given task.
174     pub fn euid(&self) -> Kuid {
175         // SAFETY: By the type invariant, we know that `self.0` is valid.
176         Kuid::from_raw(unsafe { bindings::task_euid(self.0.get()) })
177     }
178 
179     /// Determines whether the given task has pending signals.
180     pub fn signal_pending(&self) -> bool {
181         // SAFETY: By the type invariant, we know that `self.0` is valid.
182         unsafe { bindings::signal_pending(self.0.get()) != 0 }
183     }
184 
185     /// Returns the given task's pid in the current pid namespace.
186     pub fn pid_in_current_ns(&self) -> Pid {
187         // SAFETY: We know that `self.0.get()` is valid by the type invariant, and passing a null
188         // pointer as the namespace is correct for using the current namespace.
189         unsafe { bindings::task_tgid_nr_ns(self.0.get(), ptr::null_mut()) }
190     }
191 
192     /// Wakes up the task.
193     pub fn wake_up(&self) {
194         // SAFETY: By the type invariant, we know that `self.0.get()` is non-null and valid.
195         // And `wake_up_process` is safe to be called for any valid task, even if the task is
196         // running.
197         unsafe { bindings::wake_up_process(self.0.get()) };
198     }
199 }
200 
201 // SAFETY: The type invariants guarantee that `Task` is always refcounted.
202 unsafe impl crate::types::AlwaysRefCounted for Task {
203     fn inc_ref(&self) {
204         // SAFETY: The existence of a shared reference means that the refcount is nonzero.
205         unsafe { bindings::get_task_struct(self.0.get()) };
206     }
207 
208     unsafe fn dec_ref(obj: ptr::NonNull<Self>) {
209         // SAFETY: The safety requirements guarantee that the refcount is nonzero.
210         unsafe { bindings::put_task_struct(obj.cast().as_ptr()) }
211     }
212 }
213 
214 impl Kuid {
215     /// Get the current euid.
216     #[inline]
217     pub fn current_euid() -> Kuid {
218         // SAFETY: Just an FFI call.
219         Self::from_raw(unsafe { bindings::current_euid() })
220     }
221 
222     /// Create a `Kuid` given the raw C type.
223     #[inline]
224     pub fn from_raw(kuid: bindings::kuid_t) -> Self {
225         Self { kuid }
226     }
227 
228     /// Turn this kuid into the raw C type.
229     #[inline]
230     pub fn into_raw(self) -> bindings::kuid_t {
231         self.kuid
232     }
233 
234     /// Converts this kernel UID into a userspace UID.
235     ///
236     /// Uses the namespace of the current task.
237     #[inline]
238     pub fn into_uid_in_current_ns(self) -> bindings::uid_t {
239         // SAFETY: Just an FFI call.
240         unsafe { bindings::from_kuid(bindings::current_user_ns(), self.kuid) }
241     }
242 }
243 
244 impl PartialEq for Kuid {
245     #[inline]
246     fn eq(&self, other: &Kuid) -> bool {
247         // SAFETY: Just an FFI call.
248         unsafe { bindings::uid_eq(self.kuid, other.kuid) }
249     }
250 }
251 
252 impl Eq for Kuid {}
253