erik quanstrom
2012-08-22 18:53:00 UTC
i'm probablly wrong again, but we had a crash with this back trace.
the process doing the i/o was given a note. ...
src(0xe010a6b9); // dumpstack+0x10
src(0xe0112653); // panic+0x112
src(0xe010a8d7); // fault386+0x17d
src(0xe0109dc2); // trap+0x15d
src(0xe010066f); // forkret
//passing interrupt frame; last pc found at sp=0xf4ea5d94
src(0xe01babbd); // lockloop+0x34
src(0xe01bacf6); // lock+0x103
src(0xe01aeed8); // wakeup+0x18
src(0xe0111a91); // mountmux+0xf1
src(0xe01115b6); // mountio+0x21d
src(0xe011127a); // mountrpc+0x27
src(0xe011116f); // mntrdwr+0xfb
src(0xe0110faa); // mntread+0x126
src(0xe01b90e3); // sysexec+0x172
src(0xe010abbb); // syscall+0x238
src(0xe0100cb5); // _syscallintr+0x18
...
i believe the unlock(m) needs to be moved to just before the return
because mntflushfree -> mntqrm can run after we drop the lock and
before the wakeup.
- erik
----
void
mountmux(Mnt *m, Mntrpc *r)
{
Mntrpc **l, *q;
lock(m);
l = &m->queue;
for(q = *l; q; q = q->list) {
/* look for a reply to a message */
if(q->request.tag == r->reply.tag) {
*l = q->list;
if(q != r) {
/*
* Completed someone else.
* Trade pointers to receive buffer.
*/
q->reply = r->reply;
q->b = r->b;
r->b = nil;
}
q->done = 1;
unlock(m);
if(mntstats != nil)
(*mntstats)(q->request.type,
m->c, q->stime,
q->reqlen + r->replen);
if(q != r)
mountmux+0xf1 wakeup(&q->r);
return;
}
l = &q->list;
}
unlock(m);
print("unexpected reply tag %ud; type %d\n", r->reply.tag, r->reply.type);
}
the process doing the i/o was given a note. ...
src(0xe010a6b9); // dumpstack+0x10
src(0xe0112653); // panic+0x112
src(0xe010a8d7); // fault386+0x17d
src(0xe0109dc2); // trap+0x15d
src(0xe010066f); // forkret
//passing interrupt frame; last pc found at sp=0xf4ea5d94
src(0xe01babbd); // lockloop+0x34
src(0xe01bacf6); // lock+0x103
src(0xe01aeed8); // wakeup+0x18
src(0xe0111a91); // mountmux+0xf1
src(0xe01115b6); // mountio+0x21d
src(0xe011127a); // mountrpc+0x27
src(0xe011116f); // mntrdwr+0xfb
src(0xe0110faa); // mntread+0x126
src(0xe01b90e3); // sysexec+0x172
src(0xe010abbb); // syscall+0x238
src(0xe0100cb5); // _syscallintr+0x18
...
i believe the unlock(m) needs to be moved to just before the return
because mntflushfree -> mntqrm can run after we drop the lock and
before the wakeup.
- erik
----
void
mountmux(Mnt *m, Mntrpc *r)
{
Mntrpc **l, *q;
lock(m);
l = &m->queue;
for(q = *l; q; q = q->list) {
/* look for a reply to a message */
if(q->request.tag == r->reply.tag) {
*l = q->list;
if(q != r) {
/*
* Completed someone else.
* Trade pointers to receive buffer.
*/
q->reply = r->reply;
q->b = r->b;
r->b = nil;
}
q->done = 1;
unlock(m);
if(mntstats != nil)
(*mntstats)(q->request.type,
m->c, q->stime,
q->reqlen + r->replen);
if(q != r)
mountmux+0xf1 wakeup(&q->r);
return;
}
l = &q->list;
}
unlock(m);
print("unexpected reply tag %ud; type %d\n", r->reply.tag, r->reply.type);
}