Projet

Général

Profil

Télécharger (5,68 ko) Statistiques
| Branche: | Révision:

univnautes-tools / patches / stable / 10 / tun_optimization.diff @ 4ab3b90b

1
diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c
2
index f44bc0e..dd7853f 100644
3
--- a/sys/net/if_tun.c
4
+++ b/sys/net/if_tun.c
5
@@ -52,6 +52,7 @@
6
 #include <net/vnet.h>
7
 #ifdef INET
8
 #include <netinet/in.h>
9
+#include <netinet/ip.h>
10
 #endif
11
 #include <net/bpf.h>
12
 #include <net/if_tun.h>
13
@@ -110,6 +111,7 @@ static const char tunname[] = "tun";
14
 static MALLOC_DEFINE(M_TUN, tunname, "Tunnel Interface");
15
 static int tundebug = 0;
16
 static int tundclone = 1;
17
+static int tundispatch = 1;
18
 static struct clonedevs *tunclones;
19
 static TAILQ_HEAD(,tun_softc)	tunhead = TAILQ_HEAD_INITIALIZER(tunhead);
20
 SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
21
@@ -119,6 +121,8 @@ static SYSCTL_NODE(_net_link, OID_AUTO, tun, CTLFLAG_RW, 0,
22
     "IP tunnel software network interface.");
23
 SYSCTL_INT(_net_link_tun, OID_AUTO, devfs_cloning, CTLFLAG_RW, &tundclone, 0,
24
     "Enable legacy devfs interface creation.");
25
+SYSCTL_INT(_net_link_tun, OID_AUTO, tun_dispatching, CTLFLAG_RW, &tundispatch, 0,
26
+    "Queue rather than direct dispatch on write.");
27
 
28
 TUNABLE_INT("net.link.tun.devfs_cloning", &tundclone);
29
 
30
@@ -327,31 +331,28 @@ static void
31
 tunstart(struct ifnet *ifp)
32
 {
33
 	struct tun_softc *tp = ifp->if_softc;
34
-	struct mbuf *m;
35
 
36
 	TUNDEBUG(ifp,"%s starting\n", ifp->if_xname);
37
-	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
38
-		IFQ_LOCK(&ifp->if_snd);
39
-		IFQ_POLL_NOLOCK(&ifp->if_snd, m);
40
-		if (m == NULL) {
41
-			IFQ_UNLOCK(&ifp->if_snd);
42
-			return;
43
-		}
44
-		IFQ_UNLOCK(&ifp->if_snd);
45
-	}
46
+	if (IFQ_IS_EMPTY(&ifp->if_snd))
47
+		return;
48
+
49
+	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
50
 
51
-	mtx_lock(&tp->tun_mtx);
52
 	if (tp->tun_flags & TUN_RWAIT) {
53
 		tp->tun_flags &= ~TUN_RWAIT;
54
 		wakeup(tp);
55
 	}
56
-	selwakeuppri(&tp->tun_rsel, PZERO + 1);
57
-	KNOTE_LOCKED(&tp->tun_rsel.si_note, 0);
58
-	if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio) {
59
+	if (!TAILQ_EMPTY(&tp->tun_rsel.si_tdlist))
60
+		selwakeuppri(&tp->tun_rsel, PZERO + 1);
61
+	if (!KNLIST_EMPTY(&tp->tun_rsel.si_note)) {
62
+		mtx_lock(&tp->tun_mtx);
63
+		KNOTE_LOCKED(&tp->tun_rsel.si_note, 0);
64
 		mtx_unlock(&tp->tun_mtx);
65
+	}
66
+	if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio)
67
 		pgsigio(&tp->tun_sigio, SIGIO, 0);
68
-	} else
69
-		mtx_unlock(&tp->tun_mtx);
70
+
71
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
72
 }
73
 
74
 /* XXX: should return an error code so it can fail. */
75
@@ -589,9 +590,7 @@ tunoutput(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst,
76
 #endif
77
 
78
 	/* Could be unlocked read? */
79
-	mtx_lock(&tp->tun_mtx);
80
 	cached_tun_flags = tp->tun_flags;
81
-	mtx_unlock(&tp->tun_mtx);
82
 	if ((cached_tun_flags & TUN_READY) != TUN_READY) {
83
 		TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags);
84
 		m_freem (m0);
85
@@ -798,9 +797,7 @@ tunread(struct cdev *dev, struct uio *uio, int flag)
86
 	int		error=0, len;
87
 
88
 	TUNDEBUG (ifp, "read\n");
89
-	mtx_lock(&tp->tun_mtx);
90
 	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
91
-		mtx_unlock(&tp->tun_mtx);
92
 		TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags);
93
 		return (EHOSTDOWN);
94
 	}
95
@@ -811,19 +808,19 @@ tunread(struct cdev *dev, struct uio *uio, int flag)
96
 		IFQ_DEQUEUE(&ifp->if_snd, m);
