mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-16 07:27:35 +00:00
dde_linux: remove exited tasks
The commit introduces means to mark a task for destruction that is removed on the next scheduling cycle. This fixes stack leakage from dynamic kworker tasks. Issue #4575.
This commit is contained in:
parent
bc665384c3
commit
3d8c1080b1
@ -46,6 +46,8 @@ void *lx_emul_task_stack(struct task_struct const * task);
|
||||
|
||||
char lx_emul_task_another_runnable(void);
|
||||
|
||||
void lx_emul_task_mark_for_removal(struct task_struct const * task);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -34,7 +34,7 @@ class Lx_kit::Task : public Genode::List<Lx_kit::Task>::Element
|
||||
|
||||
using Name = String<64>;
|
||||
|
||||
enum State { INIT, RUNNING, BLOCKED };
|
||||
enum State { INIT, RUNNING, BLOCKED, DESTROY };
|
||||
enum Type { NORMAL, IRQ_HANDLER, TIME_HANDLER };
|
||||
|
||||
private:
|
||||
@ -100,6 +100,15 @@ class Lx_kit::Task : public Genode::List<Lx_kit::Task>::Element
|
||||
* Shortcut to enter blocking state and request scheduling
|
||||
*/
|
||||
void block_and_schedule();
|
||||
|
||||
/**
|
||||
* Mark for destruction
|
||||
*
|
||||
* Let the scheduler clean up the task when a new one is added.
|
||||
*/
|
||||
void mark_for_destruction();
|
||||
|
||||
bool destroy() const;
|
||||
};
|
||||
|
||||
#endif /* _LX_KIT__TASK_H_ */
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <linux/rcuwait.h>
|
||||
|
||||
#include <lx_emul/debug.h>
|
||||
#include <lx_emul/task.h>
|
||||
|
||||
|
||||
int rcuwait_wake_up(struct rcuwait * w)
|
||||
@ -38,6 +39,9 @@ void __noreturn do_exit(long code)
|
||||
complete(tsk->vfork_done);
|
||||
|
||||
current->flags |= PF_NOFREEZE;
|
||||
|
||||
lx_emul_task_mark_for_removal(tsk);
|
||||
|
||||
schedule();
|
||||
BUG();
|
||||
}
|
||||
|
@ -108,3 +108,9 @@ extern "C" char lx_emul_task_another_runnable()
|
||||
|
||||
return Lx_kit::env().scheduler.another_runnable(&task);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void lx_emul_task_mark_for_removal(struct task_struct const *t)
|
||||
{
|
||||
Lx_kit::env().scheduler.task((void*)t).mark_for_destruction();
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <base/thread.h>
|
||||
#include <os/backtrace.h>
|
||||
|
||||
#include <lx_kit/scheduler.h>
|
||||
#include <lx_kit/env.h>
|
||||
#include <lx_kit/task.h>
|
||||
|
||||
using namespace Genode;
|
||||
@ -119,6 +119,17 @@ void Scheduler::schedule()
|
||||
/* update jiffies before running task */
|
||||
//Lx::timer_update_jiffies();
|
||||
|
||||
for (Task * t = _present_list.first(); t; ) {
|
||||
|
||||
Task *tmp = t;
|
||||
t = t->next();
|
||||
|
||||
if (!tmp->destroy())
|
||||
continue;
|
||||
|
||||
Genode::destroy(Lx_kit::env().heap, tmp);
|
||||
}
|
||||
|
||||
for (Task * t = _present_list.first(); t; t = t->next()) {
|
||||
|
||||
if (!t->runnable())
|
||||
|
@ -27,6 +27,7 @@ bool Task::runnable() const
|
||||
case INIT: return true;
|
||||
case RUNNING: return true;
|
||||
case BLOCKED: return false;
|
||||
case DESTROY: return false;
|
||||
}
|
||||
error("Invalid task state?!");
|
||||
return false;
|
||||
@ -139,6 +140,18 @@ void Task::block_and_schedule()
|
||||
}
|
||||
|
||||
|
||||
void Task::mark_for_destruction()
|
||||
{
|
||||
_state = DESTROY;
|
||||
}
|
||||
|
||||
|
||||
bool Task::destroy() const
|
||||
{
|
||||
return _state == DESTROY;
|
||||
}
|
||||
|
||||
|
||||
Task::Task(int (* func)(void*),
|
||||
void * arg,
|
||||
void * lx_task,
|
||||
|
Loading…
x
Reference in New Issue
Block a user