Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Oct 2002 20:32:01 -0700 (PDT)
From:      Don Lewis <dl-freebsd@catspoiler.org>
To:        e0026813@stud3.tuwien.ac.at
Cc:        current@FreeBSD.ORG
Subject:   Re: Junior Kernel Hacker page updated...
Message-ID:  <200210030332.g933W1vU017519@gw.catspoiler.org>
In-Reply-To: <20021002214028.GA94673@frog.fafoe>

next in thread | previous in thread | raw e-mail | index | archive | help
On  2 Oct, Stefan Farfeleder wrote:

> /freebsd/current/src/sys/vm/uma_core.c:1307: could sleep with "filedesc structure" locked from /freebsd/current/src/sys/kern/kern_event.c:959
> 
> at me and freezes badly at some point (no breaking into ddb possible).
> This is totally repeatable.  Is anybody able to reproduce (and maybe
> fix) this?

It looks like the problem is that knote_attach() calls hashinit() while
holding the lock, and that hashinit() calls MALLOC(..., M_WAITOK).

Try the following patch:

Index: sys/kern/kern_event.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_event.c,v
retrieving revision 1.45
diff -u -r1.45 kern_event.c
--- sys/kern/kern_event.c	17 Aug 2002 02:36:16 -0000	1.45
+++ sys/kern/kern_event.c	3 Oct 2002 03:10:09 -0000
@@ -953,15 +953,27 @@
 static void
 knote_attach(struct knote *kn, struct filedesc *fdp)
 {
-	struct klist *list, *oldlist;
+	struct klist *list, *oldlist, *tmp_knhash;
+	u_long tmp_knhashmask;
 	int size, newsize;
 
 	FILEDESC_LOCK(fdp);
 
 	if (! kn->kn_fop->f_isfd) {
-		if (fdp->fd_knhashmask == 0)
-			fdp->fd_knhash = hashinit(KN_HASHSIZE, M_KQUEUE,
-			    &fdp->fd_knhashmask);
+		if (fdp->fd_knhashmask == 0) {
+			FILEDESC_UNLOCK(fdp);
+			tmp_knhash = hashinit(KN_HASHSIZE, M_KQUEUE,
+			    &tmp_knhashmask);
+			FILEDESC_LOCK(fdp);
+			if (fdp->fd_knhashmask == 0) {
+				fdp->fd_knhash = tmp_knhash;
+				fdp->fd_knhashmask = tmp_knhashmask;
+			} else {
+				FILEDESC_UNLOCK(fdp);
+				free(tmp_knhash, M_KQUEUE);
+				FILEDESC_LOCK(fdp);
+			}
+		}
 		list = &fdp->fd_knhash[KN_HASH(kn->kn_id, fdp->fd_knhashmask)];
 		goto done;
 	}



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?200210030332.g933W1vU017519>