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_caps>(
[&] () { return _pci.alloc_dma_buffer(size); },
[&] () { return _pci.alloc_dma_buffer(size, Genode::UNCACHED); },
[&] () { _pci.upgrade_caps(2); });
},
[&] () {

View File

@ -245,7 +245,7 @@ struct Pci_driver
retry<Out_of_ram>(
[&] () {
return retry<Out_of_caps>(
[&] () { return _pci.alloc_dma_buffer(size); },
[&] () { return _pci.alloc_dma_buffer(size, UNCACHED); },
[&] () { _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)
{
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>(
[&] () {
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); });
},
[&] () {

View File

@ -54,7 +54,7 @@ class Block::Session_component_base
Session_component_base(Driver_factory &factory, size_t tx_buf_size)
: _driver_factory(factory),
_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()
{

View File

@ -193,8 +193,8 @@ class Block::Driver : Genode::Interface
* Note: has to be overriden by DMA-capable devices
*/
virtual Genode::Ram_dataspace_capability
alloc_dma_buffer(Genode::size_t size) {
return _ram.alloc(size); }
alloc_dma_buffer(Genode::size_t size, Genode::Cache cache) {
return _ram.alloc(size, cache); }
/**
* 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 {
call<Rpc_release_device>(device); }
Ram_dataspace_capability alloc_dma_buffer(size_t size) override {
return call<Rpc_alloc_dma_buffer>(size); }
Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache) override {
return call<Rpc_alloc_dma_buffer>(size, cache); }
void free_dma_buffer(Ram_dataspace_capability cap) override {
call<Rpc_free_dma_buffer>(cap); }

View File

@ -64,10 +64,10 @@ class Platform::Connection : public Genode::Connection<Session>,
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 Client::alloc_dma_buffer(size); });
return Client::alloc_dma_buffer(size, cache); });
}
template <typename FN>

View File

@ -16,6 +16,7 @@
#include <base/quota_guard.h>
#include <base/rpc_args.h>
#include <base/cache.h>
#include <dataspace/capability.h>
#include <platform_device/capability.h>
#include <platform_device/platform_device.h>
@ -23,6 +24,7 @@
#include <session/session.h>
namespace Platform {
using namespace Genode;
struct Session;
@ -31,12 +33,6 @@ namespace Platform {
struct Platform::Session : Genode::Session
{
/*********************
** Exception types **
*********************/
class Fatal : public Out_of_ram { };
/**
* \noapi
*/
@ -70,7 +66,7 @@ struct Platform::Session : Genode::Session
/**
* 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
@ -94,7 +90,7 @@ struct Platform::Session : Genode::Session
GENODE_RPC(Rpc_release_device, void, release_device, Device_capability);
GENODE_RPC_THROW(Rpc_alloc_dma_buffer, Ram_dataspace_capability,
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,
Ram_dataspace_capability);
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 {
call<Rpc_release_device>(device); }
Ram_dataspace_capability alloc_dma_buffer(size_t size) override {
return call<Rpc_alloc_dma_buffer>(size); }
Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache) override {
return call<Rpc_alloc_dma_buffer>(size, cache); }
void free_dma_buffer(Ram_dataspace_capability cap) override {
call<Rpc_free_dma_buffer>(cap); }

View File

@ -17,6 +17,7 @@
/* Genode includes */
#include <session/session.h>
#include <base/ram_allocator.h>
#include <base/cache.h>
/* os includes */
#include <platform_device/platform_device.h>
@ -69,7 +70,7 @@ struct Platform::Session : Genode::Session
/**
* 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
@ -95,7 +96,7 @@ struct Platform::Session : Genode::Session
GENODE_RPC_THROW(Rpc_alloc_dma_buffer, Ram_dataspace_capability,
alloc_dma_buffer,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
size_t);
size_t, Cache);
GENODE_RPC(Rpc_free_dma_buffer, void, free_dma_buffer,
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_caps>(
[&] () { return _data.pci.alloc_dma_buffer(size); },
[&] () { return _data.pci.alloc_dma_buffer(size, Genode::UNCACHED); },
[&] () { _data.pci.upgrade_caps(2); });
},
[&] () {

View File

@ -94,7 +94,7 @@ struct Pl11x_driver::Main
Attached_dataspace _sys_mem { _env.rm(),
_sp810_dev.io_mem_dataspace() };
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 };
void _init_device();

View File

@ -171,7 +171,7 @@ struct Igd::Device
_pci.upgrade_ram(size);
try {
return _pci.with_upgrade([&] () {
return _pci.alloc_dma_buffer(size); });
return _pci.alloc_dma_buffer(size, Genode::UNCACHED); });
}
catch (Platform::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::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 },
Genode::Signal_handler<Lan9118> { env.ep(), *this, &Lan9118::_handle_irq },
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_caps>(
[&] () { return Pci::Connection::alloc_dma_buffer(size); },
[&] () { return Pci::Connection::alloc_dma_buffer(size, UNCACHED); },
[&] () { upgrade_caps(2); });
},
[&] () {

View File

@ -107,9 +107,9 @@ void Session_component::release_device(Platform::Device_capability device_cap)
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;

View File

@ -69,7 +69,7 @@ class Driver::Session_component :
Rom_session_capability devices_rom() override;
Device_capability acquire_device(String const &) 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;
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
*/
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();
if (!ram_cap.valid())

View File

@ -298,8 +298,8 @@ class Sd_card::Driver : public Driver_base,
bool dma_enabled() override { return true; }
Ram_dataspace_capability alloc_dma_buffer(size_t size) override {
return _env.ram().alloc(size, UNCACHED); }
Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache) override {
return _env.ram().alloc(size, cache); }
};
#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,
Block::Packet_descriptor &packet) override;
Ram_dataspace_capability alloc_dma_buffer(size_t size) override {
return _env.ram().alloc(size, UNCACHED); }
Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache) override {
return _env.ram().alloc(size, cache); }
};
#endif /* _DRIVER_H_ */