Skip to content

Commit

Permalink
rust: add LogTarget to print.rs
Browse files Browse the repository at this point in the history
Currently `LogTarget` can be used to specify the prefix of the log. It
can be either `CStr` or `()` (indicating no prefix). In the future, once
we've had the binding for `struct device`, we can simply add
`impl LogTarget for Device` and we'll have `dev_printk` for free.

Signed-off-by: Gary Guo <[email protected]>
  • Loading branch information
nbdd0121 committed May 26, 2021
1 parent 765221c commit 344e4a0
Showing 1 changed file with 35 additions and 31 deletions.
66 changes: 35 additions & 31 deletions rust/kernel/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,37 +94,41 @@ impl LogLevel {
pub const CONT: Self = Self(bindings::KERN_CONT);
}

/// Prints an [`Arguments`] via the kernel's [`printk`] with prefix.
///
/// [`printk`]: ../../../../include/linux/printk.h
/// [`Arguments`]: fmt::Arguments
#[doc(hidden)]
pub fn call_printk(lvl: LogLevel, prefix: &CStr, args: fmt::Arguments<'_>) {
// `printk` does not seem to fail in any path.
// SAFETY: The format string is fixed.
unsafe {
bindings::printk(
c_str!("%s%s: %pA").as_char_ptr(),
lvl.0.as_ptr(),
prefix.as_char_ptr(),
&args as *const _ as *const c_void,
);
/// Trait for types that can be used as the `target` field or printk macro family.
pub trait LogTarget {
/// Log with this target.
fn printk(&self, lvl: LogLevel, args: fmt::Arguments<'_>);
}

impl<T: ?Sized + LogTarget> LogTarget for &T {
#[inline]
fn printk(&self, lvl: LogLevel, args: fmt::Arguments<'_>) {
(*self).printk(lvl, args);
}
}

/// Prints an [`Arguments`] via the kernel's [`printk`] without prefix.
///
/// [`printk`]: ../../../../include/linux/printk.h
/// [`Arguments`]: fmt::Arguments
#[doc(hidden)]
pub fn call_printk_cont(lvl: LogLevel, args: fmt::Arguments<'_>) {
// SAFETY: The format string is fixed.
unsafe {
bindings::printk(
c_str!("%s%pA").as_char_ptr(),
lvl.0.as_ptr(),
&args as *const _ as *const c_void,
);
impl LogTarget for () {
#[inline]
fn printk(&self, lvl: LogLevel, args: fmt::Arguments<'_>) {
// SAFETY: The format string is fixed.
unsafe {
bindings::printk(c_str!("%s%pA").as_char_ptr(), lvl.0.as_ptr(), &args);
}
}
}

impl LogTarget for CStr {
#[inline]
fn printk(&self, lvl: LogLevel, args: fmt::Arguments<'_>) {
// SAFETY: The format string is fixed.
unsafe {
bindings::printk(
c_str!("%s%s: %pA").as_char_ptr(),
lvl.0.as_ptr(),
self.as_char_ptr(),
&args,
);
}
}
}

Expand Down Expand Up @@ -160,9 +164,9 @@ macro_rules! printk (
}};

(target: $target:expr, $lvl:expr, $($arg:tt)+) => {{
$crate::print::call_printk(
$crate::print::LogTarget::printk(
&($target),
$lvl,
$target,
format_args!($($arg)*)
)
}};
Expand Down Expand Up @@ -431,6 +435,6 @@ macro_rules! pr_info (
#[macro_export]
macro_rules! pr_cont (
($($arg:tt)*) => {{
$crate::print::call_printk_cont($crate::print::LogLevel::CONT, format_args!($($arg)*))
$crate::print::LogTarget::printk(&(), $crate::print::LogLevel::CONT, format_args!($($arg)*))
}}
);

0 comments on commit 344e4a0

Please sign in to comment.