hw: fix capability accounting of kernel/core

The recently implemented capability resource trading scheme unfortunately
broke the automated capability memory upgrade mechanism needed by base-hw
kernel/core. This commit splits the capability memory upgrade mechanism
from the PD session ram_quota upgrade, and moves that functionality
into a separate Pd_session::Native_pd interface.

Ref #2398
This commit is contained in:
Stefan Kalkowski 2017-06-13 14:54:08 +02:00 committed by Christian Helmuth
parent 6f8dc9054a
commit a004462096
24 changed files with 233 additions and 110 deletions

View File

@ -24,7 +24,6 @@ SRC_CC += stack_area.cc \
rpc_cap_factory_l4.cc \
ram_dataspace_factory.cc \
pd_assign_pci.cc \
pd_upgrade_ram_quota.cc \
platform.cc \
platform_pd.cc \
platform_services.cc \

View File

@ -20,7 +20,6 @@ SRC_CC += stack_area.cc \
pager.cc \
pager_object.cc \
pd_assign_pci.cc \
pd_upgrade_ram_quota.cc \
native_cpu_component.cc \
rpc_cap_factory.cc \
platform.cc \

View File

@ -0,0 +1,32 @@
/*
* \brief Client-side HW specific PD session interface
* \author Stefan Kalkowski
* \date 2017-06-12
*/
/*
* Copyright (C) 2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__HW_NATIVE_PD__CLIENT_H_
#define _INCLUDE__HW_NATIVE_PD__CLIENT_H_
#include <hw_native_pd/hw_native_pd.h>
#include <base/rpc_client.h>
namespace Genode { struct Hw_native_pd_client; }
struct Genode::Hw_native_pd_client : Rpc_client<Hw_native_pd>
{
explicit Hw_native_pd_client(Capability<Native_pd> cap)
: Rpc_client<Hw_native_pd>(static_cap_cast<Hw_native_pd>(cap)) { }
void upgrade_cap_slab() override {
call<Rpc_upgrade_cap_slab>(); }
};
#endif /* _INCLUDE__HW_NATIVE_PD__CLIENT_H_ */

View File

@ -0,0 +1,37 @@
/*
* \brief HW-specific part of the PD session interface
* \author Stefan Kalkowski
* \date 2017-06-12
*/
/*
* Copyright (C) 2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__HW_NATIVE_PD__HW_NATIVE_PD_H_
#define _INCLUDE__HW_NATIVE_PD__HW_NATIVE_PD_H_
#include <base/rpc.h>
#include <pd_session/pd_session.h>
namespace Genode { struct Hw_native_pd; }
struct Genode::Hw_native_pd : Pd_session::Native_pd
{
virtual void upgrade_cap_slab() = 0;
/*********************
** RPC declaration **
*********************/
GENODE_RPC_THROW(Rpc_upgrade_cap_slab, void, upgrade_cap_slab,
GENODE_TYPE_LIST(Out_of_ram));
GENODE_RPC_INTERFACE(Rpc_upgrade_cap_slab);
};
#endif /* _INCLUDE__HW_NATIVE_PD__HW_NATIVE_PD_H_ */

View File

@ -1,7 +1,6 @@
include $(BASE_DIR)/lib/mk/base.inc
SRC_CC += thread_start.cc
SRC_CC += env.cc
SRC_CC += capability.cc
SRC_CC += cache.cc
SRC_CC += raw_write_string.cc

View File

@ -29,7 +29,7 @@ SRC_CC += io_mem_session_component.cc
SRC_CC += io_mem_session_support.cc
SRC_CC += irq_session_component.cc
SRC_CC += main.cc
SRC_CC += pd_upgrade_ram_quota.cc
SRC_CC += native_pd_component.cc
SRC_CC += pd_assign_pci.cc
SRC_CC += platform.cc
SRC_CC += platform_pd.cc

View File

@ -16,4 +16,4 @@
using namespace Genode;
void Genode::upgrade_pd_quota_non_blocking(Ram_quota, Cap_quota) { ASSERT_NEVER_CALLED; }
void Genode::upgrade_capability_slab() { ASSERT_NEVER_CALLED; }

View File

