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>
