diff --git a/kernel/src/driver/tty/tty_port.rs b/kernel/src/driver/tty/tty_port.rs index bab9ea7fd..a44b969a4 100644 --- a/kernel/src/driver/tty/tty_port.rs +++ b/kernel/src/driver/tty/tty_port.rs @@ -6,7 +6,7 @@ use system_error::SystemError; use crate::{ libs::spinlock::{SpinLock, SpinLockGuard}, - net::event_poll::EventPoll, + net::event_poll::{EPollEventType, EventPoll}, }; use super::tty_core::TtyCore; @@ -80,17 +80,14 @@ pub trait TtyPort: Sync + Send + Debug { /// 作为客户端的tty ports接收数据 fn receive_buf(&self, buf: &[u8], _flags: &[u8], count: usize) -> Result { let tty = self.port_data().internal_tty().unwrap(); - let ld = tty.ldisc(); - let ret = ld.receive_buf2(tty.clone(), buf, None, count); - if let Err(SystemError::ENOSYS) = ret { return ld.receive_buf(tty, buf, None, count); } - - EventPoll::wakeup_epoll(tty.core().eptiems(), None)?; - + let event: usize = ld.poll(tty.clone())?; + let pollflag = EPollEventType::from_bits_truncate(event as u32); + EventPoll::wakeup_epoll(tty.core().eptiems(), pollflag)?; ret } } diff --git a/kernel/src/filesystem/eventfd.rs b/kernel/src/filesystem/eventfd.rs index fbb4ef8d2..d1e9d3575 100644 --- a/kernel/src/filesystem/eventfd.rs +++ b/kernel/src/filesystem/eventfd.rs @@ -186,7 +186,7 @@ impl IndexNode for EventFdInode { drop(eventfd); // 唤醒epoll中等待的进程 - EventPoll::wakeup_epoll(&self.epitems, Some(pollflag))?; + EventPoll::wakeup_epoll(&self.epitems, pollflag)?; return Ok(8); } @@ -240,7 +240,7 @@ impl IndexNode for EventFdInode { drop(eventfd); // 唤醒epoll中等待的进程 - EventPoll::wakeup_epoll(&self.epitems, Some(pollflag))?; + EventPoll::wakeup_epoll(&self.epitems, pollflag)?; return Ok(8); } diff --git a/kernel/src/filesystem/poll.rs b/kernel/src/filesystem/poll.rs index 66cba3695..3af25318a 100644 --- a/kernel/src/filesystem/poll.rs +++ b/kernel/src/filesystem/poll.rs @@ -64,9 +64,11 @@ impl<'a> PollAdapter<'a> { fn poll_all_fds(&mut self, timeout: Option) -> Result { let mut epoll_events = vec![EPollEvent::default(); self.poll_fds.len()]; let len = epoll_events.len() as i32; - let remain_timeout = timeout - .and_then(|t| t.duration_since(Instant::now())) - .map(|t| t.into()); + let remain_timeout = timeout.map(|t| { + t.duration_since(Instant::now()) + .unwrap_or(Duration::ZERO) + .into() + }); let events = EventPoll::epoll_wait_with_file( self.ep_file.clone(), &mut epoll_events, @@ -176,10 +178,6 @@ fn do_sys_poll(poll_fds: &mut [PollFd], timeout: Option) -> Result Option { - if timeout_ms == 0 { - return None; - } - Some(Instant::now() + Duration::from_millis(timeout_ms)) } diff --git a/kernel/src/init/init.rs b/kernel/src/init/init.rs index bdb812760..d5d979c30 100644 --- a/kernel/src/init/init.rs +++ b/kernel/src/init/init.rs @@ -93,10 +93,12 @@ fn do_start_kernel() { crate::bpf::init_bpf_system(); crate::debug::jump_label::static_keys_init(); - // #[cfg(all(target_arch = "x86_64", feature = "kvm"))] - // crate::virt::kvm::kvm_init(); #[cfg(all(target_arch = "x86_64", feature = "kvm"))] - crate::arch::vm::vmx::vmx_init().unwrap(); + { + if let Err(e) = crate::arch::vm::vmx::vmx_init() { + log::error!("KVM init failed: {:?}", e); + } + } } /// 在内存管理初始化之前,执行的初始化 diff --git a/kernel/src/ipc/pipe.rs b/kernel/src/ipc/pipe.rs index 4f69801c5..d98adeab7 100644 --- a/kernel/src/ipc/pipe.rs +++ b/kernel/src/ipc/pipe.rs @@ -287,7 +287,7 @@ impl IndexNode for LockedPipeInode { let pollflag = EPollEventType::from_bits_truncate(inner_guard.poll(&data)? as u32); drop(inner_guard); // 唤醒epoll中等待的进程 - EventPoll::wakeup_epoll(&self.epitems, Some(pollflag))?; + EventPoll::wakeup_epoll(&self.epitems, pollflag)?; //返回读取的字节数 return Ok(num); @@ -476,7 +476,7 @@ impl IndexNode for LockedPipeInode { drop(inner_guard); // 唤醒epoll中等待的进程 - EventPoll::wakeup_epoll(&self.epitems, Some(pollflag))?; + EventPoll::wakeup_epoll(&self.epitems, pollflag)?; // 返回写入的字节数 return Ok(len); diff --git a/kernel/src/net/event_poll/mod.rs b/kernel/src/net/event_poll/mod.rs index 9e80cae8b..f8fc2abd5 100644 --- a/kernel/src/net/event_poll/mod.rs +++ b/kernel/src/net/event_poll/mod.rs @@ -479,7 +479,7 @@ impl EventPoll { } } else if timespec.is_none() { // 非阻塞情况 - timeout = true; + timeout = false; } // 判断epoll上有没有就绪事件 let mut available = epoll_guard.ep_events_available(); @@ -775,52 +775,37 @@ impl EventPoll { /// ### epoll的回调,支持epoll的文件有事件到来时直接调用该方法即可 pub fn wakeup_epoll( epitems: &SpinLock>>, - pollflags: Option, + pollflags: EPollEventType, ) -> Result<(), SystemError> { - let mut epitems_guard = epitems.try_lock_irqsave()?; - // 一次只取一个,因为一次也只有一个进程能拿到对应文件的🔓 - if let Some(epitem) = epitems_guard.pop_front() { - let pollflags = match pollflags { - Some(flags) => flags, - None => { - if let Some(file) = epitem.file.upgrade() { - // warning: deadlock will happen if poll() is called when pollflags is None - EPollEventType::from_bits_truncate(file.poll()? as u32) - } else { - EPollEventType::empty() - } - } - }; + let epitems_guard = epitems.try_lock_irqsave()?; + for epitem in epitems_guard.iter() { + // The upgrade is safe because EventPoll always exists when the epitem is in the list + let epoll = epitem.epoll().upgrade().unwrap(); + let mut epoll_guard = epoll.try_lock()?; + let binding = epitem.clone(); + let event_guard = binding.event().read(); + let ep_events = EPollEventType::from_bits_truncate(event_guard.events()); + // 检查事件合理性以及是否有感兴趣的事件 + if !(ep_events + .difference(EPollEventType::EP_PRIVATE_BITS) + .is_empty() + || pollflags.difference(ep_events).is_empty()) + { + // TODO: 未处理pm相关 - if let Some(epoll) = epitem.epoll().upgrade() { - let mut epoll_guard = epoll.try_lock()?; - let binding = epitem.clone(); - let event_guard = binding.event().read(); - let ep_events = EPollEventType::from_bits_truncate(event_guard.events()); - // 检查事件合理性以及是否有感兴趣的事件 - if !(ep_events - .difference(EPollEventType::EP_PRIVATE_BITS) - .is_empty() - || pollflags.difference(ep_events).is_empty()) - { - // TODO: 未处理pm相关 - - // 首先将就绪的epitem加入等待队列 - epoll_guard.ep_add_ready(epitem.clone()); - - if epoll_guard.ep_has_waiter() { - if ep_events.contains(EPollEventType::EPOLLEXCLUSIVE) - && !pollflags.contains(EPollEventType::POLLFREE) - { - // 避免惊群 - epoll_guard.ep_wake_one(); - } else { - epoll_guard.ep_wake_all(); - } + // 首先将就绪的epitem加入等待队列 + epoll_guard.ep_add_ready(epitem.clone()); + + if epoll_guard.ep_has_waiter() { + if ep_events.contains(EPollEventType::EPOLLEXCLUSIVE) + && !pollflags.contains(EPollEventType::POLLFREE) + { + // 避免惊群 + epoll_guard.ep_wake_one(); + } else { + epoll_guard.ep_wake_all(); } } - - epitems_guard.push_back(epitem); } } Ok(()) diff --git a/kernel/src/net/net_core.rs b/kernel/src/net/net_core.rs index b90a35aa6..d1c4d0c97 100644 --- a/kernel/src/net/net_core.rs +++ b/kernel/src/net/net_core.rs @@ -245,7 +245,7 @@ fn send_event(sockets: &smoltcp::iface::SocketSet) -> Result<(), SystemError> { } EventPoll::wakeup_epoll( &posix_item.epitems, - Some(EPollEventType::from_bits_truncate(events as u32)), + EPollEventType::from_bits_truncate(events as u32), )?; drop(handle_guard); // crate::debug!( diff --git a/kernel/src/perf/mod.rs b/kernel/src/perf/mod.rs index 50e3daa17..35ca7297b 100644 --- a/kernel/src/perf/mod.rs +++ b/kernel/src/perf/mod.rs @@ -77,7 +77,7 @@ impl PerfEventInode { fn epoll_callback(&self) -> Result<()> { let pollflag = EPollEventType::from_bits_truncate(self.do_poll()? as u32); // 唤醒epoll中等待的进程 - EventPoll::wakeup_epoll(&self.epitems, Some(pollflag)) + EventPoll::wakeup_epoll(&self.epitems, pollflag) } } diff --git a/user/apps/test_epoll/main.c b/user/apps/test_epoll/main.c index e09faad62..f1cfd72e6 100644 --- a/user/apps/test_epoll/main.c +++ b/user/apps/test_epoll/main.c @@ -98,19 +98,26 @@ int main() { printf("主线程:epoll_wait 返回,事件数量 = %d\n", nfds); } + if (nfds != 2) { + printf("主线程:事件数量不匹配,预期 2,实际 %d\n", nfds); + exit(EXIT_FAILURE); + } + + // 由于dup复制了 eventfd 描述符,所以 只需要处理一个就行 + nfds -= 1; // 处理就绪事件 - // for (int i = 0; i < nfds; i++) { - // if (events[i].data.fd == efd || events[i].data.fd == efd2) { - // uint64_t count; - // int fd = events[i].data.fd; - // printf("主线程:事件发生在 fd = %d\n", fd); - // if (read(fd, &count, sizeof(count)) != sizeof(count)) { - // perror("从 eventfd 读取失败"); - // exit(EXIT_FAILURE); - // } - // printf("主线程:接收到 eventfd 事件,计数值 = %lu\n", count); - // } - // } + for (int i = 0; i < nfds; i++) { + if (events[i].data.fd == efd || events[i].data.fd == efd2) { + uint64_t count; + int fd = events[i].data.fd; + printf("主线程:事件发生在 fd = %d\n", fd); + if (read(fd, &count, sizeof(count)) != sizeof(count)) { + perror("从 eventfd 读取失败"); + exit(EXIT_FAILURE); + } + printf("主线程:接收到 eventfd 事件,计数值 = %lu\n", count); + } + } // 等待工作线程结束 pthread_join(tid, NULL);