Date: Sat, 05 Oct 2002 12:12:59 -0700 From: Terry Lambert <tlambert2@mindspring.com> To: Stefan Farfeleder <e0026813@stud3.tuwien.ac.at> Cc: John Baldwin <jhb@FreeBSD.org>, Juli Mallett <jmallett@FreeBSD.org>, current@FreeBSD.org Subject: [PATCH] Re: Junior Kernel Hacker page updated... Message-ID: <3D9F39BB.66126C35@mindspring.com> References: <20021004132203.A78223@FreeBSD.org> <XFMail.20021004163317.jhb@FreeBSD.org> <20021005135504.GA254@frog.fafoe>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------6432A5E3A2499CE19F1AEDE9 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Stefan Farfeleder wrote: > (kgdb) l *kqueue_scan+0x242 > 0xc01a1212 is in kqueue_scan > (/freebsd/current/src/sys/kern/kern_event.c:716). > 713 TAILQ_INSERT_TAIL(&kq->kq_head, &marker, kn_tqe); > 714 while (count) { > 715 kn = TAILQ_FIRST(&kq->kq_head); > translates to: mov (%edi),%ebx > 716 TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe); > translates to: cmpl $0x0,0x8(%ebx) > > This line causes the page fault because %ebx is 0. This can't happen, at least from an "empty list" perspective, even if kqueue_scan() is reentered, since the "marker" is an auto allocation on the stack, and a different stack means a different marker gets inserted (marker isn't static, so having more than one insert of the marker won't result in only a single insertion). I suspect that what is hapening is that the code is being reentered, and one marker is being treated as an event, because of whatever garbage happens to be on the stack in the allocated marker. The marker is removed, and then it is not found before you hit the end of the list. Please try the attached patch. -- Terry --------------6432A5E3A2499CE19F1AEDE9 Content-Type: text/plain; charset=us-ascii; name="kpanic.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="kpanic.diff" Index: sys/event.h =================================================================== RCS file: /cvs/src/sys/sys/event.h,v retrieving revision 1.21 diff -c -r1.21 event.h *** sys/event.h 29 Jun 2002 19:14:52 -0000 1.21 --- sys/event.h 5 Oct 2002 15:12:24 -0000 *************** *** 160,165 **** --- 160,166 ---- #define KN_QUEUED 0x02 /* event is on queue */ #define KN_DISABLED 0x04 /* event is disabled */ #define KN_DETACHED 0x08 /* knote is detached */ + #define KN_MARKER 0x10 /* knote is a scan marker */ #define kn_id kn_kevent.ident #define kn_filter kn_kevent.filter Index: kern/kern_event.c =================================================================== RCS file: /cvs/src/sys/kern/kern_event.c,v retrieving revision 1.45 diff -c -r1.45 kern_event.c *** kern/kern_event.c 17 Aug 2002 02:36:16 -0000 1.45 --- kern/kern_event.c 5 Oct 2002 15:13:26 -0000 *************** *** 653,658 **** --- 653,659 ---- FILE_LOCK_ASSERT(fp, MA_NOTOWNED); + marker.kn_status = KN_MARKER; kq = (struct kqueue *)fp->f_data; count = maxevents; if (count == 0) *************** *** 713,718 **** --- 714,727 ---- TAILQ_INSERT_TAIL(&kq->kq_head, &marker, kn_tqe); while (count) { kn = TAILQ_FIRST(&kq->kq_head); + /* + * Skip over all markers which are not ours. This looks + * unsafe, but we can't hit the end of the list without + * hitting our own marker. + */ + while ((kn->kn_status & KN_MARKER) && (kn != &marker)) { + kn = TAILQ_NEXT(kn, kn_tqe); + } TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe); if (kn == &marker) { splx(s); --------------6432A5E3A2499CE19F1AEDE9-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3D9F39BB.66126C35>