Skip to content

Commit a5aaa85

Browse files
committed
Normalize semaphore samples and add them to the CI
Signed-off-by: Miguel Ojeda <[email protected]>
1 parent 2bd985a commit a5aaa85

13 files changed

+103
-45
lines changed

.github/workflows/ci.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,14 @@ jobs:
301301
grep '] rust_stack_probing: Rust stack probing sample (init)$' qemu-stdout.log
302302
grep '] rust_stack_probing: Rust stack probing sample (exit)$' qemu-stdout.log
303303
304+
- run: |
305+
grep '] rust_semaphore: Rust semaphore sample (init)$' qemu-stdout.log
306+
grep '] rust_semaphore: Rust semaphore sample (exit)$' qemu-stdout.log
307+
308+
- run: |
309+
grep '] rust_semaphore_c: Rust semaphore sample (in C, for comparison) (init)$' qemu-stdout.log
310+
grep '] rust_semaphore_c: Rust semaphore sample (in C, for comparison) (exit)$' qemu-stdout.log
311+
304312
# Report
305313
- run: |
306314
ls -l \

.github/workflows/kernel-arm64-debug.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,6 +1427,8 @@ CONFIG_SAMPLE_RUST_SYNC=m
14271427
CONFIG_SAMPLE_RUST_CHRDEV=m
14281428
CONFIG_SAMPLE_RUST_MISCDEV=m
14291429
CONFIG_SAMPLE_RUST_STACK_PROBING=m
1430+
CONFIG_SAMPLE_RUST_SEMAPHORE=m
1431+
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
14301432

14311433
#
14321434
# arm64 Debugging

.github/workflows/kernel-arm64-release.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,6 +1345,8 @@ CONFIG_SAMPLE_RUST_SYNC=m
13451345
CONFIG_SAMPLE_RUST_CHRDEV=m
13461346
CONFIG_SAMPLE_RUST_MISCDEV=m
13471347
CONFIG_SAMPLE_RUST_STACK_PROBING=m
1348+
CONFIG_SAMPLE_RUST_SEMAPHORE=m
1349+
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
13481350

13491351
#
13501352
# arm64 Debugging

.github/workflows/kernel-ppc64le-debug.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,6 +1487,8 @@ CONFIG_SAMPLE_RUST_SYNC=m
14871487
CONFIG_SAMPLE_RUST_CHRDEV=m
14881488
CONFIG_SAMPLE_RUST_MISCDEV=m
14891489
CONFIG_SAMPLE_RUST_STACK_PROBING=m
1490+
CONFIG_SAMPLE_RUST_SEMAPHORE=m
1491+
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
14901492
CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
14911493
# CONFIG_STRICT_DEVMEM is not set
14921494

.github/workflows/kernel-ppc64le-release.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,6 +1449,8 @@ CONFIG_SAMPLE_RUST_SYNC=m
14491449
CONFIG_SAMPLE_RUST_CHRDEV=m
14501450
CONFIG_SAMPLE_RUST_MISCDEV=m
14511451
CONFIG_SAMPLE_RUST_STACK_PROBING=m
1452+
CONFIG_SAMPLE_RUST_SEMAPHORE=m
1453+
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
14521454
CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
14531455
# CONFIG_STRICT_DEVMEM is not set
14541456

.github/workflows/kernel-x86_64-debug.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,6 +1439,8 @@ CONFIG_SAMPLE_RUST_SYNC=m
14391439
CONFIG_SAMPLE_RUST_CHRDEV=m
14401440
CONFIG_SAMPLE_RUST_MISCDEV=m
14411441
CONFIG_SAMPLE_RUST_STACK_PROBING=m
1442+
CONFIG_SAMPLE_RUST_SEMAPHORE=m
1443+
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
14421444
CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
14431445
# CONFIG_STRICT_DEVMEM is not set
14441446

.github/workflows/kernel-x86_64-release.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,6 +1387,8 @@ CONFIG_SAMPLE_RUST_SYNC=m
13871387
CONFIG_SAMPLE_RUST_CHRDEV=m
13881388
CONFIG_SAMPLE_RUST_MISCDEV=m
13891389
CONFIG_SAMPLE_RUST_STACK_PROBING=m
1390+
CONFIG_SAMPLE_RUST_SEMAPHORE=m
1391+
CONFIG_SAMPLE_RUST_SEMAPHORE_C=m
13901392
CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
13911393
# CONFIG_STRICT_DEVMEM is not set
13921394

