Page MenuHomeFreeBSD

D36164.id109232.diff
No OneTemporary

D36164.id109232.diff

Index: sys/kern/kern_mbuf.c
===================================================================
--- sys/kern/kern_mbuf.c
+++ sys/kern/kern_mbuf.c
@@ -39,14 +39,12 @@
#include <sys/malloc.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
-#include <sys/domain.h>
#include <sys/eventhandler.h>
#include <sys/kernel.h>
#include <sys/ktls.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/mutex.h>
-#include <sys/protosw.h>
#include <sys/refcount.h>
#include <sys/sf_buf.h>
#include <sys/smp.h>
@@ -396,14 +394,6 @@
uma_zone_set_warning(zone_jumbo16, "kern.ipc.nmbjumbo16 limit reached");
uma_zone_set_maxaction(zone_jumbo16, mb_reclaim);
- /*
- * Hook event handler for low-memory situation, used to
- * drain protocols and push data back to the caches (UMA
- * later pushes it back to VM).
- */
- EVENTHANDLER_REGISTER(vm_lowmem, mb_reclaim, NULL,
- EVENTHANDLER_PRI_FIRST);
-
snd_tag_count = counter_u64_alloc(M_WAITOK);
}
SYSINIT(mbuf, SI_SUB_MBUF, SI_ORDER_FIRST, mbuf_init, NULL);
@@ -828,26 +818,12 @@
/*
* This is the protocol drain routine. Called by UMA whenever any of the
* mbuf zones is closed to its limit.
- *
- * No locks should be held when this is called. The drain routines have to
- * presently acquire some locks which raises the possibility of lock order
- * reversal.
*/
static void
mb_reclaim(uma_zone_t zone __unused, int pending __unused)
{
- struct epoch_tracker et;
- struct domain *dp;
- struct protosw *pr;
-
- WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK | WARN_PANIC, NULL, __func__);
-
- NET_EPOCH_ENTER(et);
- for (dp = domains; dp != NULL; dp = dp->dom_next)
- for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
- if (pr->pr_drain != NULL)
- (*pr->pr_drain)();
- NET_EPOCH_EXIT(et);
+
+ EVENTHANDLER_INVOKE(mb_lowmem, VM_LOW_MBUFS);
}
/*
Index: sys/kern/uipc_debug.c
===================================================================
--- sys/kern/uipc_debug.c
+++ sys/kern/uipc_debug.c
@@ -315,9 +315,6 @@
db_print_indent(indent);
db_printf("pr_ctloutput: %p ", pr->pr_ctloutput);
-
- db_print_indent(indent);
- db_printf("pr_drain: %p\n", pr->pr_drain);
}
static void
Index: sys/kern/uipc_domain.c
===================================================================
--- sys/kern/uipc_domain.c
+++ sys/kern/uipc_domain.c
@@ -387,7 +387,6 @@
dpr->pr_protocol = PROTO_SPACER;
dpr->pr_flags = 0;
dpr->pr_ctloutput = NULL;
- dpr->pr_drain = NULL;
dpr->pr_usrreqs = NULL;
/* Job is done, not more protection required. */
Index: sys/netinet/in_proto.c
===================================================================
--- sys/netinet/in_proto.c
+++ sys/netinet/in_proto.c
@@ -120,7 +120,6 @@
.pr_flags = PR_CONNREQUIRED|PR_IMPLOPCL|PR_WANTRCVD|
PR_CAPATTACH,
.pr_ctloutput = tcp_ctloutput,
- .pr_drain = tcp_drain,
.pr_usrreqs = &tcp_usrreqs
},
#ifdef SCTP
@@ -130,7 +129,6 @@
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_WANTRCVD,
.pr_ctloutput = sctp_ctloutput,
- .pr_drain = sctp_drain,
.pr_usrreqs = &sctp_usrreqs
},
{
@@ -139,7 +137,6 @@
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_CONNREQUIRED|PR_WANTRCVD,
.pr_ctloutput = sctp_ctloutput,
- .pr_drain = NULL, /* Covered by the SOCK_SEQPACKET entry. */
.pr_usrreqs = &sctp_usrreqs
},
#endif /* SCTP */
Index: sys/netinet/sctp_module.c
===================================================================
--- sys/netinet/sctp_module.c
+++ sys/netinet/sctp_module.c
@@ -61,7 +61,6 @@
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_CONNREQUIRED|PR_WANTRCVD,
.pr_ctloutput = sctp_ctloutput,
- .pr_drain = sctp_drain,
.pr_usrreqs = &sctp_usrreqs,
};
@@ -71,7 +70,6 @@
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_WANTRCVD,
.pr_ctloutput = sctp_ctloutput,
- .pr_drain = sctp_drain,
.pr_usrreqs = &sctp_usrreqs,
};
#endif
@@ -85,7 +83,6 @@
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_CONNREQUIRED|PR_WANTRCVD,
.pr_ctloutput = sctp_ctloutput,
- .pr_drain = sctp_drain,
.pr_usrreqs = &sctp6_usrreqs,
};
@@ -95,9 +92,6 @@
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_WANTRCVD,
.pr_ctloutput = sctp_ctloutput,
-#ifndef INET /* Do not call initialization and drain routines twice. */
- .pr_drain = sctp_drain,
-#endif
.pr_usrreqs = &sctp6_usrreqs,
};
#endif
Index: sys/netinet/sctp_pcb.h
===================================================================
--- sys/netinet/sctp_pcb.h
+++ sys/netinet/sctp_pcb.h
@@ -611,8 +611,6 @@
bool
sctp_is_vtag_good(uint32_t, uint16_t lport, uint16_t rport, struct timeval *);
-/* void sctp_drain(void); */
-
int sctp_destination_is_reachable(struct sctp_tcb *, struct sockaddr *);
int sctp_swap_inpcb_for_listen(struct sctp_inpcb *inp);
Index: sys/netinet/sctp_pcb.c
===================================================================
--- sys/netinet/sctp_pcb.c
+++ sys/netinet/sctp_pcb.c
@@ -6942,15 +6942,18 @@
*/
}
-void
+static void
sctp_drain(void)
{
+ struct epoch_tracker et;
+ VNET_ITERATOR_DECL(vnet_iter);
+
+ NET_EPOCH_ENTER(et);
/*
* We must walk the PCB lists for ALL associations here. The system
* is LOW on MBUF's and needs help. This is where reneging will
* occur. We really hope this does NOT happen!
*/
- VNET_ITERATOR_DECL(vnet_iter);
VNET_LIST_RLOCK_NOSLEEP();
VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter);
@@ -6962,6 +6965,7 @@
#ifdef VIMAGE
continue;
#else
+ NET_EPOCH_EXIT(et);
return;
#endif
}
@@ -6981,7 +6985,10 @@
CURVNET_RESTORE();
}
VNET_LIST_RUNLOCK_NOSLEEP();
+ NET_EPOCH_EXIT(et);
}
+EVENTHANDLER_DEFINE(vm_lowmem, sctp_drain, NULL, LOWMEM_PRI_DEFAULT);
+EVENTHANDLER_DEFINE(mb_lowmem, sctp_drain, NULL, LOWMEM_PRI_DEFAULT);
/*
* start a new iterator
Index: sys/netinet/sctp_var.h
===================================================================
--- sys/netinet/sctp_var.h
+++ sys/netinet/sctp_var.h
@@ -327,7 +327,6 @@
void sctp_input_with_port(struct mbuf *, int, uint16_t);
int sctp_input(struct mbuf **, int *, int);
void sctp_pathmtu_adjustment(struct sctp_tcb *, uint32_t, bool);
-void sctp_drain(void);
void
sctp_notify(struct sctp_inpcb *, struct sctp_tcb *, struct sctp_nets *,
uint8_t, uint8_t, uint16_t, uint32_t);
Index: sys/netinet/tcp_subr.c
===================================================================
--- sys/netinet/tcp_subr.c
+++ sys/netinet/tcp_subr.c
@@ -1448,6 +1448,8 @@
VNET_SYSINIT(tcp_vnet_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH,
tcp_vnet_init, NULL);
+static void tcp_drain(void);
+
static void
tcp_init(void *arg __unused)
{
@@ -1506,6 +1508,8 @@
ISN_LOCK_INIT();
EVENTHANDLER_REGISTER(shutdown_pre_sync, tcp_fini, NULL,
SHUTDOWN_PRI_DEFAULT);
+ EVENTHANDLER_REGISTER(vm_lowmem, tcp_drain, NULL, LOWMEM_PRI_DEFAULT);
+ EVENTHANDLER_REGISTER(mb_lowmem, tcp_drain, NULL, LOWMEM_PRI_DEFAULT);
tcp_inp_lro_direct_queue = counter_u64_alloc(M_WAITOK);
tcp_inp_lro_wokeup_queue = counter_u64_alloc(M_WAITOK);
@@ -2516,14 +2520,16 @@
return (tp);
}
-void
+static void
tcp_drain(void)
{
+ struct epoch_tracker et;
VNET_ITERATOR_DECL(vnet_iter);
if (!do_tcpdrain)
return;
+ NET_EPOCH_ENTER(et);
VNET_LIST_RLOCK_NOSLEEP();
VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter);
@@ -2561,6 +2567,7 @@
CURVNET_RESTORE();
}
VNET_LIST_RUNLOCK_NOSLEEP();
+ NET_EPOCH_EXIT(et);
}
/*
Index: sys/netinet/tcp_var.h
===================================================================
--- sys/netinet/tcp_var.h
+++ sys/netinet/tcp_var.h
@@ -1085,7 +1085,6 @@
void tcp_ctlinput(int, struct sockaddr *, void *);
int tcp_ctloutput(struct socket *, struct sockopt *);
void tcp_ctlinput_viaudp(int, struct sockaddr *, void *, void *);
-void tcp_drain(void);
void tcp_fini(void *);
char *tcp_log_addrs(struct in_conninfo *, struct tcphdr *, const void *,
const void *);
Index: sys/netinet6/in6_proto.c
===================================================================
--- sys/netinet6/in6_proto.c
+++ sys/netinet6/in6_proto.c
@@ -139,13 +139,6 @@
}
struct protosw inet6sw[] = {
-{
- .pr_type = 0,
- .pr_domain = &inet6domain,
- .pr_protocol = IPPROTO_IPV6,
- .pr_flags = PR_CAPATTACH,
- .pr_drain = frag6_drain,
-},
{
.pr_type = SOCK_DGRAM,
.pr_domain = &inet6domain,
@@ -161,9 +154,6 @@
.pr_flags = PR_CONNREQUIRED|PR_IMPLOPCL|PR_WANTRCVD|
PR_LISTEN|PR_CAPATTACH,
.pr_ctloutput = tcp_ctloutput,
-#ifndef INET /* don't call initialization, timeout, and drain routines twice */
- .pr_drain = tcp_drain,
-#endif
.pr_usrreqs = &tcp6_usrreqs,
},
#ifdef SCTP
@@ -173,9 +163,6 @@
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_WANTRCVD,
.pr_ctloutput = sctp_ctloutput,
-#ifndef INET /* Do not call initialization and drain routines twice. */
- .pr_drain = sctp_drain,
-#endif
.pr_usrreqs = &sctp6_usrreqs
},
{
@@ -184,7 +171,6 @@
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_CONNREQUIRED|PR_WANTRCVD,
.pr_ctloutput = sctp_ctloutput,
- .pr_drain = NULL, /* Covered by the SOCK_SEQPACKET entry. */
.pr_usrreqs = &sctp6_usrreqs
},
#endif /* SCTP */
Index: sys/netinet6/ip6_input.c
===================================================================
--- sys/netinet6/ip6_input.c
+++ sys/netinet6/ip6_input.c
@@ -298,6 +298,9 @@
callout_init(&frag6_callout, 1);
callout_reset(&frag6_callout, hz / 2, frag6_slowtimo, NULL);
+ EVENTHANDLER_REGISTER(vm_lowmem, frag6_drain, NULL, LOWMEM_PRI_DEFAULT);
+ EVENTHANDLER_REGISTER(mb_lowmem, frag6_drain, NULL, LOWMEM_PRI_DEFAULT);
+
netisr_register(&ip6_nh);
#ifdef RSS
netisr_register(&ip6_direct_nh);
Index: sys/sys/eventhandler.h
===================================================================
--- sys/sys/eventhandler.h
+++ sys/sys/eventhandler.h
@@ -205,6 +205,8 @@
typedef void (*vm_lowmem_handler_t)(void *, int);
#define LOWMEM_PRI_DEFAULT EVENTHANDLER_PRI_FIRST
EVENTHANDLER_DECLARE(vm_lowmem, vm_lowmem_handler_t);
+/* Some of mbuf(9) zones reached maximum */
+EVENTHANDLER_DECLARE(mb_lowmem, vm_lowmem_handler_t);
/* Root mounted event */
typedef void (*mountroot_handler_t)(void *);
Index: sys/sys/protosw.h
===================================================================
--- sys/sys/protosw.h
+++ sys/sys/protosw.h
@@ -52,9 +52,6 @@
* Each protocol has a handle initializing one of these structures,
* which is used for protocol-protocol and system-protocol communication.
*
- * The system will call the pr_drain entry if it is low on space and
- * this should throw away any non-critical data.
- *
* In retrospect, it would be a lot nicer to use an interface
* similar to the vnode VOP interface.
*/
@@ -65,7 +62,6 @@
/* USE THESE FOR YOUR PROTOTYPES ! */
typedef int pr_ctloutput_t(struct socket *, struct sockopt *);
-typedef void pr_drain_t(void);
typedef void pr_abort_t(struct socket *);
typedef int pr_accept_t(struct socket *, struct sockaddr **);
typedef int pr_attach_t(struct socket *, int, struct thread *);
@@ -117,7 +113,6 @@
/* protocol-protocol hooks */
pr_ctloutput_t *pr_ctloutput; /* control output (from above) */
/* utility hooks */
- pr_drain_t *pr_drain; /* flush any excess space possible */
struct pr_usrreqs *pr_usrreqs; /* user-protocol hook */
};
Index: sys/vm/vm_pageout.h
===================================================================
--- sys/vm/vm_pageout.h
+++ sys/vm/vm_pageout.h
@@ -87,6 +87,7 @@
*/
#define VM_LOW_KMEM 0x01
#define VM_LOW_PAGES 0x02
+#define VM_LOW_MBUFS 0x04
/*
* Exported routines.

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 22, 5:10 AM (13 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31891975
Default Alt Text
D36164.id109232.diff (11 KB)

Event Timeline