From 92c1a61163ff6a0655b27bd429856e171e7ce5f5 Mon Sep 17 00:00:00 2001 From: Bryan Cantrill Date: Mon, 4 Feb 2019 21:36:58 +0000 Subject: 10468 __ctype_mask[EOF] has been working by accident 10469 GCC's -faggressive-loop-optimizations is too aggressive 10470 array over-read in has_saved_fp() Reviewed by: Robert Mustacchi Reviewed by: John Levon Reviewed by: Toomas Soome Reviewed by: Igor Kozhukhov Reviewed by: Andy Fiddaman Reviewed by: Gergő Doma Reviewed by: Gary Mills Approved by: Richard Lowe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- usr/src/Makefile.master | 13 +++++++++++ usr/src/lib/libc/port/locale/table.c | 38 ++++++++++++++++++-------------- usr/src/lib/libsaveargs/Makefile.com | 5 +---- usr/src/lib/libsaveargs/amd64/saveargs.c | 9 +++++--- usr/src/uts/Makefile.uts | 1 + 5 files changed, 42 insertions(+), 24 deletions(-) diff --git a/usr/src/Makefile.master b/usr/src/Makefile.master index 501853a6ed..5321004bff 100644 --- a/usr/src/Makefile.master +++ b/usr/src/Makefile.master @@ -372,6 +372,17 @@ CCNOREORDER= \ -_gcc7=-fno-reorder-functions \ -_gcc8=-fno-reorder-functions +# +# gcc has a rather aggressive optimization on by default that infers loop +# bounds based on undefined behavior (!!). This can lead to some VERY +# surprising optimizations -- ones that may be technically correct in the +# strictest sense but also result in incorrect program behavior. We turn +# this optimization off, with extreme prejudice. +# +CCNOAGGRESSIVELOOPS= \ + -_gcc7=-fno-aggressive-loop-optimizations \ + -_gcc8=-fno-aggressive-loop-optimizations + # One optimization the compiler might perform is to turn this: # #pragma weak foo # extern int foo; @@ -601,10 +612,12 @@ $(SRCDBGBLD)CCSOURCEDEBUGFLAGS = $(CCGDEBUG) -xs CFLAGS= $(COPTFLAG) $($(MACH)_CFLAGS) $(SPACEFLAG) $(CCMODE) \ $(ILDOFF) $(CERRWARN) $(CSTD) $(CCUNBOUND) $(IROPTFLAG) \ $(CGLOBALSTATIC) $(CCNOAUTOINLINE) $(CCNOREORDER) \ + $(CCNOAGGRESSIVELOOPS) \ $(CSOURCEDEBUGFLAGS) $(CUSERFLAGS) CFLAGS64= $(COPTFLAG64) $($(MACH64)_CFLAGS) $(SPACEFLAG64) $(CCMODE64) \ $(ILDOFF) $(CERRWARN) $(CSTD) $(CCUNBOUND) $(IROPTFLAG64) \ $(CGLOBALSTATIC) $(CCNOAUTOINLINE) $(CCNOREORDER) \ + $(CCNOAGGRESSIVELOOPS) \ $(CSOURCEDEBUGFLAGS) $(CUSERFLAGS64) # # Flags that are used to build parts of the code that are subsequently diff --git a/usr/src/lib/libc/port/locale/table.c b/usr/src/lib/libc/port/locale/table.c index 3c0ce09901..0ccb3d9292 100644 --- a/usr/src/lib/libc/port/locale/table.c +++ b/usr/src/lib/libc/port/locale/table.c @@ -1,6 +1,7 @@ /* * Copyright 2013 Garrett D'Amore * Copyright 2017 Nexenta Systems, Inc. + * Copyright 2019 Joyent, Inc. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * @@ -39,7 +40,7 @@ #include "mblocal.h" #include "_ctype.h" -#define _DEFRUNETYPE { \ +#define _DEFRUNETYPE \ /* 00 */ \ _CTYPE_C, \ _CTYPE_C, \ @@ -183,10 +184,9 @@ _CTYPE_P|_CTYPE_R|_CTYPE_G, \ _CTYPE_P|_CTYPE_R|_CTYPE_G, \ _CTYPE_P|_CTYPE_R|_CTYPE_G, \ - _CTYPE_C, \ -} + _CTYPE_C -#define _DEFMAPLOWER { \ +#define _DEFMAPLOWER \ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, \ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, \ @@ -218,10 +218,9 @@ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, \ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, \ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, \ - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, \ -} + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -#define _DEFMAPUPPER { \ +#define _DEFMAPUPPER \ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, \ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, \ @@ -253,27 +252,32 @@ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, \ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, \ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, \ - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, \ -} + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, _RuneLocale _DefaultRuneLocale = { _RUNE_MAGIC_1, "NONE", - _DEFRUNETYPE, - _DEFMAPLOWER, - _DEFMAPUPPER, + { _DEFRUNETYPE }, + { _DEFMAPLOWER }, + { _DEFMAPUPPER }, }; /* * __ctype_mask, __trans_lower, and __trans_upper come from former _ctype.c and * have to stay pointers for binary compatibility, so we provide separate - * storage for them, initialized to "C" locale contents by default. + * storage for them, initialized to "C" locale contents by default. Note that + * legacy code may dereference __ctype_mask[-1] when checking against EOF, + * relying on that value to be 0. To allow this, ___ctype_mask is expanded by + * one value and prepended with a leading 0, with __ctype_mask being set to + * point to ___ctype_mask[1]. (__trans_lower and __trans_upper do not suffer + * from this as EOF access was prevented in legacy code by a check against + * isascii(), which always returned 0 for EOF.) */ -static unsigned int ___ctype_mask[_CACHED_RUNES] = _DEFRUNETYPE; -unsigned int *__ctype_mask = ___ctype_mask; +static unsigned int ___ctype_mask[_CACHED_RUNES + 1] = { 0, _DEFRUNETYPE }; +unsigned int *__ctype_mask = &___ctype_mask[1]; -static int ___trans_lower[_CACHED_RUNES] = _DEFMAPLOWER; +static int ___trans_lower[_CACHED_RUNES] = { _DEFMAPLOWER }; int *__trans_lower = ___trans_lower; -static int ___trans_upper[_CACHED_RUNES] = _DEFMAPUPPER; +static int ___trans_upper[_CACHED_RUNES] = { _DEFMAPUPPER }; int *__trans_upper = ___trans_upper; diff --git a/usr/src/lib/libsaveargs/Makefile.com b/usr/src/lib/libsaveargs/Makefile.com index 94d80c1d5b..883afb66c9 100644 --- a/usr/src/lib/libsaveargs/Makefile.com +++ b/usr/src/lib/libsaveargs/Makefile.com @@ -22,7 +22,7 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# Copyright (c) 2018, Joyent, Inc. +# Copyright (c) 2019, Joyent, Inc. # # The build process for libsaveargs is sightly different from that used by other @@ -95,9 +95,6 @@ CFLAGS += $(CFLAGS_$(CURTYPE)) $(CFLAGS_common) CFLAGS64_standalone = $(STAND_FLAGS_64) CFLAGS64 += $(CCVERBOSE) $(CFLAGS64_$(CURTYPE)) $(CFLAGS64_common) -# not linted -SMATCH=off - DYNFLAGS += $(ZINTERPOSE) .KEEP_STATE: diff --git a/usr/src/lib/libsaveargs/amd64/saveargs.c b/usr/src/lib/libsaveargs/amd64/saveargs.c index f07ef354c1..6d3ed769f2 100644 --- a/usr/src/lib/libsaveargs/amd64/saveargs.c +++ b/usr/src/lib/libsaveargs/amd64/saveargs.c @@ -23,6 +23,9 @@ * Use is subject to license terms. */ +/* + * Copyright 2019 Joyent, Inc. + */ /* * The Sun Studio and GCC (patched for opensolaris/illumos) compilers @@ -217,7 +220,7 @@ instr_size(dis_handle_t *dhp, uint8_t *ins, unsigned int i, size_t size) static boolean_t has_saved_fp(dis_handle_t *dhp, uint8_t *ins, int size) { - int i, j; + int i, j; uint32_t n; boolean_t found_push = B_FALSE; ssize_t sz = 0; @@ -231,7 +234,7 @@ has_saved_fp(dis_handle_t *dhp, uint8_t *ins, int size) continue; n = INSTR1(ins, i); - for (j = 0; j <= NUM_FP_PUSHES; j++) + for (j = 0; j < NUM_FP_PUSHES; j++) if (save_fp_pushes[j] == n) { found_push = B_TRUE; break; @@ -240,7 +243,7 @@ has_saved_fp(dis_handle_t *dhp, uint8_t *ins, int size) if (sz != 3) continue; n = INSTR3(ins, i); - for (j = 0; j <= NUM_FP_MOVS; j++) + for (j = 0; j < NUM_FP_MOVS; j++) if (save_fp_movs[j] == n) return (B_TRUE); } diff --git a/usr/src/uts/Makefile.uts b/usr/src/uts/Makefile.uts index 8f341807e1..73f9e80f99 100644 --- a/usr/src/uts/Makefile.uts +++ b/usr/src/uts/Makefile.uts @@ -247,6 +247,7 @@ CFLAGS_uts += $(CTF_FLAGS_$(CLASS)) CFLAGS_uts += $(CERRWARN) CFLAGS_uts += $(CCNOAUTOINLINE) CFLAGS_uts += $(CCNOREORDER) +CFLAGS_uts += $(CCNOAGGRESSIVELOOPS) CFLAGS_uts += $(CGLOBALSTATIC) CFLAGS_uts += $(EXTRA_CFLAGS) CFLAGS_uts += $(CSOURCEDEBUGFLAGS) -- cgit v1.2.3 From 736e6700391d17ab1494985a80076fc185722699 Mon Sep 17 00:00:00 2001 From: Jason King Date: Wed, 27 Feb 2019 20:56:49 -0600 Subject: 10473 zfs(1M) missing cross-reference to zfs-program(1M) Reviewed by: Toomas Soome Reviewed by: Andy Fiddaman Reviewed by: Peter Tribble Reviewed by: Gergő Mihály Doma Approved by: Dan McDonald MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- usr/src/man/man1m/zfs.1m | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/usr/src/man/man1m/zfs.1m b/usr/src/man/man1m/zfs.1m index 0c07d36141..806cd8c838 100644 --- a/usr/src/man/man1m/zfs.1m +++ b/usr/src/man/man1m/zfs.1m @@ -23,14 +23,13 @@ .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2016 by Delphix. All rights reserved. .\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved. -.\" Copyright (c) 2014, Joyent, Inc. All rights reserved. .\" Copyright (c) 2014 by Adam Stevko. All rights reserved. .\" Copyright (c) 2014 Integros [integros.com] .\" Copyright 2018 Nexenta Systems, Inc. -.\" Copyright 2018 Joyent, Inc. +.\" Copyright 2019 Joyent, Inc. .\" Copyright (c) 2018 Datto Inc. .\" -.Dd Jan 05, 2019 +.Dd February 26, 2019 .Dt ZFS 1M .Os .Sh NAME @@ -3496,6 +3495,7 @@ Channel programs may only be run with root privileges. .sp For full documentation of the ZFS channel program interface, see the manual page for +.Xr zfs-program 1M . .Bl -tag -width "" .It Fl j Display channel program output in JSON format. @@ -3921,6 +3921,7 @@ M F /tank/test/modified .Xr share 1M , .Xr sharemgr 1M , .Xr unshare 1M , +.Xr zfs-program 1M , .Xr zonecfg 1M , .Xr zpool 1M , .Xr chmod 2 , -- cgit v1.2.3 From a40552eda738f8ee0c3efd672257d52bfb3e8893 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Tue, 26 Feb 2019 13:38:43 +0200 Subject: 10456 libstand: arp.c cstyle cleanup Reviewed by: C Fraire Reviewed by: Andy Fiddaman Reviewed by: Gergő Doma Approved by: Dan McDonald MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- usr/src/boot/lib/libstand/arp.c | 67 +++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/usr/src/boot/lib/libstand/arp.c b/usr/src/boot/lib/libstand/arp.c index 65e421d1bb..4280b90575 100644 --- a/usr/src/boot/lib/libstand/arp.c +++ b/usr/src/boot/lib/libstand/arp.c @@ -51,11 +51,11 @@ #include "net.h" /* Cache stuff */ -#define ARP_NUM 8 /* need at most 3 arp entries */ +#define ARP_NUM 8 /* need at most 3 arp entries */ struct arp_list { struct in_addr addr; - u_char ea[6]; + uchar_t ea[6]; } arp_list[ARP_NUM] = { /* XXX - net order `INADDR_BROADCAST' must be a constant */ { {0xffffffff}, BA } @@ -67,7 +67,7 @@ static ssize_t arpsend(struct iodesc *, void *, size_t); static ssize_t arprecv(struct iodesc *, void **, void **, time_t, void *); /* Broadcast an ARP packet, asking who has addr on interface d */ -u_char * +uchar_t * arpwhohas(struct iodesc *d, struct in_addr addr) { int i; @@ -78,7 +78,7 @@ arpwhohas(struct iodesc *d, struct in_addr addr) struct ether_header eh; struct { struct ether_arp arp; - u_char pad[18]; /* 60 - sizeof(...) */ + uchar_t pad[18]; /* 60 - sizeof (...) */ } data; } wbuf; @@ -94,21 +94,21 @@ arpwhohas(struct iodesc *d, struct in_addr addr) } #ifdef ARP_DEBUG - if (debug) - printf("arpwhohas: send request for %s\n", inet_ntoa(addr)); + if (debug) + printf("arpwhohas: send request for %s\n", inet_ntoa(addr)); #endif - bzero((char*)&wbuf.data, sizeof(wbuf.data)); + bzero((char *)&wbuf.data, sizeof (wbuf.data)); ah = &wbuf.data.arp; ah->arp_hrd = htons(ARPHRD_ETHER); ah->arp_pro = htons(ETHERTYPE_IP); - ah->arp_hln = sizeof(ah->arp_sha); /* hardware address length */ - ah->arp_pln = sizeof(ah->arp_spa); /* protocol address length */ + ah->arp_hln = sizeof (ah->arp_sha); /* hardware address length */ + ah->arp_pln = sizeof (ah->arp_spa); /* protocol address length */ ah->arp_op = htons(ARPOP_REQUEST); MACPY(d->myea, ah->arp_sha); - bcopy(&d->myip, ah->arp_spa, sizeof(ah->arp_spa)); + bcopy(&d->myip, ah->arp_spa, sizeof (ah->arp_spa)); /* Leave zeros in arp_tha */ - bcopy(&addr, ah->arp_tpa, sizeof(ah->arp_tpa)); + bcopy(&addr, ah->arp_tpa, sizeof (ah->arp_tpa)); /* Store ip address in cache (incomplete entry). */ al->addr = addr; @@ -116,16 +116,15 @@ arpwhohas(struct iodesc *d, struct in_addr addr) pkt = NULL; ah = NULL; i = sendrecv(d, - arpsend, &wbuf.data, sizeof(wbuf.data), + arpsend, &wbuf.data, sizeof (wbuf.data), arprecv, &pkt, (void **)&ah, NULL); if (i == -1) { - panic("arp: no response for %s\n", - inet_ntoa(addr)); + panic("arp: no response for %s\n", inet_ntoa(addr)); } /* Store ethernet address in cache */ #ifdef ARP_DEBUG - if (debug) { + if (debug) { struct ether_header *eh; eh = (struct ether_header *)((uintptr_t)pkt + ETHER_ALIGN); @@ -146,7 +145,7 @@ arpsend(struct iodesc *d, void *pkt, size_t len) { #ifdef ARP_DEBUG - if (debug) + if (debug) printf("arpsend: called\n"); #endif @@ -162,18 +161,18 @@ arprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *extra) { ssize_t n; struct ether_arp *ah; - u_int16_t etype; /* host order */ + uint16_t etype; /* host order */ void *ptr; #ifdef ARP_DEBUG - if (debug) + if (debug) printf("arprecv: "); #endif ptr = NULL; n = readether(d, &ptr, (void **)&ah, tleft, &etype); errno = 0; /* XXX */ - if (n == -1 || n < sizeof(struct ether_arp)) { + if (n == -1 || n < sizeof (struct ether_arp)) { #ifdef ARP_DEBUG if (debug) printf("bad len=%d\n", n); @@ -194,9 +193,8 @@ arprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *extra) /* Ethernet address now checked in readether() */ if (ah->arp_hrd != htons(ARPHRD_ETHER) || ah->arp_pro != htons(ETHERTYPE_IP) || - ah->arp_hln != sizeof(ah->arp_sha) || - ah->arp_pln != sizeof(ah->arp_spa) ) - { + ah->arp_hln != sizeof (ah->arp_sha) || + ah->arp_pln != sizeof (ah->arp_spa)) { #ifdef ARP_DEBUG if (debug) printf("bad hrd/pro/hln/pln\n"); @@ -225,9 +223,7 @@ arprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *extra) } /* Is the reply from the source we want? */ - if (bcmp(&arp_list[arp_num].addr, - ah->arp_spa, sizeof(ah->arp_spa))) - { + if (bcmp(&arp_list[arp_num].addr, ah->arp_spa, sizeof (ah->arp_spa))) { #ifdef ARP_DEBUG if (debug) printf("unwanted address\n"); @@ -239,7 +235,7 @@ arprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *extra) /* We have our answer. */ #ifdef ARP_DEBUG - if (debug) + if (debug) printf("got it\n"); #endif *pkt = ptr; @@ -258,9 +254,8 @@ arp_reply(struct iodesc *d, void *pkt) if (arp->arp_hrd != htons(ARPHRD_ETHER) || arp->arp_pro != htons(ETHERTYPE_IP) || - arp->arp_hln != sizeof(arp->arp_sha) || - arp->arp_pln != sizeof(arp->arp_spa) ) - { + arp->arp_hln != sizeof (arp->arp_sha) || + arp->arp_pln != sizeof (arp->arp_spa)) { #ifdef ARP_DEBUG if (debug) printf("arp_reply: bad hrd/pro/hln/pln\n"); @@ -277,7 +272,7 @@ arp_reply(struct iodesc *d, void *pkt) } /* If we are not the target, ignore the request. */ - if (bcmp(arp->arp_tpa, &d->myip, sizeof(arp->arp_tpa))) + if (bcmp(arp->arp_tpa, &d->myip, sizeof (arp->arp_tpa))) return; #ifdef ARP_DEBUG @@ -288,16 +283,16 @@ arp_reply(struct iodesc *d, void *pkt) arp->arp_op = htons(ARPOP_REPLY); /* source becomes target */ - bcopy(arp->arp_sha, arp->arp_tha, sizeof(arp->arp_tha)); - bcopy(arp->arp_spa, arp->arp_tpa, sizeof(arp->arp_tpa)); + bcopy(arp->arp_sha, arp->arp_tha, sizeof (arp->arp_tha)); + bcopy(arp->arp_spa, arp->arp_tpa, sizeof (arp->arp_tpa)); /* here becomes source */ - bcopy(d->myea, arp->arp_sha, sizeof(arp->arp_sha)); - bcopy(&d->myip, arp->arp_spa, sizeof(arp->arp_spa)); + bcopy(d->myea, arp->arp_sha, sizeof (arp->arp_sha)); + bcopy(&d->myip, arp->arp_spa, sizeof (arp->arp_spa)); /* * No need to get fancy here. If the send fails, the * requestor will just ask again. */ - (void) sendether(d, pkt, sizeof(*arp) + 18, - arp->arp_tha, ETHERTYPE_ARP); + (void) sendether(d, pkt, sizeof (*arp) + 18, + arp->arp_tha, ETHERTYPE_ARP); } -- cgit v1.2.3 From 3733333274b54097fa204d12dc30b5b6066d05bb Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Tue, 26 Feb 2019 15:07:27 +0200 Subject: 10458 libstand: assert.c cstyle cleanup Reviewed by: Andy Fiddaman Reviewed by: Gergő Doma Approved by: Dan McDonald MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- usr/src/boot/lib/libstand/assert.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/usr/src/boot/lib/libstand/assert.c b/usr/src/boot/lib/libstand/assert.c index 8eec63a472..bfc1933dea 100644 --- a/usr/src/boot/lib/libstand/assert.c +++ b/usr/src/boot/lib/libstand/assert.c @@ -1,4 +1,4 @@ -/*- +/* * Copyright (c) 1998 Michael Smith. * All rights reserved. * @@ -25,7 +25,6 @@ */ #include -__FBSDID("$FreeBSD$"); #include -- cgit v1.2.3 From f6760972b5c27d37b896ac15627645717ee70ddf Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Tue, 26 Feb 2019 15:53:51 +0200 Subject: 10460 loader: tem.c cstyle cleanup Reviewed by: Gergő Doma Reviewed by: Andy Fiddaman Approved by: Dan McDonald MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- usr/src/boot/sys/boot/common/tem.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/usr/src/boot/sys/boot/common/tem.c b/usr/src/boot/sys/boot/common/tem.c index 1bff41718e..f06733fb78 100644 --- a/usr/src/boot/sys/boot/common/tem.c +++ b/usr/src/boot/sys/boot/common/tem.c @@ -428,7 +428,7 @@ env_screen_nounset(struct env_var *ev __unused) if (tems.ts_p_dimension.width == 0 && tems.ts_p_dimension.height == 0) return (0); - return(EPERM); + return (EPERM); } static void @@ -516,7 +516,8 @@ tems_setup_terminal(struct vis_devinit *tp, size_t height, size_t width) malloc(font_data->uncompressed_size); if (tems.ts_font.vf_bytes == NULL) panic("out of memory\n"); - (void)lz4_decompress(font_data->compressed_data, + (void) lz4_decompress( + font_data->compressed_data, tems.ts_font.vf_bytes, font_data->compressed_size, font_data->uncompressed_size, 0); @@ -696,9 +697,10 @@ tems_cursor(struct vis_conscursor *pca) static void tem_kdsetmode(int mode) { - if (tems.ts_hdl != NULL) + if (tems.ts_hdl != NULL) { (void) tems.ts_hdl->c_ioctl(tems.ts_hdl, KDSETMODE, - (void *)(intptr_t)mode); + (void *)(intptr_t)mode); + } } static void @@ -2392,7 +2394,7 @@ tem_cls(struct tem_vt_state *tem) bg_color = DEFAULT_ANSI_BACKGROUND; tem_get_color(&fg_color, &bg_color, c); cl.bg_color = bg_color; - (void)tems_cls(&cl); + (void) tems_cls(&cl); tem->tvs_c_cursor.row = 0; tem->tvs_c_cursor.col = 0; -- cgit v1.2.3 From 3ae1c8196586c672e19cabdeaf43e82e5b5dc7f5 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Tue, 26 Feb 2019 19:18:31 +0200 Subject: 10464 loader: biosdisk.c cstyle cleanup Reviewed by: Rob Johnston Reviewed by: Andy Fiddaman Approved by: Dan McDonald --- usr/src/boot/sys/boot/i386/libi386/biosdisk.c | 46 +++++++++++++-------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/usr/src/boot/sys/boot/i386/libi386/biosdisk.c b/usr/src/boot/sys/boot/i386/libi386/biosdisk.c index 608310f97d..b8fea9592a 100644 --- a/usr/src/boot/sys/boot/i386/libi386/biosdisk.c +++ b/usr/src/boot/sys/boot/i386/libi386/biosdisk.c @@ -131,7 +131,7 @@ static int bd_realstrategy(void *devdata, int flag, daddr_t dblk, size_t size, char *buf, size_t *rsize); static int bd_open(struct open_file *f, ...); static int bd_close(struct open_file *f); -static int bd_ioctl(struct open_file *f, u_long cmd, void *data); +static int bd_ioctl(struct open_file *f, ulong_t cmd, void *data); static int bd_print(int verbose); static int cd_print(int verbose); static int fd_print(int verbose); @@ -363,29 +363,29 @@ bc_add(int biosdev) int nbcinfo = 0; if (!STAILQ_EMPTY(&cdinfo)) - return (-1); - - v86.ctl = V86_FLAGS; - v86.addr = 0x13; - v86.eax = 0x4b01; - v86.edx = biosdev; - v86.ds = VTOPSEG(&bc_sp); - v86.esi = VTOPOFF(&bc_sp); - v86int(); - if ((v86.eax & 0xff00) != 0) - return (-1); + return (-1); + + v86.ctl = V86_FLAGS; + v86.addr = 0x13; + v86.eax = 0x4b01; + v86.edx = biosdev; + v86.ds = VTOPSEG(&bc_sp); + v86.esi = VTOPOFF(&bc_sp); + v86int(); + if ((v86.eax & 0xff00) != 0) + return (-1); if ((bd = calloc(1, sizeof (*bd))) == NULL) return (-1); bd->bd_flags = BD_CDROM; - bd->bd_unit = biosdev; + bd->bd_unit = biosdev; /* * Ignore result from bd_int13probe(), we will use local * workaround below. */ - (void)bd_int13probe(bd); + (void) bd_int13probe(bd); if (bd->bd_cyl == 0) { bd->bd_cyl = ((bc_sp.sp_cylsec & 0xc0) << 2) + @@ -403,10 +403,10 @@ bc_add(int biosdev) bd->bd_sectors = 4173824; STAILQ_INSERT_TAIL(&cdinfo, bd, bd_link); - printf("BIOS CD is cd%d\n", nbcinfo); - nbcinfo++; - bcache_add_dev(nbcinfo); /* register cd device in bcache */ - return(0); + printf("BIOS CD is cd%d\n", nbcinfo); + nbcinfo++; + bcache_add_dev(nbcinfo); /* register cd device in bcache */ + return (0); } /* @@ -789,7 +789,7 @@ bd_open(struct open_file *f, ...) return (EIO); } if (bd->bd_bcache == NULL) - bd->bd_bcache = bcache_allocate(); + bd->bd_bcache = bcache_allocate(); if (bd->bd_open == 0) bd->bd_sectors = bd_disk_get_sectors(dev); @@ -824,8 +824,8 @@ bd_close(struct open_file *f) bd->bd_open--; if (bd->bd_open == 0) { - bcache_free(bd->bd_bcache); - bd->bd_bcache = NULL; + bcache_free(bd->bd_bcache); + bd->bd_bcache = NULL; } if (dev->dd.d_dev->dv_type == DEVT_DISK) rc = disk_close(dev); @@ -833,7 +833,7 @@ bd_close(struct open_file *f) } static int -bd_ioctl(struct open_file *f, u_long cmd, void *data) +bd_ioctl(struct open_file *f, ulong_t cmd, void *data) { bdinfo_t *bd; struct disk_devdesc *dev; @@ -1298,7 +1298,7 @@ bd_getdev(struct i386_devdesc *d) * we pass -C to the boot args if we are the boot device. */ major = ACDMAJOR; - unit = 0; /* XXX */ + unit = 0; /* XXX */ } /* XXX a better kludge to set the root disk unit number */ -- cgit v1.2.3 From 573f5931ffa70de78fc2317b82e36d6344cf6c3c Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Tue, 26 Feb 2019 15:21:04 +0200 Subject: 10459 libstand: stand.h cstyle cleanup Reviewed by: Andy Fiddaman Reviewed by: Gergő Doma Approved by: Dan McDonald MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- usr/src/boot/lib/libstand/stand.h | 196 ++++++++++++++++++++------------------ 1 file changed, 101 insertions(+), 95 deletions(-) diff --git a/usr/src/boot/lib/libstand/stand.h b/usr/src/boot/lib/libstand/stand.h index b2cdcc18e0..1fa3055844 100644 --- a/usr/src/boot/lib/libstand/stand.h +++ b/usr/src/boot/lib/libstand/stand.h @@ -69,11 +69,14 @@ /* this header intentionally exports NULL from */ #include -#define CHK(fmt, args...) printf("%s(%d): " fmt "\n", __func__, __LINE__ , ##args) -#define PCHK(fmt, args...) {printf("%s(%d): " fmt "\n", __func__, __LINE__ , ##args); getchar();} +#define CHK(fmt, args...) \ + printf("%s(%d): " fmt "\n", __func__, __LINE__, ##args) +#define PCHK(fmt, args...) {\ + printf("%s(%d): " fmt "\n", __func__, __LINE__, ##args); getchar();\ +} /* Avoid unwanted userlandish components */ -#define _KERNEL +#define _KERNEL #include #undef _KERNEL @@ -81,7 +84,7 @@ #define EADAPT (ELAST+1) /* bad adaptor */ #define ECTLR (ELAST+2) /* bad controller */ #define EUNIT (ELAST+3) /* bad unit */ -#define ESLICE (ELAST+4) /* bad slice */ +#define ESLICE (ELAST+4) /* bad slice */ #define EPART (ELAST+5) /* bad partition */ #define ERDLAB (ELAST+6) /* can't read disk label */ #define EUNLAB (ELAST+7) /* unlabeled disk */ @@ -99,16 +102,16 @@ struct open_file; * filesystems that they require. */ struct fs_ops { - const char *fs_name; - int (*fo_open)(const char *path, struct open_file *f); - int (*fo_close)(struct open_file *f); - int (*fo_read)(struct open_file *f, void *buf, - size_t size, size_t *resid); - int (*fo_write)(struct open_file *f, const void *buf, - size_t size, size_t *resid); - off_t (*fo_seek)(struct open_file *f, off_t offset, int where); - int (*fo_stat)(struct open_file *f, struct stat *sb); - int (*fo_readdir)(struct open_file *f, struct dirent *d); + const char *fs_name; + int (*fo_open)(const char *path, struct open_file *f); + int (*fo_close)(struct open_file *f); + int (*fo_read)(struct open_file *f, void *buf, + size_t size, size_t *resid); + int (*fo_write)(struct open_file *f, const void *buf, + size_t size, size_t *resid); + off_t (*fo_seek)(struct open_file *f, off_t offset, int where); + int (*fo_stat)(struct open_file *f, struct stat *sb); + int (*fo_readdir)(struct open_file *f, struct dirent *d); }; /* @@ -135,22 +138,22 @@ extern struct fs_ops pkgfs_fsops; * Device switch */ struct devsw { - const char dv_name[8]; - int dv_type; /* opaque type constant, arch-dependant */ + const char dv_name[8]; + int dv_type; /* opaque type constant, arch-dependant */ #define DEVT_NONE 0 #define DEVT_DISK 1 #define DEVT_NET 2 #define DEVT_CD 3 #define DEVT_ZFS 4 #define DEVT_FD 5 - int (*dv_init)(void); /* early probe call */ - int (*dv_strategy)(void *devdata, int rw, daddr_t blk, + int (*dv_init)(void); /* early probe call */ + int (*dv_strategy)(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize); - int (*dv_open)(struct open_file *f, ...); - int (*dv_close)(struct open_file *f); - int (*dv_ioctl)(struct open_file *f, u_long cmd, void *data); - int (*dv_print)(int verbose); /* print device information */ - void (*dv_cleanup)(void); + int (*dv_open)(struct open_file *f, ...); + int (*dv_close)(struct open_file *f); + int (*dv_ioctl)(struct open_file *f, ulong_t cmd, void *data); + int (*dv_print)(int verbose); /* print device information */ + void (*dv_cleanup)(void); }; /* @@ -166,22 +169,22 @@ extern int errno; * overlap. */ struct devdesc { - struct devsw *d_dev; - int d_unit; - void *d_opendata; + struct devsw *d_dev; + int d_unit; + void *d_opendata; }; struct open_file { - int f_flags; /* see F_* below */ - struct devsw *f_dev; /* pointer to device operations */ - void *f_devdata; /* device specific data */ - struct fs_ops *f_ops; /* pointer to file system operations */ - void *f_fsdata; /* file system specific data */ - off_t f_offset; /* current file offset */ - char *f_rabuf; /* readahead buffer pointer */ - size_t f_ralen; /* valid data in readahead buffer */ - off_t f_raoffset; /* consumer offset in readahead buffer */ -#define SOPEN_RASIZE 512 + int f_flags; /* see F_* below */ + struct devsw *f_dev; /* pointer to device operations */ + void *f_devdata; /* device specific data */ + struct fs_ops *f_ops; /* pointer to file system operations */ + void *f_fsdata; /* file system specific data */ + off_t f_offset; /* current file offset */ + char *f_rabuf; /* readahead buffer pointer */ + size_t f_ralen; /* valid data in readahead buffer */ + off_t f_raoffset; /* consumer offset in readahead buffer */ +#define SOPEN_RASIZE 512 }; #define SOPEN_MAX 64 @@ -198,51 +201,51 @@ extern struct open_file files[]; /* Mode modifier for strategy() */ #define F_NORA (0x01 << 16) /* Disable Read-Ahead */ -#define isascii(c) (((c) & ~0x7F) == 0) +#define isascii(c) (((c) & ~0x7F) == 0) static __inline int isupper(int c) { - return c >= 'A' && c <= 'Z'; + return (c >= 'A' && c <= 'Z'); } static __inline int islower(int c) { - return c >= 'a' && c <= 'z'; + return (c >= 'a' && c <= 'z'); } static __inline int isspace(int c) { - return c == ' ' || (c >= 0x9 && c <= 0xd); + return (c == ' ' || (c >= 0x9 && c <= 0xd)); } static __inline int isdigit(int c) { - return c >= '0' && c <= '9'; + return (c >= '0' && c <= '9'); } static __inline int isxdigit(int c) { - return isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); + return (isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); } static __inline int isalpha(int c) { - return isupper(c) || islower(c); + return (isupper(c) || islower(c)); } static __inline int isalnum(int c) { - return isalpha(c) || isdigit(c); + return (isalpha(c) || isdigit(c)); } static __inline int toupper(int c) { - return islower(c) ? c - 'a' + 'A' : c; + return (islower(c) ? c - 'a' + 'A' : c); } static __inline int tolower(int c) { - return isupper(c) ? c - 'A' + 'a' : c; + return (isupper(c) ? c - 'A' + 'a' : c); } /* sbrk emulation */ @@ -252,7 +255,6 @@ extern char *sbrk(int incr); /* Matt Dillon's zalloc/zmalloc */ extern void *malloc(size_t bytes); extern void free(void *ptr); -/*#define free(p) {CHK("free %p", p); free(p);} */ /* use for catching guard violations */ extern void *calloc(size_t n1, size_t n2); extern void *realloc(void *ptr, size_t size); extern void *reallocf(void *ptr, size_t size); @@ -262,34 +264,35 @@ extern int printf(const char *fmt, ...) __printflike(1, 2); extern void vprintf(const char *fmt, __va_list); extern int asprintf(char **buf, const char *cfmt, ...) __printflike(2, 3); extern int sprintf(char *buf, const char *cfmt, ...) __printflike(2, 3); -extern int snprintf(char *buf, size_t size, const char *cfmt, ...) __printflike(3, 4); +extern int snprintf(char *buf, size_t size, const char *cfmt, ...) \ + __printflike(3, 4); extern void vsprintf(char *buf, const char *cfmt, __va_list); extern void vsnprintf(char *buf, size_t size, const char *cfmt, __va_list); -extern void twiddle(u_int callerdiv); -extern void twiddle_divisor(u_int globaldiv); +extern void twiddle(uint_t callerdiv); +extern void twiddle_divisor(uint_t globaldiv); extern void ngets(char *, int); -#define gets(x) ngets((x), 0) +#define gets(x) ngets((x), 0) extern int fgetstr(char *buf, int size, int fd); extern int open(const char *, int); #define O_RDONLY 0x0 -#define O_WRONLY 0x1 -#define O_RDWR 0x2 +#define O_WRONLY 0x1 +#define O_RDWR 0x2 extern int close(int); extern void closeall(void); extern ssize_t read(int, void *, size_t); extern ssize_t write(int, const void *, size_t); extern struct dirent *readdirfd(int); -extern void srandom(u_long seed); -extern u_long random(void); +extern void srandom(ulong_t seed); +extern ulong_t random(void); /* imports from stdlib, locally modified */ extern long strtol(const char *, char **, int); extern unsigned long strtoul(const char *, char **, int); -extern char *optarg; /* getopt(3) external variables */ +extern char *optarg; /* getopt(3) external variables */ extern int optind, opterr, optopt, optreset; extern int getopt(int, char * const [], const char *); @@ -300,13 +303,16 @@ extern int pager_output(const char *lines); extern int pager_file(const char *fname); /* No signal state to preserve */ -#define setjmp _setjmp -#define longjmp _longjmp +#define setjmp _setjmp +#define longjmp _longjmp /* environment.c */ -#define EV_DYNAMIC (1<<0) /* value was dynamically allocated, free if changed/unset */ -#define EV_VOLATILE (1<<1) /* value is volatile, make a copy of it */ -#define EV_NOHOOK (1<<2) /* don't call hook when setting */ +/* value was dynamically allocated, free if changed/unset */ +#define EV_DYNAMIC (1<<0) +/* value is volatile, make a copy of it */ +#define EV_VOLATILE (1<<1) +/* don't call hook when setting */ +#define EV_NOHOOK (1<<2) struct env_var; typedef char *(ev_format_t)(struct env_var *ev); @@ -327,11 +333,11 @@ extern struct env_var *environ; extern struct env_var *env_getenv(const char *name); extern int env_setenv(const char *name, int flags, - const void *value, ev_sethook_t sethook, - ev_unsethook_t unsethook); + const void *value, ev_sethook_t sethook, + ev_unsethook_t unsethook); extern char *getenv(const char *name); extern int setenv(const char *name, const char *value, - int overwrite); + int overwrite); extern int putenv(const char *string); extern int unsetenv(const char *name); @@ -339,8 +345,8 @@ extern ev_sethook_t env_noset; /* refuse set operation */ extern ev_unsethook_t env_nounset; /* refuse unset operation */ /* BCD conversions (undocumented) */ -extern u_char const bcd2bin_data[]; -extern u_char const bin2bcd_data[]; +extern uchar_t const bcd2bin_data[]; +extern uchar_t const bin2bcd_data[]; extern char const hex2ascii_data[]; #define bcd2bin(bcd) (bcd2bin_data[bcd]) @@ -352,40 +358,40 @@ static __inline int imax(int a, int b) { return (a > b ? a : b); } static __inline int imin(int a, int b) { return (a < b ? a : b); } static __inline long lmax(long a, long b) { return (a > b ? a : b); } static __inline long lmin(long a, long b) { return (a < b ? a : b); } -static __inline u_int max(u_int a, u_int b) { return (a > b ? a : b); } -static __inline u_int min(u_int a, u_int b) { return (a < b ? a : b); } +static __inline uint_t max(uint_t a, uint_t b) { return (a > b ? a : b); } +static __inline uint_t min(uint_t a, uint_t b) { return (a < b ? a : b); } static __inline quad_t qmax(quad_t a, quad_t b) { return (a > b ? a : b); } static __inline quad_t qmin(quad_t a, quad_t b) { return (a < b ? a : b); } -static __inline u_long ulmax(u_long a, u_long b) { return (a > b ? a : b); } -static __inline u_long ulmin(u_long a, u_long b) { return (a < b ? a : b); } +static __inline ulong_t ulmax(ulong_t a, ulong_t b) { return (a > b ? a : b); } +static __inline ulong_t ulmin(ulong_t a, ulong_t b) { return (a < b ? a : b); } /* null functions for device/filesystem switches (undocumented) */ extern int nodev(void); -extern int noioctl(struct open_file *, u_long, void *); +extern int noioctl(struct open_file *, ulong_t, void *); extern void nullsys(void); -extern int null_open(const char *path, struct open_file *f); -extern int null_close(struct open_file *f); -extern int null_read(struct open_file *f, void *buf, size_t size, size_t *resid); -extern int null_write(struct open_file *f, const void *buf, size_t size, size_t *resid); -extern off_t null_seek(struct open_file *f, off_t offset, int where); -extern int null_stat(struct open_file *f, struct stat *sb); -extern int null_readdir(struct open_file *f, struct dirent *d); +extern int null_open(const char *, struct open_file *); +extern int null_close(struct open_file *); +extern int null_read(struct open_file *, void *, size_t, size_t *); +extern int null_write(struct open_file *, const void *, size_t, size_t *); +extern off_t null_seek(struct open_file *, off_t, int); +extern int null_stat(struct open_file *, struct stat *); +extern int null_readdir(struct open_file *, struct dirent *); /* * Machine dependent functions and data, must be provided or stubbed by * the consumer */ -extern void exit(int) __dead2; -extern int getchar(void); -extern int ischar(void); -extern void putchar(int); -extern int devopen(struct open_file *, const char *, const char **); -extern int devclose(struct open_file *f); -extern void panic(const char *, ...) __dead2 __printflike(1, 2); -extern void panic_action(void) __weak_symbol __dead2; -extern time_t getsecs(void); +extern void exit(int) __dead2; +extern int getchar(void); +extern int ischar(void); +extern void putchar(int); +extern int devopen(struct open_file *, const char *, const char **); +extern int devclose(struct open_file *f); +extern void panic(const char *, ...) __dead2 __printflike(1, 2); +extern void panic_action(void) __weak_symbol __dead2; +extern time_t getsecs(void); extern struct fs_ops *file_system[]; extern struct fs_ops *exclusive_file_system; extern struct devsw *devsw[]; @@ -415,15 +421,15 @@ void *Realloc(void *, size_t, const char *, int); void Free(void *, const char *, int); #if 1 -#define malloc(x) Malloc(x, __FILE__, __LINE__) -#define calloc(x, y) Calloc(x, y, __FILE__, __LINE__) -#define free(x) Free(x, __FILE__, __LINE__) -#define realloc(x, y) Realloc(x, y, __FILE__, __LINE__) +#define malloc(x) Malloc(x, __FILE__, __LINE__) +#define calloc(x, y) Calloc(x, y, __FILE__, __LINE__) +#define free(x) Free(x, __FILE__, __LINE__) +#define realloc(x, y) Realloc(x, y, __FILE__, __LINE__) #else -#define malloc(x) Malloc(x, NULL, 0) -#define calloc(x, y) Calloc(x, y, NULL, 0) -#define free(x) Free(x, NULL, 0) -#define realloc(x, y) Realloc(x, y, NULL, 0) +#define malloc(x) Malloc(x, NULL, 0) +#define calloc(x, y) Calloc(x, y, NULL, 0) +#define free(x) Free(x, NULL, 0) +#define realloc(x, y) Realloc(x, y, NULL, 0) #endif #endif /* STAND_H */ -- cgit v1.2.3 From 42c5ef032d8316897a2ba9f9ebf4b9c2654ec345 Mon Sep 17 00:00:00 2001 From: Dan McDonald Date: Fri, 22 Feb 2019 14:42:52 -0500 Subject: 10472 Limit number of multicast NCEs Reviewed by: Cody Peter Mello Reviewed by: Jason King Reviewed by: Robert Mustacchi Reviewed by: Richard Lowe Approved by: Joshua M. Clulow --- usr/src/uts/common/inet/ip.h | 7 +- usr/src/uts/common/inet/ip/ip.c | 5 +- usr/src/uts/common/inet/ip/ip_ndp.c | 292 ++++++++++++++++++++++++++-- usr/src/uts/common/inet/ip_stack.h | 23 ++- usr/src/uts/intel/ip/ip.global-objs.debug64 | 4 +- usr/src/uts/intel/ip/ip.global-objs.obj64 | 4 +- usr/src/uts/sparc/ip/ip.global-objs.debug64 | 4 +- usr/src/uts/sparc/ip/ip.global-objs.obj64 | 4 +- 8 files changed, 313 insertions(+), 30 deletions(-) diff --git a/usr/src/uts/common/inet/ip.h b/usr/src/uts/common/inet/ip.h index 2c1b030309..f67ade9060 100644 --- a/usr/src/uts/common/inet/ip.h +++ b/usr/src/uts/common/inet/ip.h @@ -22,9 +22,9 @@ /* * Copyright (c) 1990 Mentat Inc. * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright 2017 Nexenta Systems, Inc. * Copyright 2017 OmniTI Computer Consulting, Inc. All rights reserved. + * Copyright 2019, Joyent, Inc. */ #ifndef _INET_IP_H @@ -1708,7 +1708,8 @@ typedef struct ill_s { ill_manual_dst_linklocal : 1, /* same for pt-pt dst linklocal */ - ill_pad_bit_31 : 27; + ill_mcast_ncec_cleanup : 1, /* Reaping mcast ncecs. */ + ill_pad_bit_31 : 26; /* * Used in SIOCSIFMUXID and SIOCGIFMUXID for 'ifconfig unplumb'. @@ -1770,6 +1771,7 @@ typedef struct ill_s { */ uint_t ill_ifname_pending_err; avl_node_t ill_avl_byppa; /* avl node based on ppa */ + uint_t ill_mcast_nces; /* Number of NCEs that are multicast. */ list_t ill_nce; /* pointer to nce_s list */ uint_t ill_refcnt; /* active refcnt by threads */ uint_t ill_ire_cnt; /* ires associated with this ill */ @@ -1940,6 +1942,7 @@ typedef struct ill_s { * ill_refcnt ill_lock ill_lock * ill_ire_cnt ill_lock ill_lock * ill_cv ill_lock ill_lock + * ill_mcast_nces ill_lock ill_lock * ill_ncec_cnt ill_lock ill_lock * ill_nce_cnt ill_lock ill_lock * ill_ilm_cnt ill_lock ill_lock diff --git a/usr/src/uts/common/inet/ip/ip.c b/usr/src/uts/common/inet/ip/ip.c index 18f67573be..46272b2b22 100644 --- a/usr/src/uts/common/inet/ip/ip.c +++ b/usr/src/uts/common/inet/ip/ip.c @@ -24,7 +24,7 @@ * Copyright (c) 1990 Mentat Inc. * Copyright (c) 2017 OmniTI Computer Consulting, Inc. All rights reserved. * Copyright (c) 2016 by Delphix. All rights reserved. - * Copyright (c) 2018 Joyent, Inc. All rights reserved. + * Copyright (c) 2019 Joyent, Inc. All rights reserved. */ #include @@ -13937,6 +13937,9 @@ ip_kstat2_init(netstackid_t stackid, ip_stat_t *ip_statisticsp) { "ip_ire_reclaim_deleted", KSTAT_DATA_UINT64 }, { "ip_nce_reclaim_calls", KSTAT_DATA_UINT64 }, { "ip_nce_reclaim_deleted", KSTAT_DATA_UINT64 }, + { "ip_nce_mcast_reclaim_calls", KSTAT_DATA_UINT64 }, + { "ip_nce_mcast_reclaim_deleted", KSTAT_DATA_UINT64 }, + { "ip_nce_mcast_reclaim_tqfail", KSTAT_DATA_UINT64 }, { "ip_dce_reclaim_calls", KSTAT_DATA_UINT64 }, { "ip_dce_reclaim_deleted", KSTAT_DATA_UINT64 }, { "ip_tcp_in_full_hw_cksum_err", KSTAT_DATA_UINT64 }, diff --git a/usr/src/uts/common/inet/ip/ip_ndp.c b/usr/src/uts/common/inet/ip/ip_ndp.c index 211e56633f..2ab9c6fbca 100644 --- a/usr/src/uts/common/inet/ip/ip_ndp.c +++ b/usr/src/uts/common/inet/ip/ip_ndp.c @@ -23,7 +23,7 @@ */ /* - * Copyright (c) 2018, Joyent, Inc. + * Copyright (c) 2019, Joyent, Inc. */ #include @@ -127,8 +127,8 @@ static boolean_t ill_defend_rate_limit(ill_t *, ncec_t *); static void nce_queue_mp_common(ncec_t *, mblk_t *, boolean_t); static int nce_add_common(ill_t *, uchar_t *, uint_t, const in6_addr_t *, uint16_t, uint16_t, nce_t **); -static nce_t *nce_add_impl(ill_t *, ncec_t *, nce_t *, mblk_t *); -static nce_t *nce_add(ill_t *, ncec_t *); +static nce_t *nce_add_impl(ill_t *, ncec_t *, nce_t *, mblk_t *, list_t *); +static nce_t *nce_add(ill_t *, ncec_t *, list_t *); static void nce_inactive(nce_t *); extern nce_t *nce_lookup(ill_t *, const in6_addr_t *); static nce_t *nce_ill_lookup_then_add(ill_t *, ncec_t *); @@ -1004,6 +1004,236 @@ ncec_walk(ill_t *ill, ncec_walk_cb_t cbf, void *arg1, ip_stack_t *ipst) ncec_walk_common(ipst->ips_ndp6, ill, cbf, arg1, B_TRUE); } +/* + * Cheesy globals (i.e. all netstacks) for both a limit on per-ill multicast + * NCEs, and the number to reclaim if we hit the limit. Used by + * nce_set_multicast_v[46]() to limit the linked-list length of ill_nce. Until + * we solve the multicast-mappings-shouldn't-be-NCEs problem, use this. + */ + +/* Maximum number of multicast NCEs on an ill. */ +uint_t ip_max_ill_mcast_nces = 16384; +/* + * Number of NCEs to delete if we hit the maximum above. 0 means *don't* and + * return an error. Non-zero means delete so many, and if the number is >= + * the max above, that means delete them all. + */ +uint_t ip_ill_mcast_reclaim = 256; + +/* + * Encapsulate multicast ill capping in a function, for easier DTrace + * detections. Return a list of refheld NCEs to destroy-via-refrele. That + * list can be NULL, but can only be non-NULL if we successfully reclaimed. + * + * NOTE: This function must be called while holding the ill_lock AND + * JUST PRIOR to making the insertion into the ill_nce list. + * + * We can't release the ones we delete ourselves because the ill_lock is held + * by the caller. They are, instead, passed back in a list_t for deletion + * outside of the ill_lock hold. nce_graveyard_free() actually frees them. + * + * While this covers nce_t, ncec_t gets done even further down the road. See + * nce_graveyard_free() for why. + */ +static boolean_t +nce_too_many_mcast(ill_t *ill, list_t *graveyard) +{ + uint_t reclaim_count, max_count, reclaimed = 0; + boolean_t too_many; + nce_t *nce, *deadman; + + ASSERT(graveyard != NULL); + ASSERT(list_is_empty(graveyard)); + ASSERT(MUTEX_HELD(&ill->ill_lock)); + + /* + * NOTE: Some grinning weirdo may have lowered the global max beyond + * what this ill currently has. The behavior in this case will be + * trim-back just by the reclaim amount for any new ones. + */ + max_count = ip_max_ill_mcast_nces; + reclaim_count = min(ip_ill_mcast_reclaim, max_count); + + /* All good? */ + if (ill->ill_mcast_nces < max_count) + return (B_FALSE); /* Yes, all good. */ + + if (reclaim_count == 0) + return (B_TRUE); /* Don't bother - we're stuck. */ + + /* We need to reclaim now. Exploit our held ill_lock. */ + + /* + * Start at the tail and work backwards, new nces are head-inserted, + * so we'll be reaping the oldest entries. + */ + nce = list_tail(&ill->ill_nce); + while (reclaimed < reclaim_count) { + /* Skip ahead to a multicast NCE. */ + while (nce != NULL && + (nce->nce_common->ncec_flags & NCE_F_MCAST) == 0) { + nce = list_prev(&ill->ill_nce, nce); + } + if (nce == NULL) + break; + + /* + * NOTE: For now, we just delete the first one(s) we find. + * This is not optimal, and may require some inspection of nce + * & its ncec to be better. + */ + deadman = nce; + nce = list_prev(&ill->ill_nce, nce); + + /* nce_delete() requires caller holds... */ + nce_refhold(deadman); + nce_delete(deadman); /* Bumps down ill_mcast_nces. */ + + /* Link the dead ones singly, still refheld... */ + list_insert_tail(graveyard, deadman); + reclaimed++; + } + + if (reclaimed != reclaim_count) { + /* We didn't have enough to reach reclaim_count. Why?!? */ + DTRACE_PROBE3(ill__mcast__nce__reclaim__mismatch, ill_t *, ill, + uint_t, reclaimed, uint_t, reclaim_count); + + /* In case for some REALLY weird reason we found none! */ + too_many = (reclaimed == 0); + } else { + too_many = B_FALSE; + } + + return (too_many); +} + +static void +ncec_mcast_reap_one(ncec_t *ncec, void *arg) +{ + boolean_t reapit; + ill_t *ill = (ill_t *)arg; + + /* Obvious no-lock-needed checks... */ + if (ncec == NULL || ncec->ncec_ill != ill || + (ncec->ncec_flags & NCE_F_MCAST) == 0) + return; + + mutex_enter(&ncec->ncec_lock); + /* + * It's refheld by the walk infrastructure. It has one reference for + * being in the ndp_g_hash, and if an nce_t exists, that's one more. + * We want ones without an nce_t, so 2 is the magic number. If it's + * LESS than 2, we have much bigger problems anyway. + */ + ASSERT(ncec->ncec_refcnt >= 2); + reapit = (ncec->ncec_refcnt == 2); + mutex_exit(&ncec->ncec_lock); + + if (reapit) { + IP_STAT(ill->ill_ipst, ip_nce_mcast_reclaim_deleted); + ncec_delete(ncec); + } +} + +/* + * Attempt to reap stray multicast ncec_t structures left in the wake of + * nce_graveyard_free(). This is a taskq servicing routine, as it's well + * outside any netstack-global locks being held - ndp_g_lock in this case. We + * have a reference hold on the ill, which will prevent any unplumbing races. + */ +static void +ncec_mcast_reap(void *arg) +{ + ill_t *ill = (ill_t *)arg; + + IP_STAT(ill->ill_ipst, ip_nce_mcast_reclaim_calls); + ncec_walk(ill, ncec_mcast_reap_one, ill, ill->ill_ipst); + mutex_enter(&ill->ill_lock); + ill->ill_mcast_ncec_cleanup = B_FALSE; + /* + * Inline a _notr() version of ill_refrele. See nce_graveyard_free() + * below for why. + */ + ill->ill_refcnt--; + if (ill->ill_refcnt == 0) + ipif_ill_refrele_tail(ill); /* Drops ill_lock. */ + else + mutex_exit(&ill->ill_lock); +} + +/* + * Free a list (including handling an empty list or NULL list) of + * reference-held NCEs that were reaped from a nce_too_many_mcast() + * call. Separate because the caller must have dropped ndp_g_lock first. + * + * This also schedules a taskq task to unlink underlying NCECs from the + * ndp_g_hash, which are protected by ndp_g_lock. + */ +static void +nce_graveyard_free(list_t *graveyard) +{ + nce_t *deadman, *current; + ill_t *ill; + boolean_t doit; + + if (graveyard == NULL) + return; + + current = list_head(graveyard); + if (current == NULL) { + list_destroy(graveyard); + return; + } + + ill = current->nce_ill; + /* + * Normally one should ill_refhold(ill) here. There's no _notr() + * variant like there is for ire_t, dce_t, or even ncec_t, but this is + * the ONLY case that'll break the mh_trace that IP debugging uses for + * reference counts (i.e. they assume same thread releases as + * holds). Instead, we inline ill_refhold() here. We must do the same + * in the release done by the ncec_mcast_reap() above. + */ + mutex_enter(&ill->ill_lock); + ill->ill_refcnt++; + mutex_exit(&ill->ill_lock); + + while (current != NULL) { + ASSERT3P(ill, ==, current->nce_ill); + deadman = current; + current = list_next(graveyard, deadman); + list_remove(graveyard, deadman); + ASSERT3U((deadman->nce_common->ncec_flags & NCE_F_MCAST), !=, + 0); + nce_refrele(deadman); + } + list_destroy(graveyard); + + mutex_enter(&ill->ill_lock); + if (ill->ill_mcast_ncec_cleanup) + doit = B_FALSE; + else { + ill->ill_mcast_ncec_cleanup = B_TRUE; + doit = B_TRUE; + } + mutex_exit(&ill->ill_lock); + if (!doit || taskq_dispatch(system_taskq, ncec_mcast_reap, + ill, TQ_NOSLEEP) == NULL) { + mutex_enter(&ill->ill_lock); + if (doit) { + IP_STAT(ill->ill_ipst, ip_nce_mcast_reclaim_tqfail); + ill->ill_mcast_ncec_cleanup = B_FALSE; + } + /* There's no _notr() for ill_refrele(), so inline it here. */ + ill->ill_refcnt--; + if (ill->ill_refcnt == 0) + ipif_ill_refrele_tail(ill); /* Drops ill_lock */ + else + mutex_exit(&ill->ill_lock); + } +} + /* * For each interface an entry is added for the unspecified multicast group. * Here that mapping is used to form the multicast cache entry for a particular @@ -1050,7 +1280,7 @@ nce_set_multicast_v6(ill_t *ill, const in6_addr_t *dst, ND_UNCHANGED, &nce); mutex_exit(&ipst->ips_ndp6->ndp_g_lock); if (err == 0) - err = nce_add_v6_postprocess(nce); + err = (nce != NULL) ? nce_add_v6_postprocess(nce) : ENOMEM; if (hw_addr != NULL) kmem_free(hw_addr, ill->ill_nd_lla_len); if (err != 0) { @@ -3100,7 +3330,7 @@ nce_fastpath_create(ill_t *ill, ncec_t *ncec) * method. All other callers (that pass in NULL ncec_nce) will have to do a * nce_refrele of the returned nce (when it is non-null). */ -nce_t * +static nce_t * nce_fastpath(ncec_t *ncec, boolean_t trigger_fp_req, nce_t *ncec_nce) { nce_t *nce; @@ -3158,7 +3388,7 @@ nce_fastpath_trigger(nce_t *nce) * Add ncec to the nce fastpath list on ill. */ static nce_t * -nce_ill_lookup_then_add_locked(ill_t *ill, ncec_t *ncec) +nce_ill_lookup_then_add_locked(ill_t *ill, ncec_t *ncec, list_t *graveyard) { nce_t *nce = NULL; @@ -3178,21 +3408,24 @@ nce_ill_lookup_then_add_locked(ill_t *ill, ncec_t *ncec) nce = nce_lookup(ill, &ncec->ncec_addr); if (nce != NULL) goto done; - nce = nce_add(ill, ncec); + nce = nce_add(ill, ncec, graveyard); } done: mutex_exit(&ncec->ncec_lock); return (nce); } -nce_t * +static nce_t * nce_ill_lookup_then_add(ill_t *ill, ncec_t *ncec) { nce_t *nce; + list_t graveyard; + list_create(&graveyard, sizeof (nce_t), offsetof(nce_t, nce_node)); mutex_enter(&ill->ill_lock); - nce = nce_ill_lookup_then_add_locked(ill, ncec); + nce = nce_ill_lookup_then_add_locked(ill, ncec, &graveyard); mutex_exit(&ill->ill_lock); + nce_graveyard_free(&graveyard); return (nce); } @@ -3243,7 +3476,9 @@ nce_delete_then_add(nce_t *nce) { ill_t *ill = nce->nce_ill; nce_t *newnce = NULL; + list_t graveyard; + list_create(&graveyard, sizeof (nce_t), offsetof(nce_t, nce_node)); ip0dbg(("nce_delete_then_add nce %p ill %s\n", (void *)nce, ill->ill_name)); mutex_enter(&ill->ill_lock); @@ -3255,9 +3490,10 @@ nce_delete_then_add(nce_t *nce) * ipmp_ncec_delete_nce() */ if (!NCE_ISCONDEMNED(nce->nce_common)) - newnce = nce_add(ill, nce->nce_common); + newnce = nce_add(ill, nce->nce_common, &graveyard); mutex_exit(&nce->nce_common->ncec_lock); mutex_exit(&ill->ill_lock); + nce_graveyard_free(&graveyard); nce_refrele(nce); return (newnce); /* could be null if nomem */ } @@ -3972,7 +4208,7 @@ nce_set_multicast_v4(ill_t *ill, const in_addr_t *dst, ND_UNCHANGED, &nce); mutex_exit(&ipst->ips_ndp4->ndp_g_lock); if (err == 0) - err = nce_add_v4_postprocess(nce); + err = (nce != NULL) ? nce_add_v4_postprocess(nce) : ENOMEM; if (hw_addr != NULL) kmem_free(hw_addr, ill->ill_phys_addr_length); if (err != 0) { @@ -4396,6 +4632,7 @@ nce_add_common(ill_t *ill, uchar_t *hw_addr, uint_t hw_addr_len, boolean_t fastprobe = B_FALSE; struct ndp_g_s *ndp; nce_t *nce = NULL; + list_t graveyard; mblk_t *dlur_mp = NULL; if (ill->ill_isv6) @@ -4686,9 +4923,11 @@ nce_add_common(ill_t *ill, uchar_t *hw_addr, uint_t hw_addr_len, * Since we hold the ncec_lock at this time, the ncec cannot be * condemned, and we can safely add the nce. */ - *retnce = nce_add_impl(ill, ncec, nce, dlur_mp); + list_create(&graveyard, sizeof (nce_t), offsetof(nce_t, nce_node)); + *retnce = nce_add_impl(ill, ncec, nce, dlur_mp, &graveyard); mutex_exit(&ncec->ncec_lock); mutex_exit(&ill->ill_lock); + nce_graveyard_free(&graveyard); /* caller must trigger fastpath on *retnce */ return (0); @@ -4774,10 +5013,25 @@ nce_inactive(nce_t *nce) /* * Add an nce to the ill_nce list. + * + * Adding multicast NCEs is subject to a per-ill limit. This function returns + * NULL if that's the case, and it may reap a number of multicast nces. + * Callers (and upstack) must be able to cope with NULL returns. */ static nce_t * -nce_add_impl(ill_t *ill, ncec_t *ncec, nce_t *nce, mblk_t *dlur_mp) +nce_add_impl(ill_t *ill, ncec_t *ncec, nce_t *nce, mblk_t *dlur_mp, + list_t *graveyard) { + ASSERT(MUTEX_HELD(&ill->ill_lock)); + + if ((ncec->ncec_flags & NCE_F_MCAST) != 0) { + if (nce_too_many_mcast(ill, graveyard)) { + kmem_cache_free(nce_cache, nce); + return (NULL); + } + ill->ill_mcast_nces++; + } + bzero(nce, sizeof (*nce)); mutex_init(&nce->nce_lock, NULL, MUTEX_DEFAULT, NULL); nce->nce_common = ncec; @@ -4798,7 +5052,7 @@ nce_add_impl(ill_t *ill, ncec_t *ncec, nce_t *nce, mblk_t *dlur_mp) } static nce_t * -nce_add(ill_t *ill, ncec_t *ncec) +nce_add(ill_t *ill, ncec_t *ncec, list_t *graveyard) { nce_t *nce; mblk_t *dlur_mp = NULL; @@ -4819,7 +5073,11 @@ nce_add(ill_t *ill, ncec_t *ncec) return (NULL); } } - return (nce_add_impl(ill, ncec, nce, dlur_mp)); + /* + * If nce_add_impl() returns NULL due to on multicast limiting, caller + * will (correctly) assume ENOMEM. + */ + return (nce_add_impl(ill, ncec, nce, dlur_mp, graveyard)); } /* @@ -4843,6 +5101,10 @@ nce_delete(nce_t *nce) nce->nce_is_condemned = B_TRUE; mutex_exit(&nce->nce_lock); + /* Update the count of multicast NCEs. */ + if ((nce->nce_common->ncec_flags & NCE_F_MCAST) == NCE_F_MCAST) + ill->ill_mcast_nces--; + list_remove(&ill->ill_nce, nce); /* * even though we are holding the ill_lock, it is ok to diff --git a/usr/src/uts/common/inet/ip_stack.h b/usr/src/uts/common/inet/ip_stack.h index ab954c7c31..85885f9dd9 100644 --- a/usr/src/uts/common/inet/ip_stack.h +++ b/usr/src/uts/common/inet/ip_stack.h @@ -24,6 +24,10 @@ * Use is subject to license terms. */ +/* + * Copyright 2019 Joyent, Inc. + */ + #ifndef _INET_IP_STACK_H #define _INET_IP_STACK_H @@ -64,6 +68,9 @@ typedef struct ip_stat { kstat_named_t ip_ire_reclaim_deleted; kstat_named_t ip_nce_reclaim_calls; kstat_named_t ip_nce_reclaim_deleted; + kstat_named_t ip_nce_mcast_reclaim_calls; + kstat_named_t ip_nce_mcast_reclaim_deleted; + kstat_named_t ip_nce_mcast_reclaim_tqfail; kstat_named_t ip_dce_reclaim_calls; kstat_named_t ip_dce_reclaim_deleted; kstat_named_t ip_tcp_in_full_hw_cksum_err; @@ -143,7 +150,7 @@ struct ip_stack { uint_t ips_src_generation; /* Both IPv4 and IPv6 */ - struct mod_prop_info_s *ips_propinfo_tbl; /* ip tunables table */ + struct mod_prop_info_s *ips_propinfo_tbl; /* ip tunables table */ mib2_ipIfStatsEntry_t ips_ip_mib; /* SNMP fixed size info */ mib2_icmp_t ips_icmp_mib; @@ -200,16 +207,16 @@ struct ip_stack { /* ip.c */ /* Following protected by igmp_timer_lock */ - int ips_igmp_time_to_next; /* Time since last timeout */ - int ips_igmp_timer_scheduled_last; + int ips_igmp_time_to_next; /* Time since last timeout */ + int ips_igmp_timer_scheduled_last; int ips_igmp_deferred_next; timeout_id_t ips_igmp_timeout_id; boolean_t ips_igmp_timer_setter_active; boolean_t ips_igmp_timer_quiesce; /* Following protected by mld_timer_lock */ - int ips_mld_time_to_next; /* Time since last timeout */ - int ips_mld_timer_scheduled_last; + int ips_mld_time_to_next; /* Time since last timeout */ + int ips_mld_timer_scheduled_last; int ips_mld_deferred_next; timeout_id_t ips_mld_timeout_id; boolean_t ips_mld_timer_setter_active; @@ -247,8 +254,8 @@ struct ip_stack { uint32_t ips_ip6_ftable_hash_size; - ire_stats_t ips_ire_stats_v4; /* IPv4 ire statistics */ - ire_stats_t ips_ire_stats_v6; /* IPv6 ire statistics */ + ire_stats_t ips_ire_stats_v4; /* IPv4 ire statistics */ + ire_stats_t ips_ire_stats_v6; /* IPv6 ire statistics */ /* Count how many condemned objects for kmem_cache callbacks */ uint32_t ips_num_ire_condemned; @@ -344,7 +351,7 @@ struct ip_stack { * reg_vif_num is protected by numvifs_mutex */ /* Whether or not special PIM assert processing is enabled. */ - ushort_t ips_reg_vif_num; /* Index to Register vif */ + ushort_t ips_reg_vif_num; /* Index to Register vif */ int ips_pim_assert; union ill_g_head_u *ips_ill_g_heads; /* ILL List Head */ diff --git a/usr/src/uts/intel/ip/ip.global-objs.debug64 b/usr/src/uts/intel/ip/ip.global-objs.debug64 index 3098f98265..6aa8cc87d3 100644 --- a/usr/src/uts/intel/ip/ip.global-objs.debug64 +++ b/usr/src/uts/intel/ip/ip.global-objs.debug64 @@ -21,7 +21,7 @@ # # Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2011 Nexenta Systems, Inc. All rights reserved -# Copyright 2012 Joyent, Inc. All rights reserved +# Copyright 2019 Joyent, Inc. All rights reserved # arp_m_tbl @@ -119,11 +119,13 @@ ip_g_all_ones ip_helper_stream_info ip_helper_stream_rinit ip_helper_stream_winit +ip_ill_mcast_reclaim ip_ioctl_ftbl ip_loopback_mtu_v6plus ip_loopback_mtuplus ip_m_tbl ip_max_frag_dups +ip_max_ill_mcast_nces ip_min_frag_prune_time ip_minor_arena_la ip_minor_arena_sa diff --git a/usr/src/uts/intel/ip/ip.global-objs.obj64 b/usr/src/uts/intel/ip/ip.global-objs.obj64 index f182d7198e..7e7d1a2833 100644 --- a/usr/src/uts/intel/ip/ip.global-objs.obj64 +++ b/usr/src/uts/intel/ip/ip.global-objs.obj64 @@ -21,7 +21,7 @@ # # Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2011 Nexenta Systems, Inc. All rights reserved -# Copyright 2012 Joyent, Inc. All rights reserved +# Copyright 2019 Joyent, Inc. All rights reserved # arp_m_tbl @@ -119,11 +119,13 @@ ip_g_all_ones ip_helper_stream_info ip_helper_stream_rinit ip_helper_stream_winit +ip_ill_mcast_reclaim ip_ioctl_ftbl ip_loopback_mtu_v6plus ip_loopback_mtuplus ip_m_tbl ip_max_frag_dups +ip_max_ill_mcast_nces ip_min_frag_prune_time ip_minor_arena_la ip_minor_arena_sa diff --git a/usr/src/uts/sparc/ip/ip.global-objs.debug64 b/usr/src/uts/sparc/ip/ip.global-objs.debug64 index 3098f98265..6aa8cc87d3 100644 --- a/usr/src/uts/sparc/ip/ip.global-objs.debug64 +++ b/usr/src/uts/sparc/ip/ip.global-objs.debug64 @@ -21,7 +21,7 @@ # # Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2011 Nexenta Systems, Inc. All rights reserved -# Copyright 2012 Joyent, Inc. All rights reserved +# Copyright 2019 Joyent, Inc. All rights reserved # arp_m_tbl @@ -119,11 +119,13 @@ ip_g_all_ones ip_helper_stream_info ip_helper_stream_rinit ip_helper_stream_winit +ip_ill_mcast_reclaim ip_ioctl_ftbl ip_loopback_mtu_v6plus ip_loopback_mtuplus ip_m_tbl ip_max_frag_dups +ip_max_ill_mcast_nces ip_min_frag_prune_time ip_minor_arena_la ip_minor_arena_sa diff --git a/usr/src/uts/sparc/ip/ip.global-objs.obj64 b/usr/src/uts/sparc/ip/ip.global-objs.obj64 index f182d7198e..7e7d1a2833 100644 --- a/usr/src/uts/sparc/ip/ip.global-objs.obj64 +++ b/usr/src/uts/sparc/ip/ip.global-objs.obj64 @@ -21,7 +21,7 @@ # # Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2011 Nexenta Systems, Inc. All rights reserved -# Copyright 2012 Joyent, Inc. All rights reserved +# Copyright 2019 Joyent, Inc. All rights reserved # arp_m_tbl @@ -119,11 +119,13 @@ ip_g_all_ones ip_helper_stream_info ip_helper_stream_rinit ip_helper_stream_winit +ip_ill_mcast_reclaim ip_ioctl_ftbl ip_loopback_mtu_v6plus ip_loopback_mtuplus ip_m_tbl ip_max_frag_dups +ip_max_ill_mcast_nces ip_min_frag_prune_time ip_minor_arena_la ip_minor_arena_sa -- cgit v1.2.3 From 1c802681fb0b5558958cd6f33bf56789a1b0ef29 Mon Sep 17 00:00:00 2001 From: Luca Minoja Date: Thu, 28 Feb 2019 10:56:07 +0200 Subject: 10474 OS uuid string should not refer to Solaris. Reviewed by: Toomas Soome Reviewed by: Andy Stormont Reviewed by: Peter Tribble Reviewed by: Andy Fiddaman Approved by: Dan McDonald --- usr/src/uts/common/os/dumpsubr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/src/uts/common/os/dumpsubr.c b/usr/src/uts/common/os/dumpsubr.c index 0eb96464bf..484b2042e2 100644 --- a/usr/src/uts/common/os/dumpsubr.c +++ b/usr/src/uts/common/os/dumpsubr.c @@ -3123,7 +3123,7 @@ dump_set_uuid(const char *uuidstr) (void) strncpy(dump_osimage_uuid, uuidstr, 36 + 1); - cmn_err(CE_CONT, "?This Solaris instance has UUID %s\n", + cmn_err(CE_CONT, "?This illumos instance has UUID %s\n", dump_osimage_uuid); return (0); -- cgit v1.2.3 From 946342a260bbae359b48bf142ec1fe40792ee862 Mon Sep 17 00:00:00 2001 From: Fabian Grünbichler Date: Sun, 3 Mar 2019 22:40:45 -0800 Subject: 10452 ZoL: merge in large dnode feature fixes Portions contributed by: Ned Bass Portions contributed by: Tom Caputi Reviewed by: Giuseppe Di Natale Reviewed by: Alek Pinchuk Reviewed by: Brian Behlendorf Reviewed by: Paul Dagnelie Reviewed by: George Melikov Reviewed by: Giuseppe Di Natale Reviewed by: Toomas Soome Reviewed by: Andy Fiddaman Reviewed by: Gergő Mihály Doma Reviewed by: Jerry Jelinek Approved by: Joshua M. Clulow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- usr/src/pkg/manifests/system-test-zfstest.mf | 3 + .../tests/functional/large_dnode/cleanup.ksh | 5 + .../functional/large_dnode/large_dnode_001_pos.ksh | 5 + .../functional/large_dnode/large_dnode_002_pos.ksh | 5 + .../functional/large_dnode/large_dnode_003_pos.ksh | 5 + .../functional/large_dnode/large_dnode_004_neg.ksh | 5 + .../functional/large_dnode/large_dnode_005_pos.ksh | 5 + .../functional/large_dnode/large_dnode_006_pos.ksh | 5 + .../functional/large_dnode/large_dnode_007_neg.ksh | 5 + .../tests/functional/large_dnode/setup.ksh | 5 + .../tests/functional/rsend/send_freeobjects.ksh | 81 +++++++++++++++ .../functional/rsend/send_realloc_dnode_size.ksh | 111 +++++++++++++++++++++ usr/src/uts/common/fs/zfs/dmu_object.c | 2 +- usr/src/uts/common/fs/zfs/dmu_send.c | 14 +-- usr/src/uts/common/fs/zfs/dnode.c | 3 +- 15 files changed, 249 insertions(+), 10 deletions(-) create mode 100755 usr/src/test/zfs-tests/tests/functional/rsend/send_freeobjects.ksh create mode 100755 usr/src/test/zfs-tests/tests/functional/rsend/send_realloc_dnode_size.ksh diff --git a/usr/src/pkg/manifests/system-test-zfstest.mf b/usr/src/pkg/manifests/system-test-zfstest.mf index c4d70e7980..3b5b21cd90 100644 --- a/usr/src/pkg/manifests/system-test-zfstest.mf +++ b/usr/src/pkg/manifests/system-test-zfstest.mf @@ -2548,6 +2548,9 @@ file path=opt/zfs-tests/tests/functional/rsend/send-c_volume mode=0555 file path=opt/zfs-tests/tests/functional/rsend/send-c_zstreamdump mode=0555 file path=opt/zfs-tests/tests/functional/rsend/send-cpL_varied_recsize \ mode=0555 +file path=opt/zfs-tests/tests/functional/rsend/send_freeobjects mode=0555 +file path=opt/zfs-tests/tests/functional/rsend/send_realloc_dnode_size \ + mode=0555 file path=opt/zfs-tests/tests/functional/rsend/setup mode=0555 file path=opt/zfs-tests/tests/functional/scrub_mirror/cleanup mode=0555 file path=opt/zfs-tests/tests/functional/scrub_mirror/default.cfg mode=0444 diff --git a/usr/src/test/zfs-tests/tests/functional/large_dnode/cleanup.ksh b/usr/src/test/zfs-tests/tests/functional/large_dnode/cleanup.ksh index 61caf39100..60e481d998 100755 --- a/usr/src/test/zfs-tests/tests/functional/large_dnode/cleanup.ksh +++ b/usr/src/test/zfs-tests/tests/functional/large_dnode/cleanup.ksh @@ -20,6 +20,11 @@ # CDDL HEADER END # +# +# Copyright (c) 2016 by Lawrence Livermore National Security, LLC. +# Use is subject to license terms. +# + . $STF_SUITE/include/libtest.shlib default_cleanup diff --git a/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_001_pos.ksh b/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_001_pos.ksh index c07f4e8d74..d3530292e8 100755 --- a/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_001_pos.ksh +++ b/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_001_pos.ksh @@ -20,6 +20,11 @@ # CDDL HEADER END # +# +# Copyright (c) 2016 by Lawrence Livermore National Security, LLC. +# Use is subject to license terms. +# + . $STF_SUITE/include/libtest.shlib # diff --git a/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_002_pos.ksh b/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_002_pos.ksh index 1dd8d888c3..c2b32ad662 100755 --- a/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_002_pos.ksh +++ b/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_002_pos.ksh @@ -20,6 +20,11 @@ # CDDL HEADER END # +# +# Copyright (c) 2016 by Lawrence Livermore National Security, LLC. +# Use is subject to license terms. +# + . $STF_SUITE/include/libtest.shlib # diff --git a/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_003_pos.ksh b/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_003_pos.ksh index a938c7de7c..20989e1d77 100755 --- a/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_003_pos.ksh +++ b/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_003_pos.ksh @@ -20,6 +20,11 @@ # CDDL HEADER END # +# +# Copyright (c) 2016 by Lawrence Livermore National Security, LLC. +# Use is subject to license terms. +# + . $STF_SUITE/include/libtest.shlib verify_runnable "both" diff --git a/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_004_neg.ksh b/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_004_neg.ksh index 1006ae6af5..3fa1cabe06 100755 --- a/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_004_neg.ksh +++ b/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_004_neg.ksh @@ -20,6 +20,11 @@ # CDDL HEADER END # +# +# Copyright (c) 2016 by Lawrence Livermore National Security, LLC. +# Use is subject to license terms. +# + # # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. diff --git a/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_005_pos.ksh b/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_005_pos.ksh index 13f1288e4e..a2d92673b1 100755 --- a/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_005_pos.ksh +++ b/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_005_pos.ksh @@ -20,6 +20,11 @@ # CDDL HEADER END # +# +# Copyright (c) 2016 by Lawrence Livermore National Security, LLC. +# Use is subject to license terms. +# + . $STF_SUITE/include/libtest.shlib verify_runnable "both" diff --git a/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_006_pos.ksh b/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_006_pos.ksh index 68fc5e3040..38b4ac52e5 100755 --- a/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_006_pos.ksh +++ b/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_006_pos.ksh @@ -20,6 +20,11 @@ # CDDL HEADER END # +# +# Copyright (c) 2016 by Lawrence Livermore National Security, LLC. +# Use is subject to license terms. +# + # # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. diff --git a/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_007_neg.ksh b/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_007_neg.ksh index fb4747839f..59364574b1 100755 --- a/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_007_neg.ksh +++ b/usr/src/test/zfs-tests/tests/functional/large_dnode/large_dnode_007_neg.ksh @@ -20,6 +20,11 @@ # CDDL HEADER END # +# +# Copyright (c) 2016 by Lawrence Livermore National Security, LLC. +# Use is subject to license terms. +# + # # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. diff --git a/usr/src/test/zfs-tests/tests/functional/large_dnode/setup.ksh b/usr/src/test/zfs-tests/tests/functional/large_dnode/setup.ksh index d9b1a6ee85..a9425cca98 100755 --- a/usr/src/test/zfs-tests/tests/functional/large_dnode/setup.ksh +++ b/usr/src/test/zfs-tests/tests/functional/large_dnode/setup.ksh @@ -20,6 +20,11 @@ # CDDL HEADER END # +# +# Copyright (c) 2016 by Lawrence Livermore National Security, LLC. +# Use is subject to license terms. +# + . $STF_SUITE/include/libtest.shlib DISK=${DISKS%% *} diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/send_freeobjects.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/send_freeobjects.ksh new file mode 100755 index 0000000000..6533352a9a --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/rsend/send_freeobjects.ksh @@ -0,0 +1,81 @@ +#!/bin/ksh + +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2017 by Lawrence Livermore National Security, LLC. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/rsend/rsend.kshlib + +# +# Description: +# Verify FREEOBJECTS record frees sequential objects (See +# https://github.com/zfsonlinux/zfs/issues/6694) +# +# Strategy: +# 1. Create three files with sequential object numbers, f1 f2 and f3 +# 2. Delete f2 +# 3. Take snapshot A +# 4. Delete f3 +# 5. Take snapshot B +# 6. Receive a full send of A +# 7. Receive an incremental send of B +# 8. Fail test if f3 exists on received snapshot B +# + +verify_runnable "both" + +log_assert "Verify FREEOBJECTS record frees sequential objects" + +sendds=sendfo +recvds=recvfo +f1=/$POOL/$sendds/f1 +f2=/$POOL/$sendds/f2 +f3=/$POOL/$sendds/f3 + +# +# We need to set xattr=sa and dnodesize=legacy to guarantee sequential +# object numbers for this test. Otherwise, if we used directory-based +# xattrs, SELinux extended attributes might consume intervening object +# numbers. +# +log_must zfs create -o xattr=sa -o dnodesize=legacy $POOL/$sendds + +tries=100 +for ((i=0; i<$tries; i++)); do + touch $f1 $f2 $f3 + o1=$(ls -li $f1 | awk '{print $1}') + o2=$(ls -li $f2 | awk '{print $1}') + o3=$(ls -li $f3 | awk '{print $1}') + + if [[ $o2 -ne $(( $o1 + 1 )) ]] || [[ $o3 -ne $(( $o2 + 1 )) ]]; then + rm -f $f1 $f2 $f3 + else + break + fi +done + +if [[ $i -eq $tries ]]; then + log_fail "Failed to create three sequential objects" +fi + +log_must rm $f2 +log_must zfs snap $POOL/$sendds@A +log_must rm $f3 +log_must zfs snap $POOL/$sendds@B +log_must eval "zfs send $POOL/$sendds@A | zfs recv $POOL/$recvds" +log_must eval "zfs send -i $POOL/$sendds@A $POOL/$sendds@B |" \ + "zfs recv $POOL/$recvds" +log_mustnot zdb $POOL/$recvds@B $o3 +log_pass "Verify FREEOBJECTS record frees sequential objects" diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/send_realloc_dnode_size.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/send_realloc_dnode_size.ksh new file mode 100755 index 0000000000..12a72fa092 --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/rsend/send_realloc_dnode_size.ksh @@ -0,0 +1,111 @@ +#!/bin/ksh + +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2017 by Lawrence Livermore National Security, LLC. +# Copyright (c) 2018 Datto Inc. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/rsend/rsend.kshlib + +# +# Description: +# Verify incremental receive properly handles objects with changed +# dnode slot count. +# +# Strategy: +# 1. Populate a dataset with 1k byte dnodes and snapshot +# 2. Remove objects, set dnodesize=legacy, and remount dataset so new objects +# get recycled numbers and formerly "interior" dnode slots get assigned +# to new objects +# 3. Remove objects, set dnodesize=2k, and remount dataset so new objects +# overlap with recently recycled and formerly "normal" dnode slots get +# assigned to new objects +# 4. Create an empty file and add xattrs to it to exercise reclaiming a +# dnode that requires more than 1 slot for its bonus buffer (Zol #7433) +# 5. Generate initial and incremental streams +# 6. Verify initial and incremental streams can be received +# + +verify_runnable "both" + +log_assert "Verify incremental receive handles objects with changed dnode size" + +function cleanup +{ + rm -f $BACKDIR/fs-dn-legacy + rm -f $BACKDIR/fs-dn-1k + rm -f $BACKDIR/fs-dn-2k + rm -f $BACKDIR/fs-attr + + if datasetexists $POOL/fs ; then + log_must zfs destroy -rR $POOL/fs + fi + + if datasetexists $POOL/newfs ; then + log_must zfs destroy -rR $POOL/newfs + fi +} + +log_onexit cleanup + +# 1. Populate a dataset with 1k byte dnodes and snapshot +log_must zfs create -o dnodesize=1k $POOL/fs +log_must mk_files 200 262144 0 $POOL/fs +log_must zfs snapshot $POOL/fs@a + +# 2. Remove objects, set dnodesize=legacy, and remount dataset so new objects +# get recycled numbers and formerly "interior" dnode slots get assigned +# to new objects +rm /$POOL/fs/* + +log_must zfs unmount $POOL/fs +log_must zfs set dnodesize=legacy $POOL/fs +log_must zfs mount $POOL/fs + +log_must mk_files 200 262144 0 $POOL/fs +log_must zfs snapshot $POOL/fs@b + +# 3. Remove objects, set dnodesize=2k, and remount dataset so new objects +# overlap with recently recycled and formerly "normal" dnode slots get +# assigned to new objects +rm /$POOL/fs/* + +log_must zfs unmount $POOL/fs +log_must zfs set dnodesize=2k $POOL/fs +log_must zfs mount $POOL/fs + +log_must touch /$POOL/fs/attrs +mk_files 200 262144 0 $POOL/fs +log_must zfs snapshot $POOL/fs@c + +# 4. Create an empty file and add xattrs to it to exercise reclaiming a +# dnode that requires more than 1 slot for its bonus buffer (Zol #7433) +log_must zfs set compression=on xattr=sa $POOL/fs +log_must eval "python -c 'print \"a\" * 512' | attr -s bigval /$POOL/fs/attrs" +log_must zfs snapshot $POOL/fs@d + +# 5. Generate initial and incremental streams +log_must eval "zfs send $POOL/fs@a > $BACKDIR/fs-dn-1k" +log_must eval "zfs send -i $POOL/fs@a $POOL/fs@b > $BACKDIR/fs-dn-legacy" +log_must eval "zfs send -i $POOL/fs@b $POOL/fs@c > $BACKDIR/fs-dn-2k" +log_must eval "zfs send -i $POOL/fs@c $POOL/fs@d > $BACKDIR/fs-attr" + +# 6. Verify initial and incremental streams can be received +log_must eval "zfs recv $POOL/newfs < $BACKDIR/fs-dn-1k" +log_must eval "zfs recv $POOL/newfs < $BACKDIR/fs-dn-legacy" +log_must eval "zfs recv $POOL/newfs < $BACKDIR/fs-dn-2k" +log_must eval "zfs recv $POOL/newfs < $BACKDIR/fs-attr" + +log_pass "Verify incremental receive handles objects with changed dnode size" diff --git a/usr/src/uts/common/fs/zfs/dmu_object.c b/usr/src/uts/common/fs/zfs/dmu_object.c index 9895cf4776..f835987e7d 100644 --- a/usr/src/uts/common/fs/zfs/dmu_object.c +++ b/usr/src/uts/common/fs/zfs/dmu_object.c @@ -263,7 +263,7 @@ dmu_object_reclaim(objset_t *os, uint64_t object, dmu_object_type_t ot, int blocksize, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx) { return (dmu_object_reclaim_dnsize(os, object, ot, blocksize, bonustype, - bonuslen, 0, tx)); + bonuslen, DNODE_MIN_SIZE, tx)); } int diff --git a/usr/src/uts/common/fs/zfs/dmu_send.c b/usr/src/uts/common/fs/zfs/dmu_send.c index 8a7e1c56f9..669435aa05 100644 --- a/usr/src/uts/common/fs/zfs/dmu_send.c +++ b/usr/src/uts/common/fs/zfs/dmu_send.c @@ -2205,11 +2205,13 @@ receive_object(struct receive_writer_arg *rwa, struct drr_object *drro, } else if (drro->drr_type != doi.doi_type || drro->drr_blksz != doi.doi_data_block_size || drro->drr_bonustype != doi.doi_bonus_type || - drro->drr_bonuslen != doi.doi_bonus_size) { + drro->drr_bonuslen != doi.doi_bonus_size || + drro->drr_dn_slots != (doi.doi_dnodesize >> DNODE_SHIFT)) { /* currently allocated, but with different properties */ - err = dmu_object_reclaim(rwa->os, drro->drr_object, + err = dmu_object_reclaim_dnsize(rwa->os, drro->drr_object, drro->drr_type, drro->drr_blksz, - drro->drr_bonustype, drro->drr_bonuslen, tx); + drro->drr_bonustype, drro->drr_bonuslen, + drro->drr_dn_slots << DNODE_SHIFT, tx); } if (err != 0) { dmu_tx_commit(tx); @@ -2259,12 +2261,10 @@ receive_freeobjects(struct receive_writer_arg *rwa, int err; err = dmu_object_info(rwa->os, obj, NULL); - if (err == ENOENT) { - obj++; + if (err == ENOENT) continue; - } else if (err != 0) { + else if (err != 0) return (err); - } err = dmu_free_long_object(rwa->os, obj); if (err != 0) diff --git a/usr/src/uts/common/fs/zfs/dnode.c b/usr/src/uts/common/fs/zfs/dnode.c index 972aebf45c..73b97c2449 100644 --- a/usr/src/uts/common/fs/zfs/dnode.c +++ b/usr/src/uts/common/fs/zfs/dnode.c @@ -683,8 +683,7 @@ dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize, ASSERT(DMU_OT_IS_VALID(bonustype)); ASSERT3U(bonuslen, <=, DN_BONUS_SIZE(spa_maxdnodesize(dmu_objset_spa(dn->dn_objset)))); - - dn_slots = dn_slots > 0 ? dn_slots : DNODE_MIN_SLOTS; + ASSERT3U(bonuslen, <=, DN_BONUS_SIZE(dn_slots << DNODE_SHIFT)); dnode_free_interior_slots(dn); DNODE_STAT_BUMP(dnode_reallocate); -- cgit v1.2.3