@ -0,0 +1,32 @@
/*
* \brief Kernel-specific part of the PD-session interface
* \author Stefan Kalkowski
* \date 2017-06-13
*/
/*
* Copyright (C) 2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#include <pd_session_component.h>
#include <native_pd_component.h>
using namespace Genode;
void Native_pd_component::upgrade_cap_slab() {
_pd_session._pd->upgrade_slab(_pd_session._sliced_heap);
//throw Out_of_ram();
}
Native_pd_component::Native_pd_component(Pd_session_component &pd_session,
char const *args)
: _pd_session(pd_session) {
_pd_session._ep.manage(this); }
Native_pd_component::~Native_pd_component() {
_pd_session._ep.dissolve(this); }

View File

@ -0,0 +1,46 @@
/*
* \brief Kernel-specific part of the PD-session interface
* \author Norman Feske
* \author Stefan Kalkowski
* \date 2017-06-13
*/
/*
* Copyright (C) 2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_
#define _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_
/* Genode includes */
#include <hw_native_pd/hw_native_pd.h>
/* core-local includes */
#include <rpc_cap_factory.h>
namespace Genode {
class Pd_session_component;
class Native_pd_component;
}
class Genode::Native_pd_component : public Rpc_object<Hw_native_pd>
{
private:
Pd_session_component &_pd_session;
public:
Native_pd_component(Pd_session_component &pd, char const *args);
~Native_pd_component();
void upgrade_cap_slab();
};
#endif /* _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_ */

View File

@ -1,24 +0,0 @@
/*
* \brief Core implementation of the PD session interface
* \author Norman Feske
* \date 2016-01-13
*/
/*
* Copyright (C) 2016-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* core-local includes */
#include <pd_session_component.h>
using namespace Genode;
void Pd_session_component::session_quota_upgraded()
{
_pd->upgrade_slab(_sliced_heap);
}

View File

@ -115,14 +115,10 @@ Cap_space::Cap_space() : _slab(nullptr, &_initial_sb) { }
void Cap_space::upgrade_slab(Allocator &alloc)
{
enum { NEEDED_AVAIL_ENTRIES_FOR_SUCCESSFUL_SYSCALL = 8 };
if (_slab.avail_entries() > NEEDED_AVAIL_ENTRIES_FOR_SUCCESSFUL_SYSCALL)
return;
void *block = nullptr;
if (alloc.alloc(SLAB_SIZE, &block))
_slab.insert_sb(block);
void * block = nullptr;
if (!alloc.alloc(SLAB_SIZE, &block))
throw Out_of_ram();
_slab.insert_sb(block);
}

View File

@ -14,20 +14,12 @@
#ifndef _INCLUDE__BASE__INTERNAL__NATIVE_ENV_H_
#define _INCLUDE__BASE__INTERNAL__NATIVE_ENV_H_
/* Genode includes */
#include <base/stdint.h>
#include <base/quota_guard.h>
namespace Genode
{
/**
* Upgrade quota of the PD session within my Genode environment non-blocking
*
* This function doesn't lock the environment when upgrading. This is
* needed when doing upgrades in situations where the environment is
* already locked due to the operation that triggered the upgrade.
* Upgrade quota of the PD session's capability slab allocator
*/
void upgrade_pd_quota_non_blocking(Ram_quota, Cap_quota);
void upgrade_capability_slab();
};
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_ENV_H_ */

View File

@ -1,26 +0,0 @@
/*
* \brief Implementation of non-core PD session upgrade
* \author Stefan Kalkowski
* \date 2015-05-20
*/
/*
* Copyright (C) 2015-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* Genode includes */
#include <base/env.h>
/* base-internal includes */
#include <base/internal/globals.h>
#include <base/internal/native_env.h>
void Genode::upgrade_pd_quota_non_blocking(Ram_quota ram, Cap_quota caps)
{
internal_env().parent().upgrade(Parent::Env::pd(),
String<100>("ram_quota=", ram, ", "
"cap_quota=", caps).string());
}

View File

@ -0,0 +1,73 @@
/*
* \brief Environment initialization
* \author Norman Feske
* \author Christian Helmuth
* \date 2006-07-27
*/
/*
* Copyright (C) 2006-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#include <base/internal/platform_env.h>
#include <base/internal/globals.h>
#include <base/internal/native_env.h>
#include <base/connection.h>
#include <base/service.h>
#include <hw_native_pd/client.h>
namespace Genode {
/*
* Request pointer to static environment of the Genode application
*/
Env_deprecated *env_deprecated()
{
/*
* By placing the environment as static object here, we ensure that its
* constructor gets called when this function is used the first time.
*/
static Genode::Platform_env _env;
return &_env;
}
}
using Native_pd_capability = Genode::Capability<Genode::Pd_session::Native_pd>;
static Native_pd_capability native_pd_cap;
void Genode::init_parent_resource_requests(Genode::Env & env)
{
/**
* Catch up asynchronous resource request and notification
* mechanism construction of the expanding parent environment
*/
using Parent = Expanding_parent_client;
static_cast<Parent*>(&env.parent())->init_fallback_signal_handling();
native_pd_cap = env.pd().native_pd();
}
void Genode::upgrade_capability_slab()
{
if (!native_pd_cap.valid()) {
Genode::error("Cannot upgrade capability slab "
"not initialized appropriatedly");
return;
}
retry<Genode::Out_of_ram>(
[&] () {
Genode::Hw_native_pd_client pd(native_pd_cap);
pd.upgrade_cap_slab();
},
[&] () {
internal_env().upgrade(Parent::Env::pd(),
String<100>("ram_quota=", 8192).string());
});
}

