Skip to content
This repository was archived by the owner on Oct 24, 2022. It is now read-only.

Commit e8beb23

Browse files
committed
epoll: refine the way to manage event id
Refine the way to manage epoll event id and simplify interfaces: - Change VhostUserBackend::exit_event() to return Option<EventFd> instead of Option<(EventFd, u16)>. - Delete VringEpollHandler::exit_event_id. - Add VringEpollHandler::register_event/unregister_event for internal use. - Make VringEpollHandler::register_listener/unregister_listener() for external users only, and 'data` range [0..backend.num_queues()] is reserved for queues and exit event. Signed-off-by: Liu Jiang <[email protected]>
1 parent 5998cea commit e8beb23

File tree

4 files changed

+57
-28
lines changed

4 files changed

+57
-28
lines changed

coverage_config_x86_64.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"coverage_score": 77.4,
2+
"coverage_score": 79.1,
33
"exclude_path": "",
44
"crate_features": ""
55
}

src/backend.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ where
9999
/// If an (`EventFd`, `token`) pair is returned, the returned `EventFd` will be monitored for IO
100100
/// events by using epoll with the specified `token`. When the returned EventFd is written to,
101101
/// the worker thread will exit.
102-
fn exit_event(&self, _thread_index: usize) -> Option<(EventFd, u16)> {
102+
fn exit_event(&self, _thread_index: usize) -> Option<EventFd> {
103103
None
104104
}
105105

@@ -182,7 +182,7 @@ where
182182
/// If an (`EventFd`, `token`) pair is returned, the returned `EventFd` will be monitored for IO
183183
/// events by using epoll with the specified `token`. When the returned EventFd is written to,
184184
/// the worker thread will exit.
185-
fn exit_event(&self, _thread_index: usize) -> Option<(EventFd, u16)> {
185+
fn exit_event(&self, _thread_index: usize) -> Option<EventFd> {
186186
None
187187
}
188188

@@ -249,7 +249,7 @@ where
249249
self.deref().queues_per_thread()
250250
}
251251

252-
fn exit_event(&self, thread_index: usize) -> Option<(EventFd, u16)> {
252+
fn exit_event(&self, thread_index: usize) -> Option<EventFd> {
253253
self.deref().exit_event(thread_index)
254254
}
255255

@@ -314,7 +314,7 @@ where
314314
self.lock().unwrap().queues_per_thread()
315315
}
316316

317-
fn exit_event(&self, thread_index: usize) -> Option<(EventFd, u16)> {
317+
fn exit_event(&self, thread_index: usize) -> Option<EventFd> {
318318
self.lock().unwrap().exit_event(thread_index)
319319
}
320320

@@ -380,7 +380,7 @@ where
380380
self.read().unwrap().queues_per_thread()
381381
}
382382

383-
fn exit_event(&self, thread_index: usize) -> Option<(EventFd, u16)> {
383+
fn exit_event(&self, thread_index: usize) -> Option<EventFd> {
384384
self.read().unwrap().exit_event(thread_index)
385385
}
386386

@@ -475,10 +475,10 @@ pub mod tests {
475475
vec![1, 1]
476476
}
477477

478-
fn exit_event(&self, _thread_index: usize) -> Option<(EventFd, u16)> {
478+
fn exit_event(&self, _thread_index: usize) -> Option<EventFd> {
479479
let event_fd = EventFd::new(0).unwrap();
480480

481-
Some((event_fd, 0x100))
481+
Some(event_fd)
482482
}
483483

484484
fn handle_event(

src/event_loop.rs

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ where
7070
vrings: Vec<V>,
7171
thread_id: usize,
7272
exit_event_fd: Option<EventFd>,
73-
exit_event_id: Option<u16>,
7473
phantom: PhantomData<B>,
7574
}
7675

@@ -86,12 +85,13 @@ where
8685
let epoll_file = unsafe { File::from_raw_fd(epoll_fd) };
8786

8887
let handler = match backend.exit_event(thread_id) {
89-
Some((exit_event_fd, exit_event_id)) => {
88+
Some(exit_event_fd) => {
89+
let id = backend.num_queues();
9090
epoll::ctl(
9191
epoll_file.as_raw_fd(),
9292
epoll::ControlOptions::EPOLL_CTL_ADD,
9393
exit_event_fd.as_raw_fd(),
94-
epoll::Event::new(epoll::Events::EPOLLIN, u64::from(exit_event_id)),
94+
epoll::Event::new(epoll::Events::EPOLLIN, id as u64),
9595
)
9696
.map_err(VringEpollError::RegisterExitEvent)?;
9797

@@ -101,7 +101,6 @@ where
101101
vrings,
102102
thread_id,
103103
exit_event_fd: Some(exit_event_fd),
104-
exit_event_id: Some(exit_event_id),
105104
phantom: PhantomData,
106105
}
107106
}
@@ -111,7 +110,6 @@ where
111110
vrings,
112111
thread_id,
113112
exit_event_fd: None,
114-
exit_event_id: None,
115113
phantom: PhantomData,
116114
},
117115
};
@@ -135,6 +133,38 @@ where
135133
fd: RawFd,
136134
ev_type: epoll::Events,
137135
data: u64,
136+
) -> result::Result<(), io::Error> {
137+
// `data` range [0...num_queues] is reserved for queues and exit event.
138+
if data <= self.backend.num_queues() as u64 {
139+
Err(io::Error::from_raw_os_error(libc::EINVAL))
140+
} else {
141+
self.register_event(fd, ev_type, data)
142+
}
143+
}
144+
145+
/// Unregister an event from the epoll fd.
146+
///
147+
/// If the event is triggered after this function has been called, the event will be silently
148+
/// dropped.
149+
pub fn unregister_listener(
150+
&self,
151+
fd: RawFd,
152+
ev_type: epoll::Events,
153+
data: u64,
154+
) -> result::Result<(), io::Error> {
155+
// `data` range [0...num_queues] is reserved for queues and exit event.
156+
if data <= self.backend.num_queues() as u64 {
157+
Err(io::Error::from_raw_os_error(libc::EINVAL))
158+
} else {
159+
self.unregister_event(fd, ev_type, data)
160+
}
161+
}
162+
163+
pub(crate) fn register_event(
164+
&self,
165+
fd: RawFd,
166+
ev_type: epoll::Events,
167+
data: u64,
138168
) -> result::Result<(), io::Error> {
139169
epoll::ctl(
140170
self.epoll_file.as_raw_fd(),
@@ -144,11 +174,7 @@ where
144174
)
145175
}
146176

147-
/// Unregister an event from the epoll fd.
148-
///
149-
/// If the event is triggered after this function has been called, the event will be silently
150-
/// dropped.
151-
pub fn unregister_listener(
177+
pub(crate) fn unregister_event(
152178
&self,
153179
fd: RawFd,
154180
ev_type: epoll::Events,
@@ -211,7 +237,7 @@ where
211237
}
212238

213239
fn handle_event(&self, device_event: u16, evset: epoll::Events) -> VringEpollResult<bool> {
214-
if self.exit_event_id == Some(device_event) {
240+
if self.exit_event_fd.is_some() && device_event as usize == self.backend.num_queues() {
215241
return Ok(true);
216242
}
217243

@@ -251,21 +277,28 @@ mod tests {
251277
let backend = Arc::new(Mutex::new(MockVhostBackend::new()));
252278

253279
let handler = VringEpollHandler::new(backend, vec![vring], 0x1).unwrap();
254-
assert!(handler.exit_event_id.is_some());
255280

256281
let eventfd = EventFd::new(0).unwrap();
257282
handler
258-
.register_listener(eventfd.as_raw_fd(), epoll::Events::EPOLLIN, 1)
283+
.register_listener(eventfd.as_raw_fd(), epoll::Events::EPOLLIN, 3)
259284
.unwrap();
260285
// Register an already registered fd.
286+
handler
287+
.register_listener(eventfd.as_raw_fd(), epoll::Events::EPOLLIN, 3)
288+
.unwrap_err();
289+
// Register an invalid data.
261290
handler
262291
.register_listener(eventfd.as_raw_fd(), epoll::Events::EPOLLIN, 1)
263292
.unwrap_err();
264293

265294
handler
266-
.unregister_listener(eventfd.as_raw_fd(), epoll::Events::EPOLLIN, 1)
295+
.unregister_listener(eventfd.as_raw_fd(), epoll::Events::EPOLLIN, 3)
267296
.unwrap();
268297
// unregister an already unregistered fd.
298+
handler
299+
.unregister_listener(eventfd.as_raw_fd(), epoll::Events::EPOLLIN, 3)
300+
.unwrap_err();
301+
// unregister an invalid data.
269302
handler
270303
.unregister_listener(eventfd.as_raw_fd(), epoll::Events::EPOLLIN, 1)
271304
.unwrap_err();

src/handler.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ where
350350
if shifted_queues_mask & 1u64 == 1u64 {
351351
let evt_idx = queues_mask.count_ones() - shifted_queues_mask.count_ones();
352352
self.handlers[thread_index]
353-
.unregister_listener(
353+
.unregister_event(
354354
fd.as_raw_fd(),
355355
epoll::Events::EPOLLIN,
356356
u64::from(evt_idx),
@@ -389,11 +389,7 @@ where
389389
if shifted_queues_mask & 1u64 == 1u64 {
390390
let evt_idx = queues_mask.count_ones() - shifted_queues_mask.count_ones();
391391
self.handlers[thread_index]
392-
.register_listener(
393-
fd.as_raw_fd(),
394-
epoll::Events::EPOLLIN,
395-
u64::from(evt_idx),
396-
)
392+
.register_event(fd.as_raw_fd(), epoll::Events::EPOLLIN, u64::from(evt_idx))
397393
.map_err(VhostUserError::ReqHandlerError)?;
398394
break;
399395
}

0 commit comments

Comments
 (0)