• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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