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