Skip to content

Commit 6c0f564

Browse files
committed
rust: optimize mlx4 driver basic
1 parent a8516bf commit 6c0f564

File tree

6 files changed

+138
-151
lines changed

6 files changed

+138
-151
lines changed

rust/kernel/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ pub mod task;
7676
pub mod workqueue;
7777

7878
pub mod linked_list;
79+
#[cfg(CONFIG_MLX4_EN)]
7980
pub mod mlx4;
8081
mod raw_list;
8182
pub mod rbtree;

rust/kernel/mlx4.rs

Lines changed: 134 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,37 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
//! Infiniband mlx4 devices.
4+
//!
5+
16
use alloc::boxed::Box;
2-
use cm::CmWorkQueue;
37
use core::pin::Pin;
4-
use core::{cell::UnsafeCell, marker, ptr};
8+
use core::{marker, ptr};
59
use macros::vtable;
6-
use mcg::McgWorkQueue;
7-
use qp::QpWorkQueue;
810

9-
use crate::error::{code::*, Error, Result};
11+
use crate::bindings;
12+
use crate::error::{code::*, Result};
1013
use crate::str::CStr;
1114
use crate::workqueue::{BoxedQueue, Queue};
12-
use crate::{bindings, pr_info};
1315

14-
mod cm;
15-
mod mcg;
16-
mod qp;
17-
18-
/// Soft RDMA transport registration.
16+
/// Infiband mlx4 device registration.
1917
///
2018
pub struct Registration<T: Mlx4Operation> {
2119
registered: bool,
20+
#[allow(dead_code)]
2221
name: &'static CStr,
23-
2422
wq: Mlx4WorkQueue,
2523
cm_wq: CmWorkQueue,
2624
qp_wq: QpWorkQueue,
2725
mcg_wq: McgWorkQueue,
2826
phantom: marker::PhantomData<T>,
29-
//rxe_link_ops: bindings::rdma_link_ops,
30-
//再包一层
31-
//_pin: PhantomPinned,
32-
33-
// /// Context initialised on construction and made available to all file instances on
34-
// /// [`file::Operations::open`].
35-
//open_data: MaybeUninit<T::OpenData>,
3627
}
3728

