Some more progress with debugging pager exits

This commit is contained in:
Bahadir Balban
2009-10-30 18:28:45 +02:00
parent 18ffa0b4d1
commit ee7621b2df
9 changed files with 50 additions and 23 deletions

View File

@@ -140,14 +140,13 @@ void handle_requests(void)
break; break;
} }
case L4_IPC_TAG_EXIT: { case L4_IPC_TAG_EXIT: {
/* Zombie test for kernel
struct task_ids ids; struct task_ids ids;
l4_getid(&ids); l4_getid(&ids);
printf("\n%s: Destroying self (%d), along with any tasks.\n", __TASKNAME__, self_tid()); printf("\n%s: Destroying self (%d), along with any tasks.\n", __TASKNAME__, self_tid());
l4_thread_control(THREAD_DESTROY, &ids); l4_thread_control(THREAD_DESTROY, &ids);
*/
/* An exiting task has no receive phase */ /* An exiting task has no receive phase */
sys_exit(sender, (int)mr[0]); sys_exit(sender, (int)mr[0]);
return; return;

View File

@@ -123,7 +123,12 @@ void fault_ipc_to_pager(u32 faulty_pc, u32 fsr, u32 far)
"returned error (%d). Suspend and exiting thread.\n", "returned error (%d). Suspend and exiting thread.\n",
current->tid, err); current->tid, err);
BUG_ON(current->nlocks); BUG_ON(current->nlocks);
sched_die_sync();
/* Declare our exit, currently only used by bug_on checks */
current->flags |= TASK_EXITING;
/* Try to die forever */
while (1)
sched_die_sync();
} }
} }

View File

