mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-22 06:57:51 +00:00
vfs/lwip: deferred wakeup of NIC server
This patch fosters the batching of network packets transferred by the lwIP stack over the NIC connection. It replaces the eager submission of the packet-stream's data-flow signals by explicit wakeup notifications. The commit also increases the NIC session's buffer size from 128 to 1024 packets. Issue #4697
This commit is contained in:
parent
60175631df
commit
8a9974b6f9
@ -307,13 +307,12 @@ class Main
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_blk.tx()->wakeup();
|
_blk.tx()->wakeup();
|
||||||
|
_vfs_env.io().commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Main(Env &env)
|
Main(Env &env) : _env { env }
|
||||||
:
|
|
||||||
_env { env }
|
|
||||||
{
|
{
|
||||||
if (_blk_ratio == 0) {
|
if (_blk_ratio == 0) {
|
||||||
error("backend block size not supported");
|
error("backend block size not supported");
|
||||||
|
@ -219,6 +219,8 @@ class Main
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_vfs_env.io().commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
Io_response_handler _io_response_handler { _io_handler };
|
Io_response_handler _io_response_handler { _io_handler };
|
||||||
|
@ -2526,6 +2526,7 @@ class Main
|
|||||||
_execute_cbe(progress);
|
_execute_cbe(progress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_vfs_env.io().commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -188,20 +188,7 @@ struct Fs_query::Main : Vfs::Watch_response_handler
|
|||||||
Signal_transmitter(_config_handler).submit();
|
Signal_transmitter(_config_handler).submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Vfs_env : Vfs::Env
|
Vfs::Simple_env _vfs_env { _env, _heap, _config.xml().sub_node("vfs") };
|
||||||
{
|
|
||||||
Main &_main;
|
|
||||||
|
|
||||||
Vfs_env(Main &main) : _main(main) { }
|
|
||||||
|
|
||||||
Genode::Env &env() override { return _main._env; }
|
|
||||||
Allocator &alloc() override { return _main._heap; }
|
|
||||||
Vfs::File_system &root_dir() override { return _main._root_dir_fs; }
|
|
||||||
|
|
||||||
} _vfs_env { *this };
|
|
||||||
|
|
||||||
Vfs::Dir_file_system _root_dir_fs {
|
|
||||||
_vfs_env, _config.xml().sub_node("vfs"), _fs_factory };
|
|
||||||
|
|
||||||
Directory _root_dir { _vfs_env };
|
Directory _root_dir { _vfs_env };
|
||||||
|
|
||||||
@ -229,7 +216,7 @@ struct Fs_query::Main : Vfs::Watch_response_handler
|
|||||||
|
|
||||||
Xml_node const config = _config.xml();
|
Xml_node const config = _config.xml();
|
||||||
|
|
||||||
_root_dir_fs.apply_config(config.sub_node("vfs"));
|
_vfs_env.root_dir().apply_config(config.sub_node("vfs"));
|
||||||
|
|
||||||
_dirs.for_each([&] (Registered<Watched_directory> &dir) {
|
_dirs.for_each([&] (Registered<Watched_directory> &dir) {
|
||||||
destroy(_heap, &dir); });
|
destroy(_heap, &dir); });
|
||||||
|
@ -35,20 +35,7 @@ struct Fs_tool::Main
|
|||||||
|
|
||||||
Vfs::Global_file_system_factory _fs_factory { _heap };
|
Vfs::Global_file_system_factory _fs_factory { _heap };
|
||||||
|
|
||||||
struct Vfs_env : Vfs::Env
|
Vfs::Simple_env _vfs_env { _env, _heap, _config.xml().sub_node("vfs") };
|
||||||
{
|
|
||||||
Main &_main;
|
|
||||||
|
|
||||||
Vfs_env(Main &main) : _main(main) { }
|
|
||||||
|
|
||||||
Genode::Env &env() override { return _main._env; }
|
|
||||||
Allocator &alloc() override { return _main._heap; }
|
|
||||||
Vfs::File_system &root_dir() override { return _main._root_dir_fs; }
|
|
||||||
|
|
||||||
} _vfs_env { *this };
|
|
||||||
|
|
||||||
Vfs::Dir_file_system _root_dir_fs {
|
|
||||||
_vfs_env, _config.xml().sub_node("vfs"), _fs_factory };
|
|
||||||
|
|
||||||
Directory _root_dir { _vfs_env };
|
Directory _root_dir { _vfs_env };
|
||||||
|
|
||||||
@ -71,7 +58,7 @@ struct Fs_tool::Main
|
|||||||
|
|
||||||
_verbose = config.attribute_value("verbose", false);
|
_verbose = config.attribute_value("verbose", false);
|
||||||
|
|
||||||
_root_dir_fs.apply_config(config.sub_node("vfs"));
|
_vfs_env.root_dir().apply_config(config.sub_node("vfs"));
|
||||||
|
|
||||||
config.for_each_sub_node([&] (Xml_node operation) {
|
config.for_each_sub_node([&] (Xml_node operation) {
|
||||||
|
|
||||||
|
@ -96,20 +96,7 @@ struct Menu_view::Main
|
|||||||
|
|
||||||
Heap _heap { _env.ram(), _env.rm() };
|
Heap _heap { _env.ram(), _env.rm() };
|
||||||
|
|
||||||
struct Vfs_env : Vfs::Env
|
Vfs::Env &_vfs_env;
|
||||||
{
|
|
||||||
Genode::Env &_env;
|
|
||||||
Allocator &_alloc;
|
|
||||||
Vfs::File_system &_vfs;
|
|
||||||
|
|
||||||
Vfs_env(Genode::Env &env, Allocator &alloc, Vfs::File_system &vfs)
|
|
||||||
: _env(env), _alloc(alloc), _vfs(vfs) { }
|
|
||||||
|
|
||||||
Genode::Env &env() override { return _env; }
|
|
||||||
Allocator &alloc() override { return _alloc; }
|
|
||||||
Vfs::File_system &root_dir() override { return _vfs; }
|
|
||||||
|
|
||||||
} _vfs_env;
|
|
||||||
|
|
||||||
Directory _root_dir { _vfs_env };
|
Directory _root_dir { _vfs_env };
|
||||||
Directory _fonts_dir { _root_dir, "fonts" };
|
Directory _fonts_dir { _root_dir, "fonts" };
|
||||||
@ -211,9 +198,9 @@ struct Menu_view::Main
|
|||||||
*/
|
*/
|
||||||
unsigned _frame_cnt = 0;
|
unsigned _frame_cnt = 0;
|
||||||
|
|
||||||
Main(Env &env, Vfs::File_system &libc_vfs)
|
Main(Env &env, Vfs::Env &libc_vfs_env)
|
||||||
:
|
:
|
||||||
_env(env), _vfs_env(_env, _heap, libc_vfs)
|
_env(env), _vfs_env(libc_vfs_env)
|
||||||
{
|
{
|
||||||
_dialog_rom.sigh(_dialog_update_handler);
|
_dialog_rom.sigh(_dialog_update_handler);
|
||||||
_config.sigh(_config_handler);
|
_config.sigh(_config_handler);
|
||||||
@ -470,6 +457,6 @@ extern "C" void _sigprocmask() { }
|
|||||||
|
|
||||||
void Libc::Component::construct(Libc::Env &env)
|
void Libc::Component::construct(Libc::Env &env)
|
||||||
{
|
{
|
||||||
static Menu_view::Main main(env, env.vfs());
|
static Menu_view::Main main(env, env.vfs_env());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,10 +35,10 @@ class Vfs_replay
|
|||||||
Vfs_replay(const Vfs_replay&) = delete;
|
Vfs_replay(const Vfs_replay&) = delete;
|
||||||
Vfs_replay& operator=(const Vfs_replay&) = delete;
|
Vfs_replay& operator=(const Vfs_replay&) = delete;
|
||||||
|
|
||||||
|
|
||||||
Env &_env;
|
Env &_env;
|
||||||
|
|
||||||
Vfs::File_system &_vfs;
|
Vfs::File_system &_vfs;
|
||||||
|
Vfs::Env::Io &_io;
|
||||||
Vfs::Vfs_handle *_vfs_handle;
|
Vfs::Vfs_handle *_vfs_handle;
|
||||||
|
|
||||||
Attached_ram_dataspace _write_buffer;
|
Attached_ram_dataspace _write_buffer;
|
||||||
@ -421,6 +421,8 @@ class Vfs_replay
|
|||||||
if (_finished) {
|
if (_finished) {
|
||||||
_env.parent().exit(failed ? 1 : 0);
|
_env.parent().exit(failed ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_io.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Io_response_handler : Vfs::Io_response_handler
|
struct Io_response_handler : Vfs::Io_response_handler
|
||||||
@ -441,11 +443,12 @@ class Vfs_replay
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Vfs_replay(Vfs::File_system &vfs, Env &env,
|
Vfs_replay(Env &env, Vfs::File_system &vfs, Vfs::Env::Io &io,
|
||||||
Xml_node const & config)
|
Xml_node const & config)
|
||||||
:
|
:
|
||||||
_env { env },
|
_env { env },
|
||||||
_vfs { vfs },
|
_vfs { vfs },
|
||||||
|
_io { io },
|
||||||
_vfs_handle { nullptr },
|
_vfs_handle { nullptr },
|
||||||
_write_buffer { _env.ram(), _env.rm(),
|
_write_buffer { _env.ram(), _env.rm(),
|
||||||
config.attribute_value("write_buffer_size", 1u << 20) },
|
config.attribute_value("write_buffer_size", 1u << 20) },
|
||||||
@ -513,7 +516,7 @@ struct Main : private Genode::Entrypoint::Io_progress_handler
|
|||||||
Genode::Signal_handler<Main> _reactivate_handler {
|
Genode::Signal_handler<Main> _reactivate_handler {
|
||||||
_env.ep(), *this, &Main::handle_io_progress };
|
_env.ep(), *this, &Main::handle_io_progress };
|
||||||
|
|
||||||
Vfs_replay _replay { _vfs_env.root_dir(), _env, _config_rom.xml() };
|
Vfs_replay _replay { _env, _vfs_env.root_dir(), _vfs_env.io(), _config_rom.xml() };
|
||||||
|
|
||||||
Main(Genode::Env &env) : _env { env }
|
Main(Genode::Env &env) : _env { env }
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
namespace Libc { class Env; }
|
namespace Libc { class Env; }
|
||||||
|
|
||||||
namespace Vfs { struct File_system; }
|
namespace Vfs { struct Env; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to be provided by the component implementation
|
* Interface to be provided by the component implementation
|
||||||
@ -49,9 +49,9 @@ class Libc::Env : public Genode::Env
|
|||||||
func(_config_xml()); }
|
func(_config_xml()); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Virtual File System configured for this component
|
* Virtual file system configured for this component
|
||||||
*/
|
*/
|
||||||
virtual Vfs::File_system &vfs() = 0;
|
virtual Vfs::Env &vfs_env() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Libc configuration for this component
|
* Libc configuration for this component
|
||||||
|
@ -67,16 +67,15 @@ class Libc::Env_implementation : public Libc::Env, public Config_accessor
|
|||||||
Env_implementation(Genode::Env &env, Genode::Allocator &alloc)
|
Env_implementation(Genode::Env &env, Genode::Allocator &alloc)
|
||||||
: _env(env), _vfs_env(_env, alloc, _vfs_config()) { }
|
: _env(env), _vfs_env(_env, alloc, _vfs_config()) { }
|
||||||
|
|
||||||
|
Vfs::File_system &vfs() { return _vfs_env.root_dir(); }
|
||||||
Vfs::Env &vfs_env() { return _vfs_env; }
|
|
||||||
|
|
||||||
|
|
||||||
/*************************
|
/*************************
|
||||||
** Libc::Env interface **
|
** Libc::Env interface **
|
||||||
*************************/
|
*************************/
|
||||||
|
|
||||||
Vfs::File_system &vfs() override {
|
Vfs::Env &vfs_env() override {
|
||||||
return _vfs_env.root_dir(); }
|
return _vfs_env; }
|
||||||
|
|
||||||
Xml_node libc_config() override {
|
Xml_node libc_config() override {
|
||||||
return _libc_config(); }
|
return _libc_config(); }
|
||||||
|
@ -703,7 +703,7 @@ struct Libc::Kernel final : Vfs::Io_response_handler,
|
|||||||
|
|
||||||
void wakeup_remote_peers()
|
void wakeup_remote_peers()
|
||||||
{
|
{
|
||||||
_libc_env.vfs_env().deferred_wakeups().trigger();
|
_libc_env.vfs_env().io().commit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ class Libc::Vfs_plugin final : public Plugin
|
|||||||
Xml_node config)
|
Xml_node config)
|
||||||
:
|
:
|
||||||
_alloc(alloc),
|
_alloc(alloc),
|
||||||
_root_fs(env.vfs()),
|
_root_fs(env.vfs_env().root_dir()),
|
||||||
_response_handler(handler),
|
_response_handler(handler),
|
||||||
_update_mtime(update_mtime),
|
_update_mtime(update_mtime),
|
||||||
_current_real_time(current_real_time),
|
_current_real_time(current_real_time),
|
||||||
|
@ -75,14 +75,25 @@ extern "C" {
|
|||||||
|
|
||||||
class Lwip::Nic_netif
|
class Lwip::Nic_netif
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct Wakeup_scheduler : Genode::Noncopyable, Genode::Interface
|
||||||
|
{
|
||||||
|
virtual void schedule_nic_server_wakeup() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
Genode::Entrypoint &_ep;
|
||||||
|
|
||||||
|
Wakeup_scheduler &_wakeup_scheduler;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE,
|
PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE,
|
||||||
BUF_SIZE = 128 * PACKET_SIZE,
|
BUF_SIZE = 1024*PACKET_SIZE,
|
||||||
};
|
};
|
||||||
|
|
||||||
Genode::Tslab<Nic_netif_pbuf, 128*sizeof(Nic_netif_pbuf)> _pbuf_alloc;
|
Genode::Tslab<Nic_netif_pbuf, 1024*sizeof(Nic_netif_pbuf)> _pbuf_alloc;
|
||||||
|
|
||||||
Nic::Packet_allocator _nic_tx_alloc;
|
Nic::Packet_allocator _nic_tx_alloc;
|
||||||
Nic::Connection _nic;
|
Nic::Connection _nic;
|
||||||
@ -103,11 +114,17 @@ class Lwip::Nic_netif
|
|||||||
|
|
||||||
void free_pbuf(Nic_netif_pbuf &pbuf)
|
void free_pbuf(Nic_netif_pbuf &pbuf)
|
||||||
{
|
{
|
||||||
if (!_nic.rx()->ready_to_ack()) {
|
bool msg_once = true;
|
||||||
Genode::error("Nic rx acknowledgement queue congested, blocking to free pbuf");
|
while (!_nic.rx()->ready_to_ack()) {
|
||||||
|
if (msg_once)
|
||||||
|
Genode::error("Nic rx acknowledgement queue congested, blocking to free pbuf");
|
||||||
|
msg_once = false;
|
||||||
|
_ep.wait_and_dispatch_one_io_signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
_nic.rx()->acknowledge_packet(pbuf.packet);
|
_nic.rx()->try_ack_packet(pbuf.packet);
|
||||||
|
_wakeup_scheduler.schedule_nic_server_wakeup();
|
||||||
|
|
||||||
destroy(_pbuf_alloc, &pbuf);
|
destroy(_pbuf_alloc, &pbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,9 +161,12 @@ class Lwip::Nic_netif
|
|||||||
{
|
{
|
||||||
auto &rx = *_nic.rx();
|
auto &rx = *_nic.rx();
|
||||||
|
|
||||||
|
bool progress = false;
|
||||||
|
|
||||||
while (rx.packet_avail() && rx.ready_to_ack()) {
|
while (rx.packet_avail() && rx.ready_to_ack()) {
|
||||||
|
|
||||||
Nic::Packet_descriptor packet = rx.get_packet();
|
Nic::Packet_descriptor packet = rx.try_get_packet();
|
||||||
|
progress = true;
|
||||||
|
|
||||||
Nic_netif_pbuf *nic_pbuf = new (_pbuf_alloc)
|
Nic_netif_pbuf *nic_pbuf = new (_pbuf_alloc)
|
||||||
Nic_netif_pbuf(*this, packet);
|
Nic_netif_pbuf(*this, packet);
|
||||||
@ -165,6 +185,9 @@ class Lwip::Nic_netif
|
|||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (progress)
|
||||||
|
_wakeup_scheduler.schedule_nic_server_wakeup();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,12 +197,19 @@ class Lwip::Nic_netif
|
|||||||
{
|
{
|
||||||
auto &tx = *_nic.tx();
|
auto &tx = *_nic.tx();
|
||||||
|
|
||||||
|
bool progress = false;
|
||||||
|
|
||||||
/* flush acknowledgements */
|
/* flush acknowledgements */
|
||||||
while (tx.ack_avail())
|
while (tx.ack_avail()) {
|
||||||
tx.release_packet(tx.get_acked_packet());
|
tx.release_packet(tx.try_get_acked_packet());
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* notify subclass to resume pending transmissions */
|
/* notify subclass to resume pending transmissions */
|
||||||
status_callback();
|
status_callback();
|
||||||
|
|
||||||
|
if (progress)
|
||||||
|
_wakeup_scheduler.schedule_nic_server_wakeup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void configure(Genode::Xml_node const &config)
|
void configure(Genode::Xml_node const &config)
|
||||||
@ -240,8 +270,11 @@ class Lwip::Nic_netif
|
|||||||
|
|
||||||
Nic_netif(Genode::Env &env,
|
Nic_netif(Genode::Env &env,
|
||||||
Genode::Allocator &alloc,
|
Genode::Allocator &alloc,
|
||||||
Genode::Xml_node config)
|
Genode::Xml_node config,
|
||||||
|
Wakeup_scheduler &wakeup_scheduler)
|
||||||
:
|
:
|
||||||
|
_ep(env.ep()),
|
||||||
|
_wakeup_scheduler(wakeup_scheduler),
|
||||||
_pbuf_alloc(alloc), _nic_tx_alloc(&alloc),
|
_pbuf_alloc(alloc), _nic_tx_alloc(&alloc),
|
||||||
_nic(env, &_nic_tx_alloc,
|
_nic(env, &_nic_tx_alloc,
|
||||||
BUF_SIZE, BUF_SIZE,
|
BUF_SIZE, BUF_SIZE,
|
||||||
@ -365,7 +398,8 @@ class Lwip::Nic_netif
|
|||||||
dst += q->len;
|
dst += q->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
tx.submit_packet(packet);
|
tx.try_submit_packet(packet);
|
||||||
|
_wakeup_scheduler.schedule_nic_server_wakeup();
|
||||||
LINK_STATS_INC(link.xmit);
|
LINK_STATS_INC(link.xmit);
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
@ -375,6 +409,15 @@ class Lwip::Nic_netif
|
|||||||
return netif_is_up(&_netif) &&
|
return netif_is_up(&_netif) &&
|
||||||
!ip_addr_isany(&_netif.ip_addr);
|
!ip_addr_isany(&_netif.ip_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger submission of deferred packet-stream signals
|
||||||
|
*/
|
||||||
|
void wakeup_nic_server()
|
||||||
|
{
|
||||||
|
_nic.rx()->wakeup();
|
||||||
|
_nic.tx()->wakeup();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1713,8 +1713,12 @@ class Lwip::File_system final : public Vfs::File_system, public Lwip::Directory
|
|||||||
/**
|
/**
|
||||||
* LwIP connection to Nic service
|
* LwIP connection to Nic service
|
||||||
*/
|
*/
|
||||||
struct Vfs_netif : Lwip::Nic_netif
|
struct Vfs_netif : Lwip::Nic_netif,
|
||||||
|
private Vfs::Remote_io,
|
||||||
|
private Lwip::Nic_netif::Wakeup_scheduler
|
||||||
{
|
{
|
||||||
|
Remote_io::Peer _peer;
|
||||||
|
|
||||||
Tcp_proto_dir tcp_dir;
|
Tcp_proto_dir tcp_dir;
|
||||||
Udp_proto_dir udp_dir;
|
Udp_proto_dir udp_dir;
|
||||||
|
|
||||||
@ -1725,10 +1729,11 @@ class Lwip::File_system final : public Vfs::File_system, public Lwip::Directory
|
|||||||
|
|
||||||
Handle_queue blocked_handles { };
|
Handle_queue blocked_handles { };
|
||||||
|
|
||||||
Vfs_netif(Vfs::Env &vfs_env,
|
Vfs_netif(Vfs::Env &vfs_env, Genode::Xml_node config)
|
||||||
Genode::Xml_node config)
|
:
|
||||||
: Lwip::Nic_netif(vfs_env.env(), vfs_env.alloc(), config),
|
Lwip::Nic_netif(vfs_env.env(), vfs_env.alloc(), config, *this),
|
||||||
tcp_dir(vfs_env), udp_dir(vfs_env)
|
_peer(vfs_env.deferred_wakeups(), *this),
|
||||||
|
tcp_dir(vfs_env), udp_dir(vfs_env)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~Vfs_netif()
|
~Vfs_netif()
|
||||||
@ -1737,6 +1742,26 @@ class Lwip::File_system final : public Vfs::File_system, public Lwip::Directory
|
|||||||
status_callback();
|
status_callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lwip::Nic_netif::Wakeup_scheduler interface
|
||||||
|
*
|
||||||
|
* Called from Lwip::Nic_netif.
|
||||||
|
*/
|
||||||
|
void schedule_nic_server_wakeup() override
|
||||||
|
{
|
||||||
|
_peer.schedule_wakeup();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remote_io interface
|
||||||
|
*
|
||||||
|
* Called from VFS user when going idle.
|
||||||
|
*/
|
||||||
|
void wakeup_remote_peer() override
|
||||||
|
{
|
||||||
|
Lwip::Nic_netif::wakeup_nic_server();
|
||||||
|
}
|
||||||
|
|
||||||
void enqueue(Vfs_handle &handle)
|
void enqueue(Vfs_handle &handle)
|
||||||
{
|
{
|
||||||
Handle_element *elem = new (handle.alloc())
|
Handle_element *elem = new (handle.alloc())
|
||||||
@ -1802,14 +1827,17 @@ class Lwip::File_system final : public Vfs::File_system, public Lwip::Directory
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
File_system(Vfs::Env &vfs_env, Genode::Xml_node config)
|
File_system(Vfs::Env &vfs_env, Genode::Xml_node config)
|
||||||
: _ep(vfs_env.env().ep()), _netif(vfs_env, config)
|
:
|
||||||
|
_ep(vfs_env.env().ep()), _netif(vfs_env, config)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reconfigure the LwIP Nic interface with the VFS config hook
|
* Reconfigure the LwIP Nic interface with the VFS config hook
|
||||||
*/
|
*/
|
||||||
void apply_config(Genode::Xml_node const &node) override {
|
void apply_config(Genode::Xml_node const &node) override
|
||||||
_netif.configure(node); }
|
{
|
||||||
|
_netif.configure(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
|
@ -194,7 +194,7 @@ struct Genode::Directory : Noncopyable, Interface
|
|||||||
_handle->seek(i * sizeof(entry._dirent));
|
_handle->seek(i * sizeof(entry._dirent));
|
||||||
|
|
||||||
while (!_handle->fs().queue_read(_handle, sizeof(entry._dirent)))
|
while (!_handle->fs().queue_read(_handle, sizeof(entry._dirent)))
|
||||||
_io.progress();
|
_io.commit_and_wait();
|
||||||
|
|
||||||
Vfs::File_io_service::Read_result read_result;
|
Vfs::File_io_service::Read_result read_result;
|
||||||
Vfs::file_size out_count = 0;
|
Vfs::file_size out_count = 0;
|
||||||
@ -209,7 +209,7 @@ struct Genode::Directory : Noncopyable, Interface
|
|||||||
if (read_result != Vfs::File_io_service::READ_QUEUED)
|
if (read_result != Vfs::File_io_service::READ_QUEUED)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
_io.progress();
|
_io.commit_and_wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((read_result != Vfs::File_io_service::READ_OK) ||
|
if ((read_result != Vfs::File_io_service::READ_OK) ||
|
||||||
@ -298,7 +298,7 @@ struct Genode::Directory : Noncopyable, Interface
|
|||||||
Vfs::file_size count = sizeof(buf)-1;
|
Vfs::file_size count = sizeof(buf)-1;
|
||||||
Vfs::file_size out_count = 0;
|
Vfs::file_size out_count = 0;
|
||||||
while (!link_handle->fs().queue_read(link_handle, count)) {
|
while (!link_handle->fs().queue_read(link_handle, count)) {
|
||||||
_io.progress();
|
_io.commit_and_wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
File_io_service::Read_result result;
|
File_io_service::Read_result result;
|
||||||
@ -310,7 +310,7 @@ struct Genode::Directory : Noncopyable, Interface
|
|||||||
if (result != File_io_service::READ_QUEUED)
|
if (result != File_io_service::READ_QUEUED)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
_io.progress();
|
_io.commit_and_wait();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (result != File_io_service::READ_OK)
|
if (result != File_io_service::READ_OK)
|
||||||
@ -463,7 +463,7 @@ class Genode::Readonly_file : public File
|
|||||||
_handle->seek(at.value);
|
_handle->seek(at.value);
|
||||||
|
|
||||||
while (!_handle->fs().queue_read(_handle, bytes))
|
while (!_handle->fs().queue_read(_handle, bytes))
|
||||||
_io.progress();
|
_io.commit_and_wait();
|
||||||
|
|
||||||
Vfs::File_io_service::Read_result result;
|
Vfs::File_io_service::Read_result result;
|
||||||
|
|
||||||
@ -474,7 +474,7 @@ class Genode::Readonly_file : public File
|
|||||||
if (result != Vfs::File_io_service::READ_QUEUED)
|
if (result != Vfs::File_io_service::READ_QUEUED)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
_io.progress();
|
_io.commit_and_wait();
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -720,7 +720,7 @@ class Genode::Writeable_file : Noncopyable
|
|||||||
static void _sync(Vfs::Vfs_handle &handle, Vfs::Env::Io &io)
|
static void _sync(Vfs::Vfs_handle &handle, Vfs::Env::Io &io)
|
||||||
{
|
{
|
||||||
while (handle.fs().queue_sync(&handle) == false)
|
while (handle.fs().queue_sync(&handle) == false)
|
||||||
io.progress();
|
io.commit_and_wait();
|
||||||
|
|
||||||
for (bool sync_done = false; !sync_done; ) {
|
for (bool sync_done = false; !sync_done; ) {
|
||||||
|
|
||||||
@ -740,7 +740,7 @@ class Genode::Writeable_file : Noncopyable
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!sync_done)
|
if (!sync_done)
|
||||||
io.progress();
|
io.commit_and_wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -786,7 +786,7 @@ class Genode::Writeable_file : Noncopyable
|
|||||||
stalled = true; }
|
stalled = true; }
|
||||||
|
|
||||||
if (stalled)
|
if (stalled)
|
||||||
io.progress();
|
io.commit_and_wait();
|
||||||
}
|
}
|
||||||
return write_error ? Append_result::WRITE_ERROR
|
return write_error ? Append_result::WRITE_ERROR
|
||||||
: Append_result::OK;
|
: Append_result::OK;
|
||||||
|
@ -46,7 +46,17 @@ struct Vfs::Env : Interface
|
|||||||
*/
|
*/
|
||||||
struct Io : Interface, Genode::Noncopyable
|
struct Io : Interface, Genode::Noncopyable
|
||||||
{
|
{
|
||||||
virtual void progress() = 0;
|
/**
|
||||||
|
* Trigger the deferred wakeup of remote peers
|
||||||
|
*/
|
||||||
|
virtual void commit() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wakeup remote peers and wait for I/O progress
|
||||||
|
*
|
||||||
|
* This method is intended for implementing synchronous I/O.
|
||||||
|
*/
|
||||||
|
virtual void commit_and_wait() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual Io &io() = 0;
|
virtual Io &io() = 0;
|
||||||
|
@ -60,7 +60,12 @@ class Vfs::Simple_env : public Vfs::Env, private Vfs::Env::Io
|
|||||||
/**
|
/**
|
||||||
* Vfs::Env::Io interface
|
* Vfs::Env::Io interface
|
||||||
*/
|
*/
|
||||||
void progress() override
|
void commit() override { _deferred_wakeups.trigger(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vfs::Env::Io interface
|
||||||
|
*/
|
||||||
|
void commit_and_wait() override
|
||||||
{
|
{
|
||||||
_deferred_wakeups.trigger();
|
_deferred_wakeups.trigger();
|
||||||
_env.ep().wait_and_dispatch_one_io_signal();
|
_env.ep().wait_and_dispatch_one_io_signal();
|
||||||
|
@ -108,10 +108,10 @@ class Fs_report::Session_component : public Genode::Rpc_object<Report::Session>
|
|||||||
|
|
||||||
/* sync file operations before close */
|
/* sync file operations before close */
|
||||||
while (!handle->fs().queue_sync(handle))
|
while (!handle->fs().queue_sync(handle))
|
||||||
_io.progress();
|
_io.commit_and_wait();
|
||||||
|
|
||||||
while (handle->fs().complete_sync(handle) == Vfs::File_io_service::SYNC_QUEUED)
|
while (handle->fs().complete_sync(handle) == Vfs::File_io_service::SYNC_QUEUED)
|
||||||
_io.progress();
|
_io.commit_and_wait();
|
||||||
|
|
||||||
handle->close();
|
handle->close();
|
||||||
}
|
}
|
||||||
|
@ -89,10 +89,7 @@ class Vfs_server::Session_component : private Session_resources,
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
Vfs::File_system &_vfs;
|
Vfs::File_system &_vfs;
|
||||||
|
Vfs::Env::Io &_io;
|
||||||
using Deferred_wakeups = Vfs::Remote_io::Deferred_wakeups;
|
|
||||||
|
|
||||||
Deferred_wakeups &_deferred_wakeups;
|
|
||||||
|
|
||||||
Genode::Entrypoint &_ep;
|
Genode::Entrypoint &_ep;
|
||||||
|
|
||||||
@ -197,7 +194,6 @@ class Vfs_server::Session_component : private Session_resources,
|
|||||||
{
|
{
|
||||||
drop_packet_from_submit_queue();
|
drop_packet_from_submit_queue();
|
||||||
packet.succeeded(false);
|
packet.succeeded(false);
|
||||||
Genode::log("consume_and_ack_invalid_packet");
|
|
||||||
_stream.try_ack_packet(packet);
|
_stream.try_ack_packet(packet);
|
||||||
|
|
||||||
overall_progress = true;
|
overall_progress = true;
|
||||||
@ -278,12 +274,7 @@ class Vfs_server::Session_component : private Session_resources,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (node.acknowledgement_pending()) {
|
if (node.acknowledgement_pending()) {
|
||||||
auto packet = node.dequeue_acknowledgement();
|
_stream.try_ack_packet(node.dequeue_acknowledgement());
|
||||||
|
|
||||||
if (!packet.succeeded())
|
|
||||||
Genode::warning("_try_acknowledge_jobs failed packet");
|
|
||||||
|
|
||||||
_stream.try_ack_packet(packet);
|
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,7 +380,7 @@ class Vfs_server::Session_component : private Session_resources,
|
|||||||
if (progress == Process_packets_result::PROGRESS)
|
if (progress == Process_packets_result::PROGRESS)
|
||||||
_io_progress_handler.handle_io_progress();
|
_io_progress_handler.handle_io_progress();
|
||||||
|
|
||||||
_deferred_wakeups.trigger();
|
_io.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -454,7 +445,7 @@ class Vfs_server::Session_component : private Session_resources,
|
|||||||
Genode::Cap_quota cap_quota,
|
Genode::Cap_quota cap_quota,
|
||||||
size_t tx_buf_size,
|
size_t tx_buf_size,
|
||||||
Vfs::File_system &vfs,
|
Vfs::File_system &vfs,
|
||||||
Deferred_wakeups &deferred_wakeups,
|
Vfs::Env::Io &io,
|
||||||
Session_queue &active_sessions,
|
Session_queue &active_sessions,
|
||||||
Io_progress_handler &io_progress_handler,
|
Io_progress_handler &io_progress_handler,
|
||||||
char const *root_path,
|
char const *root_path,
|
||||||
@ -463,7 +454,7 @@ class Vfs_server::Session_component : private Session_resources,
|
|||||||
Session_resources(env.pd(), env.rm(), ram_quota, cap_quota, tx_buf_size),
|
Session_resources(env.pd(), env.rm(), ram_quota, cap_quota, tx_buf_size),
|
||||||
Session_rpc_object(_packet_ds.cap(), env.rm(), env.ep().rpc_ep()),
|
Session_rpc_object(_packet_ds.cap(), env.rm(), env.ep().rpc_ep()),
|
||||||
_vfs(vfs),
|
_vfs(vfs),
|
||||||
_deferred_wakeups(deferred_wakeups),
|
_io(io),
|
||||||
_ep(env.ep()),
|
_ep(env.ep()),
|
||||||
_io_progress_handler(io_progress_handler),
|
_io_progress_handler(io_progress_handler),
|
||||||
_active_sessions(active_sessions),
|
_active_sessions(active_sessions),
|
||||||
@ -867,7 +858,7 @@ class Vfs_server::Root : public Genode::Root_component<Session_component>,
|
|||||||
if (yield)
|
if (yield)
|
||||||
Genode::Signal_transmitter(_reactivate_handler).submit();
|
Genode::Signal_transmitter(_reactivate_handler).submit();
|
||||||
|
|
||||||
_vfs_env.deferred_wakeups().trigger();
|
_vfs_env.io().commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -952,7 +943,7 @@ class Vfs_server::Root : public Genode::Root_component<Session_component>,
|
|||||||
Genode::Ram_quota{ram_quota},
|
Genode::Ram_quota{ram_quota},
|
||||||
Genode::Cap_quota{cap_quota},
|
Genode::Cap_quota{cap_quota},
|
||||||
tx_buf_size, _vfs_env.root_dir(),
|
tx_buf_size, _vfs_env.root_dir(),
|
||||||
_vfs_env.deferred_wakeups(),
|
_vfs_env.io(),
|
||||||
_active_sessions, *this,
|
_active_sessions, *this,
|
||||||
session_root.base(), writeable);
|
session_root.base(), writeable);
|
||||||
|
|
||||||
|
@ -226,22 +226,20 @@ struct Block_session_component : Rpc_object<Block::Session>,
|
|||||||
using Block::Request_stream::try_acknowledge;
|
using Block::Request_stream::try_acknowledge;
|
||||||
using Block::Request_stream::wakeup_client_if_needed;
|
using Block::Request_stream::wakeup_client_if_needed;
|
||||||
|
|
||||||
using Vfs_peers = Vfs::Remote_io::Deferred_wakeups;
|
|
||||||
|
|
||||||
Vfs_block::File &_file;
|
Vfs_block::File &_file;
|
||||||
Vfs_peers &_vfs_peers;
|
Vfs::Env::Io &_io;
|
||||||
|
|
||||||
Block_session_component(Region_map &rm,
|
Block_session_component(Region_map &rm,
|
||||||
Entrypoint &ep,
|
Entrypoint &ep,
|
||||||
Dataspace_capability ds,
|
Dataspace_capability ds,
|
||||||
Signal_context_capability sigh,
|
Signal_context_capability sigh,
|
||||||
Vfs_block::File &file,
|
Vfs_block::File &file,
|
||||||
Vfs_peers &vfs_peers)
|
Vfs::Env::Io &io)
|
||||||
:
|
:
|
||||||
Request_stream { rm, ds, ep, sigh, file.block_info() },
|
Request_stream { rm, ds, ep, sigh, file.block_info() },
|
||||||
_ep { ep },
|
_ep { ep },
|
||||||
_file { file },
|
_file { file },
|
||||||
_vfs_peers { vfs_peers }
|
_io { io }
|
||||||
{
|
{
|
||||||
_ep.manage(*this);
|
_ep.manage(*this);
|
||||||
}
|
}
|
||||||
@ -308,7 +306,7 @@ struct Block_session_component : Rpc_object<Block::Session>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_vfs_peers.trigger();
|
_io.commit();
|
||||||
|
|
||||||
wakeup_client_if_needed();
|
wakeup_client_if_needed();
|
||||||
}
|
}
|
||||||
@ -385,7 +383,7 @@ struct Main : Rpc_object<Typed_root<Block::Session>>
|
|||||||
_block_session.construct(_env.rm(), _env.ep(),
|
_block_session.construct(_env.rm(), _env.ep(),
|
||||||
_block_ds->cap(),
|
_block_ds->cap(),
|
||||||
_request_handler, *_block_file,
|
_request_handler, *_block_file,
|
||||||
_vfs_env.deferred_wakeups());
|
_vfs_env.io());
|
||||||
|
|
||||||
return _block_session->cap();
|
return _block_session->cap();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
@ -304,7 +304,7 @@ struct Write_test : public Stress_test
|
|||||||
handle->fs().queue_sync(handle);
|
handle->fs().queue_sync(handle);
|
||||||
while (handle->fs().complete_sync(handle) ==
|
while (handle->fs().complete_sync(handle) ==
|
||||||
Vfs::File_io_service::SYNC_QUEUED)
|
Vfs::File_io_service::SYNC_QUEUED)
|
||||||
_io.progress();
|
_io.commit_and_wait();
|
||||||
count += n;
|
count += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,7 +382,7 @@ struct Read_test : public Stress_test
|
|||||||
while ((read_result =
|
while ((read_result =
|
||||||
handle->fs().complete_read(handle, tmp, sizeof(tmp), n)) ==
|
handle->fs().complete_read(handle, tmp, sizeof(tmp), n)) ==
|
||||||
Vfs::File_io_service::READ_QUEUED)
|
Vfs::File_io_service::READ_QUEUED)
|
||||||
_io.progress();
|
_io.commit_and_wait();
|
||||||
|
|
||||||
assert_read(read_result);
|
assert_read(read_result);
|
||||||
|
|
||||||
@ -457,7 +457,7 @@ struct Unlink_test : public Stress_test
|
|||||||
while (dir_handle->fs().complete_read(dir_handle, (char*)&dirent,
|
while (dir_handle->fs().complete_read(dir_handle, (char*)&dirent,
|
||||||
sizeof(dirent), out_count) ==
|
sizeof(dirent), out_count) ==
|
||||||
Vfs::File_io_service::READ_QUEUED)
|
Vfs::File_io_service::READ_QUEUED)
|
||||||
_io.progress();
|
_io.commit_and_wait();
|
||||||
|
|
||||||
subpath.append(dirent.name.buf);
|
subpath.append(dirent.name.buf);
|
||||||
switch (dirent.type) {
|
switch (dirent.type) {
|
||||||
@ -540,11 +540,11 @@ void Component::construct(Genode::Env &env)
|
|||||||
auto vfs_root_sync = [&] ()
|
auto vfs_root_sync = [&] ()
|
||||||
{
|
{
|
||||||
while (!vfs_root_handle->fs().queue_sync(vfs_root_handle))
|
while (!vfs_root_handle->fs().queue_sync(vfs_root_handle))
|
||||||
vfs_env.io().progress();
|
vfs_env.io().commit_and_wait();
|
||||||
|
|
||||||
while (vfs_root_handle->fs().complete_sync(vfs_root_handle) ==
|
while (vfs_root_handle->fs().complete_sync(vfs_root_handle) ==
|
||||||
Vfs::File_io_service::SYNC_QUEUED)
|
Vfs::File_io_service::SYNC_QUEUED)
|
||||||
vfs_env.io().progress();
|
vfs_env.io().commit_and_wait();
|
||||||
};
|
};
|
||||||
|
|
||||||
char path[Vfs::MAX_PATH_LEN];
|
char path[Vfs::MAX_PATH_LEN];
|
||||||
|
Loading…
Reference in New Issue
Block a user