From be07528c53cd0aa3a8b5f9338f55148cac709ea8 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 23 May 2011 09:02:44 +0000 Subject: [PATCH 01/23] Diff reduction against NetBSD. The most notable change is to zdiff(1) to handle more file formats including bzip2 and xz. MFC after: 2 weeks --- usr.bin/gzip/Makefile | 2 +- usr.bin/gzip/gzip.c | 9 +-- usr.bin/gzip/zdiff | 119 +++++++++++++++++++++++-------------- usr.bin/gzip/zdiff.1 | 59 ++++++++++++++---- usr.bin/gzip/zuncompress.c | 2 +- 5 files changed, 128 insertions(+), 63 deletions(-) diff --git a/usr.bin/gzip/Makefile b/usr.bin/gzip/Makefile index 04803373875..16a825f6613 100644 --- a/usr.bin/gzip/Makefile +++ b/usr.bin/gzip/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.10 2006/05/12 02:01:15 mrg Exp $ +# $NetBSD: Makefile,v 1.13 2009/04/14 22:15:20 lukem Exp $ # $FreeBSD$ .include diff --git a/usr.bin/gzip/gzip.c b/usr.bin/gzip/gzip.c index d86e84b6540..474575caf9a 100644 --- a/usr.bin/gzip/gzip.c +++ b/usr.bin/gzip/gzip.c @@ -1,4 +1,4 @@ -/* $NetBSD: gzip.c,v 1.97 2009/10/11 09:17:21 mrg Exp $ */ +/* $NetBSD: gzip.c,v 1.99 2011/03/23 12:59:44 tsutsui Exp $ */ /*- * Copyright (c) 1997, 1998, 2003, 2004, 2006 Matthew R. Green @@ -31,7 +31,7 @@ #ifndef lint __COPYRIGHT("@(#) Copyright (c) 1997, 1998, 2003, 2004, 2006\ Matthew R. Green. All rights reserved."); -__RCSID("$FreeBSD$"); +__FBSDID("$FreeBSD$"); #endif /* not lint */ /* @@ -146,7 +146,7 @@ static suffixes_t suffixes[] = { #define NUM_SUFFIXES (sizeof suffixes / sizeof suffixes[0]) #define SUFFIX_MAXLEN 30 -static const char gzip_version[] = "FreeBSD gzip 20100407"; +static const char gzip_version[] = "FreeBSD gzip 20110523"; #ifndef SMALL static const char gzip_copyright[] = \ @@ -314,7 +314,7 @@ main(int argc, char **argv) dflag = cflag = 1; #ifdef SMALL -#define OPT_LIST "123456789cdhltV" +#define OPT_LIST "123456789cdhlV" #else #define OPT_LIST "123456789acdfhklLNnqrS:tVv" #endif @@ -918,6 +918,7 @@ gz_uncompress(int in, int out, char *pre, size_t prelen, off_t *gsizep, case Z_BUF_ERROR: if (z.avail_out > 0 && !done_reading) continue; + case Z_STREAM_END: case Z_OK: break; diff --git a/usr.bin/gzip/zdiff b/usr.bin/gzip/zdiff index 34caf2bdfb8..9e9aca677e2 100644 --- a/usr.bin/gzip/zdiff +++ b/usr.bin/gzip/zdiff @@ -1,10 +1,12 @@ #!/bin/sh - # -# $NetBSD: zdiff,v 1.3 2004/03/29 10:01:00 wiz Exp $ +# $NetBSD: zdiff,v 1.5 2010/04/14 20:30:28 joerg Exp $ +# # $OpenBSD: zdiff,v 1.2 2003/07/29 07:42:44 otto Exp $ # #- # Copyright (c) 2003 Todd C. Miller +# Copyright (c) 2010 Joerg Sonnenberger # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -31,7 +33,57 @@ case $0 in *) prog=diff ;; esac -USAGE="usage: z$prog [options] file1 [file2]" +USAGE="usage: $0 [options] file1 [file2]" + +check_suffix() { + case "$1" in + *[._-][Zz]) + setvar $2 "${1%??}" + setvar $3 "gzip -cdqf" + ;; + *[._-]bz) + setvar $2 "${1%???}" + setvar $3 "bzip2 -cdqf" + ;; + *[._-]gz) + setvar $2 "${1%???}" + setvar $3 "gzip -cdqf" + ;; + *[._-]xz) + setvar $2 "${1%???}" + setvar $3 "xz -cdqf" + ;; + *[._-]bz2) + setvar $2 "${1%????}" + setvar $3 "bzip2 -cdqf" + ;; + *[._-]lzma) + setvar $2 "${1%?????}" + setvar $3 "xz -cdqf" + ;; + *.t[ag]z) + setvar $2 "${1%??}"ar + setvar $3 "gzip -cdqf" + ;; + *.tbz) + setvar $2 "${1%??}"ar + setvar $3 "bzip2 -cdqf" + ;; + *.tbz2) + setvar $2 "${1%???}"ar + setvar $3 "bzip2 -cdqf" + ;; + *.t[lx]z) + setvar $2 "${1%??}"ar + setvar $3 "xz -cdqf" + ;; + *) + setvar $2 "$1" + setvar $3 "" + ;; + esac +} + # Pull out any command line flags so we can pass them to diff/cmp # XXX - assumes there is no optarg @@ -42,6 +94,9 @@ while test $# -ne 0; do shift break ;; + -) + break + ;; -*) flags="$flags $1" shift @@ -55,52 +110,28 @@ done if [ $# -eq 1 ]; then # One file given, compare compressed to uncompressed files="$1" - case "$1" in - *[._-][Zz]) - files="${1%??}" - ;; - *[._-]gz) - files="${1%???}" - ;; - *.t[ag]z) - files="${1%??}"ar - ;; - *) echo "z$prog: unknown suffix" 1>&2 - exit 1 - esac - gzip -cdfq "$1" | $prog $flags - "$files" + check_suffix "$1" files filt + if [ -z "$filt" ]; then + echo "z$prog: unknown suffix" 1>&2 + exit 1 + fi + $filt -- "$1" | $prog $flags -- - "$files" status=$? elif [ $# -eq 2 ]; then # Two files given, compare the two uncompressing as needed - case "$1" in - *[._-][Zz]|*[._-]gz|*.t[ag]z) - files=- - filt="gzip -cdfq $1" - ;; - *) - files="$1" - ;; - esac - case "$2" in - *[._-][Zz]|*[._-]gz|*.t[ag]z) - if [ "$files" = "-" ]; then - tmp=`mktemp -t z$prog.XXXXXXXXXX` || exit 1 - trap "rm -f $tmp" 0 1 2 3 13 15 - gzip -cdfq "$2" > $tmp - files="$files $tmp" - else - files="$files -" - filt="gzip -cdfq $2" - fi - ;; - *) - files="$files $2" - ;; - esac - if [ -n "$filt" ]; then - $filt | $prog $flags $files + check_suffix "$1" files filt + check_suffix "$2" files2 filt2 + if [ -z "$filt" -a -z "$filt2" ]; then + $prog $flags -- "$1" "$2" + elif [ -z "$filt" -a -n "$filt2" -a "$1" != "-" ]; then + $filt2 -- "$2" | $prog $flags -- "$1" - + elif [ -n "$filt" -a -z "$filt2" -a "$2" != "-" ]; then + $filt -- "$1" | $prog $flags -- - "$2" else - $prog $flags $files + tmp=`mktemp -t z$prog.XXXXXXXXXX` || exit 1 + trap "rm -f $tmp" 0 1 2 3 13 15 + ${filt2:-cat} -- "$2" > $tmp || exit $? + ${filt:-cat} -- "$1" | $prog $flags -- - "$tmp" fi status=$? else diff --git a/usr.bin/gzip/zdiff.1 b/usr.bin/gzip/zdiff.1 index 2a6a4c8c74a..52b5fbd100e 100644 --- a/usr.bin/gzip/zdiff.1 +++ b/usr.bin/gzip/zdiff.1 @@ -1,7 +1,8 @@ -.\" $NetBSD: zdiff.1,v 1.3 2003/12/28 12:48:03 wiz Exp $ +.\" $NetBSD: zdiff.1,v 1.5 2010/04/14 19:52:05 wiz Exp $ .\" $OpenBSD: zdiff.1,v 1.2 2003/07/13 17:39:14 millert Exp $ .\" .\" Copyright (c) 2003 Todd C. Miller +.\" Copyright (c) 2010 Joerg Sonnenberger .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -20,7 +21,7 @@ .\" Materiel Command, USAF, under agreement number F39502-99-1-0512. .\" .\" $FreeBSD$ -.Dd January 26, 2007 +.Dd May 23, 2011 .Dt ZDIFF 1 .Os .Sh NAME @@ -45,15 +46,6 @@ are filters that invoke or .Xr diff 1 respectively to compare compressed files. -Such files generally have a -.Dq Z -or -.Dq gz -extension (both the -.Xr compress 1 -and -.Xr gzip 1 -formats are supported). Any .Ar options that are specified are passed to @@ -70,6 +62,45 @@ When both or .Ar file2 are specified, either file may be compressed. +.Pp +Extensions handled by +.Xr gzip 1 : +.Bl -bullet -compact +.It +z, Z, +.It +gz, +.It +taz, +.It +tgz. +.El +.Pp +Extensions handled by +.Xr bzip2 1 : +.Bl -bullet -compact +.It +bz, +.It +bz2, +.It +tbz, +.It +tbz2. +.El +.Pp +Extensions handled by +.Xr xz 1 : +.Bl -bullet -compact +.It +lzma, +.It +xz, +.It +tlz, +.It +txz. +.El .Sh ENVIRONMENT .Bl -tag -width "TMPDIR" .It Ev TMPDIR @@ -88,9 +119,11 @@ Temporary file for .Nm zdiff . .El .Sh SEE ALSO +.Xr bzip2 1 , .Xr cmp 1 , -.Xr compress 1 , -.Xr diff 1 +.Xr diff 1 , +.Xr gzip 1 , +.Xr xz 1 .Sh CAVEATS .Nm zcmp and diff --git a/usr.bin/gzip/zuncompress.c b/usr.bin/gzip/zuncompress.c index 8e619bde154..f68ba595680 100644 --- a/usr.bin/gzip/zuncompress.c +++ b/usr.bin/gzip/zuncompress.c @@ -1,4 +1,4 @@ -/* $NetBSD: zuncompress.c,v 1.7 2009/04/12 10:31:14 lukem Exp $ */ +/* $NetBSD: zuncompress.c,v 1.8 2010/11/06 21:42:32 mrg Exp $ */ /*- * Copyright (c) 1985, 1986, 1992, 1993 From fc2689100470c2feae5d70c01efa073294bb8b1e Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 23 May 2011 09:40:21 +0000 Subject: [PATCH 02/23] Match symbolic link handling behavior with GNU gzip, bzip2 and xz: When we are operating on a symbolic link pointing to an existing file, bail out by default, but go ahead if -f is specified. Submitted by: arundel MFC after: 2 weeks --- usr.bin/gzip/gzip.1 | 8 ++++---- usr.bin/gzip/gzip.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/usr.bin/gzip/gzip.1 b/usr.bin/gzip/gzip.1 index 848a4b391c9..c0dc670a2cf 100644 --- a/usr.bin/gzip/gzip.1 +++ b/usr.bin/gzip/gzip.1 @@ -25,7 +25,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd April 27, 2010 +.Dd May 23, 2011 .Dt GZIP 1 .Os .Sh NAME @@ -127,9 +127,9 @@ stream, leaving files intact. This option selects decompression rather than compression. .It Fl f , -force This option turns on force mode. -This allows files with multiple links, overwriting of pre-existing -files, reading from or writing to a terminal, and when combined -with the +This allows files with multiple links, symbolic links to regular files, +overwriting of pre-existing files, reading from or writing to a terminal, +and when combined with the .Fl c option, allowing non-compressed data to pass through unchanged. .It Fl h , -help diff --git a/usr.bin/gzip/gzip.c b/usr.bin/gzip/gzip.c index 474575caf9a..927493eced7 100644 --- a/usr.bin/gzip/gzip.c +++ b/usr.bin/gzip/gzip.c @@ -1782,7 +1782,7 @@ handle_pathname(char *path) } retry: - if (stat(path, &sb) != 0) { + if (stat(path, &sb) != 0 || (fflag == 0 && lstat(path, &sb) != 0)) { /* lets try .gz if we're decompressing */ if (dflag && s == NULL && errno == ENOENT) { len = strlen(path); From 82a5be494a04b64553b0299662402aaea2c02c2a Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 23 May 2011 13:51:57 +0000 Subject: [PATCH 03/23] A number of quite incremental refinements to struct inpcbinfo's definition: (1) Add a locking guide for inpcbinfo. (2) Annotate inpcbinfo fields with synchronisation information; not all annotations are 100% satisfactory. (3) Reorder inpcbinfo fields so that the lock is at the head of the structure, and close to fields it protects. (4) Sort fields that will eventually be hashlock/pcbgroup-related together even though they remain locked by ipi_lock for now. Reviewed by: bz Sponsored by: Juniper Networks X-MFC after: KBI analysis required --- sys/netinet/in_pcb.h | 75 ++++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index 813011ecbf1..52debb063ce 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -1,8 +1,12 @@ /*- * Copyright (c) 1982, 1986, 1990, 1993 * The Regents of the University of California. + * Copyright (c) 2010-2011 Juniper Networks, Inc. * All rights reserved. * + * Portions of this software were developed by Robert N. M. Watson under + * contract to Juniper Networks, Inc. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -260,53 +264,70 @@ struct inpcbport { u_short phd_port; }; -/* +/*- * Global data structure for each high-level protocol (UDP, TCP, ...) in both * IPv4 and IPv6. Holds inpcb lists and information for managing them. + * + * Each pcbinfo is protected by ipi_lock, covering mutable global fields (such + * as the global pcb list) and hashed lookup tables. The lock order is: + * + * ipi_lock (before) inpcb locks + * + * Locking key: + * + * (c) Constant or nearly constant after initialisation + * (g) Locked by ipi_lock + * (h) Read using either ipi_lock or inpcb lock; write requires both. + * (x) Synchronisation properties poorly defined */ struct inpcbinfo { + /* + * Global lock protecting global inpcb list, inpcb count, hash tables, + * etc. + */ + struct rwlock ipi_lock; + /* * Global list of inpcbs on the protocol. */ - struct inpcbhead *ipi_listhead; - u_int ipi_count; + struct inpcbhead *ipi_listhead; /* (g) */ + u_int ipi_count; /* (g) */ + + /* + * Generation count -- incremented each time a connection is allocated + * or freed. + */ + u_quad_t ipi_gencnt; /* (g) */ + + /* + * Fields associated with port lookup and allocation. + */ + u_short ipi_lastport; /* (x) */ + u_short ipi_lastlow; /* (x) */ + u_short ipi_lasthi; /* (x) */ + + /* + * UMA zone from which inpcbs are allocated for this protocol. + */ + struct uma_zone *ipi_zone; /* (c) */ /* * Global hash of inpcbs, hashed by local and foreign addresses and * port numbers. */ - struct inpcbhead *ipi_hashbase; - u_long ipi_hashmask; + struct inpcbhead *ipi_hashbase; /* (g) */ + u_long ipi_hashmask; /* (g) */ /* * Global hash of inpcbs, hashed by only local port number. */ - struct inpcbporthead *ipi_porthashbase; - u_long ipi_porthashmask; - - /* - * Fields associated with port lookup and allocation. - */ - u_short ipi_lastport; - u_short ipi_lastlow; - u_short ipi_lasthi; - - /* - * UMA zone from which inpcbs are allocated for this protocol. - */ - struct uma_zone *ipi_zone; - - /* - * Generation count--incremented each time a connection is allocated - * or freed. - */ - u_quad_t ipi_gencnt; - struct rwlock ipi_lock; + struct inpcbporthead *ipi_porthashbase; /* (g) */ + u_long ipi_porthashmask; /* (g) */ /* * Pointer to network stack instance */ - struct vnet *ipi_vnet; + struct vnet *ipi_vnet; /* (c) */ /* * general use 2 From 68e0d7e06a1876d72d1b0fdce1811c550e601fb7 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 23 May 2011 15:23:18 +0000 Subject: [PATCH 04/23] Move from passing a wildcard boolean to a general set up lookup flags into in_pcb_lport(), in_pcblookup_local(), and in_pcblookup_hash(), and similarly for IPv6 functions. In the future, we would like to support other flags relating to locking strategy. This change doesn't appear to modify the KBI in practice, as callers already passed in INPLOOKUP_WILDCARD rather than a simple boolean. MFC after: 3 weeks Reviewed by: bz Sponsored by: Juniper Networks, Inc. --- sys/netinet/in_pcb.c | 30 ++++++++++++++++++------------ sys/netinet6/in6_pcb.c | 25 ++++++++++++++++--------- sys/netinet6/in6_src.c | 6 +++--- 3 files changed, 37 insertions(+), 24 deletions(-) diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index b3bb8d9bb01..515bd415e15 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -329,7 +329,7 @@ in_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred) #if defined(INET) || defined(INET6) int in_pcb_lport(struct inpcb *inp, struct in_addr *laddrp, u_short *lportp, - struct ucred *cred, int wild) + struct ucred *cred, int lookupflags) { struct inpcbinfo *pcbinfo; struct inpcb *tmpinp; @@ -424,14 +424,14 @@ in_pcb_lport(struct inpcb *inp, struct in_addr *laddrp, u_short *lportp, #ifdef INET6 if ((inp->inp_vflag & INP_IPV6) != 0) tmpinp = in6_pcblookup_local(pcbinfo, - &inp->in6p_laddr, lport, wild, cred); + &inp->in6p_laddr, lport, lookupflags, cred); #endif #if defined(INET) && defined(INET6) else #endif #ifdef INET tmpinp = in_pcblookup_local(pcbinfo, laddr, - lport, wild, cred); + lport, lookupflags, cred); #endif } while (tmpinp != NULL); @@ -464,7 +464,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp, struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; struct in_addr laddr; u_short lport = 0; - int wild = 0, reuseport = (so->so_options & SO_REUSEPORT); + int lookupflags = 0, reuseport = (so->so_options & SO_REUSEPORT); int error; /* @@ -480,7 +480,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp, if (nam != NULL && laddr.s_addr != INADDR_ANY) return (EINVAL); if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0) - wild = INPLOOKUP_WILDCARD; + lookupflags = INPLOOKUP_WILDCARD; if (nam == NULL) { if ((error = prison_local_ip4(cred, &laddr)) != 0) return (error); @@ -561,7 +561,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp, return (EADDRINUSE); } t = in_pcblookup_local(pcbinfo, sin->sin_addr, - lport, wild, cred); + lport, lookupflags, cred); if (t && (t->inp_flags & INP_TIMEWAIT)) { /* * XXXRW: If an incpb has had its timewait @@ -590,7 +590,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp, if (*lportp != 0) lport = *lportp; if (lport == 0) { - error = in_pcb_lport(inp, &laddr, &lport, cred, wild); + error = in_pcb_lport(inp, &laddr, &lport, cred, lookupflags); if (error != 0) return (error); @@ -1307,7 +1307,7 @@ in_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp) #define INP_LOOKUP_MAPPED_PCB_COST 3 struct inpcb * in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr, - u_short lport, int wild_okay, struct ucred *cred) + u_short lport, int lookupflags, struct ucred *cred) { struct inpcb *inp; #ifdef INET6 @@ -1317,9 +1317,12 @@ in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr, #endif int wildcard; + KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0, + ("%s: invalid lookup flags %d", __func__, lookupflags)); + INP_INFO_LOCK_ASSERT(pcbinfo); - if (!wild_okay) { + if ((lookupflags & INPLOOKUP_WILDCARD) == 0) { struct inpcbhead *head; /* * Look for an unconnected (wildcard foreign addr) PCB that @@ -1425,13 +1428,16 @@ in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr, */ struct inpcb * in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in_addr faddr, - u_int fport_arg, struct in_addr laddr, u_int lport_arg, int wildcard, + u_int fport_arg, struct in_addr laddr, u_int lport_arg, int lookupflags, struct ifnet *ifp) { struct inpcbhead *head; struct inpcb *inp, *tmpinp; u_short fport = fport_arg, lport = lport_arg; + KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0, + ("%s: invalid lookup flags %d", __func__, lookupflags)); + INP_INFO_LOCK_ASSERT(pcbinfo); /* @@ -1467,7 +1473,7 @@ in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in_addr faddr, /* * Then look for a wildcard match, if requested. */ - if (wildcard == INPLOOKUP_WILDCARD) { + if ((lookupflags & INPLOOKUP_WILDCARD) != 0) { struct inpcb *local_wild = NULL, *local_exact = NULL; #ifdef INET6 struct inpcb *local_wild_mapped = NULL; @@ -1538,7 +1544,7 @@ in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in_addr faddr, if (local_wild_mapped != NULL) return (local_wild_mapped); #endif /* defined(INET6) */ - } /* if (wildcard == INPLOOKUP_WILDCARD) */ + } /* if ((lookupflags & INPLOOKUP_WILDCARD) != 0) */ return (NULL); } diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index 9e64562f936..eacce8c5376 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -111,7 +111,8 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam, struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)NULL; struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; u_short lport = 0; - int error, wild = 0, reuseport = (so->so_options & SO_REUSEPORT); + int error, lookupflags = 0; + int reuseport = (so->so_options & SO_REUSEPORT); INP_INFO_WLOCK_ASSERT(pcbinfo); INP_WLOCK_ASSERT(inp); @@ -121,7 +122,7 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam, if (inp->inp_lport || !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) return (EINVAL); if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0) - wild = INPLOOKUP_WILDCARD; + lookupflags = INPLOOKUP_WILDCARD; if (nam == NULL) { if ((error = prison_local_ip6(cred, &inp->in6p_laddr, ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0) @@ -226,7 +227,7 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam, #endif } t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr, - lport, wild, cred); + lport, lookupflags, cred); if (t && (reuseport & ((t->inp_flags & INP_TIMEWAIT) ? intotw(t)->tw_so_options : t->inp_socket->so_options)) == 0) @@ -238,7 +239,7 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam, in6_sin6_2_sin(&sin, sin6); t = in_pcblookup_local(pcbinfo, sin.sin_addr, - lport, wild, cred); + lport, lookupflags, cred); if (t && t->inp_flags & INP_TIMEWAIT) { if ((reuseport & intotw(t)->tw_so_options) == 0 && @@ -652,14 +653,17 @@ in6_pcbnotify(struct inpcbinfo *pcbinfo, struct sockaddr *dst, */ struct inpcb * in6_pcblookup_local(struct inpcbinfo *pcbinfo, struct in6_addr *laddr, - u_short lport, int wild_okay, struct ucred *cred) + u_short lport, int lookupflags, struct ucred *cred) { register struct inpcb *inp; int matchwild = 3, wildcard; + KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0, + ("%s: invalid lookup flags %d", __func__, lookupflags)); + INP_INFO_WLOCK_ASSERT(pcbinfo); - if (!wild_okay) { + if ((lookupflags & INPLOOKUP_WILDCARD) == 0) { struct inpcbhead *head; /* * Look for an unconnected (wildcard foreign addr) PCB that @@ -815,7 +819,7 @@ in6_rtchange(struct inpcb *inp, int errno) */ struct inpcb * in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, - u_int fport_arg, struct in6_addr *laddr, u_int lport_arg, int wildcard, + u_int fport_arg, struct in6_addr *laddr, u_int lport_arg, int lookupflags, struct ifnet *ifp) { struct inpcbhead *head; @@ -823,6 +827,9 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, u_short fport = fport_arg, lport = lport_arg; int faith; + KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0, + ("%s: invalid lookup flags %d", __func__, lookupflags)); + INP_INFO_LOCK_ASSERT(pcbinfo); if (faithprefix_p != NULL) @@ -862,7 +869,7 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, /* * Then look for a wildcard match, if requested. */ - if (wildcard == INPLOOKUP_WILDCARD) { + if ((lookupflags & INPLOOKUP_WILDCARD) != 0) { struct inpcb *local_wild = NULL, *local_exact = NULL; struct inpcb *jail_wild = NULL; int injail; @@ -919,7 +926,7 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, return (local_exact); if (local_wild != NULL) return (local_wild); - } /* if (wildcard == INPLOOKUP_WILDCARD) */ + } /* if ((lookupflags & INPLOOKUP_WILDCARD) != 0) */ /* * Not found. diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index b491e0e7ab1..5202e091bc9 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -851,7 +851,7 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct ucred *cred) { struct socket *so = inp->inp_socket; u_int16_t lport = 0; - int error, wild = 0; + int error, lookupflags = 0; #ifdef INVARIANTS struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; #endif @@ -866,11 +866,11 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct ucred *cred) /* XXX: this is redundant when called from in6_pcbbind */ if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0) - wild = INPLOOKUP_WILDCARD; + lookupflags = INPLOOKUP_WILDCARD; inp->inp_flags |= INP_ANONPORT; - error = in_pcb_lport(inp, NULL, &lport, cred, wild); + error = in_pcb_lport(inp, NULL, &lport, cred, lookupflags); if (error != 0) return (error); From f53edc909e1a03842ed21db6a851c8aa8b405953 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Mon, 23 May 2011 16:40:44 +0000 Subject: [PATCH 05/23] In init_dynamic_kenv(), ignore environment strings exceeding the KENV_MNAMELEN + 1 + KENV_MVALLEN + 1 length limit to avoid buffer overflow in getenv(). Currenly loader(8) doesn't limit the length of environment strings. PR: kern/132104 MFC after: 1 month --- sys/kern/kern_environment.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_environment.c b/sys/kern/kern_environment.c index 41a9fa8e831..16760ce90c5 100644 --- a/sys/kern/kern_environment.c +++ b/sys/kern/kern_environment.c @@ -225,13 +225,19 @@ static void init_dynamic_kenv(void *data __unused) { char *cp; - int len, i; + size_t len; + int i; kenvp = malloc((KENV_SIZE + 1) * sizeof(char *), M_KENV, M_WAITOK | M_ZERO); i = 0; for (cp = kern_envp; cp != NULL; cp = kernenv_next(cp)) { len = strlen(cp) + 1; + if (len > KENV_MNAMELEN + 1 + KENV_MVALLEN + 1) { + printf("WARNING: too long kenv string, ignoring %s\n", + cp); + continue; + } if (i < KENV_SIZE) { kenvp[i] = malloc(len, M_KENV, M_WAITOK); strcpy(kenvp[i++], cp); From 79bdc6e5d368f0411e7680cac68cefa046dfbc65 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 23 May 2011 19:32:02 +0000 Subject: [PATCH 06/23] Continue to refine inpcb reference counting and locking, in preparation for reworking of inpcbinfo locking: (1) Convert inpcb reference counting from manually manipulated integers to the refcount(9) KPI. This allows the refcount to be managed atomically with an inpcb read lock rather than write lock, or even with no inpcb lock at all. As a result, in_pcbref() also no longer requires an inpcb lock, so can be performed solely using the lock used to look up an inpcb. (2) Shift more inpcb freeing activity from the in_pcbrele() context (via in_pcbfree_internal) to the explicit in_pcbfree() context. This means that the inpcb refcount is increasingly used only to maintain memory stability, not actually defer the clean up of inpcb protocol parts. This is desirable as many of those protocol parts required the pcbinfo lock, which we'd like not to acquire in in_pcbrele() contexts. Document this in comments better. (3) Introduce new read-locked and write-locked in_pcbrele() variations, in_pcbrele_rlocked() and in_pcbrele_wlocked(), which allow the inpcb to be properly unlocked as needed. in_pcbrele() is a wrapper around the latter, and should probably go away at some point. This makes it easier to use this weak reference model when holding only a read lock, as will happen in the future. This may well be safe to MFC, but some more KBI analysis is required. Reviewed by: bz MFC after: 3 weeks Sponsored by: Juniper Networks, Inc. --- sys/netinet/in_pcb.c | 198 ++++++++++++++++++++++++------------------- sys/netinet/in_pcb.h | 2 + 2 files changed, 115 insertions(+), 85 deletions(-) diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 515bd415e15..9bde3c82124 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -2,8 +2,12 @@ * Copyright (c) 1982, 1986, 1991, 1993, 1995 * The Regents of the University of California. * Copyright (c) 2007-2009 Robert N. M. Watson + * Copyright (c) 2010-2011 Juniper Networks, Inc. * All rights reserved. * + * Portions of this software were developed by Robert N. M. Watson under + * contract to Juniper Networks, Inc. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -50,6 +54,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -287,7 +292,7 @@ in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo) #endif INP_WLOCK(inp); inp->inp_gencnt = ++pcbinfo->ipi_gencnt; - inp->inp_refcount = 1; /* Reference from the inpcbinfo */ + refcount_init(&inp->inp_refcount, 1); /* Reference from inpcbinfo */ #if defined(IPSEC) || defined(MAC) out: if (error != 0) { @@ -1028,26 +1033,121 @@ in_pcbdetach(struct inpcb *inp) } /* - * in_pcbfree_internal() frees an inpcb that has been detached from its - * socket, and whose reference count has reached 0. It will also remove the - * inpcb from any global lists it might remain on. + * in_pcbref() bumps the reference count on an inpcb in order to maintain + * stability of an inpcb pointer despite the inpcb lock being released. This + * is used in TCP when the inpcbinfo lock needs to be acquired or upgraded, + * but where the inpcb lock is already held. + * + * in_pcbref() should be used only to provide brief memory stability, and + * must always be followed by a call to INP_WLOCK() and in_pcbrele() to + * garbage collect the inpcb if it has been in_pcbfree()'d from another + * context. Until in_pcbrele() has returned that the inpcb is still valid, + * lock and rele are the *only* safe operations that may be performed on the + * inpcb. + * + * While the inpcb will not be freed, releasing the inpcb lock means that the + * connection's state may change, so the caller should be careful to + * revalidate any cached state on reacquiring the lock. Drop the reference + * using in_pcbrele(). */ -static void -in_pcbfree_internal(struct inpcb *inp) +void +in_pcbref(struct inpcb *inp) { - struct inpcbinfo *ipi = inp->inp_pcbinfo; - KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__)); - KASSERT(inp->inp_refcount == 0, ("%s: refcount !0", __func__)); - - INP_INFO_WLOCK_ASSERT(ipi); INP_WLOCK_ASSERT(inp); + KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__)); + + refcount_acquire(&inp->inp_refcount); +} + +/* + * Drop a refcount on an inpcb elevated using in_pcbref(); because a call to + * in_pcbfree() may have been made between in_pcbref() and in_pcbrele(), we + * return a flag indicating whether or not the inpcb remains valid. If it is + * valid, we return with the inpcb lock held. + * + * Notice that, unlike in_pcbref(), the inpcb lock must be held to drop a + * reference on an inpcb. Historically more work was done here (actually, in + * in_pcbfree_internal()) but has been moved to in_pcbfree() to avoid the + * need for the pcbinfo lock in in_pcbrele(). Deferring the free is entirely + * about memory stability (and continued use of the write lock). + */ +int +in_pcbrele_rlocked(struct inpcb *inp) +{ + struct inpcbinfo *pcbinfo; + + KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__)); + + INP_RLOCK_ASSERT(inp); + + if (refcount_release(&inp->inp_refcount) == 0) + return (0); + + KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__)); + + INP_RUNLOCK(inp); + pcbinfo = inp->inp_pcbinfo; + uma_zfree(pcbinfo->ipi_zone, inp); + return (1); +} + +int +in_pcbrele_wlocked(struct inpcb *inp) +{ + struct inpcbinfo *pcbinfo; + + KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__)); + + INP_WLOCK_ASSERT(inp); + + if (refcount_release(&inp->inp_refcount) == 0) + return (0); + + KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__)); + + INP_WUNLOCK(inp); + pcbinfo = inp->inp_pcbinfo; + uma_zfree(pcbinfo->ipi_zone, inp); + return (1); +} + +/* + * Temporary wrapper. + */ +int +in_pcbrele(struct inpcb *inp) +{ + + return (in_pcbrele_wlocked(inp)); +} + +/* + * Unconditionally schedule an inpcb to be freed by decrementing its + * reference count, which should occur only after the inpcb has been detached + * from its socket. If another thread holds a temporary reference (acquired + * using in_pcbref()) then the free is deferred until that reference is + * released using in_pcbrele(), but the inpcb is still unlocked. Almost all + * work, including removal from global lists, is done in this context, where + * the pcbinfo lock is held. + */ +void +in_pcbfree(struct inpcb *inp) +{ + struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; + + KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__)); + + INP_INFO_WLOCK_ASSERT(pcbinfo); + INP_WLOCK_ASSERT(inp); + + /* XXXRW: Do as much as possible here. */ #ifdef IPSEC if (inp->inp_sp != NULL) ipsec_delete_pcbpolicy(inp); #endif /* IPSEC */ - inp->inp_gencnt = ++ipi->ipi_gencnt; + inp->inp_gencnt = ++pcbinfo->ipi_gencnt; in_pcbremlists(inp); #ifdef INET6 if (inp->inp_vflag & INP_IPV6PROTO) { @@ -1064,82 +1164,10 @@ in_pcbfree_internal(struct inpcb *inp) #endif inp->inp_vflag = 0; crfree(inp->inp_cred); - #ifdef MAC mac_inpcb_destroy(inp); #endif - INP_WUNLOCK(inp); - uma_zfree(ipi->ipi_zone, inp); -} - -/* - * in_pcbref() bumps the reference count on an inpcb in order to maintain - * stability of an inpcb pointer despite the inpcb lock being released. This - * is used in TCP when the inpcbinfo lock needs to be acquired or upgraded, - * but where the inpcb lock is already held. - * - * While the inpcb will not be freed, releasing the inpcb lock means that the - * connection's state may change, so the caller should be careful to - * revalidate any cached state on reacquiring the lock. Drop the reference - * using in_pcbrele(). - */ -void -in_pcbref(struct inpcb *inp) -{ - - INP_WLOCK_ASSERT(inp); - - KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__)); - - inp->inp_refcount++; -} - -/* - * Drop a refcount on an inpcb elevated using in_pcbref(); because a call to - * in_pcbfree() may have been made between in_pcbref() and in_pcbrele(), we - * return a flag indicating whether or not the inpcb remains valid. If it is - * valid, we return with the inpcb lock held. - */ -int -in_pcbrele(struct inpcb *inp) -{ -#ifdef INVARIANTS - struct inpcbinfo *ipi = inp->inp_pcbinfo; -#endif - - KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__)); - - INP_INFO_WLOCK_ASSERT(ipi); - INP_WLOCK_ASSERT(inp); - - inp->inp_refcount--; - if (inp->inp_refcount > 0) - return (0); - in_pcbfree_internal(inp); - return (1); -} - -/* - * Unconditionally schedule an inpcb to be freed by decrementing its - * reference count, which should occur only after the inpcb has been detached - * from its socket. If another thread holds a temporary reference (acquired - * using in_pcbref()) then the free is deferred until that reference is - * released using in_pcbrele(), but the inpcb is still unlocked. - */ -void -in_pcbfree(struct inpcb *inp) -{ -#ifdef INVARIANTS - struct inpcbinfo *ipi = inp->inp_pcbinfo; -#endif - - KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", - __func__)); - - INP_INFO_WLOCK_ASSERT(ipi); - INP_WLOCK_ASSERT(inp); - - if (!in_pcbrele(inp)) + if (!in_pcbrele_wlocked(inp)) INP_WUNLOCK(inp); } diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index 52debb063ce..14d4ea23375 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -534,6 +534,8 @@ void in_pcbnotifyall(struct inpcbinfo *pcbinfo, struct in_addr, void in_pcbref(struct inpcb *); void in_pcbrehash(struct inpcb *); int in_pcbrele(struct inpcb *); +int in_pcbrele_rlocked(struct inpcb *); +int in_pcbrele_wlocked(struct inpcb *); void in_pcbsetsolabel(struct socket *so); int in_getpeeraddr(struct socket *so, struct sockaddr **nam); int in_getsockaddr(struct socket *so, struct sockaddr **nam); From e28b1e2d03daf1202df953902f58f001854d2518 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Mon, 23 May 2011 19:57:12 +0000 Subject: [PATCH 07/23] expr -> sh arithmetic expansion --- sys/conf/newvers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index 6fe0a639a54..9681c7904d4 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -139,4 +139,4 @@ int osreldate = ${RELDATE}; char kern_ident[] = "${i}"; EOF -echo `expr ${v} + 1` > version +echo $((v + 1)) > version From 10e71e226056600fbc6bcceaeabc2d974e4c6b85 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 23 May 2011 19:58:08 +0000 Subject: [PATCH 08/23] Do not blindly clear entire GPHY control register. It seems some bits of the register is used for other purposes such that clearing these bits resulted in unexpected results such as corrupted RX frames or missing LE status updates. For old controllers like Yukon EC it had no effect but it caused all kind of troubles on Yukon Supreme. This change shall improve stability of controllers like Yukon Ultra, Ultra2, Extreme, Optima and Supreme. --- sys/dev/msk/if_msk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 3af1b205fda..8dc2d30d823 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -1362,8 +1362,8 @@ mskc_reset(struct msk_softc *sc) /* Reset GPHY/GMAC Control */ for (i = 0; i < sc->msk_num_port; i++) { /* GPHY Control reset. */ - CSR_WRITE_4(sc, MR_ADDR(i, GPHY_CTRL), GPC_RST_SET); - CSR_WRITE_4(sc, MR_ADDR(i, GPHY_CTRL), GPC_RST_CLR); + CSR_WRITE_1(sc, MR_ADDR(i, GPHY_CTRL), GPC_RST_SET); + CSR_WRITE_1(sc, MR_ADDR(i, GPHY_CTRL), GPC_RST_CLR); /* GMAC Control reset. */ CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_RST_SET); CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_RST_CLR); From 5e863acb636a9ccb850bc78cae90fcff2407eaa9 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Mon, 23 May 2011 19:59:01 +0000 Subject: [PATCH 09/23] BKVASIZE was bumped to 16k more than a decade ago. --- sys/kern/vfs_bio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 0b5e973bc73..00681cae2f9 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -654,7 +654,7 @@ bufinit(void) * To support extreme low-memory systems, make sure hidirtybuffers cannot * eat up all available buffer space. This occurs when our minimum cannot * be met. We try to size hidirtybuffers to 3/4 our buffer space assuming - * BKVASIZE'd (8K) buffers. + * BKVASIZE'd buffers. */ while ((long)hidirtybuffers * BKVASIZE > 3 * hibufspace / 4) { hidirtybuffers >>= 1; From 7b4f47c1db3b9f1e49acf496b65cd69ba391b1f9 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 23 May 2011 20:09:32 +0000 Subject: [PATCH 10/23] Rework store and forward configuration of TX MAC FIFO. Basically it enables store and forward mode except for jumbo frame on Yukon Ultra. --- sys/dev/msk/if_msk.c | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 8dc2d30d823..312e626686c 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -3654,37 +3654,24 @@ msk_set_tx_stfwd(struct msk_if_softc *sc_if) ifp = sc_if->msk_ifp; sc = sc_if->msk_softc; - switch (sc->msk_hw_id) { - case CHIP_ID_YUKON_EX: - if (sc->msk_hw_rev == CHIP_REV_YU_EX_A0) - goto yukon_ex_workaround; - if (ifp->if_mtu > ETHERMTU) - CSR_WRITE_4(sc, - MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T), - TX_JUMBO_ENA | TX_STFW_ENA); - else - CSR_WRITE_4(sc, - MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T), - TX_JUMBO_DIS | TX_STFW_ENA); - break; - default: -yukon_ex_workaround: + if ((sc->msk_hw_id == CHIP_ID_YUKON_EX && + sc->msk_hw_rev != CHIP_REV_YU_EX_A0) || + sc->msk_hw_id >= CHIP_ID_YUKON_SUPR) { + CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T), + TX_STFW_ENA); + } else { if (ifp->if_mtu > ETHERMTU) { /* Set Tx GMAC FIFO Almost Empty Threshold. */ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_AE_THR), MSK_ECU_JUMBO_WM << 16 | MSK_ECU_AE_THR); /* Disable Store & Forward mode for Tx. */ - CSR_WRITE_4(sc, - MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T), - TX_JUMBO_ENA | TX_STFW_DIS); + CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T), + TX_STFW_DIS); } else { - /* Enable Store & Forward mode for Tx. */ - CSR_WRITE_4(sc, - MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T), - TX_JUMBO_DIS | TX_STFW_ENA); + CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T), + TX_STFW_ENA); } - break; } } From ca5f1efdd9403258db867e40cc32ae6c434318ea Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Mon, 23 May 2011 20:12:36 +0000 Subject: [PATCH 11/23] Decrease ACPI-fast timecounter quality to 900 and increase HPET timecounter quality to 950. HPET on modern platforms usually have better resolution and lower latency than ACPI timer. Effectively this changes default timecounter hardware from ACPI-fast to HPET by default when both are available. Discussed with: avg --- sys/dev/acpica/acpi_hpet.c | 2 +- sys/dev/acpica/acpi_timer.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/acpica/acpi_hpet.c b/sys/dev/acpica/acpi_hpet.c index 4ea5c8583b1..40e8676fceb 100644 --- a/sys/dev/acpica/acpi_hpet.c +++ b/sys/dev/acpica/acpi_hpet.c @@ -476,7 +476,7 @@ hpet_attach(device_t dev) sc->tc.tc_get_timecount = hpet_get_timecount, sc->tc.tc_counter_mask = ~0u, sc->tc.tc_name = "HPET", - sc->tc.tc_quality = 900, + sc->tc.tc_quality = 950, sc->tc.tc_frequency = sc->freq; sc->tc.tc_priv = sc; tc_init(&sc->tc); diff --git a/sys/dev/acpica/acpi_timer.c b/sys/dev/acpica/acpi_timer.c index f4562067080..17416838e9e 100644 --- a/sys/dev/acpica/acpi_timer.c +++ b/sys/dev/acpica/acpi_timer.c @@ -203,7 +203,7 @@ acpi_timer_probe(device_t dev) if (j == 10) { acpi_timer_timecounter.tc_name = "ACPI-fast"; acpi_timer_timecounter.tc_get_timecount = acpi_timer_get_timecount; - acpi_timer_timecounter.tc_quality = 1000; + acpi_timer_timecounter.tc_quality = 900; } else { acpi_timer_timecounter.tc_name = "ACPI-safe"; acpi_timer_timecounter.tc_get_timecount = acpi_timer_get_timecount_safe; From d91192e329c7f80be69b13240cc363ef1156b5e8 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 23 May 2011 20:18:09 +0000 Subject: [PATCH 12/23] Do not configure RAM registers for controllers that do not have them. These registers are defined only for Yukon XL, Yukon EC and Yukon FE. --- sys/dev/msk/if_msk.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 312e626686c..e733114408e 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -1300,7 +1300,7 @@ mskc_reset(struct msk_softc *sc) bus_addr_t addr; uint16_t status; uint32_t val; - int i; + int i, initram; CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR); @@ -1396,8 +1396,14 @@ mskc_reset(struct msk_softc *sc) CSR_WRITE_1(sc, GMAC_TI_ST_CTRL, GMT_ST_STOP); CSR_WRITE_1(sc, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ); + initram = 0; + if (sc->msk_hw_id == CHIP_ID_YUKON_XL || + sc->msk_hw_id == CHIP_ID_YUKON_EC || + sc->msk_hw_id == CHIP_ID_YUKON_FE) + initram++; + /* Configure timeout values. */ - for (i = 0; i < sc->msk_num_port; i++) { + for (i = 0; initram > 0 && i < sc->msk_num_port; i++) { CSR_WRITE_2(sc, SELECT_RAM_BUFFER(i, B3_RI_CTRL), RI_RST_SET); CSR_WRITE_2(sc, SELECT_RAM_BUFFER(i, B3_RI_CTRL), RI_RST_CLR); CSR_WRITE_1(sc, SELECT_RAM_BUFFER(i, B3_RI_WTO_R1), From 1c6689d58d435ba2bbc0f336b7c13a6511f38a42 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 23 May 2011 20:59:50 +0000 Subject: [PATCH 13/23] To handle BIO_FLUSH and BIO_DELETE requests in secondary worker we need to use ioctl(2). This is why we can't use capsicum for now to sandbox secondary. Capsicum is still used to sandbox hastctl. MFC after: 1 week --- sbin/hastd/subr.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sbin/hastd/subr.c b/sbin/hastd/subr.c index 29f33e7d32c..806338b4bfc 100644 --- a/sbin/hastd/subr.c +++ b/sbin/hastd/subr.c @@ -224,7 +224,13 @@ drop_privs(struct hast_resource *res) return (-1); } - if (res == NULL || res->hr_role != HAST_ROLE_PRIMARY) + /* + * Until capsicum doesn't allow ioctl(2) we cannot use it to sandbox + * primary and secondary worker processes, as primary uses GGATE + * ioctls and secondary uses ioctls to handle BIO_DELETE and BIO_FLUSH. + * For now capsicum is only used to sandbox hastctl. + */ + if (res == NULL) capsicum = (cap_enter() == 0); else capsicum = false; From 204a4e196a0b29990ecb3564f1bee1eed29dd423 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 23 May 2011 21:00:37 +0000 Subject: [PATCH 14/23] Recognize BIO_FLUSH requests and pass them to userland. MFC after: 1 week --- sys/geom/gate/g_gate.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/geom/gate/g_gate.c b/sys/geom/gate/g_gate.c index 9b4d782aa41..22338a513ca 100644 --- a/sys/geom/gate/g_gate.c +++ b/sys/geom/gate/g_gate.c @@ -180,6 +180,7 @@ g_gate_start(struct bio *bp) break; case BIO_DELETE: case BIO_WRITE: + case BIO_FLUSH: /* XXX: Hack to allow read-only mounts. */ if ((sc->sc_flags & G_GATE_FLAG_READONLY) != 0) { g_io_deliver(bp, EPERM); @@ -580,6 +581,7 @@ g_gate_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct threa switch (bp->bio_cmd) { case BIO_READ: case BIO_DELETE: + case BIO_FLUSH: break; case BIO_WRITE: error = copyout(bp->bio_data, ggio->gctl_data, @@ -643,6 +645,7 @@ start_end: break; case BIO_DELETE: case BIO_WRITE: + case BIO_FLUSH: break; } } From c6a34f768e4e3873c69d5a9f345d01a8fabc186c Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 23 May 2011 21:00:56 +0000 Subject: [PATCH 15/23] Make sure to enable all clocks before accessing registers. Releasing PHY from power down/COMA is done after enabling all clocks. While I'm here remove unnecessary controller reset. --- sys/dev/msk/if_msk.c | 54 +++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index e733114408e..d14a3baefda 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -1212,37 +1212,30 @@ msk_phy_power(struct msk_softc *sc, int mode) */ CSR_WRITE_1(sc, B2_Y2_CLK_GATE, val); - val = CSR_PCI_READ_4(sc, PCI_OUR_REG_1); - val &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); + our = CSR_PCI_READ_4(sc, PCI_OUR_REG_1); + our &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); if (sc->msk_hw_id == CHIP_ID_YUKON_XL) { if (sc->msk_hw_rev > CHIP_REV_YU_XL_A1) { /* Deassert Low Power for 1st PHY. */ - val |= PCI_Y2_PHY1_COMA; + our |= PCI_Y2_PHY1_COMA; if (sc->msk_num_port > 1) - val |= PCI_Y2_PHY2_COMA; + our |= PCI_Y2_PHY2_COMA; } } - /* Release PHY from PowerDown/COMA mode. */ - CSR_PCI_WRITE_4(sc, PCI_OUR_REG_1, val); - switch (sc->msk_hw_id) { - case CHIP_ID_YUKON_EC_U: - case CHIP_ID_YUKON_EX: - case CHIP_ID_YUKON_FE_P: - case CHIP_ID_YUKON_UL_2: - case CHIP_ID_YUKON_OPT: - CSR_WRITE_2(sc, B0_CTST, Y2_HW_WOL_OFF); - - /* Enable all clocks. */ - CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, 0); - our = CSR_PCI_READ_4(sc, PCI_OUR_REG_4); - our &= (PCI_FORCE_ASPM_REQUEST|PCI_ASPM_GPHY_LINK_DOWN| - PCI_ASPM_INT_FIFO_EMPTY|PCI_ASPM_CLKRUN_REQUEST); + if (sc->msk_hw_id == CHIP_ID_YUKON_EC_U || + sc->msk_hw_id == CHIP_ID_YUKON_EX || + sc->msk_hw_id >= CHIP_ID_YUKON_FE_P) { + val = CSR_PCI_READ_4(sc, PCI_OUR_REG_4); + val &= (PCI_FORCE_ASPM_REQUEST | + PCI_ASPM_GPHY_LINK_DOWN | PCI_ASPM_INT_FIFO_EMPTY | + PCI_ASPM_CLKRUN_REQUEST); /* Set all bits to 0 except bits 15..12. */ - CSR_PCI_WRITE_4(sc, PCI_OUR_REG_4, our); - our = CSR_PCI_READ_4(sc, PCI_OUR_REG_5); - our &= PCI_CTL_TIM_VMAIN_AV_MSK; - CSR_PCI_WRITE_4(sc, PCI_OUR_REG_5, our); + CSR_PCI_WRITE_4(sc, PCI_OUR_REG_4, val); + val = CSR_PCI_READ_4(sc, PCI_OUR_REG_5); + val &= PCI_CTL_TIM_VMAIN_AV_MSK; + CSR_PCI_WRITE_4(sc, PCI_OUR_REG_5, val); CSR_PCI_WRITE_4(sc, PCI_CFG_REG_1, 0); + CSR_WRITE_2(sc, B0_CTST, Y2_HW_WOL_ON); /* * Disable status race, workaround for * Yukon EC Ultra & Yukon EX. @@ -1251,10 +1244,10 @@ msk_phy_power(struct msk_softc *sc, int mode) val |= GLB_GPIO_STAT_RACE_DIS; CSR_WRITE_4(sc, B2_GP_IO, val); CSR_READ_4(sc, B2_GP_IO); - break; - default: - break; } + /* Release PHY from PowerDown/COMA mode. */ + CSR_PCI_WRITE_4(sc, PCI_OUR_REG_1, our); + for (i = 0; i < sc->msk_num_port; i++) { CSR_WRITE_2(sc, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET); @@ -1302,8 +1295,6 @@ mskc_reset(struct msk_softc *sc) uint32_t val; int i, initram; - CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR); - /* Disable ASF. */ if (sc->msk_hw_id == CHIP_ID_YUKON_EX) { status = CSR_READ_2(sc, B28_Y2_ASF_HCU_CCSR); @@ -1712,6 +1703,9 @@ mskc_attach(device_t dev) } } + /* Enable all clocks before accessing any registers. */ + CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, 0); + CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR); sc->msk_hw_id = CSR_READ_1(sc, B2_CHIP_ID); sc->msk_hw_rev = (CSR_READ_1(sc, B2_MAC_CFG) >> 4) & 0x0f; @@ -1752,9 +1746,6 @@ mskc_attach(device_t dev) resource_int_value(device_get_name(dev), device_get_unit(dev), "int_holdoff", &sc->msk_int_holdoff); - /* Soft reset. */ - CSR_WRITE_2(sc, B0_CTST, CS_RST_SET); - CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR); sc->msk_pmd = CSR_READ_1(sc, B2_PMD_TYP); /* Check number of MACs. */ sc->msk_num_port = 1; @@ -2969,6 +2960,7 @@ mskc_resume(device_t dev) MSK_LOCK(sc); + CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, 0); mskc_reset(sc); for (i = 0; i < sc->msk_num_port; i++) { if (sc->msk_if[i] != NULL && sc->msk_if[i]->msk_ifp != NULL && From fe0b141e733e1cc79fa76daf2f4f49a285a06020 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 23 May 2011 21:11:46 +0000 Subject: [PATCH 16/23] Do not touch ASF related register for controllers that do not have these registers. Also disable Watchdog of ASF microcontroller. --- sys/dev/msk/if_msk.c | 41 ++++++++++++++++++++++++----------------- sys/dev/msk/if_mskreg.h | 1 + 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index d14a3baefda..868a9facf36 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -1296,23 +1296,30 @@ mskc_reset(struct msk_softc *sc) int i, initram; /* Disable ASF. */ - if (sc->msk_hw_id == CHIP_ID_YUKON_EX) { - status = CSR_READ_2(sc, B28_Y2_ASF_HCU_CCSR); - /* Clear AHB bridge & microcontroller reset. */ - status &= ~(Y2_ASF_HCU_CCSR_AHB_RST | - Y2_ASF_HCU_CCSR_CPU_RST_MODE); - /* Clear ASF microcontroller state. */ - status &= ~ Y2_ASF_HCU_CCSR_UC_STATE_MSK; - CSR_WRITE_2(sc, B28_Y2_ASF_HCU_CCSR, status); - } else - CSR_WRITE_1(sc, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); - CSR_WRITE_2(sc, B0_CTST, Y2_ASF_DISABLE); - - /* - * Since we disabled ASF, S/W reset is required for Power Management. - */ - CSR_WRITE_2(sc, B0_CTST, CS_RST_SET); - CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR); + if (sc->msk_hw_id >= CHIP_ID_YUKON_XL && + sc->msk_hw_id <= CHIP_ID_YUKON_SUPR) { + if (sc->msk_hw_id == CHIP_ID_YUKON_EX || + sc->msk_hw_id == CHIP_ID_YUKON_SUPR) { + CSR_WRITE_4(sc, B28_Y2_CPU_WDOG, 0); + status = CSR_READ_2(sc, B28_Y2_ASF_HCU_CCSR); + /* Clear AHB bridge & microcontroller reset. */ + status &= ~(Y2_ASF_HCU_CCSR_AHB_RST | + Y2_ASF_HCU_CCSR_CPU_RST_MODE); + /* Clear ASF microcontroller state. */ + status &= ~Y2_ASF_HCU_CCSR_UC_STATE_MSK; + status &= ~Y2_ASF_HCU_CCSR_CPU_CLK_DIVIDE_MSK; + CSR_WRITE_2(sc, B28_Y2_ASF_HCU_CCSR, status); + CSR_WRITE_4(sc, B28_Y2_CPU_WDOG, 0); + } else + CSR_WRITE_1(sc, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); + CSR_WRITE_2(sc, B0_CTST, Y2_ASF_DISABLE); + /* + * Since we disabled ASF, S/W reset is required for + * Power Management. + */ + CSR_WRITE_2(sc, B0_CTST, CS_RST_SET); + CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR); + } /* Clear all error bits in the PCI status register. */ status = pci_read_config(sc->msk_dev, PCIR_STATUS, 2); diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h index 3b05b9ba858..0179608d4cb 100644 --- a/sys/dev/msk/if_mskreg.h +++ b/sys/dev/msk/if_mskreg.h @@ -677,6 +677,7 @@ /* ASF Subsystem Registers (Yukon-2 only) */ #define B28_Y2_SMB_CONFIG 0x0e40 /* 32 bit ASF SMBus Config Register */ #define B28_Y2_SMB_CSD_REG 0x0e44 /* 32 bit ASF SMB Control/Status/Data */ +#define B28_Y2_CPU_WDOG 0x0e48 /* 32 bit Watchdog Register */ #define B28_Y2_ASF_IRQ_V_BASE 0x0e60 /* 32 bit ASF IRQ Vector Base */ #define B28_Y2_ASF_STAT_CMD 0x0e68 /* 32 bit ASF Status and Command Reg */ #define B28_Y2_ASF_HCU_CCSR 0x0e68 /* 32 bit ASF HCU CCSR (Yukon EX) */ From 3db86c39aed2f276a65d71b8362cf30baed64beb Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 23 May 2011 21:15:19 +0000 Subject: [PATCH 17/23] Keep statistics on number of BIO_READ, BIO_WRITE, BIO_DELETE and BIO_FLUSH requests as well as number of activemap updates. Number of BIO_WRITEs and activemap updates are especially interesting, because if those two are too close to each other, it means that your workload needs bigger number of dirty extents. Activemap should be updated as rarely as possible. MFC after: 1 week --- sbin/hastctl/hastctl.c | 11 +++++++++++ sbin/hastd/control.c | 17 +++++++++++++++++ sbin/hastd/hast.h | 11 +++++++++++ sbin/hastd/primary.c | 11 +++++++++++ sbin/hastd/secondary.c | 14 ++++++++++++++ 5 files changed, 64 insertions(+) diff --git a/sbin/hastctl/hastctl.c b/sbin/hastctl/hastctl.c index c4cd6a4b91c..2f8a6eb8dff 100644 --- a/sbin/hastctl/hastctl.c +++ b/sbin/hastctl/hastctl.c @@ -341,6 +341,17 @@ control_status(struct nv *nv) printf(" dirty: %ju (%NB)\n", (uintmax_t)nv_get_uint64(nv, "dirty%u", ii), (intmax_t)nv_get_uint64(nv, "dirty%u", ii)); + printf(" statistics:\n"); + printf(" reads: %ju\n", + (uint64_t)nv_get_uint64(nv, "stat_read%u", ii)); + printf(" writes: %ju\n", + (uint64_t)nv_get_uint64(nv, "stat_write%u", ii)); + printf(" deletes: %ju\n", + (uint64_t)nv_get_uint64(nv, "stat_delete%u", ii)); + printf(" flushes: %ju\n", + (uint64_t)nv_get_uint64(nv, "stat_flush%u", ii)); + printf(" activemap updates: %ju\n", + (uint64_t)nv_get_uint64(nv, "stat_activemap_update%u", ii)); } return (ret); } diff --git a/sbin/hastd/control.c b/sbin/hastd/control.c index dce2d53bcc3..4d00403924d 100644 --- a/sbin/hastd/control.c +++ b/sbin/hastd/control.c @@ -199,6 +199,16 @@ control_status_worker(struct hast_resource *res, struct nv *nvout, "extentsize%u", no); nv_add_uint32(nvout, nv_get_uint32(cnvin, "keepdirty"), "keepdirty%u", no); + nv_add_uint64(nvout, nv_get_uint64(cnvin, "stat_read"), + "stat_read%u", no); + nv_add_uint64(nvout, nv_get_uint64(cnvin, "stat_write"), + "stat_write%u", no); + nv_add_uint64(nvout, nv_get_uint64(cnvin, "stat_delete"), + "stat_delete%u", no); + nv_add_uint64(nvout, nv_get_uint64(cnvin, "stat_flush"), + "stat_flush%u", no); + nv_add_uint64(nvout, nv_get_uint64(cnvin, "stat_activemap_update"), + "stat_activemap_update%u", no); end: if (cnvin != NULL) nv_free(cnvin); @@ -446,6 +456,13 @@ ctrl_thread(void *arg) nv_add_uint32(nvout, (uint32_t)0, "keepdirty"); nv_add_uint64(nvout, (uint64_t)0, "dirty"); } + nv_add_uint64(nvout, res->hr_stat_read, "stat_read"); + nv_add_uint64(nvout, res->hr_stat_write, "stat_write"); + nv_add_uint64(nvout, res->hr_stat_delete, + "stat_delete"); + nv_add_uint64(nvout, res->hr_stat_flush, "stat_flush"); + nv_add_uint64(nvout, res->hr_stat_activemap_update, + "stat_activemap_update"); nv_add_int16(nvout, 0, "error"); break; case CONTROL_RELOAD: diff --git a/sbin/hastd/hast.h b/sbin/hastd/hast.h index 3f261622835..a62b63a263f 100644 --- a/sbin/hastd/hast.h +++ b/sbin/hastd/hast.h @@ -218,6 +218,17 @@ struct hast_resource { /* Locked used to synchronize access to hr_amp. */ pthread_mutex_t hr_amp_lock; + /* Number of BIO_READ requests. */ + uint64_t hr_stat_read; + /* Number of BIO_WRITE requests. */ + uint64_t hr_stat_write; + /* Number of BIO_DELETE requests. */ + uint64_t hr_stat_delete; + /* Number of BIO_FLUSH requests. */ + uint64_t hr_stat_flush; + /* Number of activemap updates. */ + uint64_t hr_stat_activemap_update; + /* Next resource. */ TAILQ_ENTRY(hast_resource) hr_next; }; diff --git a/sbin/hastd/primary.c b/sbin/hastd/primary.c index d8eb664740c..1f6585c87a1 100644 --- a/sbin/hastd/primary.c +++ b/sbin/hastd/primary.c @@ -1117,6 +1117,7 @@ ggate_recv_thread(void *arg) */ switch (ggio->gctl_cmd) { case BIO_READ: + res->hr_stat_read++; pjdlog_debug(2, "ggate_recv: (%p) Moving request to the send queue.", hio); @@ -1145,6 +1146,7 @@ ggate_recv_thread(void *arg) QUEUE_INSERT1(hio, send, ncomp); break; case BIO_WRITE: + res->hr_stat_write++; if (res->hr_resuid == 0) { /* * This is first write, initialize localcnt and @@ -1183,12 +1185,21 @@ ggate_recv_thread(void *arg) mtx_lock(&res->hr_amp_lock); if (activemap_write_start(res->hr_amp, ggio->gctl_offset, ggio->gctl_length)) { + res->hr_stat_activemap_update++; (void)hast_activemap_flush(res); } mtx_unlock(&res->hr_amp_lock); /* FALLTHROUGH */ case BIO_DELETE: case BIO_FLUSH: + switch (ggio->gctl_cmd) { + case BIO_DELETE: + res->hr_stat_delete++; + break; + case BIO_FLUSH: + res->hr_stat_flush++; + break; + } pjdlog_debug(2, "ggate_recv: (%p) Moving request to the send queues.", hio); diff --git a/sbin/hastd/secondary.c b/sbin/hastd/secondary.c index 176d0470eed..1597af83a85 100644 --- a/sbin/hastd/secondary.c +++ b/sbin/hastd/secondary.c @@ -612,6 +612,20 @@ recv_thread(void *arg) QUEUE_INSERT(send, hio); continue; } + switch (hio->hio_cmd) { + case HIO_READ: + res->hr_stat_read++; + break; + case HIO_WRITE: + res->hr_stat_write++; + break; + case HIO_DELETE: + res->hr_stat_delete++; + break; + case HIO_FLUSH: + res->hr_stat_flush++; + break; + } reqlog(LOG_DEBUG, 2, -1, hio, "recv: (%p) Got request header: ", hio); if (hio->hio_cmd == HIO_KEEPALIVE) { From ff239280c643985c0fc14f6e11d8884427b0447c Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 23 May 2011 21:32:45 +0000 Subject: [PATCH 18/23] Test against "no" rather than "yes" for MK_KERNEL_SYMBOLS Also, change DEBUG back to DEBUG_FLAGS in kmod.mk. The latter accidentally snuck in with my backwards compat fix. Submitted by: ru,gcooper --- sys/conf/kern.post.mk | 4 ++-- sys/conf/kmod.mk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/conf/kern.post.mk b/sys/conf/kern.post.mk index 21d9572d8d5..8cb36f9f0fd 100644 --- a/sys/conf/kern.post.mk +++ b/sys/conf/kern.post.mk @@ -228,7 +228,7 @@ kernel-install: mkdir -p ${DESTDIR}${KODIR} ${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO} ${DESTDIR}${KODIR} .if defined(DEBUG) && !defined(INSTALL_NODEBUG) && \ - (defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} == "yes") + (defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} != "no") ${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO}.symbols ${DESTDIR}${KODIR} .endif .if defined(KERNEL_EXTRA_INSTALL) @@ -241,7 +241,7 @@ kernel-reinstall: @-chflags -R noschg ${DESTDIR}${KODIR} ${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO} ${DESTDIR}${KODIR} .if defined(DEBUG) && !defined(INSTALL_NODEBUG) && \ - (defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} == "yes") + (defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} != "no") ${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO}.symbols ${DESTDIR}${KODIR} .endif diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk index b50fc6833fb..36e0b9d51bf 100644 --- a/sys/conf/kmod.mk +++ b/sys/conf/kmod.mk @@ -286,8 +286,8 @@ realinstall: _kmodinstall _kmodinstall: ${INSTALL} -o ${KMODOWN} -g ${KMODGRP} -m ${KMODMODE} \ ${_INSTALLFLAGS} ${PROG} ${DESTDIR}${KMODDIR} -.if defined(DEBUG) && !defined(INSTALL_NODEBUG) && \ - (defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} == "yes") +.if defined(DEBUG_FLAGS) && !defined(INSTALL_NODEBUG) && \ + (defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} != "no") ${INSTALL} -o ${KMODOWN} -g ${KMODGRP} -m ${KMODMODE} \ ${_INSTALLFLAGS} ${PROG}.symbols ${DESTDIR}${KMODDIR} .endif From e0029a7260da2ca2acaf4481d779d05e2fd4fb80 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 23 May 2011 21:51:47 +0000 Subject: [PATCH 19/23] Add initial support for Marvell 88E8055/88E8075 Yukon Supreme. --- sys/dev/msk/if_msk.c | 23 +++++++++++++++++++---- sys/dev/msk/if_mskreg.h | 9 +++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 868a9facf36..74264daa69e 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -221,6 +221,10 @@ static struct msk_product { "Marvell Yukon 88E8071 Gigabit Ethernet" }, { VENDORID_MARVELL, DEVICEID_MRVL_436C, "Marvell Yukon 88E8072 Gigabit Ethernet" }, + { VENDORID_MARVELL, DEVICEID_MRVL_436D, + "Marvell Yukon 88E8055 Gigabit Ethernet" }, + { VENDORID_MARVELL, DEVICEID_MRVL_4370, + "Marvell Yukon 88E8075 Gigabit Ethernet" }, { VENDORID_MARVELL, DEVICEID_MRVL_4380, "Marvell Yukon 88E8057 Gigabit Ethernet" }, { VENDORID_MARVELL, DEVICEID_MRVL_4381, @@ -1366,11 +1370,16 @@ mskc_reset(struct msk_softc *sc) CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_RST_SET); CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_RST_CLR); CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_F_LOOPB_OFF); - if (sc->msk_hw_id == CHIP_ID_YUKON_EX) + if (sc->msk_hw_id == CHIP_ID_YUKON_EX || + sc->msk_hw_id == CHIP_ID_YUKON_SUPR) CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON | GMC_BYP_RETR_ON); } + + if (sc->msk_hw_id == CHIP_ID_YUKON_SUPR && + sc->msk_hw_rev > CHIP_REV_YU_SU_B0) + CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, PCI_CLK_MACSEC_DIS); if (sc->msk_hw_id == CHIP_ID_YUKON_OPT && sc->msk_hw_rev == 0) { /* Disable PCIe PHY powerdown(reg 0x80, bit7). */ CSR_WRITE_4(sc, Y2_PEX_PHY_DATA, (0x0080 << 16) | 0x0080); @@ -1719,7 +1728,6 @@ mskc_attach(device_t dev) /* Bail out if chip is not recognized. */ if (sc->msk_hw_id < CHIP_ID_YUKON_XL || sc->msk_hw_id > CHIP_ID_YUKON_OPT || - sc->msk_hw_id == CHIP_ID_YUKON_SUPR || sc->msk_hw_id == CHIP_ID_YUKON_UNKNOWN) { device_printf(dev, "unknown device: id=0x%02x, rev=0x%02x\n", sc->msk_hw_id, sc->msk_hw_rev); @@ -1826,6 +1834,11 @@ mskc_attach(device_t dev) sc->msk_clock = 156; /* 156 MHz */ sc->msk_pflags |= MSK_FLAG_JUMBO; break; + case CHIP_ID_YUKON_SUPR: + sc->msk_clock = 125; /* 125 MHz */ + sc->msk_pflags |= MSK_FLAG_JUMBO | MSK_FLAG_DESCV2 | + MSK_FLAG_AUTOTX_CSUM; + break; case CHIP_ID_YUKON_UL_2: sc->msk_clock = 125; /* 125 MHz */ sc->msk_pflags |= MSK_FLAG_JUMBO; @@ -3729,7 +3742,8 @@ msk_init_locked(struct msk_if_softc *sc_if) CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_SET); CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_CLR); CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_F_LOOPB_OFF); - if (sc->msk_hw_id == CHIP_ID_YUKON_EX) + if (sc->msk_hw_id == CHIP_ID_YUKON_EX || + sc->msk_hw_id == CHIP_ID_YUKON_SUPR) CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON | GMC_BYP_RETR_ON); @@ -3924,7 +3938,8 @@ msk_init_locked(struct msk_if_softc *sc_if) msk_stop(sc_if); return; } - if (sc->msk_hw_id == CHIP_ID_YUKON_EX) { + if (sc->msk_hw_id == CHIP_ID_YUKON_EX || + sc->msk_hw_id == CHIP_ID_YUKON_SUPR) { /* Disable flushing of non-ASF packets. */ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T), GMF_RX_MACSEC_FLUSH_OFF); diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h index 0179608d4cb..583f5e88ef8 100644 --- a/sys/dev/msk/if_mskreg.h +++ b/sys/dev/msk/if_mskreg.h @@ -144,6 +144,8 @@ #define DEVICEID_MRVL_436A 0x436A #define DEVICEID_MRVL_436B 0x436B #define DEVICEID_MRVL_436C 0x436C +#define DEVICEID_MRVL_436D 0x436D +#define DEVICEID_MRVL_4370 0x4370 #define DEVICEID_MRVL_4380 0x4380 #define DEVICEID_MRVL_4381 0x4381 @@ -321,6 +323,9 @@ #define PCI_OS_SPD_X100 2 /* PCI-X 100MHz Bus */ #define PCI_OS_SPD_X133 3 /* PCI-X 133MHz Bus */ +/* PCI_OUR_REG_3 32 bit Our Register 3 (Yukon-ECU only) */ +#define PCI_CLK_MACSEC_DIS BIT_17 /* Disable Clock MACSec. */ + /* PCI_OUR_REG_4 32 bit Our Register 4 (Yukon-ECU only) */ #define PCI_TIMER_VALUE_MSK (0xff<<16) /* Bit 23..16: Timer Value Mask */ #define PCI_FORCE_ASPM_REQUEST BIT_15 /* Force ASPM Request (A1 only) */ @@ -919,6 +924,10 @@ #define CHIP_REV_YU_EX_A0 1 /* Chip Rev. for Yukon-2 EX A0 */ #define CHIP_REV_YU_EX_B0 2 /* Chip Rev. for Yukon-2 EX B0 */ +#define CHIP_REV_YU_SU_A0 0 /* Chip Rev. for Yukon-2 SUPR A0 */ +#define CHIP_REV_YU_SU_B0 1 /* Chip Rev. for Yukon-2 SUPR B0 */ +#define CHIP_REV_YU_SU_B1 3 /* Chip Rev. for Yukon-2 SUPR B1 */ + /* B2_Y2_CLK_GATE 8 bit Clock Gating (Yukon-2 only) */ #define Y2_STATUS_LNK2_INAC BIT_7 /* Status Link 2 inactiv (0 = activ) */ #define Y2_CLK_GAT_LNK2_DIS BIT_6 /* Disable clock gating Link 2 */ From 8be664b8b7de21140755e3cf3cbdba94a7246494 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 23 May 2011 21:56:04 +0000 Subject: [PATCH 20/23] When MTU is changed, check whether driver should be reinitialized or not. If reinitialized is required, clear driver running flag. --- sys/dev/msk/if_msk.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 74264daa69e..2adbf1cb2c7 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -1034,7 +1034,10 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } } ifp->if_mtu = ifr->ifr_mtu; - msk_init_locked(sc_if); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + msk_init_locked(sc_if); + } } MSK_IF_UNLOCK(sc_if); break; From e7b49f6068bb73e55f7c57c59be93bde52c32e20 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 23 May 2011 22:02:15 +0000 Subject: [PATCH 21/23] Add 88E8075 Yukon Supreme to the list of supported hardware list. --- share/man/man4/msk.4 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/share/man/man4/msk.4 b/share/man/man4/msk.4 index fe32a68a422..200c6f7f3e5 100644 --- a/share/man/man4/msk.4 +++ b/share/man/man4/msk.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 23, 2010 +.Dd May 23, 2011 .Dt MSK 4 .Os .Sh NAME @@ -195,6 +195,8 @@ Marvell Yukon 88E8071 Gigabit Ethernet .It Marvell Yukon 88E8072 Gigabit Ethernet .It +Marvell Yukon 88E8075 Gigabit Ethernet +.It SysKonnect SK-9Sxx Gigabit Ethernet .It SysKonnect SK-9Exx Gigabit Ethernet From 484c842d57529159f014f94f2a544cebc7d6e123 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Mon, 23 May 2011 22:31:42 +0000 Subject: [PATCH 22/23] Set the MNT_NFS4ACLS flag for an NFSv4 client mount if the NFSv4 server supports it. Requested by trasz. MFC after: 2 weeks --- sys/fs/nfsclient/nfs_clvfsops.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 8dc5b0b4b0f..84725dde0e1 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -79,6 +79,7 @@ FEATURE(nfscl, "NFSv4 client"); extern int nfscl_ticks; extern struct timeval nfsboottime; extern struct nfsstats newnfsstats; +extern int nfsrv_useacl; MALLOC_DEFINE(M_NEWNFSREQ, "newnfsclient_req", "New NFS request header"); MALLOC_DEFINE(M_NEWNFSMNT, "newnfsmnt", "New NFS mount struct"); @@ -1331,6 +1332,15 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, if (argp->flags & NFSMNT_NFSV3) ncl_fsinfo(nmp, *vpp, cred, td); + /* Mark if the mount point supports NFSv4 ACLs. */ + if ((argp->flags & NFSMNT_NFSV4) != 0 && nfsrv_useacl != 0 && + ret == 0 && + NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL)) { + MNT_ILOCK(mp); + mp->mnt_flag |= MNT_NFS4ACLS; + MNT_IUNLOCK(mp); + } + /* * Lose the lock but keep the ref. */ From f7a10dcfe0f98f117b8bbbf2923db660259e3ffa Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Mon, 23 May 2011 23:35:50 +0000 Subject: [PATCH 23/23] Merge r221846 from largeSMP project branch: Fix arguments passing to _long() version of atomic function for mips. The native implementation is bogus in that regard and offers the same problem solved for powerpc as r222198, but mips' guys just wanted a small and self-contained patch for mips rather than rewriting the whole support. Reviewed by: art, imp Tested by: gonzo MFC after: 2 weeks --- sys/mips/include/atomic.h | 61 ++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/sys/mips/include/atomic.h b/sys/mips/include/atomic.h index 7b4a82cb06a..9a0c557ee08 100644 --- a/sys/mips/include/atomic.h +++ b/sys/mips/include/atomic.h @@ -581,32 +581,47 @@ atomic_fetchadd_64(__volatile uint64_t *p, uint64_t v) #else /* !__mips_n64 */ /* Operations on longs. */ -#define atomic_set_long atomic_set_32 -#define atomic_set_acq_long atomic_set_acq_32 -#define atomic_set_rel_long atomic_set_rel_32 -#define atomic_clear_long atomic_clear_32 -#define atomic_clear_acq_long atomic_clear_acq_32 -#define atomic_clear_rel_long atomic_clear_rel_32 -#define atomic_add_long(p, v) \ +#define atomic_set_long(p, v) \ + atomic_set_32((volatile u_int *)(p), (u_int)(v)) +#define atomic_set_acq_long(p, v) \ + atomic_set_acq_32((volatile u_int *)(p), (u_int)(v)) +#define atomic_set_rel_long(p, v) \ + atomic_set_rel_32((volatile u_int *)(p), (u_int)(v)) +#define atomic_clear_long(p, v) \ + atomic_clear_32((volatile u_int *)(p), (u_int)(v)) +#define atomic_clear_acq_long(p, v) \ + atomic_clear_acq_32((volatile u_int *)(p), (u_int)(v)) +#define atomic_clear_rel_long(p, v) \ + atomic_clear_rel_32((volatile u_int *)(p), (u_int)(v)) +#define atomic_add_long(p, v) \ atomic_add_32((volatile u_int *)(p), (u_int)(v)) -#define atomic_add_acq_long atomic_add_acq_32 -#define atomic_add_rel_long atomic_add_rel_32 -#define atomic_subtract_long(p, v) \ +#define atomic_add_acq_long(p, v) \ + atomic_add_32((volatile u_int *)(p), (u_int)(v)) +#define atomic_add_rel_long(p, v) \ + atomic_add_32((volatile u_int *)(p), (u_int)(v)) +#define atomic_subtract_long(p, v) \ atomic_subtract_32((volatile u_int *)(p), (u_int)(v)) -#define atomic_subtract_acq_long atomic_subtract_acq_32 -#define atomic_subtract_rel_long atomic_subtract_rel_32 -#define atomic_cmpset_long atomic_cmpset_32 -#define atomic_cmpset_acq_long(p, cmpval, newval) \ - atomic_cmpset_acq_32((volatile u_int *)(p), \ - (u_int)(cmpval), (u_int)(newval)) -#define atomic_cmpset_rel_long(p, cmpval, newval) \ - atomic_cmpset_rel_32((volatile u_int *)(p), \ - (u_int)(cmpval), (u_int)(newval)) -#define atomic_load_acq_long atomic_load_acq_32 -#define atomic_store_rel_long atomic_store_rel_32 -#define atomic_fetchadd_long(p, v) \ +#define atomic_subtract_acq_long(p, v) \ + atomic_subtract_acq_32((volatile u_int *)(p), (u_int)(v)) +#define atomic_subtract_rel_long(p, v) \ + atomic_subtract_rel_32((volatile u_int *)(p), (u_int)(v)) +#define atomic_cmpset_long(p, cmpval, newval) \ + atomic_cmpset_32((volatile u_int *)(p), (u_int)(cmpval), \ + (u_int)(newval)) +#define atomic_cmpset_acq_long(p, cmpval, newval) \ + atomic_cmpset_acq_32((volatile u_int *)(p), (u_int)(cmpval), \ + (u_int)(newval)) +#define atomic_cmpset_rel_long(p, cmpval, newval) \ + atomic_cmpset_rel_32((volatile u_int *)(p), (u_int)(cmpval), \ + (u_int)(newval)) +#define atomic_load_acq_long(p) \ + (u_long)atomic_load_acq_32((volatile u_int *)(p)) +#define atomic_store_rel_long(p, v) \ + atomic_store_rel_32((volatile u_int *)(p), (u_int)(v)) +#define atomic_fetchadd_long(p, v) \ atomic_fetchadd_32((volatile u_int *)(p), (u_int)(v)) -#define atomic_readandclear_long atomic_readandclear_32 +#define atomic_readandclear_long(p) \ + atomic_readandclear_32((volatile u_int *)(p)) #endif /* __mips_n64 */