*_drain() routines may be called with locks held, so instead of doing

any work in *_drain(), set a drain-needed flag.  Do the work in the
fasttimo handler.

Contributed by Coyote Point Systems, Inc.
This commit is contained in:
dyoung 2011-05-03 17:44:30 +00:00
parent 6372875351
commit ac162b774b
8 changed files with 78 additions and 17 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: in_proto.c,v 1.100 2011/03/31 19:40:52 dyoung Exp $ */
/* $NetBSD: in_proto.c,v 1.101 2011/05/03 17:44:31 dyoung Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.100 2011/03/31 19:40:52 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.101 2011/05/03 17:44:31 dyoung Exp $");
#include "opt_mrouting.h"
#include "opt_eon.h" /* ISO CLNL over IP */
@ -215,8 +215,9 @@ const struct protosw inetsw[] = {
{ .pr_domain = &inetdomain,
.pr_init = ip_init,
.pr_output = ip_output,
.pr_fasttimo = ip_fasttimo,
.pr_slowtimo = ip_slowtimo,
.pr_drain = ip_drain,
.pr_drain = ip_drainstub,
},
{ .pr_type = SOCK_DGRAM,
.pr_domain = &inetdomain,
@ -237,8 +238,9 @@ const struct protosw inetsw[] = {
.pr_ctloutput = tcp_ctloutput,
.pr_usrreq = tcp_usrreq,
.pr_init = tcp_init,
.pr_fasttimo = tcp_fasttimo,
.pr_slowtimo = tcp_slowtimo,
.pr_drain = tcp_drain,
.pr_drain = tcp_drainstub,
},
{ .pr_type = SOCK_RAW,
.pr_domain = &inetdomain,

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_input.c,v 1.294 2011/04/14 20:32:04 dyoung Exp $ */
/* $NetBSD: ip_input.c,v 1.295 2011/05/03 17:44:31 dyoung Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -91,7 +91,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.294 2011/04/14 20:32:04 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.295 2011/05/03 17:44:31 dyoung Exp $");
#include "opt_inet.h"
#include "opt_compat_netbsd.h"
@ -278,6 +278,8 @@ static struct ip_srcrt {
struct in_addr route[MAX_IPOPTLEN/sizeof(struct in_addr)];
} ip_srcrt;
static int ip_drainwanted;
static void save_rte(u_char *, struct in_addr);
#ifdef MBUFTRACE
@ -1282,6 +1284,21 @@ const int inetctlerrmap[PRC_NCMDS] = {
[PRC_PARAMPROB] = ENOPROTOOPT,
};
void
ip_fasttimo(void)
{
if (ip_drainwanted) {
ip_drain();
ip_drainwanted = 0;
}
}
void
ip_drainstub(void)
{
ip_drainwanted = 1;
}
/*
* Forward a packet. If some error occurs return the sender
* an icmp packet. Note we can't always generate a meaningful

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_var.h,v 1.96 2010/11/05 00:21:51 rmind Exp $ */
/* $NetBSD: ip_var.h,v 1.97 2011/05/03 17:44:31 dyoung Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
@ -185,6 +185,7 @@ struct sockopt;
int ip_ctloutput(int, struct socket *, struct sockopt *);
int ip_dooptions(struct mbuf *);
void ip_drain(void);
void ip_drainstub(void);
void ip_forward(struct mbuf *, int);
void ip_freemoptions(struct ip_moptions *);
int ip_getmoptions(struct ip_moptions *, struct sockopt *);
@ -206,6 +207,7 @@ void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *,
struct mbuf *);
int ip_setmoptions(struct ip_moptions **, const struct sockopt *);
void ip_slowtimo(void);
void ip_fasttimo(void);
struct mbuf *
ip_srcroute(void);
int ip_sysctl(int *, u_int, void *, size_t *, void *, size_t);

View File

@ -1,4 +1,4 @@
/* $NetBSD: tcp_subr.c,v 1.239 2011/04/20 13:35:51 gdt Exp $ */
/* $NetBSD: tcp_subr.c,v 1.240 2011/05/03 17:44:31 dyoung Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -91,7 +91,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.239 2011/04/20 13:35:51 gdt Exp $");
__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.240 2011/05/03 17:44:31 dyoung Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@ -234,6 +234,8 @@ void tcp6_mtudisc(struct in6pcb *, int);
static struct pool tcpcb_pool;
static int tcp_drainwanted;
#ifdef TCP_CSUM_COUNTERS
#include <sys/device.h>
@ -1292,6 +1294,21 @@ tcp_freeq(struct tcpcb *tp)
return (rv);
}
void
tcp_fasttimo(void)
{
if (tcp_drainwanted) {
tcp_drain();
tcp_drainwanted = 0;
}
}
void
tcp_drainstub(void)
{
tcp_drainwanted = 1;
}
/*
* Protocol drain routine. Called when memory is in short supply.
* Don't acquire softnet_lock as can be called from hardware

View File

@ -1,4 +1,4 @@
/* $NetBSD: tcp_var.h,v 1.164 2011/04/20 13:35:52 gdt Exp $ */
/* $NetBSD: tcp_var.h,v 1.165 2011/05/03 17:44:31 dyoung Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -890,6 +890,7 @@ int tcp_signature(struct mbuf *, struct tcphdr *, int, struct secasvar *,
char *);
#endif
void tcp_drain(void);
void tcp_drainstub(void);
void tcp_established(struct tcpcb *);
void tcp_init(void);
#ifdef INET6
@ -929,6 +930,7 @@ int tcp_signature_compute(struct mbuf *, struct tcphdr *, int, int,
int, u_char *, u_int);
#endif
void tcp_slowtimo(void);
void tcp_fasttimo(void);
struct mbuf *
tcp_template(struct tcpcb *);
void tcp_trace(short, short, struct tcpcb *, struct mbuf *, int);

View File

@ -1,4 +1,4 @@
/* $NetBSD: frag6.c,v 1.48 2011/01/22 18:26:36 mlelstv Exp $ */
/* $NetBSD: frag6.c,v 1.49 2011/05/03 17:44:30 dyoung Exp $ */
/* $KAME: frag6.c,v 1.40 2002/05/27 21:40:31 itojun Exp $ */
/*
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: frag6.c,v 1.48 2011/01/22 18:26:36 mlelstv Exp $");
__KERNEL_RCSID(0, "$NetBSD: frag6.c,v 1.49 2011/05/03 17:44:30 dyoung Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -65,6 +65,8 @@ static void frag6_remque(struct ip6q *);
static void frag6_freef(struct ip6q *);
static int ip6q_locked;
static int frag6_drainwanted;
u_int frag6_nfragpackets;
u_int frag6_nfrags;
struct ip6q ip6q; /* ip6 reassemble queue */
@ -670,6 +672,15 @@ frag6_remque(struct ip6q *p6)
p6->ip6q_next->ip6q_prev = p6->ip6q_prev;
}
void
frag6_fasttimo(void)
{
if (frag6_drainwanted) {
frag6_drain();
frag6_drainwanted = 0;
}
}
/*
* IPv6 reassembling timer processing;
* if a timer expires on a reassembly
@ -722,6 +733,12 @@ frag6_slowtimo(void)
mutex_exit(softnet_lock);
}
void
frag6_drainstub(void)
{
frag6_drainwanted = 1;
}
/*
* Drain off all datagram fragments.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6_proto.c,v 1.90 2011/03/31 19:40:52 dyoung Exp $ */
/* $NetBSD: in6_proto.c,v 1.91 2011/05/03 17:44:30 dyoung Exp $ */
/* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: in6_proto.c,v 1.90 2011/03/31 19:40:52 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: in6_proto.c,v 1.91 2011/05/03 17:44:30 dyoung Exp $");
#include "opt_gateway.h"
#include "opt_inet.h"
@ -193,8 +193,9 @@ const struct ip6protosw inet6sw[] = {
{ .pr_domain = &inet6domain,
.pr_protocol = IPPROTO_IPV6,
.pr_init = ip6_init,
.pr_fasttimo = frag6_fasttimo,
.pr_slowtimo = frag6_slowtimo,
.pr_drain = frag6_drain,
.pr_drain = frag6_drainstub,
},
{ .pr_type = SOCK_DGRAM,
.pr_domain = &inet6domain,
@ -216,8 +217,9 @@ const struct ip6protosw inet6sw[] = {
.pr_usrreq = tcp_usrreq,
#ifndef INET /* don't call initialization and timeout routines twice */
.pr_init = tcp_init,
.pr_fasttimo = tcp_fasttimo,
.pr_slowtimo = tcp_slowtimo,
.pr_drain = tcp_drain,
.pr_drain = tcp_drainstub,
#endif
},
{ .pr_type = SOCK_RAW,

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6_var.h,v 1.53 2009/05/06 21:41:59 elad Exp $ */
/* $NetBSD: ip6_var.h,v 1.54 2011/05/03 17:44:30 dyoung Exp $ */
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
/*
@ -358,7 +358,9 @@ int route6_input(struct mbuf **, int *, int);
void frag6_init(void);
int frag6_input(struct mbuf **, int *, int);
void frag6_slowtimo(void);
void frag6_fasttimo(void);
void frag6_drain(void);
void frag6_drainstub(void);
int ip6flow_init(int);
void ip6flow_poolinit(void);