Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: another crash



On Mon, Jun 20, 2016 at 10:01:14AM +0100, Robert Swindells wrote:
> 
> Maybe try the patch here:
> 
> <http://mail-index.netbsd.org/current-users/2016/05/16/msg029380.html>
> 

Sorry, that didn't help.  I was still seeing kernel panics in
filt_sowdetach().  The process running when the crash occurred is
actually squid.  I sprinkled a few more null checks about and some more
printf's.  This looks to be a race of some sort.  I put a couple printf
statements around the SLIST_REMOVE and all of a sudden browsing the web
does not cause a crash.  None of the NULL catches seem to trigger, I
have lots of "about to remove" then "remove done" messages which sort of
indicates to me there printf is throwing the race timing off enough for
the kernel to survive.  Sounds like we need some better locking around
the manipulation of this stuff.

This patch makes the machine stay up for me - it isn't a solution but
more of a indication of what is happening...


Index: uipc_socket.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_socket.c,v
retrieving revision 1.248
diff -u -r1.248 uipc_socket.c
--- uipc_socket.c	10 Jun 2016 13:27:15 -0000	1.248
+++ uipc_socket.c	1 Jul 2016 02:37:47 -0000
@@ -709,6 +709,12 @@
 	/* Remove acccept filter if one is present. */
 	if (so->so_accf != NULL)
 		(void)accept_filt_clear(so);
+	if (so->so_rcv.sb_flags & SB_KNOTE) {
+		printf("sofree: rcv knote\n");
+	}
+	if (so->so_snd.sb_flags & SB_KNOTE) {
+		printf("sofree: snd knote\n");
+	}
 	sounlock(so);
 	if (refs == 0)		/* XXX */
 		soput(so);
@@ -2221,6 +2227,10 @@
 	struct socket	*so;
 
 	so = ((file_t *)kn->kn_obj)->f_socket;
+	if (so == NULL) {
+		printf("filt_sordetach: no socket\n");
+		return;
+	}
 	solock(so);
 	SLIST_REMOVE(&so->so_rcv.sb_sel.sel_klist, kn, knote, kn_selnext);
 	if (SLIST_EMPTY(&so->so_rcv.sb_sel.sel_klist))
@@ -2259,9 +2269,28 @@
 {
 	struct socket	*so;
 
+	if (kn == NULL) {
+		printf("filt_sowdetach: no knote\n");
+		return;
+	}
+	if (kn->kn_obj == NULL) {
+		printf("filt_sowdetach: no knote obj\n");
+		return;
+	}
 	so = ((file_t *)kn->kn_obj)->f_socket;
+	if (so == NULL) {
+		printf("filt_sowdetach: no socket\n");
+		return;
+	}
 	solock(so);
+	if (SLIST_EMPTY(&so->so_snd.sb_sel.sel_klist)) {
+		printf("filt_sowdetach: no klist\n");
+		sounlock(so);
+		return;
+	}
+printf("filt_sowdetach: about to remove\n");
 	SLIST_REMOVE(&so->so_snd.sb_sel.sel_klist, kn, knote, kn_selnext);
+printf("filt_sowdetach: remove done\n");
 	if (SLIST_EMPTY(&so->so_snd.sb_sel.sel_klist))
 		so->so_snd.sb_flags &= ~SB_KNOTE;
 	sounlock(so);

-- 
Brett Lymn


Home | Main Index | Thread Index | Old Index