97
 		if (m == NULL) {
98
 			if (flag & O_NONBLOCK) {
99
-				mtx_unlock(&tp->tun_mtx);
100
 				return (EWOULDBLOCK);
101
 			}
102
+			mtx_lock(&tp->tun_mtx);
103
 			tp->tun_flags |= TUN_RWAIT;
104
 			error = mtx_sleep(tp, &tp->tun_mtx, PCATCH | (PZERO + 1),
105
 			    "tunread", 0);
106
+			tp->tun_flags &= ~TUN_RWAIT;
107
+			mtx_unlock(&tp->tun_mtx);
108
 			if (error != 0) {
109
-				mtx_unlock(&tp->tun_mtx);
110
 				return (error);
111
 			}
112
 		}
113
 	} while (m == NULL);
114
-	mtx_unlock(&tp->tun_mtx);
115
 
116
 	while (m && uio->uio_resid > 0 && error == 0) {
117
 		len = min(uio->uio_resid, m->m_len);
118
@@ -848,6 +845,7 @@ tunwrite(struct cdev *dev, struct uio *uio, int flag)
119
 	struct tun_softc *tp = dev->si_drv1;
120
 	struct ifnet	*ifp = TUN2IFP(tp);
121
 	struct mbuf	*m;
122
+	struct ip	*ip;
123
 	uint32_t	family;
124
 	int 		isr;
125
 
126
@@ -875,18 +873,26 @@ tunwrite(struct cdev *dev, struct uio *uio, int flag)
127
 	mac_ifnet_create_mbuf(ifp, m);
128
 #endif
129
 
130
-	/* Could be unlocked read? */
131
-	mtx_lock(&tp->tun_mtx);
132
+	/* XXX: unlocked read? */
133
 	if (tp->tun_flags & TUN_IFHEAD) {
134
-		mtx_unlock(&tp->tun_mtx);
135
 		if (m->m_len < sizeof(family) &&
136
 		    (m = m_pullup(m, sizeof(family))) == NULL)
137
 			return (ENOBUFS);
138
 		family = ntohl(*mtod(m, u_int32_t *));
139
 		m_adj(m, sizeof(family));
140
 	} else {
141
-		mtx_unlock(&tp->tun_mtx);
142
-		family = AF_INET;
143
+		if (m->m_len < sizeof(struct ip) &&
144
+		    (m = m_pullup(m, sizeof(struct ip))) == NULL)
145
+			return (ENOBUFS);
146
+		ip = mtod(m, struct ip *);
147
+		if (ip->ip_v == IPVERSION)
148
+			family = AF_INET;
149
+		else if (ip->ip_v == AF_INET6)
150
+			family = AF_INET6;
151
+		else {
152
+			m_freem(m);
153
+			return (EINVAL);
154
+		}
155
 	}
156
 
157
 	BPF_MTAP2(ifp, &family, sizeof(family), m);
158
@@ -922,7 +928,10 @@ tunwrite(struct cdev *dev, struct uio *uio, int flag)
159
 	ifp->if_ipackets++;
160
 	CURVNET_SET(ifp->if_vnet);
161
 	M_SETFIB(m, ifp->if_fib);
162
-	netisr_dispatch(isr, m);
163
+	if (tundispatch)
164
+		netisr_queue(isr, m);
165
+	else
166
+		netisr_dispatch(isr, m);
167
 	CURVNET_RESTORE();
168
 	return (0);
169
 }
170
@@ -938,21 +947,17 @@ tunpoll(struct cdev *dev, int events, struct thread *td)
171
 	struct tun_softc *tp = dev->si_drv1;
172
 	struct ifnet	*ifp = TUN2IFP(tp);
173
 	int		revents = 0;
174
-	struct mbuf	*m;
175
 
176
 	TUNDEBUG(ifp, "tunpoll\n");
177
 
178
 	if (events & (POLLIN | POLLRDNORM)) {
179
-		IFQ_LOCK(&ifp->if_snd);
180
-		IFQ_POLL_NOLOCK(&ifp->if_snd, m);
181
-		if (m != NULL) {
182
-			TUNDEBUG(ifp, "tunpoll q=%d\n", ifp->if_snd.ifq_len);
183
-			revents |= events & (POLLIN | POLLRDNORM);
184
-		} else {
185
+		if (IFQ_IS_EMPTY(&ifp->if_snd)) {
186
 			TUNDEBUG(ifp, "tunpoll waiting\n");
187
 			selrecord(td, &tp->tun_rsel);
188
+		} else {
189
+			TUNDEBUG(ifp, "tunpoll q=%d\n", ifp->if_snd.ifq_len);
190
+			revents |= events & (POLLIN | POLLRDNORM);
191
 		}
192
-		IFQ_UNLOCK(&ifp->if_snd);
193
 	}
194
 	if (events & (POLLOUT | POLLWRNORM))
195
 		revents |= events & (POLLOUT | POLLWRNORM);
(65-65/67)