Source-Changes-HG archive

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

[src/trunk]: src/sys/netinet After discussion with ad@: it appears that KERNE...



details:   https://anonhg.NetBSD.org/src/rev/ccf08707e003
branches:  trunk
changeset: 753541:ccf08707e003
user:      tls <tls%NetBSD.org@localhost>
date:      Thu Apr 01 00:24:41 2010 +0000

description:
After discussion with ad@: it appears that KERNEL_LOCK also protects
the driver output path (that is, ifp->if_output()).  In the case of
entry through the socket code, we are fine, because pru_usrreq takes
KERNEL_LOCK.  However, there are a few other ways to cause output
which require protection:

        1) direct calls to tcp_output() in tcp_input()
        2) fast-forwarding code (ip_flow) -- protected elsewise
           against itself by the softnet lock.
        3) *Possibly* the ARP code.  I have currently persuaded
           myself that it is safe because of how it's called.
        4) Possibly the ICMP code.

This change addresses #1 and #2.

diffstat:

 sys/netinet/ip_flow.c   |   6 ++++--
 sys/netinet/tcp_input.c |  14 ++++++++++++--
 2 files changed, 16 insertions(+), 4 deletions(-)

diffs (101 lines):

diff -r 47342f6ac8f7 -r ccf08707e003 sys/netinet/ip_flow.c
--- a/sys/netinet/ip_flow.c     Wed Mar 31 21:55:23 2010 +0000
+++ b/sys/netinet/ip_flow.c     Thu Apr 01 00:24:41 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip_flow.c,v 1.58 2009/03/15 22:16:09 cegger Exp $      */
+/*     $NetBSD: ip_flow.c,v 1.59 2010/04/01 00:24:41 tls Exp $ */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_flow.c,v 1.58 2009/03/15 22:16:09 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_flow.c,v 1.59 2010/04/01 00:24:41 tls Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -301,12 +301,14 @@
        else
                dst = rtcache_getdst(&ipf->ipf_ro);
 
+       KERNEL_LOCK(1, NULL);
        if ((error = (*rt->rt_ifp->if_output)(rt->rt_ifp, m, dst, rt)) != 0) {
                if (error == ENOBUFS)
                        ipf->ipf_dropped++;
                else
                        ipf->ipf_errors++;
        }
+       KERNEL_UNLOCK_ONE(NULL);
        return 1;
 }
 
diff -r 47342f6ac8f7 -r ccf08707e003 sys/netinet/tcp_input.c
--- a/sys/netinet/tcp_input.c   Wed Mar 31 21:55:23 2010 +0000
+++ b/sys/netinet/tcp_input.c   Thu Apr 01 00:24:41 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tcp_input.c,v 1.300 2010/01/26 18:09:07 pooka Exp $    */
+/*     $NetBSD: tcp_input.c,v 1.301 2010/04/01 00:24:41 tls Exp $      */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -145,7 +145,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.300 2010/01/26 18:09:07 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.301 2010/04/01 00:24:41 tls Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -1787,7 +1787,9 @@
 
                                sowwakeup(so);
                                if (so->so_snd.sb_cc)
+                                       KERNEL_LOCK(1, NULL);
                                        (void) tcp_output(tp);
+                                       KERNEL_UNLOCK_ONE(NULL);
                                if (tcp_saveti)
                                        m_freem(tcp_saveti);
                                return;
@@ -1883,7 +1885,9 @@
                        sorwakeup(so);
                        tcp_setup_ack(tp, th);
                        if (tp->t_flags & TF_ACKNOW)
+                               KERNEL_LOCK(1, NULL);
                                (void) tcp_output(tp);
+                               KERNEL_UNLOCK_ONE(NULL);
                        if (tcp_saveti)
                                m_freem(tcp_saveti);
                        return;
@@ -2369,7 +2373,9 @@
                                                goto drop;
                                } else if (tp->t_dupacks > tcprexmtthresh) {
                                        tp->snd_cwnd += tp->t_segsz;
+                                       KERNEL_LOCK(1, NULL);
                                        (void) tcp_output(tp);
+                                       KERNEL_UNLOCK_ONE(NULL);
                                        goto drop;
                                }
                        } else {
@@ -2730,7 +2736,9 @@
         * Return any desired output.
         */
        if (needoutput || (tp->t_flags & TF_ACKNOW)) {
+               KERNEL_LOCK(1, NULL);
                (void) tcp_output(tp);
+               KERNEL_UNLOCK_ONE(NULL);
        }
        if (tcp_saveti)
                m_freem(tcp_saveti);
@@ -2767,7 +2775,9 @@
 dropafterack2:
        m_freem(m);
        tp->t_flags |= TF_ACKNOW;
+       KERNEL_LOCK(1, NULL);
        (void) tcp_output(tp);
+       KERNEL_UNLOCK_ONE(NULL);
        if (tcp_saveti)
                m_freem(tcp_saveti);
        return;



Home | Main Index | Thread Index | Old Index