Skip to content

Commit e044290

Browse files
727HsjhuangshijiaAsakuraMizu
authored
fix(net/vsock): receiving logic (#37)
* fix: modify the receiving logic of vsock * fix * style: format code * chore: lower log level * update axdriver crates --------- Co-authored-by: huangshijia <[email protected]> Co-authored-by: 朝倉水希 <[email protected]>
1 parent b70776a commit e044290

File tree

2 files changed

+61
-23
lines changed

2 files changed

+61
-23
lines changed

Cargo.toml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@ allocator = { git = "https://github.com/arceos-org/allocator.git", tag = "v0.1.2
7171
"axerrno",
7272
] }
7373
axbacktrace = "0.1"
74-
axdriver_base = { git = "https://github.com/arceos-org/axdriver_crates.git", tag = "dev-v01" }
75-
axdriver_block = { git = "https://github.com/arceos-org/axdriver_crates.git", tag = "dev-v01" }
76-
axdriver_display = { git = "https://github.com/arceos-org/axdriver_crates.git", tag = "dev-v01" }
77-
axdriver_input = { git = "https://github.com/arceos-org/axdriver_crates.git", tag = "dev-v01" }
78-
axdriver_net = { git = "https://github.com/arceos-org/axdriver_crates.git", tag = "dev-v01" }
79-
axdriver_pci = { git = "https://github.com/arceos-org/axdriver_crates.git", tag = "dev-v01" }
80-
axdriver_virtio = { git = "https://github.com/arceos-org/axdriver_crates.git", tag = "dev-v01" }
81-
axdriver_vsock = { git = "https://github.com/arceos-org/axdriver_crates.git", tag = "dev-v01" }
74+
axdriver_base = { git = "https://github.com/arceos-org/axdriver_crates.git", tag = "v0.1.2-dev.0" }
75+
axdriver_block = { git = "https://github.com/arceos-org/axdriver_crates.git", tag = "v0.1.2-dev.0" }
76+
axdriver_display = { git = "https://github.com/arceos-org/axdriver_crates.git", tag = "v0.1.2-dev.0" }
77+
axdriver_input = { git = "https://github.com/arceos-org/axdriver_crates.git", tag = "v0.1.2-dev.0" }
78+
axdriver_net = { git = "https://github.com/arceos-org/axdriver_crates.git", tag = "v0.1.2-dev.0" }
79+
axdriver_pci = { git = "https://github.com/arceos-org/axdriver_crates.git", tag = "v0.1.2-dev.0" }
80+
axdriver_virtio = { git = "https://github.com/arceos-org/axdriver_crates.git", tag = "v0.1.2-dev.0" }
81+
axdriver_vsock = { git = "https://github.com/arceos-org/axdriver_crates.git", tag = "v0.1.2-dev.0" }
8282
axerrno = "0.2"
8383
axfs-ng-vfs = "0.1"
8484
axio = "0.3.0-pre.1"