View File

@ -109,8 +109,7 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst,
}
},
[&] () { upgrade_pd_quota_non_blocking(Ram_quota{3 * 1024 * sizeof(addr_t)},
Cap_quota{0}); });
[&] () { upgrade_capability_slab(); });
return Rpc_exception_code(utcb.exception_code());
}
@ -155,8 +154,7 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &,
default: break;
}
},
[&] () { upgrade_pd_quota_non_blocking(Ram_quota{3 * 1024 * sizeof(addr_t)},
Cap_quota{0}); });
[&] () { upgrade_capability_slab(); });
copy_utcb_to_msg(utcb, request_msg);

View File

@ -105,7 +105,9 @@ Signal_context_capability Signal_receiver::manage(Signal_context * const c)
catch (Out_of_ram) { ram_upgrade = Ram_quota { 1024*sizeof(long) }; }
catch (Out_of_caps) { cap_upgrade = Cap_quota { 4 }; }
upgrade_pd_quota_non_blocking(ram_upgrade, cap_upgrade);
internal_env().upgrade(Parent::Env::pd(),
String<100>("ram_quota=", ram_upgrade, ", "
"cap_quota=", cap_upgrade).string());
}
}

View File

@ -14,7 +14,6 @@ SRC_CC = main.cc \
cpu_session_component.cc \
cpu_session_support.cc \
cpu_thread_component.cc \
pd_upgrade_ram_quota.cc \
pd_assign_pci.cc \
dataspace_component.cc \
native_pd_component.cc \

View File

@ -24,7 +24,6 @@ SRC_CC += stack_area.cc \
pager.cc \
native_cpu_component.cc \
native_pd_component.cc \
pd_upgrade_ram_quota.cc \
pd_assign_pci.cc \
rpc_cap_factory.cc \
ram_dataspace_factory.cc \

View File

@ -24,7 +24,6 @@ SRC_CC += stack_area.cc \
pager.cc \
pager_ep.cc \
pager_object.cc \
pd_upgrade_ram_quota.cc \
pd_assign_pci.cc \
rpc_cap_factory_l4.cc \
ram_dataspace_factory.cc \

View File

@ -22,7 +22,6 @@ SRC_CC = stack_area.cc \
rpc_cap_factory_l4.cc \
ram_dataspace_factory.cc \
pd_assign_pci.cc \
pd_upgrade_ram_quota.cc \
pager.cc \
pager_ep.cc \
pager_object.cc \

View File

@ -11,7 +11,6 @@ SRC_CC += \
rpc_cap_factory.cc \
ram_dataspace_factory.cc \
pd_assign_pci.cc \
pd_upgrade_ram_quota.cc \
io_mem_session_component.cc \
io_mem_session_support.cc \
io_port_session_component.cc \

View File

@ -62,7 +62,6 @@ class Genode::Pd_root : public Genode::Root_component<Genode::Pd_session_compone
{
pd->Ram_quota_guard::upgrade(ram_quota_from_args(args));
pd->Cap_quota_guard::upgrade(cap_quota_from_args(args));
pd->session_quota_upgraded();
}
public:

View File

@ -150,11 +150,6 @@ class Genode::Pd_session_component : public Session_object<Pd_session>
_ram_account.construct(*this, _label);
}
/**
* Session_object interface
*/
void session_quota_upgraded() override;
/**
* Associate thread with PD
*

View File

@ -1,21 +0,0 @@
/*
* \brief Core implementation of the PD session interface
* \author Norman Feske
* \date 2016-01-13
*/
/*
* Copyright (C) 2016-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* core-local includes */
#include <pd_session_component.h>
using namespace Genode;
void Pd_session_component::session_quota_upgraded() { }