1 // Copyright 2019 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 use std::fmt; 6 use std::fmt::Display; 7 use std::sync::Arc; 8 use std::sync::MutexGuard; 9 10 use anyhow::Context; 11 use base::debug; 12 use base::error; 13 use base::info; 14 use base::Error as SysError; 15 use base::Event; 16 use base::EventType; 17 use remain::sorted; 18 use sync::Mutex; 19 use thiserror::Error; 20 use vm_memory::GuestAddress; 21 use vm_memory::GuestMemory; 22 23 use super::ring_buffer::RingBuffer; 24 use super::ring_buffer_stop_cb::RingBufferStopCallback; 25 use super::xhci_abi::TransferDescriptor; 26 use crate::utils; 27 use crate::utils::EventHandler; 28 use crate::utils::EventLoop; 29 30 #[sorted] 31 #[derive(Error, Debug)] 32 pub enum Error { 33 #[error("failed to add event to event loop: {0}")] 34 AddEvent(utils::Error), 35 #[error("failed to create event: {0}")] 36 CreateEvent(SysError), 37 } 38 39 type Result<T> = std::result::Result<T, Error>; 40 41 #[derive(PartialEq, Copy, Clone, Eq)] 42 enum RingBufferState { 43 /// Running: RingBuffer is running, consuming transfer descriptor. 44 Running, 45 /// Stopping: Some thread requested RingBuffer stop. It will stop when current descriptor is 46 /// handled. 47 Stopping, 48 /// Stopped: RingBuffer already stopped. 49 Stopped, 50 } 51 52 /// TransferDescriptorHandler handles transfer descriptor. User should implement this trait and 53 /// build a ring buffer controller with the struct. 54 pub trait TransferDescriptorHandler { 55 /// Process descriptor asynchronously, write complete_event when done. handle_transfer_descriptor( &self, descriptor: TransferDescriptor, complete_event: Event, ) -> anyhow::Result<()>56 fn handle_transfer_descriptor( 57 &self, 58 descriptor: TransferDescriptor, 59 complete_event: Event, 60 ) -> anyhow::Result<()>; 61 62 /// Stop is called when trying to stop ring buffer controller. Returns true when stop must be 63 /// performed asynchronously. This happens because the handler is handling some descriptor 64 /// asynchronously, the stop callback of ring buffer controller must be called after the 65 /// `async` part is handled or canceled. If the TransferDescriptorHandler decide it could stop 66 /// immediately, it could return false. 67 /// For example, if a handler submitted a transfer but the transfer has not yet finished. Then 68 /// guest kernel requests to stop the ring buffer controller. Transfer descriptor handler will 69 /// return true, thus RingBufferController would transfer to Stopping state. It will be stopped 70 /// when all pending transfer completed. 71 /// On the other hand, if hander does not have any pending transfers, it would return false. stop(&self) -> bool72 fn stop(&self) -> bool { 73 true 74 } 75 } 76 77 /// RingBufferController owns a ring buffer. It lives on a event_loop. It will pop out transfer 78 /// descriptor and let TransferDescriptorHandler handle it. 79 pub struct RingBufferController<T: 'static + TransferDescriptorHandler> { 80 name: String, 81 state: Mutex<RingBufferState>, 82 stop_callback: Mutex<Vec<RingBufferStopCallback>>, 83 ring_buffer: Mutex<RingBuffer>, 84 handler: Mutex<T>, 85 event_loop: Arc<EventLoop>, 86 event: Event, 87 } 88 89 impl<T: 'static + TransferDescriptorHandler> Display for RingBufferController<T> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result90 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 91 write!(f, "RingBufferController `{}`", self.name) 92 } 93 } 94 95 impl<T: Send> RingBufferController<T> 96 where 97 T: 'static + TransferDescriptorHandler, 98 { 99 /// Create a ring buffer controller and add it to event loop. new_with_handler( name: String, mem: GuestMemory, event_loop: Arc<EventLoop>, handler: T, ) -> Result<Arc<RingBufferController<T>>>100 pub fn new_with_handler( 101 name: String, 102 mem: GuestMemory, 103 event_loop: Arc<EventLoop>, 104 handler: T, 105 ) -> Result<Arc<RingBufferController<T>>> { 106 let evt = Event::new().map_err(Error::CreateEvent)?; 107 let controller = Arc::new(RingBufferController { 108 name: name.clone(), 109 state: Mutex::new(RingBufferState::Stopped), 110 stop_callback: Mutex::new(Vec::new()), 111 ring_buffer: Mutex::new(RingBuffer::new(name, mem)), 112 handler: Mutex::new(handler), 113 event_loop: event_loop.clone(), 114 event: evt, 115 }); 116 let event_handler: Arc<dyn EventHandler> = controller.clone(); 117 event_loop 118 .add_event( 119 &controller.event, 120 EventType::Read, 121 Arc::downgrade(&event_handler), 122 ) 123 .map_err(Error::AddEvent)?; 124 Ok(controller) 125 } 126 lock_ring_buffer(&self) -> MutexGuard<RingBuffer>127 fn lock_ring_buffer(&self) -> MutexGuard<RingBuffer> { 128 self.ring_buffer.lock() 129 } 130 131 /// Get dequeue pointer of the internal ring buffer. get_dequeue_pointer(&self) -> GuestAddress132 pub fn get_dequeue_pointer(&self) -> GuestAddress { 133 self.lock_ring_buffer().get_dequeue_pointer() 134 } 135 136 /// Set dequeue pointer of the internal ring buffer. set_dequeue_pointer(&self, ptr: GuestAddress)137 pub fn set_dequeue_pointer(&self, ptr: GuestAddress) { 138 xhci_trace!("{}: set_dequeue_pointer({:x})", self.name, ptr.0); 139 // Fast because this should only happen during xhci setup. 140 self.lock_ring_buffer().set_dequeue_pointer(ptr); 141 } 142 143 /// Get consumer cycle state. get_consumer_cycle_state(&self) -> bool144 pub fn get_consumer_cycle_state(&self) -> bool { 145 self.lock_ring_buffer().get_consumer_cycle_state() 146 } 147 148 /// Set consumer cycle state. set_consumer_cycle_state(&self, state: bool)149 pub fn set_consumer_cycle_state(&self, state: bool) { 150 xhci_trace!("{}: set consumer cycle state: {}", self.name, state); 151 // Fast because this should only happen during xhci setup. 152 self.lock_ring_buffer().set_consumer_cycle_state(state); 153 } 154 155 /// Start the ring buffer. start(&self)156 pub fn start(&self) { 157 xhci_trace!("start {}", self.name); 158 let mut state = self.state.lock(); 159 if *state != RingBufferState::Running { 160 *state = RingBufferState::Running; 161 if let Err(e) = self.event.signal() { 162 error!("cannot start event ring: {}", e); 163 } 164 } 165 } 166 167 /// Stop the ring buffer asynchronously. stop(&self, callback: RingBufferStopCallback)168 pub fn stop(&self, callback: RingBufferStopCallback) { 169 xhci_trace!("stop {}", self.name); 170 let mut state = self.state.lock(); 171 if *state == RingBufferState::Stopped { 172 info!("xhci: {} is already stopped", self.name); 173 return; 174 } 175 if self.handler.lock().stop() { 176 *state = RingBufferState::Stopping; 177 self.stop_callback.lock().push(callback); 178 } else { 179 *state = RingBufferState::Stopped; 180 } 181 } 182 } 183 184 impl<T> Drop for RingBufferController<T> 185 where 186 T: 'static + TransferDescriptorHandler, 187 { drop(&mut self)188 fn drop(&mut self) { 189 // Remove self from the event loop. 190 if let Err(e) = self.event_loop.remove_event_for_descriptor(&self.event) { 191 error!( 192 "cannot remove ring buffer controller from event loop: {}", 193 e 194 ); 195 } 196 } 197 } 198 199 impl<T> EventHandler for RingBufferController<T> 200 where 201 T: 'static + TransferDescriptorHandler + Send, 202 { on_event(&self) -> anyhow::Result<()>203 fn on_event(&self) -> anyhow::Result<()> { 204 // `self.event` triggers ring buffer controller to run. 205 self.event.wait().context("cannot read from event")?; 206 let mut state = self.state.lock(); 207 208 match *state { 209 RingBufferState::Stopped => return Ok(()), 210 RingBufferState::Stopping => { 211 debug!("xhci: {}: stopping ring buffer controller", self.name); 212 *state = RingBufferState::Stopped; 213 self.stop_callback.lock().clear(); 214 return Ok(()); 215 } 216 RingBufferState::Running => {} 217 } 218 219 let transfer_descriptor = self 220 .lock_ring_buffer() 221 .dequeue_transfer_descriptor() 222 .context("cannot dequeue transfer descriptor")?; 223 224 let transfer_descriptor = match transfer_descriptor { 225 Some(t) => t, 226 None => { 227 *state = RingBufferState::Stopped; 228 self.stop_callback.lock().clear(); 229 return Ok(()); 230 } 231 }; 232 233 let event = self.event.try_clone().context("cannot clone event")?; 234 self.handler 235 .lock() 236 .handle_transfer_descriptor(transfer_descriptor, event) 237 } 238 } 239 240 #[cfg(test)] 241 mod tests { 242 use std::mem::size_of; 243 use std::sync::mpsc::channel; 244 use std::sync::mpsc::Sender; 245 246 use base::pagesize; 247 248 use super::super::xhci_abi::LinkTrb; 249 use super::super::xhci_abi::NormalTrb; 250 use super::super::xhci_abi::Trb; 251 use super::super::xhci_abi::TrbType; 252 use super::*; 253 254 struct TestHandler { 255 sender: Sender<i32>, 256 } 257 258 impl TransferDescriptorHandler for TestHandler { handle_transfer_descriptor( &self, descriptor: TransferDescriptor, complete_event: Event, ) -> anyhow::Result<()>259 fn handle_transfer_descriptor( 260 &self, 261 descriptor: TransferDescriptor, 262 complete_event: Event, 263 ) -> anyhow::Result<()> { 264 for atrb in descriptor { 265 assert_eq!(atrb.trb.get_trb_type().unwrap(), TrbType::Normal); 266 self.sender.send(atrb.trb.get_parameter() as i32).unwrap(); 267 } 268 complete_event.signal().unwrap(); 269 Ok(()) 270 } 271 } 272 setup_mem() -> GuestMemory273 fn setup_mem() -> GuestMemory { 274 let trb_size = size_of::<Trb>() as u64; 275 let gm = GuestMemory::new(&[(GuestAddress(0), pagesize() as u64)]).unwrap(); 276 277 // Structure of ring buffer: 278 // 0x100 --> 0x200 --> 0x300 279 // trb 1 | trb 3 | trb 5 280 // trb 2 | trb 4 | trb 6 281 // l trb - l trb - l trb to 0x100 282 let mut trb = NormalTrb::new(); 283 trb.set_trb_type(TrbType::Normal); 284 trb.set_data_buffer(1); 285 trb.set_chain(true); 286 gm.write_obj_at_addr(trb, GuestAddress(0x100)).unwrap(); 287 288 trb.set_data_buffer(2); 289 gm.write_obj_at_addr(trb, GuestAddress(0x100 + trb_size)) 290 .unwrap(); 291 292 let mut ltrb = LinkTrb::new(); 293 ltrb.set_trb_type(TrbType::Link); 294 ltrb.set_ring_segment_pointer(0x200); 295 gm.write_obj_at_addr(ltrb, GuestAddress(0x100 + 2 * trb_size)) 296 .unwrap(); 297 298 trb.set_data_buffer(3); 299 gm.write_obj_at_addr(trb, GuestAddress(0x200)).unwrap(); 300 301 // Chain bit is false. 302 trb.set_data_buffer(4); 303 trb.set_chain(false); 304 gm.write_obj_at_addr(trb, GuestAddress(0x200 + 1 * trb_size)) 305 .unwrap(); 306 307 ltrb.set_ring_segment_pointer(0x300); 308 gm.write_obj_at_addr(ltrb, GuestAddress(0x200 + 2 * trb_size)) 309 .unwrap(); 310 311 trb.set_data_buffer(5); 312 trb.set_chain(true); 313 gm.write_obj_at_addr(trb, GuestAddress(0x300)).unwrap(); 314 315 // Chain bit is false. 316 trb.set_data_buffer(6); 317 trb.set_chain(false); 318 gm.write_obj_at_addr(trb, GuestAddress(0x300 + 1 * trb_size)) 319 .unwrap(); 320 321 ltrb.set_ring_segment_pointer(0x100); 322 gm.write_obj_at_addr(ltrb, GuestAddress(0x300 + 2 * trb_size)) 323 .unwrap(); 324 gm 325 } 326 327 #[test] test_ring_buffer_controller()328 fn test_ring_buffer_controller() { 329 let (tx, rx) = channel(); 330 let mem = setup_mem(); 331 let (l, j) = EventLoop::start("test".to_string(), None).unwrap(); 332 let l = Arc::new(l); 333 let controller = RingBufferController::new_with_handler( 334 "".to_string(), 335 mem, 336 l.clone(), 337 TestHandler { sender: tx }, 338 ) 339 .unwrap(); 340 controller.set_dequeue_pointer(GuestAddress(0x100)); 341 controller.set_consumer_cycle_state(false); 342 controller.start(); 343 assert_eq!(rx.recv().unwrap(), 1); 344 assert_eq!(rx.recv().unwrap(), 2); 345 assert_eq!(rx.recv().unwrap(), 3); 346 assert_eq!(rx.recv().unwrap(), 4); 347 assert_eq!(rx.recv().unwrap(), 5); 348 assert_eq!(rx.recv().unwrap(), 6); 349 l.stop(); 350 j.join().unwrap(); 351 } 352 } 353