MCPcopy Create free account
hub / github.com/cloud-hypervisor/cloud-hypervisor / uffd_handler_loop

Method uffd_handler_loop

vmm/src/memory_manager.rs:1110–1273  ·  view source on GitHub ↗
(
        uffd_fd: OwnedFd,
        stop_event: EventFd,
        mut snapshot_file: File,
        ranges: &[UffdRange],
        page_size: u64,
        ready_tx: &SyncSender<()>,
    )

Source from the content-addressed store, hash-verified

1108 /// `UFFDIO_COPY` to resolve the fault and wake the faulting thread.
1109 #[allow(clippy::needless_pass_by_value)]
1110 fn uffd_handler_loop(
1111 uffd_fd: OwnedFd,
1112 stop_event: EventFd,
1113 mut snapshot_file: File,
1114 ranges: &[UffdRange],
1115 page_size: u64,
1116 ready_tx: &SyncSender<()>,
1117 ) -> Result<(), io::Error> {
1118 let uffd_raw_fd = uffd_fd.as_raw_fd();
1119 let mut page_buf = vec![0u8; page_size as usize];
1120
1121 let total_pages: u64 = ranges.iter().map(|r| r.length.div_ceil(r.page_size)).sum();
1122 let mut pages_served: u64 = 0;
1123
1124 const EVENT_STOP: u64 = 0;
1125 const EVENT_UFFD: u64 = 1;
1126
1127 let epoll_fd = epoll::create(true).map_err(io::Error::other)?;
1128 // SAFETY: epoll_fd is valid and owned by this scope.
1129 let _epoll_file = unsafe { File::from_raw_fd(epoll_fd) };
1130
1131 epoll::ctl(
1132 epoll_fd,
1133 epoll::ControlOptions::EPOLL_CTL_ADD,
1134 stop_event.as_raw_fd(),
1135 epoll::Event::new(epoll::Events::EPOLLIN, EVENT_STOP),
1136 )
1137 .map_err(io::Error::other)?;
1138
1139 epoll::ctl(
1140 epoll_fd,
1141 epoll::ControlOptions::EPOLL_CTL_ADD,
1142 uffd_raw_fd,
1143 epoll::Event::new(epoll::Events::EPOLLIN | epoll::Events::EPOLLHUP, EVENT_UFFD),
1144 )
1145 .map_err(io::Error::other)?;
1146
1147 ready_tx.send(()).ok();
1148
1149 let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); 2];
1150 loop {
1151 let num_events = match epoll::wait(epoll_fd, -1, &mut events) {
1152 Ok(n) => n,
1153 Err(e) if e.kind() == io::ErrorKind::Interrupted => continue,
1154 Err(e) => return Err(e),
1155 };
1156
1157 let mut got_uffd_data = false;
1158 for event in events.iter().take(num_events) {
1159 let token = event.data;
1160 let evt_flags = event.events;
1161
1162 if token == EVENT_STOP {
1163 stop_event.read().ok();
1164 info!("UFFD handler: received stop event, exiting");
1165 return Ok(());
1166 }
1167

Callers

nothing calls this directly

Calls 15

createFunction · 0.85
newFunction · 0.85
readFunction · 0.85
copyFunction · 0.85
wakeFunction · 0.85
iterMethod · 0.80
okMethod · 0.80
kindMethod · 0.80
takeMethod · 0.80
as_raw_fdMethod · 0.45
mapMethod · 0.45
sendMethod · 0.45

Tested by

no test coverage detected