3829
impl<T: Mlx4Operation> Registration<T> {
30+
/// Creates a new [`Registration`] but does not register it yet.
31+
///
32+
/// It is allowed to move.
3933
pub fn new(name: &'static CStr) -> Self {
34+
// INVARIANT: `registered` is `false`
4035
Self {
4136
registered: false,
4237
name,
@@ -45,18 +40,29 @@ impl<T: Mlx4Operation> Registration<T> {
4540
qp_wq: QpWorkQueue::new(),
4641
mcg_wq: McgWorkQueue::new(),
4742
phantom: marker::PhantomData,
48-
//rxe_link_ops:bindings::rdma_link_ops::default(),
4943
}
5044
}
5145

46+
/// Registers a infiband mlx4 device.
47+
///
48+
/// Returns a pinned heap-allocated representation of the registration.
5249
pub fn new_pinned(name: &'static CStr) -> Result<Pin<Box<Self>>> {
5350
let mut r = Pin::from(Box::try_new(Self::new(name))?);
5451
r.as_mut().register()?;
5552
Ok(r)
5653
}
5754

55+
// Registers a infiband mlx4 device with the rest of the kernel.
56+
///
57+
/// It must be pinned because the memory block that represents the registration is
58+
/// self-referential.
5859
pub fn register(self: Pin<&mut Self>) -> Result {
60+
// SAFETY: We must ensure that we never move out of `this`.
5961
let this = unsafe { self.get_unchecked_mut() };
62+
if this.registered {
63+
// Already registered.
64+
return Err(EINVAL);
65+
}
6066

6167
match this.wq.init() {
6268
Ok(()) => {}
@@ -90,8 +96,7 @@ impl<T: Mlx4Operation> Registration<T> {
9096
}
9197
}
9298

93-
// interface用vtable替换掉
94-
99+
// SAFETY: The adapter is compatible with the mlx4 register
95100
unsafe {
96101
bindings::mlx4_register_interface(Mlx4OperationTable::<T>::build());
97102
}
@@ -102,9 +107,9 @@ impl<T: Mlx4Operation> Registration<T> {
102107
}
103108

104109
impl<T: Mlx4Operation> Drop for Registration<T> {
110+
/// Removes the registration from the kernel if it has completed successfully before.
105111
fn drop(&mut self) {
106112
if self.registered {
107-
//unsafe{bindings::mlx4_unregister_interface();}
108113
self.mcg_wq.clean();
109114
self.cm_wq.clean();
110115
self.qp_wq.clean();
@@ -113,9 +118,15 @@ impl<T: Mlx4Operation> Drop for Registration<T> {
113118
}
114119
}
115120

121+
/// Build kernel's `struct mlx4_interface` type with mlx4 device operation.
116122
pub struct Mlx4OperationTable<T>(marker::PhantomData<T>);
117123

118124
impl<T: Mlx4Operation> Mlx4OperationTable<T> {
125+
/// Builds an instance of [`struct mlx4_interface`].
126+
///
127+
/// # Safety
128+
///
129+
/// The caller must ensure that the adapter is compatible with the way the device is registered.
119130
pub fn build() -> *mut bindings::mlx4_interface {
120131
return &mut bindings::mlx4_interface {
121132
add: Some(Self::add_callback),
@@ -134,58 +145,39 @@ impl<T: Mlx4Operation> Mlx4OperationTable<T> {
134145
};
135146
}
136147

137-
unsafe extern "C" fn add_callback(dev: *mut bindings::mlx4_dev) -> *mut core::ffi::c_void {
148+
unsafe extern "C" fn add_callback(_dev: *mut bindings::mlx4_dev) -> *mut core::ffi::c_void {
149+
let _ = T::add();
138150
return ptr::null_mut();
139151
}
140152

141153
unsafe extern "C" fn remove_callback(
142-
dev: *mut bindings::mlx4_dev,
143-
context: *mut core::ffi::c_void,
154+
_dev: *mut bindings::mlx4_dev,
155+
_context: *mut core::ffi::c_void,
144156
) {
157+
let _ = T::remove();
145158
}
146159

147160
unsafe extern "C" fn event_callback(
148-
dev: *mut bindings::mlx4_dev,
149-
context: *mut core::ffi::c_void,
150-
event: bindings::mlx4_dev_event,
151-
param: core::ffi::c_ulong,
161+
_dev: *mut bindings::mlx4_dev,
162+
_context: *mut core::ffi::c_void,
163+
_event: bindings::mlx4_dev_event,
164+
_param: core::ffi::c_ulong,
152165
) {
166+
let _ = T::event();
153167
}
154-
155-
// unsafe extern "C" fn get_dev_callback(
156-
// dev: *mut mlx4_dev,
157-
// context: *mut core::ffi::c_void,
158-
// port: u8_,
159-
// ) -> *mut core::ffi::c_void {
160-
// }
161-
162-
// unsafe extern "C" fn activate_callback(
163-
// dev: *mut mlx4_dev,
164-
// context: *mut core::ffi::c_void
165-
// ) {
166-
// }
167-
168-
// MLX4FUNC:bindings::mlx4_interface=bindings::mlx4_interface {
169-
// add:Some(Self::add_callback),
170-
// remove:Some(Self::remove_callback),
171-
// event:Some(Self::event_callback),
172-
// get_dev:None,
173-
// activate:None,
174-
// list:bindings::list_head{next:ptr::null_mut(),prev:ptr::null_mut()},
175-
// // MLX4_PROT_IB_IPV6
176-
// protocol:0,
177-
// // MLX4_INTFF_BONDING
178-
// flags:1,
179-
// };
180168
}
181169

170+
/// Corresponds to the kernel's `struct mlx4_interface`.
171+
///
172+
/// You implement this trait whenever you would create a `struct mlx4_interface`.
182173
#[vtable]
183174
pub trait Mlx4Operation {
184-
fn add();
185-
fn remove();
186-
fn event();
187-
// fn get_dev();
188-
// fn activate();
175+
/// Add a new mlx4 ib device.
176+
fn add() -> Result;
177+
/// Remove mlx4 ib device.
178+
fn remove() -> Result;
179+
/// Respond to specific mlx4 ib device event
180+
fn event() -> Result;
189181
}
190182

191183
pub(crate) struct Mlx4WorkQueue {
@@ -213,3 +205,84 @@ impl Mlx4WorkQueue {
213205
}
214206
}
215207
}
208+
209+
pub(crate) struct CmWorkQueue {
210+
cm_wq: Option<BoxedQueue>,
211+
}
212+
213+
impl CmWorkQueue {
214+
pub(crate) fn new() -> Self {
215+
Self { cm_wq: None }
216+
}
217+
218+
pub(crate) fn init(&mut self) -> Result {
219+
let cm_wq_tmp = Queue::try_new(format_args!("mlx4_ib_cm"), 0, 0);
220+
self.cm_wq = match cm_wq_tmp {
221+
Ok(cm_wq) => Some(cm_wq),
222+
Err(e) => return Err(e),
223+
};
224+
225+
Ok(())
226+
}
227+
228+
pub(crate) fn clean(&mut self) {
229+
if self.cm_wq.is_some() {
230+
drop(self.cm_wq.take().unwrap());
231+
}
232+
}
233+
}
234+
235+
pub(crate) struct McgWorkQueue {
236+
clean_wq: Option<BoxedQueue>,
237+
}
238+
239+
impl McgWorkQueue {
240+
pub(crate) fn new() -> Self {
241+
Self { clean_wq: None }
242+
}
243+
244+
pub(crate) fn init(&mut self) -> Result {
245+
let clean_wq_tmp = Queue::try_new(format_args!("mlx4_ib_mcg"), 655369, 1);
246+
self.clean_wq = match clean_wq_tmp {
247+
Ok(clean_wq) => Some(clean_wq),
248+
Err(e) => return Err(e),
249+
};
250+
251+
Ok(())
252+
}
253+
254+
pub(crate) fn clean(&mut self) {
255+
if self.clean_wq.is_some() {
256+
drop(self.clean_wq.take().unwrap());
257+
}
258+
}
259+
}
260+
261+
pub(crate) struct QpWorkQueue {
262+
mlx4_ib_qp_event_wq: Option<BoxedQueue>,
263+
}
264+
265+
impl QpWorkQueue {
266+
pub(crate) fn new() -> Self {
267+
Self {
268+
mlx4_ib_qp_event_wq: None,
269+
}
270+
}
271+
272+
pub(crate) fn init(&mut self) -> Result {
273+
let mlx4_ib_qp_event_wq_tmp =
274+
Queue::try_new(format_args!("mlx4_ib_qp_event_wq"), 655361, 1);
275+
self.mlx4_ib_qp_event_wq = match mlx4_ib_qp_event_wq_tmp {
276+
Ok(mlx4_ib_qp_event_wq) => Some(mlx4_ib_qp_event_wq),
277+
Err(e) => return Err(e),
278+
};
279+
280+
Ok(())
281+
}
282+
283+
pub(crate) fn clean(&mut self) {
284+
if self.mlx4_ib_qp_event_wq.is_some() {
285+
drop(self.mlx4_ib_qp_event_wq.take().unwrap());
286+
}
287+
}
288+
}

rust/kernel/mlx4/cm.rs

Lines changed: 0 additions & 29 deletions
This file was deleted.

rust/kernel/mlx4/mcg.rs

Lines changed: 0 additions & 29 deletions
This file was deleted.

rust/kernel/mlx4/qp.rs

Lines changed: 0 additions & 32 deletions
This file was deleted.

rust/kernel/workqueue.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,9 @@ pub struct BoxedQueue {
408408
ptr: NonNull<Queue>,
409409
}
410410

411+
// SAFETY: Kernel workqueues are usable from any thread.
412+
unsafe impl Sync for BoxedQueue {}
413+
411414
impl BoxedQueue {
412415
/// Creates a new instance of [`BoxedQueue`].
413416
///

0 commit comments

Comments
 (0)