Skip to content

Commit 1ba7e21

Browse files
committed
ldd ch06: impl init_completion
bindings_generated.rs does not implement init_completion but only provide Default trait with writing 0. So I adds init_swait_queue_head implementation for myself. Now it generated dead-lock as below. 1. read locks inner to get the mutable reference to completion 2. write also should locks the inner to get the mutable reference to completion as well 3. dead-lock I MUST find out how to get the mutable reference to a object which is inside of an object wrapped by ArcBorrow. / # insmod share/rust_ldd06.ko [ 466.173709] rust_ldd06: module verification failed: signature and/or required key missing - tainting kernel [ 466.176106] rust_completion: rust_ldd06 is loaded [ 466.177064] rust_completion: completion_dev created / # mknod /dev/rust_ldd06 c 10 124 / # cat /dev/rust_ldd06 & / # [ 489.911819] rust_completion: open is invoked [ 489.913171] rust_completion: read is invoked [ 489.913932] rust_completion: read:dummy=1 / # echo "asdf" > /dev/rust_ldd06 [ 500.059213] rust_completion: open is invoked [ 500.060580] rust_completion: write is invoked Signed-off-by: Gioh Kim <gurugio@gmail.com>
1 parent f9655d7 commit 1ba7e21

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

samples/rust/rust_ldd06.rs

+24-8
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
//! How to use:
1010
//! / # insmod rust_ldd06.ko
1111
//! / # mknod /dev/rust_ldd06 c 10 124
12+
//! / # cat /dev/rust_ldd06 &
1213
//! / # echo "hello" > /dev/rust_ldd06
13-
//! / # cat /dev/rust_ldd06
1414
use kernel::prelude::*;
1515
use kernel::{
16-
bindings,
16+
bindings, c_str,
1717
file::{self, File},
1818
fmt,
1919
io_buffer::{IoBufferReader, IoBufferWriter},
@@ -25,7 +25,7 @@ module! {
2525
type: RustCompletion,
2626
name: "rust_completion",
2727
author: "Rust for Linux Contributors",
28-
description: "Rust LDD ch06 scull",
28+
description: "Rust LDD ch06",
2929
license: "GPL",
3030
}
3131

@@ -44,8 +44,6 @@ struct CompletionInner {
4444
// internal info between file operations
4545
#[pin_data]
4646
struct CompletionDev {
47-
pub completion: bindings::completion,
48-
4947
#[pin]
5048
inner: Mutex<CompletionInner>,
5149
}
@@ -54,10 +52,28 @@ struct CompletionDev {
5452
impl CompletionDev {
5553
fn try_new() -> Result<Arc<Self>> {
5654
pr_info!("completion_dev created\n");
55+
56+
//
57+
// #define init_swait_queue_head(q) \
58+
// do { \
59+
// static struct lock_class_key __key; \
60+
// __init_swait_queue_head((q), #q, &__key); \
61+
//} while (0)
62+
let mut compl = bindings::completion::default();
63+
let compl_name = c_str!("completion_dev");
64+
let mut key: bindings::lock_class_key = bindings::lock_class_key::default();
65+
compl.done = 0;
66+
unsafe {
67+
bindings::__init_swait_queue_head(
68+
&mut compl.wait,
69+
compl_name.as_char_ptr() as *mut core::ffi::c_char,
70+
&mut key,
71+
);
72+
}
73+
5774
let dev = Arc::pin_init(pin_init!(Self {
58-
completion: bindings::completion::default(), // Default trait is implmented by bindget. See rust/bindings/bindings_generates.rs
5975
inner <- new_mutex!(CompletionInner {
60-
completion: bindings::completion::default(),
76+
completion: compl,
6177
dummy: 0,
6278
}),
6379
}))?;
@@ -108,7 +124,7 @@ impl file::Operations for RustFile {
108124
data: &mut impl IoBufferReader,
109125
_offset: u64,
110126
) -> Result<usize> {
111-
pr_debug!("write is invoked\n");
127+
pr_info!("write is invoked\n");
112128

113129
let mut inner_guard = shared.inner.lock();
114130
pr_info!("write:dummy={}\n", inner_guard.dummy);

0 commit comments

Comments
 (0)