modules/axnet/src/device/vsock.rs

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use alloc::collections::VecDeque;
12
use core::{
23
sync::atomic::{AtomicBool, AtomicU64, Ordering},
34
time::Duration,
@@ -12,6 +13,9 @@ use crate::{alloc::string::ToString, vsock::connection_manager::VSOCK_CONN_MANAG
1213

1314
// we need a global and static only one vsock device
1415
static VSOCK_DEVICE: Mutex<Option<AxVsockDevice>> = Mutex::new(None);
16+
static PENDING_EVENTS: Mutex<VecDeque<VsockDriverEvent>> = Mutex::new(VecDeque::new());
17+
18+
const VSOCK_RX_TMPBUF_SIZE: usize = 0x1000; // 4KiB buffer for vsock receive
1519

1620
/// Registers a vsock device. Only one vsock device can be registered.
1721
pub fn register_vsock_device(dev: AxVsockDevice) -> AxResult {
@@ -90,7 +94,7 @@ pub fn stop_vsock_poll() {
9094
}
9195
*count -= 1;
9296
let new_count = *count;
93-
debug!("stop_vsock_poll: ref_count -> {}", new_count);
97+
debug!("stop_vsock_poll: ref_count -> {new_count}");
9498
}
9599

96100
fn vsock_poll_loop() {
@@ -118,10 +122,7 @@ async fn poll_interfaces_adaptive() -> AxResult<()> {
118122

119123
let (idle_count, interval_us) = POLL_FREQUENCY.stats();
120124
if idle_count > 0 && idle_count % 10 == 0 {
121-
trace!(
122-
"Poll frequency: idle_count={}, interval={}μs",
123-
idle_count, interval_us
124-
);
125+
trace!("Poll frequency: idle_count={idle_count}, interval={interval_us}μs",);
125126
}
126127
axtask::future::sleep(interval).await;
127128
Ok(())
@@ -131,43 +132,80 @@ fn poll_vsock_interfaces() -> AxResult<bool> {
131132
let mut guard = VSOCK_DEVICE.lock();
132133
let dev = guard.as_mut().ok_or(AxError::NotFound)?;
133134
let mut event_count = 0;
134-
let mut buf = alloc::vec![0; 0x1000]; // 4KiB buffer for receiving data
135+
let mut buf = alloc::vec![0; VSOCK_RX_TMPBUF_SIZE];
136+
137+
// Process pending events first
138+
// Use core::mem::take to atomically move all events out and empty the global queue
139+
let pending_events = core::mem::take(&mut *PENDING_EVENTS.lock());
140+
for event in pending_events {
141+
handle_vsock_event(event, dev, &mut buf);
142+
}
135143

136144
loop {
137-
match dev.poll_event(&mut buf) {
145+
match dev.poll_event() {
138146
Ok(None) => break, // no more events
139147
Ok(Some(event)) => {
140148
event_count += 1;
141-
handle_vsock_event(event, &buf);
149+
handle_vsock_event(event, dev, &mut buf);
142150
}
143151
Err(e) => {
144-
info!("Failed to poll vsock event: {:?}", e);
152+
info!("Failed to poll vsock event: {e:?}");
145153
break;
146154
}
147155
}
148156
}
149157
Ok(event_count > 0)
150158
}
151159

152-
fn handle_vsock_event(event: VsockDriverEvent, buf: &[u8]) {
160+
fn handle_vsock_event(event: VsockDriverEvent, dev: &mut AxVsockDevice, buf: &mut [u8]) {
153161
let mut manager = VSOCK_CONN_MANAGER.lock();
154-
debug!("Handling vsock event: {:?}", event);
162+
debug!("Handling vsock event: {event:?}");
155163

156164
match event {
157165
VsockDriverEvent::ConnectionRequest(conn_id) => {
158-
let _ = manager.on_connection_request(conn_id);
166+
if let Err(e) = manager.on_connection_request(conn_id) {
167+
info!("Connection request failed: {conn_id:?}, error={e:?}");
168+
}
159169
}
160170

161171
VsockDriverEvent::Received(conn_id, len) => {
162-
let _ = manager.on_data_received(conn_id, &buf[..len]);
172+
let free_space = if let Some(conn) = manager.get_connection(conn_id) {
173+
conn.lock().rx_buffer_free()
174+
} else {
175+
info!("Received data for unknown connection: {conn_id:?}");
176+
return;
177+
};
178+
179+
if free_space == 0 {
180+
PENDING_EVENTS
181+
.lock()
182+
.push_back(VsockDriverEvent::Received(conn_id, len));
183+
return;
184+
}
185+
186+
let max_read = core::cmp::min(free_space, buf.len());
187+
match dev.recv(conn_id, &mut buf[..max_read]) {
188+
Ok(read_len) => {
189+
if let Err(e) = manager.on_data_received(conn_id, &buf[..read_len]) {
190+
info!("Failed to handle received data: conn_id={conn_id:?}, error={e:?}",);
191+
}
192+
}
193+
Err(e) => {
194+
info!("Failed to receive vsock data: conn_id={conn_id:?}, error={e:?}",);
195+
}
196+
}
163197
}
164198

165199
VsockDriverEvent::Disconnected(conn_id) => {
166-
let _ = manager.on_disconnected(conn_id);
200+
if let Err(e) = manager.on_disconnected(conn_id) {
201+
info!("Failed to handle disconnection: {conn_id:?}, error={e:?}",);
202+
}
167203
}
168204

169205
VsockDriverEvent::Connected(conn_id) => {
170-
let _ = manager.on_connected(conn_id);
206+
if let Err(e) = manager.on_connected(conn_id) {
207+
info!("Failed to handle connection established: {conn_id:?}, error={e:?}",);
208+
}
171209
}
172210

173211
VsockDriverEvent::Unknown => warn!("Received unknown vsock event"),

0 commit comments

Comments
 (0)