@@ -102,7 +102,8 @@ int init_pager(struct pager *pager,
address_space_attach(task, space); address_space_attach(task, space);
} else { } else {
/* Otherwise allocate conventionally */ /* Otherwise allocate conventionally */
task->space = address_space_create(0); space = address_space_create(0);
address_space_attach(task, space);
} }
/* Initialize ktcb */ /* Initialize ktcb */
@@ -115,6 +116,13 @@ int init_pager(struct pager *pager,
task->tgid = task->tid; task->tgid = task->tid;
task->container = cont; task->container = cont;
/*
* Setup dummy container pointer so that curcont works,
* and add the address space to container space list
*/
current->container = cont;
address_space_add(task->space);
/* Initialize uninitialized capability fields while on dummy */ /* Initialize uninitialized capability fields while on dummy */
list_foreach_struct(cap, &current->cap_list.caps, list) { list_foreach_struct(cap, &current->cap_list.caps, list) {
/* Initialize owner */ /* Initialize owner */
@@ -156,7 +164,6 @@ int init_pager(struct pager *pager,
/* Container list that keeps all tasks */ /* Container list that keeps all tasks */
tcb_add(task); tcb_add(task);
return 0; return 0;
} }
@@ -169,16 +176,19 @@ int container_init_pagers(struct kernel_resources *kres,
{ {
struct container *cont; struct container *cont;
struct pager *pager; struct pager *pager;
int first = 1;
list_foreach_struct(cont, &kres->containers.list, list) { list_foreach_struct(cont, &kres->containers.list, list) {
for (int i = 0; i < cont->npagers; i++) { for (int i = 0; i < cont->npagers; i++) {
pager = &cont->pager[i]; pager = &cont->pager[i];
/* First pager initializes specially */ /* First pager initializes specially */
if (i == 0) if (first) {
init_pager(pager, cont, current_pgd); init_pager(pager, cont, current_pgd);
else first = 0;
} else {
init_pager(pager, cont, 0); init_pager(pager, cont, 0);
}
} }
} }

View File

@@ -301,6 +301,8 @@ void sched_die_pager(void)
*/ */
void sched_die_child(void) void sched_die_child(void)
{ {
int err;
/* /*
* Find pager, he _must_ be there because he never * Find pager, he _must_ be there because he never
* quits before quitting us * quits before quitting us
@@ -308,7 +310,8 @@ void sched_die_child(void)
struct ktcb *pager = tcb_find(current->pagerid); struct ktcb *pager = tcb_find(current->pagerid);
/* Lock its task_dead queue */ /* Lock its task_dead queue */
mutex_lock(&pager->task_dead.list_lock); if ((err = mutex_lock(&pager->task_dead.list_lock)) < 0)
return err;
/* Remove from container task list, /* Remove from container task list,
* callers get -ESRCH */ * callers get -ESRCH */
@@ -332,7 +335,7 @@ void sched_die_child(void)
* Add self to pager's dead tasks list, * Add self to pager's dead tasks list,
* to be deleted by pager * to be deleted by pager
*/ */
ktcb_list_add(current, &pager->task_dead); __ktcb_list_add_nolock(current, &pager->task_dead);
/* Now quit the scheduler */ /* Now quit the scheduler */
preempt_disable(); preempt_disable();
@@ -354,15 +357,20 @@ void sched_die_child(void)
* pager can safely delete us * pager can safely delete us
*/ */
mutex_unlock(&pager->task_dead.list_lock); mutex_unlock(&pager->task_dead.list_lock);
schedule();
BUG(); BUG();
} }
void sched_die_sync(void) void sched_die_sync(void)
{ {
if (current->tid == current->pagerid) /*
sched_die_pager(); * Infinitely retry if mutexes get interrupted
else */
sched_die_child(); while (1)
if (current->tid == current->pagerid)
sched_die_pager();
else
sched_die_child();
} }
/* /*

View File

@@ -68,7 +68,12 @@ void address_space_add(struct address_space *space)
void address_space_remove(struct address_space *space) void address_space_remove(struct address_space *space)
{ {
spin_lock(&curcont->space_list.list_lock); spin_lock(&curcont->space_list.list_lock);
BUG_ON(list_empty(&space->list));
/*
* If current is quitting as the last task of this space,
* its tcb may already be removed, and this is fine
*/
BUG_ON(list_empty(&space->list) && space != current->space);
BUG_ON(--curcont->space_list.count < 0); BUG_ON(--curcont->space_list.count < 0);
list_remove_init(&space->list); list_remove_init(&space->list);
spin_unlock(&curcont->space_list.list_lock); spin_unlock(&curcont->space_list.list_lock);

View File

@@ -70,7 +70,8 @@ void tcb_delete(struct ktcb *tcb)
BUG_ON(tcb->wqh_pager.sleepers > 0); BUG_ON(tcb->wqh_pager.sleepers > 0);
BUG_ON(tcb->wqh_send.sleepers > 0); BUG_ON(tcb->wqh_send.sleepers > 0);
BUG_ON(tcb->wqh_recv.sleepers > 0); BUG_ON(tcb->wqh_recv.sleepers > 0);
BUG_ON(!list_empty(&tcb->task_list)); BUG_ON(!list_empty(&tcb->task_list) &&
!(tcb->flags & TASK_EXITING));
BUG_ON(!list_empty(&tcb->rq_list) && tcb != current); BUG_ON(!list_empty(&tcb->rq_list) && tcb != current);
BUG_ON(tcb->rq && tcb != current); BUG_ON(tcb->rq && tcb != current);
BUG_ON(tcb->nlocks); BUG_ON(tcb->nlocks);

View File

@@ -283,12 +283,6 @@ void init_finalize(struct kernel_resources *kres)
*/ */
kip.utcb = (u32)current->utcb_address; kip.utcb = (u32)current->utcb_address;
/*
* Added the first pager's space area to
* the address space list of the related container
*/
address_space_add(current->space);
/* /*
* Start the scheduler, jumping to task * Start the scheduler, jumping to task
*/ */

View File

@@ -117,6 +117,7 @@ int mutex_lock(struct mutex *mutex)
* undeterministic as to how many retries will result in success. * undeterministic as to how many retries will result in success.
* We may need to add priority-based locking. * We may need to add priority-based locking.
*/ */
printk("Thread (%d) locking (%p) nlocks: %d\n", current->tid, mutex, current->nlocks);
for (;;) { for (;;) {
spin_lock(&mutex->wqh.slock); spin_lock(&mutex->wqh.slock);
if (!__mutex_lock(&mutex->lock)) { /* Could not lock, sleep. */ if (!__mutex_lock(&mutex->lock)) { /* Could not lock, sleep. */
@@ -131,6 +132,7 @@ int mutex_lock(struct mutex *mutex)
/* Did we wake up normally or get interrupted */ /* Did we wake up normally or get interrupted */
if (current->flags & TASK_INTERRUPTED) { if (current->flags & TASK_INTERRUPTED) {
printk("Thread (%d) interrupted on mutex sleep\n", current->tid);
current->flags &= ~TASK_INTERRUPTED; current->flags &= ~TASK_INTERRUPTED;
return -EINTR; return -EINTR;
} }
@@ -140,11 +142,14 @@ int mutex_lock(struct mutex *mutex)
} }
} }
spin_unlock(&mutex->wqh.slock); spin_unlock(&mutex->wqh.slock);
printk("Thread (%d) locked (%p) nlocks: %d\n", current->tid, mutex, current->nlocks);
return 0; return 0;
} }
static inline void mutex_unlock_common(struct mutex *mutex, int sync) static inline void mutex_unlock_common(struct mutex *mutex, int sync)
{ {
struct ktcb *c = current; if (c);
printk("Thread (%d) unlocking (%p) nlocks: %d\n", c->tid, mutex, c->nlocks);
spin_lock(&mutex->wqh.slock); spin_lock(&mutex->wqh.slock);
__mutex_unlock(&mutex->lock); __mutex_unlock(&mutex->lock);
current->nlocks--; current->nlocks--;

View File

@@ -38,7 +38,7 @@ void task_unset_wqh(struct ktcb *task)
/* /*
* Initiate wait on current task that * Initiate wait on current task that
* has already been placed in a waitqueue * has already been placed in a waitqueue
* *
* NOTE: This enables preemption and wait_on_prepare() * NOTE: This enables preemption and wait_on_prepare()
* should be called first. * should be called first.
*/ */
@@ -63,7 +63,7 @@ int wait_on_prepared_wait(void)
* Do all preparations to sleep but return without sleeping. * Do all preparations to sleep but return without sleeping.
* This is useful if the task needs to get in the waitqueue before * This is useful if the task needs to get in the waitqueue before
* it releases a lock. * it releases a lock.
* *
* NOTE: This disables preemption and it should be enabled by a * NOTE: This disables preemption and it should be enabled by a
* call to wait_on_prepared_wait() - the other function of the pair. * call to wait_on_prepared_wait() - the other function of the pair.
*/ */