.github/workflows/qemu-init.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ busybox rmmod rust_miscdev.ko
2121
busybox insmod rust_stack_probing.ko
2222
busybox rmmod rust_stack_probing.ko
2323

24+
busybox insmod rust_semaphore.ko
25+
busybox rmmod rust_semaphore.ko
26+
27+
busybox insmod rust_semaphore_c.ko
28+
busybox rmmod rust_semaphore_c.ko
29+
2430
busybox insmod rust_module_parameters_loadable_default.ko
2531
busybox insmod rust_module_parameters_loadable_custom.ko \
2632
my_bool=n \

.github/workflows/qemu-initramfs.desc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ file /rust_sync.ko samples/rust/rust_sync.ko 0755
1212
file /rust_chrdev.ko samples/rust/rust_chrdev.ko 0755 0 0
1313
file /rust_miscdev.ko samples/rust/rust_miscdev.ko 0755 0 0
1414
file /rust_stack_probing.ko samples/rust/rust_stack_probing.ko 0755 0 0
15+
file /rust_semaphore.ko samples/rust/rust_semaphore.ko 0755 0 0
16+
file /rust_semaphore_c.ko samples/rust/rust_semaphore_c.ko 0755 0 0
1517

1618
file /rust_module_parameters_loadable_default.ko samples/rust/rust_module_parameters_loadable_default.ko 0755 0 0
1719
file /rust_module_parameters_loadable_custom.ko samples/rust/rust_module_parameters_loadable_custom.ko 0755 0 0

samples/rust/Kconfig

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,20 +80,24 @@ config SAMPLE_RUST_STACK_PROBING
8080

8181
If unsure, say N.
8282

83-
config SAMPLE_SEMAPHORE
84-
tristate "Semaphore in C"
83+
config SAMPLE_RUST_SEMAPHORE
84+
tristate "Semaphore"
8585
help
86-
This option builds the C semaphore sample.
86+
This option builds the Rust semaphore sample.
8787

8888
To compile this as a module, choose M here:
89-
the module will be called semaphore.
89+
the module will be called rust_semaphore.
9090

91-
config SAMPLE_RUST_SEMAPHORE
92-
tristate "Semaphore in Rust"
91+
If unsure, say N.
92+
93+
config SAMPLE_RUST_SEMAPHORE_C
94+
tristate "Semaphore (in C, for comparison)"
9395
help
94-
This option builds the Rust semaphore sample.
96+
This option builds the Rust semaphore sample (in C, for comparison).
9597

9698
To compile this as a module, choose M here:
97-
the module will be called rust_semaphore.
99+
the module will be called rust_semaphore_c.
100+
101+
If unsure, say N.
98102

99103
endif # SAMPLES_RUST

samples/rust/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ obj-$(CONFIG_SAMPLE_RUST_SYNC) += rust_sync.o
77
obj-$(CONFIG_SAMPLE_RUST_CHRDEV) += rust_chrdev.o
88
obj-$(CONFIG_SAMPLE_RUST_MISCDEV) += rust_miscdev.o
99
obj-$(CONFIG_SAMPLE_RUST_STACK_PROBING) += rust_stack_probing.o
10-
obj-$(CONFIG_SAMPLE_SEMAPHORE) += semaphore.o
1110
obj-$(CONFIG_SAMPLE_RUST_SEMAPHORE) += rust_semaphore.o
11+
obj-$(CONFIG_SAMPLE_RUST_SEMAPHORE_C) += rust_semaphore_c.o

samples/rust/rust_semaphore.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0
22

3+
//! Rust semaphore sample
4+
//!
35
//! A counting semaphore that can be used by userspace.
46
//!
57
//! The count is incremented by writes to the device. A write of `n` bytes results in an increment
@@ -31,10 +33,10 @@ use kernel::{
3133
};
3234

3335
module! {
34-
type: RustSemaphoreModule,
36+
type: RustSemaphore,
3537
name: b"rust_semaphore",
3638
author: b"Rust for Linux Contributors",
37-
description: b"An example kernel module written in Rust",
39+
description: b"Rust semaphore sample",
3840
license: b"GPL v2",
3941
params: {},
4042
}
@@ -111,15 +113,18 @@ impl FileOperations for FileState {
111113
fn release(_obj: Box<Self>, _file: &File) {}
112114
}
113115

