mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-10 22:44:30 +00:00
usb_session: align USB packet allocation correctly
To prevent caching side-effects of USB DMA memory taken from the packet stream all allocations of USB packets need to be on separated cachelines at least. Fix genodelabs/genode#4655
This commit is contained in:
parent
b03059b933
commit
3082950e74
@ -105,7 +105,7 @@ struct Driver
|
||||
private:
|
||||
|
||||
Usb::Session_client & _usb;
|
||||
Usb::Packet_descriptor _packet { _usb.source()->alloc_packet(0) };
|
||||
Usb::Packet_descriptor _packet { _usb.alloc_packet(0) };
|
||||
completion _comp;
|
||||
|
||||
public:
|
||||
|
@ -103,7 +103,7 @@ struct Driver
|
||||
private:
|
||||
|
||||
Usb::Session_client & _usb;
|
||||
Usb::Packet_descriptor _packet { _usb.source()->alloc_packet(0) };
|
||||
Usb::Packet_descriptor _packet { _usb.alloc_packet(0) };
|
||||
completion _comp;
|
||||
|
||||
public:
|
||||
|
@ -26,7 +26,7 @@ class Urb : public Usb::Completion
|
||||
Usb::Session_client & _usb;
|
||||
urb & _urb;
|
||||
Usb::Packet_descriptor _packet {
|
||||
_usb.source()->alloc_packet(_urb.transfer_buffer_length) };
|
||||
_usb.alloc_packet(_urb.transfer_buffer_length) };
|
||||
bool _completed { false };
|
||||
|
||||
public:
|
||||
|
@ -80,7 +80,7 @@ struct Usb_device
|
||||
raw_config_descriptor = (char*)malloc(config_descriptor.total_length);
|
||||
|
||||
Usb::Packet_descriptor p =
|
||||
usb_connection->source()->alloc_packet(config_descriptor.total_length);
|
||||
usb_connection->alloc_packet(config_descriptor.total_length);
|
||||
|
||||
p.type = Usb::Packet_descriptor::CTRL;
|
||||
p.control.request = LIBUSB_REQUEST_GET_DESCRIPTOR;
|
||||
@ -121,7 +121,7 @@ struct Usb_device
|
||||
return false;
|
||||
|
||||
Usb::Packet_descriptor p =
|
||||
usb_connection->source()->alloc_packet(0);
|
||||
usb_connection->alloc_packet(0);
|
||||
|
||||
p.type = Usb::Packet_descriptor::ALT_SETTING;
|
||||
p.interface.number = number;
|
||||
@ -521,7 +521,7 @@ static int genode_submit_transfer(struct usbi_transfer * itransfer)
|
||||
Usb::Packet_descriptor p;
|
||||
|
||||
try {
|
||||
p = usb_device->usb_connection->source()->alloc_packet(setup->wLength);
|
||||
p = usb_device->usb_connection->alloc_packet(setup->wLength);
|
||||
} catch (Usb::Session::Tx::Source::Packet_alloc_failed) {
|
||||
return LIBUSB_ERROR_BUSY;
|
||||
}
|
||||
@ -565,7 +565,7 @@ static int genode_submit_transfer(struct usbi_transfer * itransfer)
|
||||
Usb::Packet_descriptor p;
|
||||
|
||||
try {
|
||||
p = usb_device->usb_connection->source()->alloc_packet(transfer->length);
|
||||
p = usb_device->usb_connection->alloc_packet(transfer->length);
|
||||
} catch (Usb::Session::Tx::Source::Packet_alloc_failed) {
|
||||
return LIBUSB_ERROR_BUSY;
|
||||
}
|
||||
@ -601,7 +601,7 @@ static int genode_submit_transfer(struct usbi_transfer * itransfer)
|
||||
|
||||
Usb::Packet_descriptor p;
|
||||
try {
|
||||
p = usb_device->usb_connection->source()->alloc_packet(total_length);
|
||||
p = usb_device->usb_connection->alloc_packet(total_length);
|
||||
} catch (Usb::Session::Tx::Source::Packet_alloc_failed) {
|
||||
return LIBUSB_ERROR_BUSY;
|
||||
}
|
||||
|
@ -534,7 +534,7 @@ struct Usb_host_device : List<Usb_host_device>::Element
|
||||
throw Packet_alloc_failed();
|
||||
}
|
||||
|
||||
Usb::Packet_descriptor packet = usb_raw.source()->alloc_packet(length);
|
||||
Usb::Packet_descriptor packet = usb_raw.alloc_packet(length);
|
||||
|
||||
if (!completion) {
|
||||
packet.completion = nullptr;
|
||||
|
@ -94,7 +94,7 @@ class Usb::Packet_handler
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
Packet_descriptor p = _connection.source()->alloc_packet(size);
|
||||
Packet_descriptor p = _connection.alloc_packet(size);
|
||||
return p;
|
||||
} catch (Usb::Session::Tx::Source::Packet_alloc_failed) {
|
||||
/* block until some packets are freed */
|
||||
|
@ -52,6 +52,20 @@ class Usb::Session_client : public Genode::Rpc_client<Session>
|
||||
sigh_state_change(state_change);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper utility to always allocate correctly aligned USB packets
|
||||
*/
|
||||
Packet_descriptor alloc_packet(Genode::size_t size)
|
||||
{
|
||||
/*
|
||||
* At least on ARM the minimal alignment for distinct
|
||||
* DMA-capable USB URBs shall meet a maximum cache-line
|
||||
* size of 128 bytes
|
||||
*/
|
||||
enum { URB_PAYLOAD_MIN_ALIGN_LOG2 = 7 };
|
||||
return source()->alloc_packet(size, URB_PAYLOAD_MIN_ALIGN_LOG2);
|
||||
}
|
||||
|
||||
/***************************
|
||||
** USB session interface **
|
||||
***************************/
|
||||
|
Loading…
x
Reference in New Issue
Block a user