mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
nova: handle oom during assign_pci
This commit is contained in:
parent
89085096d2
commit
c732aef227
@ -346,6 +346,7 @@ namespace Genode {
|
||||
enum Oom {
|
||||
SEND = 1, REPLY = 2, SELF = 4,
|
||||
SRC_CORE_PD = ~0UL, SRC_PD_UNKNOWN = 0,
|
||||
NO_NOTIFICATION = 0
|
||||
};
|
||||
|
||||
/**
|
||||
@ -362,10 +363,17 @@ namespace Genode {
|
||||
* /param pd debug feature - string of PD (transfer_from)
|
||||
* /param thread debug feature - string of EC (transfer_from)
|
||||
*/
|
||||
uint8_t handle_oom(addr_t pd_sel = SRC_CORE_PD,
|
||||
const char * pd = "core",
|
||||
uint8_t handle_oom(addr_t pd_sel = SRC_CORE_PD,
|
||||
const char * pd = "core",
|
||||
const char * thread = "unknown",
|
||||
Policy = Policy::UPGRADE_CORE_TO_DST);
|
||||
static uint8_t handle_oom(addr_t pd_from, addr_t pd_to,
|
||||
char const * src_pd,
|
||||
char const * src_thread,
|
||||
Policy policy,
|
||||
addr_t sm_notify = NO_NOTIFICATION,
|
||||
char const * dst_pd = "unknown",
|
||||
char const * dst_thread = "unknown");
|
||||
|
||||
void print(Output &out) const;
|
||||
};
|
||||
|
@ -694,23 +694,30 @@ uint8_t Pager_object::handle_oom(addr_t transfer_from,
|
||||
char const * src_pd, char const * src_thread,
|
||||
enum Pager_object::Policy policy)
|
||||
{
|
||||
char const * dst_pd = client_pd();
|
||||
char const * dst_thread = client_thread();
|
||||
return handle_oom(transfer_from, pd_sel(), src_pd, src_thread, policy,
|
||||
sel_sm_block_oom(), client_pd(), client_thread());
|
||||
}
|
||||
|
||||
uint8_t Pager_object::handle_oom(addr_t pd_from, addr_t pd_to,
|
||||
char const * src_pd, char const * src_thread,
|
||||
Policy policy, addr_t sm_notify,
|
||||
char const * dst_pd, char const * dst_thread)
|
||||
{
|
||||
addr_t const core_pd_sel = platform_specific()->core_pd_sel();
|
||||
|
||||
enum { QUOTA_TRANSFER_PAGES = 2 };
|
||||
|
||||
if (transfer_from == SRC_CORE_PD)
|
||||
transfer_from = core_pd_sel;
|
||||
if (pd_from == SRC_CORE_PD)
|
||||
pd_from = core_pd_sel;
|
||||
|
||||
/* request current kernel quota usage of target pd */
|
||||
addr_t limit_before = 0, usage_before = 0;
|
||||
Nova::pd_ctrl_debug(pd_sel(), limit_before, usage_before);
|
||||
Nova::pd_ctrl_debug(pd_to, limit_before, usage_before);
|
||||
|
||||
if (verbose_oom) {
|
||||
addr_t limit_source = 0, usage_source = 0;
|
||||
/* request current kernel quota usage of source pd */
|
||||
Nova::pd_ctrl_debug(transfer_from, limit_source, usage_source);
|
||||
Nova::pd_ctrl_debug(pd_from, limit_source, usage_source);
|
||||
|
||||
log("oom - '", dst_pd, "':'", dst_thread, "' "
|
||||
"(", usage_before, "/", limit_before, ") - "
|
||||
@ -721,19 +728,19 @@ uint8_t Pager_object::handle_oom(addr_t transfer_from,
|
||||
|
||||
uint8_t res = Nova::NOVA_PD_OOM;
|
||||
|
||||
if (transfer_from != pd_sel()) {
|
||||
if (pd_from != pd_to) {
|
||||
/* upgrade quota */
|
||||
uint8_t res = Nova::pd_ctrl(transfer_from, Pd_op::TRANSFER_QUOTA,
|
||||
pd_sel(), QUOTA_TRANSFER_PAGES);
|
||||
uint8_t res = Nova::pd_ctrl(pd_from, Pd_op::TRANSFER_QUOTA,
|
||||
pd_to, QUOTA_TRANSFER_PAGES);
|
||||
if (res == Nova::NOVA_OK)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* retry upgrade using core quota if policy permits */
|
||||
if (policy == UPGRADE_PREFER_SRC_TO_DST) {
|
||||
if (transfer_from != core_pd_sel) {
|
||||
if (pd_from != core_pd_sel) {
|
||||
res = Nova::pd_ctrl(core_pd_sel, Pd_op::TRANSFER_QUOTA,
|
||||
pd_sel(), QUOTA_TRANSFER_PAGES);
|
||||
pd_to, QUOTA_TRANSFER_PAGES);
|
||||
if (res == Nova::NOVA_OK)
|
||||
return res;
|
||||
}
|
||||
@ -747,11 +754,11 @@ uint8_t Pager_object::handle_oom(addr_t transfer_from,
|
||||
/* if nothing helps try to revoke memory */
|
||||
enum { REMOTE_REVOKE = true, PD_SELF = true };
|
||||
Mem_crd crd_all(0, ~0U, Rights(true, true, true));
|
||||
Nova::revoke(crd_all, PD_SELF, REMOTE_REVOKE, pd_sel(), sel_sm_block_oom());
|
||||
Nova::revoke(crd_all, PD_SELF, REMOTE_REVOKE, pd_to, sm_notify);
|
||||
|
||||
/* re-request current kernel quota usage of target pd */
|
||||
addr_t limit_after = 0, usage_after = 0;
|
||||
Nova::pd_ctrl_debug(pd_sel(), limit_after, usage_after);
|
||||
Nova::pd_ctrl_debug(pd_to, limit_after, usage_after);
|
||||
/* if we could free up memory we continue */
|
||||
if (usage_after < usage_before)
|
||||
return Nova::NOVA_OK;
|
||||
|
@ -19,6 +19,14 @@ using namespace Genode;
|
||||
|
||||
bool Pd_session_component::assign_pci(addr_t pci_config_memory, uint16_t bdf)
|
||||
{
|
||||
uint8_t res = Nova::assign_pci(_pd.pd_sel(), pci_config_memory, bdf);
|
||||
uint8_t res = Nova::NOVA_PD_OOM;
|
||||
do {
|
||||
res = Nova::assign_pci(_pd.pd_sel(), pci_config_memory, bdf);
|
||||
} while (res == Nova::NOVA_PD_OOM &&
|
||||
Nova::NOVA_OK == Pager_object::handle_oom(Pager_object::SRC_CORE_PD,
|
||||
_pd.pd_sel(),
|
||||
"core", "ep",
|
||||
Pager_object::Policy::UPGRADE_CORE_TO_DST));
|
||||
|
||||
return res == Nova::NOVA_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user