e35d543ec1
o Separate fields of struct socket that belong to listening from fields that belong to normal dataflow, and unionize them. This shrinks the structure a bit. - Take out selinfo's from the socket buffers into the socket. The first reason is to support braindamaged scenario when a socket is added to kevent(2) and then listen(2) is cast on it. The second reason is that there is future plan to make socket buffers pluggable, so that for a dataflow socket a socket buffer can be changed, and in this case we also want to keep same selinfos through the lifetime of a socket. - Remove struct struct so_accf. Since now listening stuff no longer affects struct socket size, just move its fields into listening part of the union. - Provide sol_upcall field and enforce that so_upcall_set() may be called only on a dataflow socket, which has buffers, and for listening sockets provide solisten_upcall_set(). o Remove ACCEPT_LOCK() global. - Add a mutex to socket, to be used instead of socket buffer lock to lock fields of struct socket that don't belong to a socket buffer. - Allow to acquire two socket locks, but the first one must belong to a listening socket. - Make soref()/sorele() to use atomic(9). This allows in some situations to do soref() without owning socket lock. There is place for improvement here, it is possible to make sorele() also to lock optionally. - Most protocols aren't touched by this change, except UNIX local sockets. See below for more information. o Reduce copy-and-paste in kernel modules that accept connections from listening sockets: provide function solisten_dequeue(), and use it in the following modules: ctl(4), iscsi(4), ng_btsocket(4), ng_ksocket(4), infiniband, rpc. o UNIX local sockets. - Removal of ACCEPT_LOCK() global uncovered several races in the UNIX local sockets. Most races exist around spawning a new socket, when we are connecting to a local listening socket. To cover them, we need to hold locks on both PCBs when spawning a third one. This means holding them across sonewconn(). This creates a LOR between pcb locks and unp_list_lock. - To fix the new LOR, abandon the global unp_list_lock in favor of global unp_link_lock. Indeed, separating these two locks didn't provide us any extra parralelism in the UNIX sockets. - Now call into uipc_attach() may happen with unp_link_lock hold if, we are accepting, or without unp_link_lock in case if we are just creating a socket. - Another problem in UNIX sockets is that uipc_close() basicly did nothing for a listening socket. The vnode remained opened for connections. This is fixed by removing vnode in uipc_close(). Maybe the right way would be to do it for all sockets (not only listening), simply move the vnode teardown from uipc_detach() to uipc_close()? Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D9770 |
||
---|---|---|
.. | ||
cc | ||
khelp | ||
libalias | ||
tcp_stacks | ||
accf_data.c | ||
accf_dns.c | ||
accf_http.c | ||
icmp6.h | ||
icmp_var.h | ||
if_ether.c | ||
if_ether.h | ||
igmp_var.h | ||
igmp.c | ||
igmp.h | ||
in_cksum.c | ||
in_debug.c | ||
in_fib.c | ||
in_fib.h | ||
in_gif.c | ||
in_jail.c | ||
in_kdtrace.c | ||
in_kdtrace.h | ||
in_mcast.c | ||
in_pcb.c | ||
in_pcb.h | ||
in_pcbgroup.c | ||
in_prot.c | ||
in_proto.c | ||
in_rmx.c | ||
in_rss.c | ||
in_rss.h | ||
in_systm.h | ||
in_var.h | ||
in.c | ||
in.h | ||
ip6.h | ||
ip_carp.c | ||
ip_carp.h | ||
ip_divert.c | ||
ip_divert.h | ||
ip_dummynet.h | ||
ip_ecn.c | ||
ip_ecn.h | ||
ip_encap.c | ||
ip_encap.h | ||
ip_fastfwd.c | ||
ip_fw.h | ||
ip_gre.c | ||
ip_icmp.c | ||
ip_icmp.h | ||
ip_id.c | ||
ip_input.c | ||
ip_mroute.c | ||
ip_mroute.h | ||
ip_options.c | ||
ip_options.h | ||
ip_output.c | ||
ip_reass.c | ||
ip_var.h | ||
ip.h | ||
pim_var.h | ||
pim.h | ||
raw_ip.c | ||
sctp_asconf.c | ||
sctp_asconf.h | ||
sctp_auth.c | ||
sctp_auth.h | ||
sctp_bsd_addr.c | ||
sctp_bsd_addr.h | ||
sctp_cc_functions.c | ||
sctp_constants.h | ||
sctp_crc32.c | ||
sctp_crc32.h | ||
sctp_dtrace_declare.h | ||
sctp_dtrace_define.h | ||
sctp_header.h | ||
sctp_indata.c | ||
sctp_indata.h | ||
sctp_input.c | ||
sctp_input.h | ||
sctp_lock_bsd.h | ||
sctp_os_bsd.h | ||
sctp_os.h | ||
sctp_output.c | ||
sctp_output.h | ||
sctp_pcb.c | ||
sctp_pcb.h | ||
sctp_peeloff.c | ||
sctp_peeloff.h | ||
sctp_ss_functions.c | ||
sctp_structs.h | ||
sctp_syscalls.c | ||
sctp_sysctl.c | ||
sctp_sysctl.h | ||
sctp_timer.c | ||
sctp_timer.h | ||
sctp_uio.h | ||
sctp_usrreq.c | ||
sctp_var.h | ||
sctp.h | ||
sctputil.c | ||
sctputil.h | ||
siftr.c | ||
tcp_debug.c | ||
tcp_debug.h | ||
tcp_fastopen.c | ||
tcp_fastopen.h | ||
tcp_fsm.h | ||
tcp_hostcache.c | ||
tcp_hostcache.h | ||
tcp_input.c | ||
tcp_lro.c | ||
tcp_lro.h | ||
tcp_offload.c | ||
tcp_offload.h | ||
tcp_output.c | ||
tcp_pcap.c | ||
tcp_pcap.h | ||
tcp_reass.c | ||
tcp_sack.c | ||
tcp_seq.h | ||
tcp_subr.c | ||
tcp_syncache.c | ||
tcp_syncache.h | ||
tcp_timer.c | ||
tcp_timer.h | ||
tcp_timewait.c | ||
tcp_usrreq.c | ||
tcp_var.h | ||
tcp.h | ||
tcpip.h | ||
toecore.c | ||
toecore.h | ||
udp_usrreq.c | ||
udp_var.h | ||
udp.h | ||
udplite.h |