platform_session: cache arg for alloc_dma_buffer

This patch extends the 'Platform_session::alloc_dma_buffer' interface
with a 'Cache' argument that corresponds to the argument accepted by
'Ram_allocator::alloc', which is used by the platform driver under the
hood.

Since the x86 platform driver used to be hardwired to allocate DMA
buffers as UNCACHED, I adjusted all drivers by specifying the UNCACHED
argument. Right now, this is needed as a hint for core to steer the
allocation of I/O page tables. Once we eliminate the need for such hints
(by introducing an explicit 'Region_map::attach_dma' operation), we can
revisit the drivers individually because cached DMA buffers should
generally be fine on the x86 architecture.

Issue #2243
This commit is contained in:
Norman Feske 2021-04-08 17:44:11 +02:00
parent 53e44f8bfd
commit 0339318572
21 changed files with 34 additions and 37 deletions

View File

@ -138,7 +138,7 @@ class Pci_driver : public Bsd::Bus_driver
return Genode::retry<Genode::Out_of_ram>( return Genode::retry<Genode::Out_of_ram>(
[&] () { [&] () {
return Genode::retry<Genode::Out_of_caps>( return Genode::retry<Genode::Out_of_caps>(
[&] () { return _pci.alloc_dma_buffer(size); }, [&] () { return _pci.alloc_dma_buffer(size, Genode::UNCACHED); },
[&] () { _pci.upgrade_caps(2); }); [&] () { _pci.upgrade_caps(2); });
}, },
[&] () { [&] () {

View File

@ -245,7 +245,7 @@ struct Pci_driver
retry<Out_of_ram>( retry<Out_of_ram>(
[&] () { [&] () {
return retry<Out_of_caps>( return retry<Out_of_caps>(
[&] () { return _pci.alloc_dma_buffer(size); }, [&] () { return _pci.alloc_dma_buffer(size, UNCACHED); },
[&] () { _pci.upgrade_caps(2); }); [&] () { _pci.upgrade_caps(2); });
}, },
[&] () { [&] () {

View File

@ -174,7 +174,7 @@ void backend_alloc_init(Env & env, Ram_allocator&, Allocator&)
Ram_dataspace_capability Lx::backend_alloc(addr_t size, Cache) Ram_dataspace_capability Lx::backend_alloc(addr_t size, Cache)
{ {
return resource_env().platform.alloc_dma_buffer(size); return resource_env().platform.alloc_dma_buffer(size, UNCACHED);
} }

View File

@ -128,7 +128,7 @@ Lx::backend_alloc(Genode::addr_t size, Genode::Cache cache)
cap = retry<Genode::Out_of_ram>( cap = retry<Genode::Out_of_ram>(
[&] () { [&] () {
return retry<Genode::Out_of_caps>( return retry<Genode::Out_of_caps>(
[&] () { return _global_pci->alloc_dma_buffer(size); }, [&] () { return _global_pci->alloc_dma_buffer(size, UNCACHED); },
[&] () { _global_pci->upgrade_caps(2); }); [&] () { _global_pci->upgrade_caps(2); });
}, },
[&] () { [&] () {

View File

@ -54,7 +54,7 @@ class Block::Session_component_base
Session_component_base(Driver_factory &factory, size_t tx_buf_size) Session_component_base(Driver_factory &factory, size_t tx_buf_size)
: _driver_factory(factory), : _driver_factory(factory),
_driver(*factory.create()), _driver(*factory.create()),
_rq_ds(_driver.alloc_dma_buffer(tx_buf_size)) {} _rq_ds(_driver.alloc_dma_buffer(tx_buf_size, UNCACHED)) {}
~Session_component_base() ~Session_component_base()
{ {

View File

@ -193,8 +193,8 @@ class Block::Driver : Genode::Interface
* Note: has to be overriden by DMA-capable devices * Note: has to be overriden by DMA-capable devices
*/ */
virtual Genode::Ram_dataspace_capability virtual Genode::Ram_dataspace_capability
alloc_dma_buffer(Genode::size_t size) { alloc_dma_buffer(Genode::size_t size, Genode::Cache cache) {
return _ram.alloc(size); } return _ram.alloc(size, cache); }
/** /**
* Free buffer which is suitable for DMA. * Free buffer which is suitable for DMA.

View File

@ -39,8 +39,8 @@ struct Platform::Client : public Genode::Rpc_client<Session>
void release_device(Device_capability device) override { void release_device(Device_capability device) override {
call<Rpc_release_device>(device); } call<Rpc_release_device>(device); }
Ram_dataspace_capability alloc_dma_buffer(size_t size) override { Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache) override {
return call<Rpc_alloc_dma_buffer>(size); } return call<Rpc_alloc_dma_buffer>(size, cache); }
void free_dma_buffer(Ram_dataspace_capability cap) override { void free_dma_buffer(Ram_dataspace_capability cap) override {
call<Rpc_free_dma_buffer>(cap); } call<Rpc_free_dma_buffer>(cap); }

View File

@ -64,10 +64,10 @@ class Platform::Connection : public Genode::Connection<Session>,
return Client::acquire_device(device); }); return Client::acquire_device(device); });
} }
Ram_dataspace_capability alloc_dma_buffer(size_t size) override Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache) override
{ {
return retry_with_upgrade(Ram_quota{size}, Cap_quota{2}, [&] () { return retry_with_upgrade(Ram_quota{size}, Cap_quota{2}, [&] () {
return Client::alloc_dma_buffer(size); }); return Client::alloc_dma_buffer(size, cache); });
} }
template <typename FN> template <typename FN>

View File

@ -16,6 +16,7 @@
#include <base/quota_guard.h> #include <base/quota_guard.h>
#include <base/rpc_args.h> #include <base/rpc_args.h>
#include <base/cache.h>
#include <dataspace/capability.h> #include <dataspace/capability.h>
#include <platform_device/capability.h> #include <platform_device/capability.h>
#include <platform_device/platform_device.h> #include <platform_device/platform_device.h>
@ -23,6 +24,7 @@
#include <session/session.h> #include <session/session.h>
namespace Platform { namespace Platform {
using namespace Genode; using namespace Genode;
struct Session; struct Session;
@ -31,12 +33,6 @@ namespace Platform {
struct Platform::Session : Genode::Session struct Platform::Session : Genode::Session
{ {
/*********************
** Exception types **
*********************/
class Fatal : public Out_of_ram { };
/** /**
* \noapi * \noapi
*/ */
@ -70,7 +66,7 @@ struct Platform::Session : Genode::Session
/** /**
* Allocate memory suitable for DMA. * Allocate memory suitable for DMA.
*/ */
virtual Ram_dataspace_capability alloc_dma_buffer(size_t) = 0; virtual Ram_dataspace_capability alloc_dma_buffer(size_t, Cache) = 0;
/** /**
* Free previously allocated DMA memory * Free previously allocated DMA memory
@ -94,7 +90,7 @@ struct Platform::Session : Genode::Session
GENODE_RPC(Rpc_release_device, void, release_device, Device_capability); GENODE_RPC(Rpc_release_device, void, release_device, Device_capability);
GENODE_RPC_THROW(Rpc_alloc_dma_buffer, Ram_dataspace_capability, GENODE_RPC_THROW(Rpc_alloc_dma_buffer, Ram_dataspace_capability,
alloc_dma_buffer, alloc_dma_buffer,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps, Fatal), size_t); GENODE_TYPE_LIST(Out_of_ram, Out_of_caps), size_t, Cache);
GENODE_RPC(Rpc_free_dma_buffer, void, free_dma_buffer, GENODE_RPC(Rpc_free_dma_buffer, void, free_dma_buffer,
Ram_dataspace_capability); Ram_dataspace_capability);
GENODE_RPC(Rpc_dma_addr, addr_t, dma_addr, GENODE_RPC(Rpc_dma_addr, addr_t, dma_addr,

View File

@ -37,8 +37,8 @@ struct Platform::Client : public Rpc_client<Session>
void release_device(Device_capability device) override { void release_device(Device_capability device) override {
call<Rpc_release_device>(device); } call<Rpc_release_device>(device); }
Ram_dataspace_capability alloc_dma_buffer(size_t size) override { Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache) override {
return call<Rpc_alloc_dma_buffer>(size); } return call<Rpc_alloc_dma_buffer>(size, cache); }
void free_dma_buffer(Ram_dataspace_capability cap) override { void free_dma_buffer(Ram_dataspace_capability cap) override {
call<Rpc_free_dma_buffer>(cap); } call<Rpc_free_dma_buffer>(cap); }

View File

@ -17,6 +17,7 @@
/* Genode includes */ /* Genode includes */
#include <session/session.h> #include <session/session.h>
#include <base/ram_allocator.h> #include <base/ram_allocator.h>
#include <base/cache.h>
/* os includes */ /* os includes */
#include <platform_device/platform_device.h> #include <platform_device/platform_device.h>
@ -69,7 +70,7 @@ struct Platform::Session : Genode::Session
/** /**
* Allocate memory suitable for DMA * Allocate memory suitable for DMA
*/ */
virtual Ram_dataspace_capability alloc_dma_buffer(size_t) = 0; virtual Ram_dataspace_capability alloc_dma_buffer(size_t, Cache) = 0;
/** /**
* Free previously allocated DMA memory * Free previously allocated DMA memory
@ -95,7 +96,7 @@ struct Platform::Session : Genode::Session
GENODE_RPC_THROW(Rpc_alloc_dma_buffer, Ram_dataspace_capability, GENODE_RPC_THROW(Rpc_alloc_dma_buffer, Ram_dataspace_capability,
alloc_dma_buffer, alloc_dma_buffer,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps), GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
size_t); size_t, Cache);
GENODE_RPC(Rpc_free_dma_buffer, void, free_dma_buffer, GENODE_RPC(Rpc_free_dma_buffer, void, free_dma_buffer,
Ram_dataspace_capability); Ram_dataspace_capability);
GENODE_RPC(Rpc_dma_addr, addr_t, dma_addr, Ram_dataspace_capability); GENODE_RPC(Rpc_dma_addr, addr_t, dma_addr, Ram_dataspace_capability);

View File

@ -71,7 +71,7 @@ Genode::Ram_dataspace_capability Ahci::Platform::alloc_dma_buffer(size_t size)
return retry<Genode::Out_of_ram>( return retry<Genode::Out_of_ram>(
[&] () { [&] () {
return retry<Genode::Out_of_caps>( return retry<Genode::Out_of_caps>(
[&] () { return _data.pci.alloc_dma_buffer(size); }, [&] () { return _data.pci.alloc_dma_buffer(size, Genode::UNCACHED); },
[&] () { _data.pci.upgrade_caps(2); }); [&] () { _data.pci.upgrade_caps(2); });
}, },
[&] () { [&] () {

View File

@ -94,7 +94,7 @@ struct Pl11x_driver::Main
Attached_dataspace _sys_mem { _env.rm(), Attached_dataspace _sys_mem { _env.rm(),
_sp810_dev.io_mem_dataspace() }; _sp810_dev.io_mem_dataspace() };
Ram_dataspace_capability _fb_ds_cap { Ram_dataspace_capability _fb_ds_cap {
_platform.alloc_dma_buffer(FRAMEBUFFER_SIZE) }; _platform.alloc_dma_buffer(FRAMEBUFFER_SIZE, UNCACHED) };
Attached_dataspace _fb_ds { _env.rm(), _fb_ds_cap }; Attached_dataspace _fb_ds { _env.rm(), _fb_ds_cap };
void _init_device(); void _init_device();

View File

@ -171,7 +171,7 @@ struct Igd::Device
_pci.upgrade_ram(size); _pci.upgrade_ram(size);
try { try {
return _pci.with_upgrade([&] () { return _pci.with_upgrade([&] () {
return _pci.alloc_dma_buffer(size); }); return _pci.alloc_dma_buffer(size, Genode::UNCACHED); });
} }
catch (Platform::Out_of_ram) { catch (Platform::Out_of_ram) {
throw Out_of_ram(); } throw Out_of_ram(); }

View File

@ -450,7 +450,7 @@ class Lan9118 : public Nic::Session_component,
Genode::Allocator & rx_block_md_alloc, Genode::Allocator & rx_block_md_alloc,
Genode::Env & env) Genode::Env & env)
: :
Session_component { tx_buf_size, rx_buf_size, Genode::CACHED, Session_component { tx_buf_size, rx_buf_size, Genode::UNCACHED,
rx_block_md_alloc, env }, rx_block_md_alloc, env },
Genode::Signal_handler<Lan9118> { env.ep(), *this, &Lan9118::_handle_irq }, Genode::Signal_handler<Lan9118> { env.ep(), *this, &Lan9118::_handle_irq },
Lan9118_base { ds_cap, irq_cap, *this, env } Lan9118_base { ds_cap, irq_cap, *this, env }

View File

@ -126,7 +126,7 @@ struct Nvme::Pci : Platform::Connection,
return retry<Out_of_ram>( return retry<Out_of_ram>(
[&] () { [&] () {
return retry<Out_of_caps>( return retry<Out_of_caps>(
[&] () { return Pci::Connection::alloc_dma_buffer(size); }, [&] () { return Pci::Connection::alloc_dma_buffer(size, UNCACHED); },
[&] () { upgrade_caps(2); }); [&] () { upgrade_caps(2); });
}, },
[&] () { [&] () {

View File

@ -107,9 +107,9 @@ void Session_component::release_device(Platform::Device_capability device_cap)
Genode::Ram_dataspace_capability Genode::Ram_dataspace_capability
Session_component::alloc_dma_buffer(size_t const size) Session_component::alloc_dma_buffer(size_t const size, Cache cache)
{ {
Ram_dataspace_capability ram_cap = _env_ram.alloc(size, UNCACHED); Ram_dataspace_capability ram_cap = _env_ram.alloc(size, cache);
if (!ram_cap.valid()) return ram_cap; if (!ram_cap.valid()) return ram_cap;

View File

@ -69,7 +69,7 @@ class Driver::Session_component :
Rom_session_capability devices_rom() override; Rom_session_capability devices_rom() override;
Device_capability acquire_device(String const &) override; Device_capability acquire_device(String const &) override;
void release_device(Device_capability) override; void release_device(Device_capability) override;
Ram_dataspace_capability alloc_dma_buffer(size_t const) override; Ram_dataspace_capability alloc_dma_buffer(size_t, Cache) override;
void free_dma_buffer(Ram_dataspace_capability ram_cap) override; void free_dma_buffer(Ram_dataspace_capability ram_cap) override;
addr_t dma_addr(Ram_dataspace_capability) override; addr_t dma_addr(Ram_dataspace_capability) override;

View File

@ -807,9 +807,9 @@ class Platform::Session_component : public Rpc_object<Session>
* De-/Allocation of dma capable dataspaces * De-/Allocation of dma capable dataspaces
*/ */
Ram_dataspace_capability alloc_dma_buffer(size_t const size) override Ram_dataspace_capability alloc_dma_buffer(size_t const size, Cache cache) override
{ {
Ram_dataspace_capability ram_cap = _env_ram.alloc(size, UNCACHED); Ram_dataspace_capability ram_cap = _env_ram.alloc(size, cache);
addr_t const dma_addr = Dataspace_client(ram_cap).phys_addr(); addr_t const dma_addr = Dataspace_client(ram_cap).phys_addr();
if (!ram_cap.valid()) if (!ram_cap.valid())

View File

@ -298,8 +298,8 @@ class Sd_card::Driver : public Driver_base,
bool dma_enabled() override { return true; } bool dma_enabled() override { return true; }
Ram_dataspace_capability alloc_dma_buffer(size_t size) override { Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache) override {
return _env.ram().alloc(size, UNCACHED); } return _env.ram().alloc(size, cache); }
}; };
#endif /* _SRC__DRIVERS__SD_CARD__SPEC__IMX__DRIVER_H_ */ #endif /* _SRC__DRIVERS__SD_CARD__SPEC__IMX__DRIVER_H_ */

View File

@ -218,8 +218,8 @@ class Sd_card::Driver : public Driver_base,
char const *buffer, char const *buffer,
Block::Packet_descriptor &packet) override; Block::Packet_descriptor &packet) override;
Ram_dataspace_capability alloc_dma_buffer(size_t size) override { Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache) override {
return _env.ram().alloc(size, UNCACHED); } return _env.ram().alloc(size, cache); }
}; };
#endif /* _DRIVER_H_ */ #endif /* _DRIVER_H_ */