114-
struct RustSemaphoreModule {
116+
struct RustSemaphore {
115117
_dev: Pin<Box<Registration<Arc<Semaphore>>>>,
116118
}
117119

118-
impl KernelModule for RustSemaphoreModule {
120+
impl KernelModule for RustSemaphore {
119121
fn init() -> KernelResult<Self> {
122+
info!("Rust semaphore sample (init)");
123+
120124
let sema = Arc::try_new(Semaphore {
121125
// SAFETY: `condvar_init!` is called below.
122126
changed: unsafe { CondVar::new() },
127+
123128
// SAFETY: `mutex_init!` is called below.
124129
inner: unsafe {
125130
Mutex::new(SemaphoreInner {
@@ -128,16 +133,25 @@ impl KernelModule for RustSemaphoreModule {
128133
})
129134
},
130135
})?;
136+
131137
// SAFETY: `changed` is pinned behind `Arc`.
132138
condvar_init!(Pin::new_unchecked(&sema.changed), "Semaphore::changed");
139+
133140
// SAFETY: `inner` is pinned behind `Arc`.
134141
mutex_init!(Pin::new_unchecked(&sema.inner), "Semaphore::inner");
142+
135143
Ok(Self {
136144
_dev: Registration::new_pinned::<FileState>(cstr!("rust_semaphore"), None, sema)?,
137145
})
138146
}
139147
}
140148

149+
impl Drop for RustSemaphore {
150+
fn drop(&mut self) {
151+
info!("Rust semaphore sample (exit)");
152+
}
153+
}
154+
141155
const IOCTL_GET_READ_COUNT: u32 = 0x80086301;
142156
const IOCTL_SET_READ_COUNT: u32 = 0x40086301;
143157

samples/rust/semaphore.c renamed to samples/rust/rust_semaphore_c.c

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Rust semaphore sample (in C, for comparison)
4+
*
5+
* This is a C implementation of `rust_semaphore.rs`. Refer to the description
6+
* in that file for details on the device.
7+
*/
8+
9+
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
210

3-
// This is a C implementation of `rust_semaphore.rs`. Refer to the description
4-
// in that file for details on the device.
511
#include <linux/miscdevice.h>
612
#include <linux/module.h>
713
#include <linux/fs.h>
@@ -12,7 +18,7 @@
1218
#define IOCTL_GET_READ_COUNT _IOR('c', 1, u64)
1319
#define IOCTL_SET_READ_COUNT _IOW('c', 1, u64)
1420

15-
struct semaphore_state {
21+
struct rust_semaphore_c_state {
1622
struct kref ref;
1723
struct miscdevice miscdev;
1824
wait_queue_head_t changed;
@@ -23,10 +29,10 @@ struct semaphore_state {
2329

2430
struct file_state {
2531
atomic64_t read_count;
26-
struct semaphore_state *shared;
32+
struct rust_semaphore_c_state *shared;
2733
};
2834

29-
static int semaphore_consume(struct semaphore_state *state)
35+
static int rust_semaphore_c_consume(struct rust_semaphore_c_state *state)
3036
{
3137
DEFINE_WAIT(wait);
3238

@@ -47,10 +53,10 @@ static int semaphore_consume(struct semaphore_state *state)
4753
return 0;
4854
}
4955

50-
static int semaphore_open(struct inode *nodp, struct file *filp)
56+
static int rust_semaphore_c_open(struct inode *nodp, struct file *filp)
5157
{
52-
struct semaphore_state *shared =
53-
container_of(filp->private_data, struct semaphore_state, miscdev);
58+
struct rust_semaphore_c_state *shared =
59+
container_of(filp->private_data, struct rust_semaphore_c_state, miscdev);
5460
struct file_state *state;
5561

5662
state = kzalloc(sizeof(*state), GFP_KERNEL);
@@ -66,11 +72,11 @@ static int semaphore_open(struct inode *nodp, struct file *filp)
6672
return 0;
6773
}
6874

69-
static ssize_t semaphore_write(struct file *filp, const char __user *buffer, size_t count,
75+
static ssize_t rust_semaphore_c_write(struct file *filp, const char __user *buffer, size_t count,
7076
loff_t *ppos)
7177
{
7278
struct file_state *state = filp->private_data;
73-
struct semaphore_state *shared = state->shared;
79+
struct rust_semaphore_c_state *shared = state->shared;
7480

7581
mutex_lock(&shared->mutex);
7682

@@ -88,7 +94,7 @@ static ssize_t semaphore_write(struct file *filp, const char __user *buffer, siz
8894
return count;
8995
}
9096

91-
static ssize_t semaphore_read(struct file *filp, char __user *buffer,
97+
static ssize_t rust_semaphore_c_read(struct file *filp, char __user *buffer,
9298
size_t count, loff_t *ppos)
9399
{
94100
struct file_state *state = filp->private_data;
@@ -98,7 +104,7 @@ static ssize_t semaphore_read(struct file *filp, char __user *buffer,
98104
if (count == 0 || *ppos > 0)
99105
return 0;
100106

101-
ret = semaphore_consume(state->shared);
107+
ret = rust_semaphore_c_consume(state->shared);
102108
if (ret)
103109
return ret;
104110

@@ -110,7 +116,7 @@ static ssize_t semaphore_read(struct file *filp, char __user *buffer,
110116
return 1;
111117
}
112118

113-
static long semaphore_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
119+
static long rust_semaphore_c_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
114120
{
115121
struct file_state *state = filp->private_data;
116122
void __user *buffer = (void __user *)arg;
@@ -132,38 +138,40 @@ static long semaphore_ioctl(struct file *filp, unsigned int cmd, unsigned long a
132138
}
133139
}
134140

135-
static void semaphore_free(struct kref *kref)
141+
static void rust_semaphore_c_free(struct kref *kref)
136142
{
137-
struct semaphore_state *device;
143+
struct rust_semaphore_c_state *device;
138144

139-
device = container_of(kref, struct semaphore_state, ref);
145+
device = container_of(kref, struct rust_semaphore_c_state, ref);
140146
kfree(device);
141147
}
142148

143-
static int semaphore_release(struct inode *nodp, struct file *filp)
149+
static int rust_semaphore_c_release(struct inode *nodp, struct file *filp)
144150
{
145151
struct file_state *state = filp->private_data;
146152

147-
kref_put(&state->shared->ref, semaphore_free);
153+
kref_put(&state->shared->ref, rust_semaphore_c_free);
148154
kfree(state);
149155
return 0;
150156
}
151157

152-
static const struct file_operations semaphore_fops = {
158+
static const struct file_operations rust_semaphore_c_fops = {
153159
.owner = THIS_MODULE,
154-
.open = semaphore_open,
155-
.read = semaphore_read,
156-
.write = semaphore_write,
157-
.compat_ioctl = semaphore_ioctl,
158-
.release = semaphore_release,
160+
.open = rust_semaphore_c_open,
161+
.read = rust_semaphore_c_read,
162+
.write = rust_semaphore_c_write,
163+
.compat_ioctl = rust_semaphore_c_ioctl,
164+
.release = rust_semaphore_c_release,
159165
};
160166

161-
static struct semaphore_state *device;
167+
static struct rust_semaphore_c_state *device;
162168

163-
static int __init semaphore_init(void)
169+
static int __init rust_semaphore_c_init(void)
164170
{
165171
int ret;
166-
struct semaphore_state *state;
172+
struct rust_semaphore_c_state *state;
173+
174+
pr_info("Rust semaphore sample (in C, for comparison) (init)\n");
167175

168176
state = kzalloc(sizeof(*state), GFP_KERNEL);
169177
if (!state)
@@ -173,7 +181,7 @@ static int __init semaphore_init(void)
173181
kref_init(&state->ref);
174182
init_waitqueue_head(&state->changed);
175183

176-
state->miscdev.fops = &semaphore_fops;
184+
state->miscdev.fops = &rust_semaphore_c_fops;
177185
state->miscdev.minor = MISC_DYNAMIC_MINOR;
178186
state->miscdev.name = "semaphore";
179187

@@ -188,13 +196,17 @@ static int __init semaphore_init(void)
188196
return 0;
189197
}
190198

191-
static void __exit semaphore_exit(void)
199+
static void __exit rust_semaphore_c_exit(void)
192200
{
201+
pr_info("Rust semaphore sample (in C, for comparison) (exit)\n");
202+
193203
misc_deregister(&device->miscdev);
194-
kref_put(&device->ref, semaphore_free);
204+
kref_put(&device->ref, rust_semaphore_c_free);
195205
}
196206

197-
module_init(semaphore_init);
198-
module_exit(semaphore_exit);
207+
module_init(rust_semaphore_c_init);
208+
module_exit(rust_semaphore_c_exit);
199209

200210
MODULE_LICENSE("GPL v2");
211+
MODULE_AUTHOR("Rust for Linux Contributors");
212+
MODULE_DESCRIPTION("Rust semaphore sample (in C, for comparison)");

0 commit comments

Comments
 (0)