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