Print this page
NEX-18463 Parallel dump produces corrupted dump file
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-17845 Remove support for BZIP2 from dump
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-17857 Parallel dump threshold (dump_ncpu_low) is not applied
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-17501 Enable parallel crash dump
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-17762 After a live dump (savecore -L) a subsequent panic will be saved in wrong directory
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Alexander Eremin <alexander.eremin@nexenta.com>
NEX-17182 Parallel dump hangs (fix typo)
Reviewed by: Jean McCormack <jean.mccormack@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-17182 Parallel dump hangs
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-9338 improve the layout of the crash directory (use sys/uuid.h)
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-9338 improve the layout of the crash directory
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Steve Peng <steve.peng@nexenta.com>
NEX-5164 backport illumos 6514 AS_* lock macros simplification
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
6514 AS_* lock macros simplification
Reviewed by: Piotr Jasiukajtis <estibi@me.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Albert Lee <trisk@omniti.com>
Approved by: Dan McDonald <danmcd@omniti.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/os/dumpsubr.c
          +++ new/usr/src/uts/common/os/dumpsubr.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright 2016 Joyent, Inc.
       25 + * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
  25   26   */
  26   27  
  27   28  #include <sys/types.h>
  28   29  #include <sys/param.h>
  29   30  #include <sys/systm.h>
  30   31  #include <sys/vm.h>
  31   32  #include <sys/proc.h>
  32   33  #include <sys/file.h>
  33   34  #include <sys/conf.h>
  34   35  #include <sys/kmem.h>
↓ open down ↓ 29 lines elided ↑ open up ↑
  64   65  #include <sys/fs/zfs.h>
  65   66  
  66   67  #include <vm/hat.h>
  67   68  #include <vm/as.h>
  68   69  #include <vm/page.h>
  69   70  #include <vm/pvn.h>
  70   71  #include <vm/seg.h>
  71   72  #include <vm/seg_kmem.h>
  72   73  #include <sys/clock_impl.h>
  73   74  #include <sys/hold_page.h>
       75 +#include <sys/cpu.h>
  74   76  
  75      -#include <bzip2/bzlib.h>
       77 +#include <sys/uuid.h>
  76   78  
  77   79  /*
  78      - * Crash dump time is dominated by disk write time.  To reduce this,
  79      - * the stronger compression method bzip2 is applied to reduce the dump
  80      - * size and hence reduce I/O time.  However, bzip2 is much more
  81      - * computationally expensive than the existing lzjb algorithm, so to
  82      - * avoid increasing compression time, CPUs that are otherwise idle
  83      - * during panic are employed to parallelize the compression task.
  84      - * Many helper CPUs are needed to prevent bzip2 from being a
  85      - * bottleneck, and on systems with too few CPUs, the lzjb algorithm is
  86      - * parallelized instead. Lastly, I/O and compression are performed by
  87      - * different CPUs, and are hence overlapped in time, unlike the older
  88      - * serial code.
  89      - *
  90      - * Another important consideration is the speed of the dump
  91      - * device. Faster disks need less CPUs in order to benefit from
  92      - * parallel lzjb versus parallel bzip2. Therefore, the CPU count
  93      - * threshold for switching from parallel lzjb to paralled bzip2 is
  94      - * elevated for faster disks. The dump device speed is adduced from
  95      - * the setting for dumpbuf.iosize, see dump_update_clevel.
       80 + * Parallel Dump:
       81 + * CPUs that are otherwise idle during panic are employed to parallelize
       82 + * the compression task. I/O and compression are performed by different
       83 + * CPUs, and are hence overlapped in time, unlike the older serial code.
  96   84   */
  97   85  
  98   86  /*
  99   87   * exported vars
 100   88   */
 101   89  kmutex_t        dump_lock;              /* lock for dump configuration */
 102   90  dumphdr_t       *dumphdr;               /* dump header */
 103   91  int             dump_conflags = DUMP_KERNEL; /* dump configuration flags */
 104   92  vnode_t         *dumpvp;                /* dump device vnode pointer */
 105   93  u_offset_t      dumpvp_size;            /* size of dump device, in bytes */
 106   94  char            *dumppath;              /* pathname of dump device */
 107   95  int             dump_timeout = 120;     /* timeout for dumping pages */
 108   96  int             dump_timeleft;          /* portion of dump_timeout remaining */
 109   97  int             dump_ioerr;             /* dump i/o error */
 110   98  int             dump_check_used;        /* enable check for used pages */
 111      -char        *dump_stack_scratch; /* scratch area for saving stack summary */
       99 +char            *dump_stack_scratch; /* scratch area for saving stack summary */
 112  100  
 113  101  /*
 114      - * Tunables for dump compression and parallelism. These can be set via
 115      - * /etc/system.
      102 + * Tunables for dump compression and parallelism.
      103 + * These can be set via /etc/system.
 116  104   *
 117      - * dump_ncpu_low        number of helpers for parallel lzjb
 118      - *      This is also the minimum configuration.
      105 + * dump_ncpu_low:
      106 + * This is the minimum configuration for parallel lzjb.
      107 + * A special value of 0 means that parallel dump will not be used.
 119  108   *
 120      - * dump_bzip2_level     bzip2 compression level: 1-9
 121      - *      Higher numbers give greater compression, but take more memory
 122      - *      and time. Memory used per helper is ~(dump_bzip2_level * 1MB).
 123      - *
 124      - * dump_plat_mincpu     the cross-over limit for using bzip2 (per platform):
 125      - *      if dump_plat_mincpu == 0, then always do single threaded dump
 126      - *      if ncpu >= dump_plat_mincpu then try to use bzip2
 127      - *
 128      - * dump_metrics_on      if set, metrics are collected in the kernel, passed
 129      - *      to savecore via the dump file, and recorded by savecore in
 130      - *      METRICS.txt.
      109 + * dump_metrics_on:
      110 + * If set, metrics are collected in the kernel, passed to savecore
      111 + * via the dump file, and recorded by savecore in METRICS.txt.
 131  112   */
 132  113  uint_t dump_ncpu_low = 4;       /* minimum config for parallel lzjb */
 133      -uint_t dump_bzip2_level = 1;    /* bzip2 level (1-9) */
 134  114  
 135      -/* Use dump_plat_mincpu_default unless this variable is set by /etc/system */
 136      -#define MINCPU_NOT_SET  ((uint_t)-1)
 137      -uint_t dump_plat_mincpu = MINCPU_NOT_SET;
 138      -
 139  115  /* tunables for pre-reserved heap */
 140  116  uint_t dump_kmem_permap = 1024;
 141  117  uint_t dump_kmem_pages = 8;
 142  118  
 143  119  /* Define multiple buffers per helper to avoid stalling */
 144  120  #define NCBUF_PER_HELPER        2
 145  121  #define NCMAP_PER_HELPER        4
 146  122  
 147  123  /* minimum number of helpers configured */
 148      -#define MINHELPERS      (dump_ncpu_low)
      124 +#define MINHELPERS      (MAX(dump_ncpu_low, 1))
 149  125  #define MINCBUFS        (MINHELPERS * NCBUF_PER_HELPER)
 150  126  
 151  127  /*
 152  128   * Define constant parameters.
 153  129   *
 154  130   * CBUF_SIZE            size of an output buffer
 155  131   *
 156  132   * CBUF_MAPSIZE         size of virtual range for mapping pages
 157  133   *
 158  134   * CBUF_MAPNP           size of virtual range in pages
↓ open down ↓ 94 lines elided ↑ open up ↑
 253  229          cbufstate_t state;              /* processing state */
 254  230          size_t used;                    /* amount used */
 255  231          size_t size;                    /* mem size */
 256  232          char *buf;                      /* kmem or vmem */
 257  233          pgcnt_t pagenum;                /* index to pfn map */
 258  234          pgcnt_t bitnum;                 /* first set bitnum */
 259  235          pfn_t pfn;                      /* first pfn in mapped range */
 260  236          int off;                        /* byte offset to first pfn */
 261  237  };
 262  238  
 263      -static char dump_osimage_uuid[36 + 1];
      239 +static char dump_osimage_uuid[UUID_PRINTABLE_STRING_LENGTH];
 264  240  
 265  241  #define isdigit(ch)     ((ch) >= '0' && (ch) <= '9')
 266  242  #define isxdigit(ch)    (isdigit(ch) || ((ch) >= 'a' && (ch) <= 'f') || \
 267  243                          ((ch) >= 'A' && (ch) <= 'F'))
 268  244  
 269  245  /*
 270  246   * cqueue_t queues: a uni-directional channel for communication
 271  247   * from the master to helper tasks or vice-versa using put and
 272  248   * get primitives. Both mappings and data buffers are passed via
 273  249   * queues. Producers close a queue when done. The number of
↓ open down ↓ 99 lines elided ↑ open up ↑
 373  349          int tag;                        /* compression stream tag */
 374  350          perpage_t perpage;              /* per page metrics */
 375  351          perpage_t perpagets;            /* per page metrics (timestamps) */
 376  352          taskqid_t taskqid;              /* live dump task ptr */
 377  353          int in, out;                    /* buffer offsets */
 378  354          cbuf_t *cpin, *cpout, *cperr;   /* cbuf objects in process */
 379  355          dumpsync_t *ds;                 /* pointer to sync vars */
 380  356          size_t used;                    /* counts input consumed */
 381  357          char *page;                     /* buffer for page copy */
 382  358          char *lzbuf;                    /* lzjb output */
 383      -        bz_stream bzstream;             /* bzip2 state */
 384  359  } helper_t;
 385  360  
 386  361  #define MAINHELPER      (-1)            /* helper is also the main task */
 387  362  #define FREEHELPER      (-2)            /* unbound helper */
 388  363  #define DONEHELPER      (-3)            /* helper finished */
 389  364  
 390  365  /*
 391  366   * configuration vars for dumpsys
 392  367   */
 393  368  typedef struct dumpcfg {
 394      -        int     threshold;      /* ncpu threshold for bzip2 */
 395  369          int     nhelper;        /* number of helpers */
 396  370          int     nhelper_used;   /* actual number of helpers used */
 397  371          int     ncmap;          /* number VA pages for compression */
 398  372          int     ncbuf;          /* number of bufs for compression */
 399  373          int     ncbuf_used;     /* number of bufs in use */
 400  374          uint_t  clevel;         /* dump compression level */
 401  375          helper_t *helper;       /* array of helpers */
 402  376          cbuf_t  *cmap;          /* array of input (map) buffers */
 403  377          cbuf_t  *cbuf;          /* array of output  buffers */
 404  378          ulong_t *helpermap;     /* set of dumpsys helper CPU ids */
↓ open down ↓ 26 lines elided ↑ open up ↑
 431  405          char    *cur;           /* dump write pointer */
 432  406          char    *start;         /* dump buffer address */
 433  407          char    *end;           /* dump buffer end */
 434  408          size_t  size;           /* size of dumpbuf in bytes */
 435  409          size_t  iosize;         /* best transfer size for device */
 436  410  } dumpbuf_t;
 437  411  
 438  412  dumpbuf_t dumpbuf;              /* I/O buffer */
 439  413  
 440  414  /*
      415 + * DUMP_HELPER_MAX_WAIT
      416 + * For parallel dump, defines maximum time main task thread will wait
      417 + * for at least one helper to register in dumpcfg.helpermap, before
      418 + * assuming there are no helpers and falling back to serial mode.
      419 + */
      420 +#define DUMP_HELPER_MAX_WAIT    1000    /* millisec */
      421 +
      422 +/*
 441  423   * The dump I/O buffer must be at least one page, at most xfer_size
 442  424   * bytes, and should scale with physmem in between.  The transfer size
 443  425   * passed in will either represent a global default (maxphys) or the
 444  426   * best size for the device.  The size of the dumpbuf I/O buffer is
 445  427   * limited by dumpbuf_limit (8MB by default) because the dump
 446  428   * performance saturates beyond a certain size.  The default is to
 447  429   * select 1/4096 of the memory.
 448  430   */
 449  431  static int      dumpbuf_fraction = 12;  /* memory size scale factor */
 450  432  static size_t   dumpbuf_limit = 8 * DUMP_1MB;   /* max I/O buf size */
↓ open down ↓ 31 lines elided ↑ open up ↑
 482  464  
 483  465          new_buf = kmem_alloc(new_size, KM_SLEEP);
 484  466          dumpbuf.size = new_size;
 485  467          dumpbuf.start = new_buf;
 486  468          dumpbuf.end = new_buf + new_size;
 487  469          kmem_free(old_buf, old_size);
 488  470  }
 489  471  
 490  472  /*
 491  473   * dump_update_clevel is called when dumpadm configures the dump device.
 492      - *      Calculate number of helpers and buffers.
 493      - *      Allocate the minimum configuration for now.
      474 + *      Determine the compression level / type
      475 + *      - DUMP_CLEVEL_SERIAL is single threaded lzjb
      476 + *      - DUMP_CLEVEL_LZJB   is parallel lzjb
      477 + *      Calculate number of helpers and buffers.
      478 + *      Allocate the minimum configuration for now.
 494  479   *
 495  480   * When the dump file is configured we reserve a minimum amount of
 496  481   * memory for use at crash time. But we reserve VA for all the memory
 497  482   * we really want in order to do the fastest dump possible. The VA is
 498  483   * backed by pages not being dumped, according to the bitmap. If
 499  484   * there is insufficient spare memory, however, we fall back to the
 500  485   * minimum.
 501  486   *
 502  487   * Live dump (savecore -L) always uses the minimum config.
 503  488   *
 504      - * clevel 0 is single threaded lzjb
 505      - * clevel 1 is parallel lzjb
 506      - * clevel 2 is parallel bzip2
 507      - *
 508      - * The ncpu threshold is selected with dump_plat_mincpu.
 509      - * On OPL, set_platform_defaults() overrides the sun4u setting.
 510      - * The actual values are defined via DUMP_PLAT_*_MINCPU macros.
 511      - *
 512      - * Architecture         Threshold       Algorithm
 513      - * sun4u                <  51           parallel lzjb
 514      - * sun4u                >= 51           parallel bzip2(*)
 515      - * sun4u OPL            <  8            parallel lzjb
 516      - * sun4u OPL            >= 8            parallel bzip2(*)
 517      - * sun4v                <  128          parallel lzjb
 518      - * sun4v                >= 128          parallel bzip2(*)
 519      - * x86                  < 11            parallel lzjb
 520      - * x86                  >= 11           parallel bzip2(*)
 521      - * 32-bit               N/A             single-threaded lzjb
 522      - *
 523      - * (*) bzip2 is only chosen if there is sufficient available
 524      - * memory for buffers at dump time. See dumpsys_get_maxmem().
 525      - *
 526      - * Faster dump devices have larger I/O buffers. The threshold value is
 527      - * increased according to the size of the dump I/O buffer, because
 528      - * parallel lzjb performs better with faster disks. For buffers >= 1MB
 529      - * the threshold is 3X; for buffers >= 256K threshold is 2X.
 530      - *
 531  489   * For parallel dumps, the number of helpers is ncpu-1. The CPU
 532  490   * running panic runs the main task. For single-threaded dumps, the
 533  491   * panic CPU does lzjb compression (it is tagged as MAINHELPER.)
 534  492   *
 535  493   * Need multiple buffers per helper so that they do not block waiting
 536  494   * for the main task.
 537  495   *                              parallel        single-threaded
 538  496   * Number of output buffers:    nhelper*2               1
 539  497   * Number of mapping buffers:   nhelper*4               1
 540  498   *
 541  499   */
 542  500  static void
 543  501  dump_update_clevel()
 544  502  {
 545  503          int tag;
 546      -        size_t bz2size;
 547  504          helper_t *hp, *hpend;
 548  505          cbuf_t *cp, *cpend;
 549  506          dumpcfg_t *old = &dumpcfg;
 550  507          dumpcfg_t newcfg = *old;
 551  508          dumpcfg_t *new = &newcfg;
 552  509  
 553  510          ASSERT(MUTEX_HELD(&dump_lock));
 554  511  
 555  512          /*
 556  513           * Free the previously allocated bufs and VM.
↓ open down ↓ 32 lines elided ↑ open up ↑
 589  546           * Allocate memory and VM.
 590  547           * One CPU runs dumpsys, the rest are helpers.
 591  548           */
 592  549          new->nhelper = ncpus - 1;
 593  550          if (new->nhelper < 1)
 594  551                  new->nhelper = 1;
 595  552  
 596  553          if (new->nhelper > DUMP_MAX_NHELPER)
 597  554                  new->nhelper = DUMP_MAX_NHELPER;
 598  555  
 599      -        /* use platform default, unless /etc/system overrides */
 600      -        if (dump_plat_mincpu == MINCPU_NOT_SET)
 601      -                dump_plat_mincpu = dump_plat_mincpu_default;
 602      -
 603      -        /* increase threshold for faster disks */
 604      -        new->threshold = dump_plat_mincpu;
 605      -        if (dumpbuf.iosize >= DUMP_1MB)
 606      -                new->threshold *= 3;
 607      -        else if (dumpbuf.iosize >= (256 * DUMP_1KB))
 608      -                new->threshold *= 2;
 609      -
 610      -        /* figure compression level based upon the computed threshold. */
 611      -        if (dump_plat_mincpu == 0 || new->nhelper < 2) {
 612      -                new->clevel = 0;
      556 +        /* If dump_ncpu_low is 0 or greater than ncpus, do serial dump */
      557 +        if (dump_ncpu_low == 0 || dump_ncpu_low > ncpus || new->nhelper < 2) {
      558 +                new->clevel = DUMP_CLEVEL_SERIAL;
 613  559                  new->nhelper = 1;
 614      -        } else if ((new->nhelper + 1) >= new->threshold) {
 615      -                new->clevel = DUMP_CLEVEL_BZIP2;
 616      -        } else {
 617      -                new->clevel = DUMP_CLEVEL_LZJB;
 618      -        }
 619      -
 620      -        if (new->clevel == 0) {
 621  560                  new->ncbuf = 1;
 622  561                  new->ncmap = 1;
 623  562          } else {
      563 +                new->clevel = DUMP_CLEVEL_LZJB;
 624  564                  new->ncbuf = NCBUF_PER_HELPER * new->nhelper;
 625  565                  new->ncmap = NCMAP_PER_HELPER * new->nhelper;
 626  566          }
 627  567  
 628  568          /*
 629  569           * Allocate new data structures and buffers for MINHELPERS,
 630  570           * and also figure the max desired size.
 631  571           */
 632      -        bz2size = BZ2_bzCompressInitSize(dump_bzip2_level);
 633  572          new->maxsize = 0;
 634  573          new->maxvmsize = 0;
 635  574          new->maxvm = NULL;
 636  575          tag = 1;
 637  576          new->helper = kmem_zalloc(new->nhelper * sizeof (helper_t), KM_SLEEP);
 638  577          hpend = &new->helper[new->nhelper];
 639  578          for (hp = new->helper; hp != hpend; hp++) {
 640  579                  hp->tag = tag++;
 641  580                  if (hp < &new->helper[MINHELPERS]) {
 642  581                          hp->lzbuf = kmem_alloc(PAGESIZE, KM_SLEEP);
 643  582                          hp->page = kmem_alloc(PAGESIZE, KM_SLEEP);
 644      -                } else if (new->clevel < DUMP_CLEVEL_BZIP2) {
      583 +                } else  {
 645  584                          new->maxsize += 2 * PAGESIZE;
 646      -                } else {
 647      -                        new->maxsize += PAGESIZE;
 648  585                  }
 649      -                if (new->clevel >= DUMP_CLEVEL_BZIP2)
 650      -                        new->maxsize += bz2size;
 651  586          }
 652  587  
 653  588          new->cbuf = kmem_zalloc(new->ncbuf * sizeof (cbuf_t), KM_SLEEP);
 654  589          cpend = &new->cbuf[new->ncbuf];
 655  590          for (cp = new->cbuf; cp != cpend; cp++) {
 656  591                  cp->state = CBUF_FREEBUF;
 657  592                  cp->size = CBUF_SIZE;
 658  593                  if (cp < &new->cbuf[MINCBUFS])
 659  594                          cp->buf = kmem_alloc(cp->size, KM_SLEEP);
 660  595                  else
↓ open down ↓ 132 lines elided ↑ open up ↑
 793  728          bitnum = dump_pfn_to_bitnum(pfn);
 794  729          ASSERT(bitnum != (pgcnt_t)-1);
 795  730  
 796  731          rbitnum = CBUF_MAPP2R(bitnum);
 797  732          ASSERT(rbitnum < dumpcfg.rbitmapsize);
 798  733  
 799  734          return (BT_TEST(dumpcfg.rbitmap, rbitnum));
 800  735  }
 801  736  
 802  737  /*
 803      - * dumpbzalloc and dumpbzfree are callbacks from the bzip2 library.
 804      - * dumpsys_get_maxmem() uses them for BZ2_bzCompressInit().
 805      - */
 806      -static void *
 807      -dumpbzalloc(void *opaque, int items, int size)
 808      -{
 809      -        size_t *sz;
 810      -        char *ret;
 811      -
 812      -        ASSERT(opaque != NULL);
 813      -        sz = opaque;
 814      -        ret = dumpcfg.maxvm + *sz;
 815      -        *sz += items * size;
 816      -        *sz = P2ROUNDUP(*sz, BZ2_BZALLOC_ALIGN);
 817      -        ASSERT(*sz <= dumpcfg.maxvmsize);
 818      -        return (ret);
 819      -}
 820      -
 821      -/*ARGSUSED*/
 822      -static void
 823      -dumpbzfree(void *opaque, void *addr)
 824      -{
 825      -}
 826      -
 827      -/*
 828  738   * Perform additional checks on the page to see if we can really use
 829  739   * it. The kernel (kas) pages are always set in the bitmap. However,
 830  740   * boot memory pages (prom_ppages or P_BOOTPAGES) are not in the
 831  741   * bitmap. So we check for them.
 832  742   */
 833  743  static inline int
 834  744  dump_pfn_check(pfn_t pfn)
 835  745  {
 836  746          page_t *pp = page_numtopp_nolock(pfn);
 837  747          if (pp == NULL || pp->p_pagenum != pfn ||
↓ open down ↓ 18 lines elided ↑ open up ↑
 856  766                  if (BT_TEST(dumpcfg.bitmap, start))
 857  767                          return (0);
 858  768                  if (!dump_pfn_check(pfn))
 859  769                          return (0);
 860  770          }
 861  771          return (1);
 862  772  }
 863  773  
 864  774  /*
 865  775   * dumpsys_get_maxmem() is called during panic. Find unused ranges
 866      - * and use them for buffers. If we find enough memory switch to
 867      - * parallel bzip2, otherwise use parallel lzjb.
 868      - *
      776 + * and use them for buffers.
 869  777   * It searches the dump bitmap in 2 passes. The first time it looks
 870  778   * for CBUF_MAPSIZE ranges. On the second pass it uses small pages.
 871  779   */
 872  780  static void
 873  781  dumpsys_get_maxmem()
 874  782  {
 875  783          dumpcfg_t *cfg = &dumpcfg;
 876  784          cbuf_t *endcp = &cfg->cbuf[cfg->ncbuf];
 877  785          helper_t *endhp = &cfg->helper[cfg->nhelper];
 878  786          pgcnt_t bitnum, end;
 879      -        size_t sz, endsz, bz2size;
      787 +        size_t sz, endsz;
 880  788          pfn_t pfn, off;
 881  789          cbuf_t *cp;
 882      -        helper_t *hp, *ohp;
      790 +        helper_t *hp;
 883  791          dumpmlw_t mlw;
 884  792          int k;
 885  793  
 886  794          /*
 887      -         * Setting dump_plat_mincpu to 0 at any time forces a serial
 888      -         * dump.
      795 +         * Setting dump_ncpu_low to 0 forces a single threaded dump.
 889  796           */
 890      -        if (dump_plat_mincpu == 0) {
 891      -                cfg->clevel = 0;
      797 +        if (dump_ncpu_low == 0) {
      798 +                cfg->clevel = DUMP_CLEVEL_SERIAL;
 892  799                  return;
 893  800          }
 894  801  
 895  802          /*
 896  803           * There may be no point in looking for spare memory. If
 897  804           * dumping all memory, then none is spare. If doing a serial
 898  805           * dump, then already have buffers.
 899  806           */
 900      -        if (cfg->maxsize == 0 || cfg->clevel < DUMP_CLEVEL_LZJB ||
      807 +        if (cfg->maxsize == 0 || cfg->clevel == DUMP_CLEVEL_SERIAL ||
 901  808              (dump_conflags & DUMP_ALL) != 0) {
 902      -                if (cfg->clevel > DUMP_CLEVEL_LZJB)
 903      -                        cfg->clevel = DUMP_CLEVEL_LZJB;
 904  809                  return;
 905  810          }
 906  811  
 907  812          sz = 0;
 908  813          cfg->found4m = 0;
 909  814          cfg->foundsm = 0;
 910  815  
 911  816          /* bitmap of ranges used to estimate which pfns are being used */
 912  817          bzero(dumpcfg.rbitmap, BT_SIZEOFMAP(dumpcfg.rbitmapsize));
 913  818  
↓ open down ↓ 63 lines elided ↑ open up ↑
 977  882                          hat_devload(kas.a_hat, cfg->maxvm + sz, PAGESIZE, pfn,
 978  883                              PROT_READ | PROT_WRITE, HAT_LOAD_NOCONSIST);
 979  884                          sz += PAGESIZE;
 980  885                          cfg->foundsm++;
 981  886                          dump_set_used(pfn);
 982  887                          if (sz >= cfg->maxsize)
 983  888                                  goto foundmax;
 984  889                  }
 985  890          }
 986  891  
 987      -        /* Fall back to lzjb if we did not get enough memory for bzip2. */
 988      -        endsz = (cfg->maxsize * cfg->threshold) / cfg->nhelper;
 989      -        if (sz < endsz) {
 990      -                cfg->clevel = DUMP_CLEVEL_LZJB;
 991      -        }
 992      -
 993  892          /* Allocate memory for as many helpers as we can. */
 994  893  foundmax:
 995  894  
 996  895          /* Byte offsets into memory found and mapped above */
 997  896          endsz = sz;
 998  897          sz = 0;
 999  898  
1000      -        /* Set the size for bzip2 state. Only bzip2 needs it. */
1001      -        bz2size = BZ2_bzCompressInitSize(dump_bzip2_level);
1002      -
1003  899          /* Skip the preallocate output buffers. */
1004  900          cp = &cfg->cbuf[MINCBUFS];
1005  901  
1006      -        /* Use this to move memory up from the preallocated helpers. */
1007      -        ohp = cfg->helper;
1008      -
1009  902          /* Loop over all helpers and allocate memory. */
1010  903          for (hp = cfg->helper; hp < endhp; hp++) {
1011  904  
1012  905                  /* Skip preallocated helpers by checking hp->page. */
1013  906                  if (hp->page == NULL) {
1014      -                        if (cfg->clevel <= DUMP_CLEVEL_LZJB) {
1015      -                                /* lzjb needs 2 1-page buffers */
1016      -                                if ((sz + (2 * PAGESIZE)) > endsz)
1017      -                                        break;
1018      -                                hp->page = cfg->maxvm + sz;
1019      -                                sz += PAGESIZE;
1020      -                                hp->lzbuf = cfg->maxvm + sz;
1021      -                                sz += PAGESIZE;
1022      -
1023      -                        } else if (ohp->lzbuf != NULL) {
1024      -                                /* re-use the preallocted lzjb page for bzip2 */
1025      -                                hp->page = ohp->lzbuf;
1026      -                                ohp->lzbuf = NULL;
1027      -                                ++ohp;
1028      -
1029      -                        } else {
1030      -                                /* bzip2 needs a 1-page buffer */
1031      -                                if ((sz + PAGESIZE) > endsz)
1032      -                                        break;
1033      -                                hp->page = cfg->maxvm + sz;
1034      -                                sz += PAGESIZE;
1035      -                        }
      907 +                        /* lzjb needs 2 1-page buffers */
      908 +                        if ((sz + (2 * PAGESIZE)) > endsz)
      909 +                                break;
      910 +                        hp->page = cfg->maxvm + sz;
      911 +                        sz += PAGESIZE;
      912 +                        hp->lzbuf = cfg->maxvm + sz;
      913 +                        sz += PAGESIZE;
1036  914                  }
1037  915  
1038  916                  /*
1039  917                   * Add output buffers per helper. The number of
1040  918                   * buffers per helper is determined by the ratio of
1041  919                   * ncbuf to nhelper.
1042  920                   */
1043  921                  for (k = 0; cp < endcp && (sz + CBUF_SIZE) <= endsz &&
1044  922                      k < NCBUF_PER_HELPER; k++) {
1045  923                          cp->state = CBUF_FREEBUF;
1046  924                          cp->size = CBUF_SIZE;
1047  925                          cp->buf = cfg->maxvm + sz;
1048  926                          sz += CBUF_SIZE;
1049  927                          ++cp;
1050  928                  }
1051      -
1052      -                /*
1053      -                 * bzip2 needs compression state. Use the dumpbzalloc
1054      -                 * and dumpbzfree callbacks to allocate the memory.
1055      -                 * bzip2 does allocation only at init time.
1056      -                 */
1057      -                if (cfg->clevel >= DUMP_CLEVEL_BZIP2) {
1058      -                        if ((sz + bz2size) > endsz) {
1059      -                                hp->page = NULL;
1060      -                                break;
1061      -                        } else {
1062      -                                hp->bzstream.opaque = &sz;
1063      -                                hp->bzstream.bzalloc = dumpbzalloc;
1064      -                                hp->bzstream.bzfree = dumpbzfree;
1065      -                                (void) BZ2_bzCompressInit(&hp->bzstream,
1066      -                                    dump_bzip2_level, 0, 0);
1067      -                                hp->bzstream.opaque = NULL;
1068      -                        }
1069      -                }
1070  929          }
1071  930  
1072  931          /* Finish allocating output buffers */
1073  932          for (; cp < endcp && (sz + CBUF_SIZE) <= endsz; cp++) {
1074  933                  cp->state = CBUF_FREEBUF;
1075  934                  cp->size = CBUF_SIZE;
1076  935                  cp->buf = cfg->maxvm + sz;
1077  936                  sz += CBUF_SIZE;
1078  937          }
1079  938  
↓ open down ↓ 823 lines elided ↑ open up ↑
1903 1762                          HRSTOP(hp->perpage, copy);
1904 1763                          break;
1905 1764  
1906 1765                  } else {
1907 1766  
1908 1767                          /*
1909 1768                           * Done with the input. Flush the VM and
1910 1769                           * return the buffer to the main task.
1911 1770                           */
1912 1771                          if (panicstr && hp->helper != MAINHELPER)
1913      -                                hat_flush_range(kas.a_hat,
1914      -                                    hp->cpin->buf, hp->cpin->size);
     1772 +                                hat_flush();
1915 1773                          dumpsys_errmsg(hp, NULL);
1916 1774                          CQ_PUT(mainq, hp->cpin, CBUF_USEDMAP);
1917 1775                          hp->cpin = NULL;
1918 1776                  }
1919 1777          }
1920 1778  
1921 1779          return (hp->cpin != NULL);
1922 1780  }
1923 1781  
1924 1782  /*
1925      - * Compress size bytes starting at buf with bzip2
1926      - * mode:
1927      - *      BZ_RUN          add one more compressed page
1928      - *      BZ_FINISH       no more input, flush the state
1929      - */
1930      -static void
1931      -dumpsys_bzrun(helper_t *hp, void *buf, size_t size, int mode)
1932      -{
1933      -        dumpsync_t *ds = hp->ds;
1934      -        const int CSIZE = sizeof (dumpcsize_t);
1935      -        bz_stream *ps = &hp->bzstream;
1936      -        int rc = 0;
1937      -        uint32_t csize;
1938      -        dumpcsize_t cs;
1939      -
1940      -        /* Set input pointers to new input page */
1941      -        if (size > 0) {
1942      -                ps->avail_in = size;
1943      -                ps->next_in = buf;
1944      -        }
1945      -
1946      -        /* CONSTCOND */
1947      -        while (1) {
1948      -
1949      -                /* Quit when all input has been consumed */
1950      -                if (ps->avail_in == 0 && mode == BZ_RUN)
1951      -                        break;
1952      -
1953      -                /* Get a new output buffer */
1954      -                if (hp->cpout == NULL) {
1955      -                        HRSTART(hp->perpage, outwait);
1956      -                        hp->cpout = CQ_GET(freebufq);
1957      -                        HRSTOP(hp->perpage, outwait);
1958      -                        ps->avail_out = hp->cpout->size - CSIZE;
1959      -                        ps->next_out = hp->cpout->buf + CSIZE;
1960      -                }
1961      -
1962      -                /* Compress input, or finalize */
1963      -                HRSTART(hp->perpage, compress);
1964      -                rc = BZ2_bzCompress(ps, mode);
1965      -                HRSTOP(hp->perpage, compress);
1966      -
1967      -                /* Check for error */
1968      -                if (mode == BZ_RUN && rc != BZ_RUN_OK) {
1969      -                        dumpsys_errmsg(hp, "%d: BZ_RUN error %s at page %lx\n",
1970      -                            hp->helper, BZ2_bzErrorString(rc),
1971      -                            hp->cpin->pagenum);
1972      -                        break;
1973      -                }
1974      -
1975      -                /* Write the buffer if it is full, or we are flushing */
1976      -                if (ps->avail_out == 0 || mode == BZ_FINISH) {
1977      -                        csize = hp->cpout->size - CSIZE - ps->avail_out;
1978      -                        cs = DUMP_SET_TAG(csize, hp->tag);
1979      -                        if (csize > 0) {
1980      -                                (void) memcpy(hp->cpout->buf, &cs, CSIZE);
1981      -                                dumpsys_swrite(hp, hp->cpout, csize + CSIZE);
1982      -                                hp->cpout = NULL;
1983      -                        }
1984      -                }
1985      -
1986      -                /* Check for final complete */
1987      -                if (mode == BZ_FINISH) {
1988      -                        if (rc == BZ_STREAM_END)
1989      -                                break;
1990      -                        if (rc != BZ_FINISH_OK) {
1991      -                                dumpsys_errmsg(hp, "%d: BZ_FINISH error %s\n",
1992      -                                    hp->helper, BZ2_bzErrorString(rc));
1993      -                                break;
1994      -                        }
1995      -                }
1996      -        }
1997      -
1998      -        /* Cleanup state and buffers */
1999      -        if (mode == BZ_FINISH) {
2000      -
2001      -                /* Reset state so that it is re-usable. */
2002      -                (void) BZ2_bzCompressReset(&hp->bzstream);
2003      -
2004      -                /* Give any unused outout buffer to the main task */
2005      -                if (hp->cpout != NULL) {
2006      -                        hp->cpout->used = 0;
2007      -                        CQ_PUT(mainq, hp->cpout, CBUF_ERRMSG);
2008      -                        hp->cpout = NULL;
2009      -                }
2010      -        }
2011      -}
2012      -
2013      -static void
2014      -dumpsys_bz2compress(helper_t *hp)
2015      -{
2016      -        dumpsync_t *ds = hp->ds;
2017      -        dumpstreamhdr_t sh;
2018      -
2019      -        (void) strcpy(sh.stream_magic, DUMP_STREAM_MAGIC);
2020      -        sh.stream_pagenum = (pgcnt_t)-1;
2021      -        sh.stream_npages = 0;
2022      -        hp->cpin = NULL;
2023      -        hp->cpout = NULL;
2024      -        hp->cperr = NULL;
2025      -        hp->in = 0;
2026      -        hp->out = 0;
2027      -        hp->bzstream.avail_in = 0;
2028      -
2029      -        /* Bump reference to mainq while we are running */
2030      -        CQ_OPEN(mainq);
2031      -
2032      -        /* Get one page at a time */
2033      -        while (dumpsys_sread(hp)) {
2034      -                if (sh.stream_pagenum != hp->cpin->pagenum) {
2035      -                        sh.stream_pagenum = hp->cpin->pagenum;
2036      -                        sh.stream_npages = btop(hp->cpin->used);
2037      -                        dumpsys_bzrun(hp, &sh, sizeof (sh), BZ_RUN);
2038      -                }
2039      -                dumpsys_bzrun(hp, hp->page, PAGESIZE, 0);
2040      -        }
2041      -
2042      -        /* Done with input, flush any partial buffer */
2043      -        if (sh.stream_pagenum != (pgcnt_t)-1) {
2044      -                dumpsys_bzrun(hp, NULL, 0, BZ_FINISH);
2045      -                dumpsys_errmsg(hp, NULL);
2046      -        }
2047      -
2048      -        ASSERT(hp->cpin == NULL && hp->cpout == NULL && hp->cperr == NULL);
2049      -
2050      -        /* Decrement main queue count, we are done */
2051      -        CQ_CLOSE(mainq);
2052      -}
2053      -
2054      -/*
2055 1783   * Compress with lzjb
2056 1784   * write stream block if full or size==0
2057 1785   * if csize==0 write stream header, else write <csize, data>
2058 1786   * size==0 is a call to flush a buffer
2059 1787   * hp->cpout is the buffer we are flushing or filling
2060 1788   * hp->out is the next index to fill data
2061 1789   * osize is either csize+data, or the size of a stream header
2062 1790   */
2063 1791  static void
2064 1792  dumpsys_lzjbrun(helper_t *hp, size_t csize, void *buf, size_t size)
↓ open down ↓ 121 lines elided ↑ open up ↑
2186 1914  dumpsys_helper()
2187 1915  {
2188 1916          dumpsys_spinlock(&dumpcfg.helper_lock);
2189 1917          if (dumpcfg.helpers_wanted) {
2190 1918                  helper_t *hp, *hpend = &dumpcfg.helper[dumpcfg.nhelper];
2191 1919  
2192 1920                  for (hp = dumpcfg.helper; hp != hpend; hp++) {
2193 1921                          if (hp->helper == FREEHELPER) {
2194 1922                                  hp->helper = CPU->cpu_id;
2195 1923                                  BT_SET(dumpcfg.helpermap, CPU->cpu_seqid);
2196      -
2197 1924                                  dumpsys_spinunlock(&dumpcfg.helper_lock);
2198      -
2199      -                                if (dumpcfg.clevel < DUMP_CLEVEL_BZIP2)
2200      -                                        dumpsys_lzjbcompress(hp);
2201      -                                else
2202      -                                        dumpsys_bz2compress(hp);
2203      -
     1925 +                                dumpsys_lzjbcompress(hp);
2204 1926                                  hp->helper = DONEHELPER;
2205 1927                                  return;
2206 1928                          }
2207 1929                  }
2208 1930  
2209 1931                  /* No more helpers are needed. */
2210 1932                  dumpcfg.helpers_wanted = 0;
2211 1933  
2212 1934          }
2213 1935          dumpsys_spinunlock(&dumpcfg.helper_lock);
↓ open down ↓ 16 lines elided ↑ open up ↑
2230 1952  /*
2231 1953   * Dump helper for live dumps.
2232 1954   * These run as a system task.
2233 1955   */
2234 1956  static void
2235 1957  dumpsys_live_helper(void *arg)
2236 1958  {
2237 1959          helper_t *hp = arg;
2238 1960  
2239 1961          BT_ATOMIC_SET(dumpcfg.helpermap, CPU->cpu_seqid);
2240      -        if (dumpcfg.clevel < DUMP_CLEVEL_BZIP2)
2241      -                dumpsys_lzjbcompress(hp);
2242      -        else
2243      -                dumpsys_bz2compress(hp);
     1962 +        dumpsys_lzjbcompress(hp);
2244 1963  }
2245 1964  
2246 1965  /*
2247 1966   * Compress one page with lzjb (single threaded case)
2248 1967   */
2249 1968  static void
2250 1969  dumpsys_lzjb_page(helper_t *hp, cbuf_t *cp)
2251 1970  {
2252 1971          dumpsync_t *ds = hp->ds;
2253 1972          uint32_t csize;
↓ open down ↓ 26 lines elided ↑ open up ↑
2280 1999   */
2281 2000  static void
2282 2001  dumpsys_main_task(void *arg)
2283 2002  {
2284 2003          dumpsync_t *ds = arg;
2285 2004          pgcnt_t pagenum = 0, bitnum = 0, hibitnum;
2286 2005          dumpmlw_t mlw;
2287 2006          cbuf_t *cp;
2288 2007          pgcnt_t baseoff, pfnoff;
2289 2008          pfn_t base, pfn;
2290      -        int i, dumpserial;
     2009 +        int i;
2291 2010  
2292 2011          /*
2293 2012           * Fall back to serial mode if there are no helpers.
2294      -         * dump_plat_mincpu can be set to 0 at any time.
     2013 +         * dump_ncpu_low can be set to 0 at any time.
2295 2014           * dumpcfg.helpermap must contain at least one member.
     2015 +         *
     2016 +         * It is possible that the helpers haven't registered
     2017 +         * in helpermap yet; wait up to DUMP_HELPER_MAX_WAIT.
2296 2018           */
2297      -        dumpserial = 1;
     2019 +        if (dump_ncpu_low != 0 && dumpcfg.clevel != DUMP_CLEVEL_SERIAL) {
     2020 +                boolean_t dumpserial = B_TRUE;
     2021 +                hrtime_t hrtmax = MSEC2NSEC(DUMP_HELPER_MAX_WAIT);
     2022 +                hrtime_t hrtstart = gethrtime();
2298 2023  
2299      -        if (dump_plat_mincpu != 0 && dumpcfg.clevel != 0) {
2300      -                for (i = 0; i < BT_BITOUL(NCPU); ++i) {
2301      -                        if (dumpcfg.helpermap[i] != 0) {
2302      -                                dumpserial = 0;
     2024 +                for (;;) {
     2025 +                        for (i = 0; i < BT_BITOUL(NCPU); ++i) {
     2026 +                                if (dumpcfg.helpermap[i] != 0) {
     2027 +                                        dumpserial = B_FALSE;
     2028 +                                        break;
     2029 +                                }
     2030 +                        }
     2031 +
     2032 +                        if ((!dumpserial) ||
     2033 +                            ((gethrtime() - hrtstart) >= hrtmax)) {
2303 2034                                  break;
2304 2035                          }
     2036 +
     2037 +                        ht_pause();
2305 2038                  }
2306      -        }
2307 2039  
2308      -        if (dumpserial) {
2309      -                dumpcfg.clevel = 0;
2310      -                if (dumpcfg.helper[0].lzbuf == NULL)
2311      -                        dumpcfg.helper[0].lzbuf = dumpcfg.helper[1].page;
     2040 +                if (dumpserial) {
     2041 +                        dumpcfg.clevel = DUMP_CLEVEL_SERIAL;
     2042 +                        if (dumpcfg.helper[0].lzbuf == NULL) {
     2043 +                                dumpcfg.helper[0].lzbuf =
     2044 +                                    dumpcfg.helper[1].page;
     2045 +                        }
     2046 +                }
2312 2047          }
2313 2048  
2314 2049          dump_init_memlist_walker(&mlw);
2315 2050  
2316 2051          for (;;) {
2317 2052                  int sec = (gethrtime() - ds->start) / NANOSEC;
2318 2053  
2319 2054                  /*
2320 2055                   * Render a simple progress display on the system console to
2321 2056                   * make clear to the operator that the system has not hung.
↓ open down ↓ 122 lines elided ↑ open up ↑
2444 2179  
2445 2180                          ds->pages_mapped += btop(cp->size);
2446 2181                          ds->pages_used += pagenum - cp->pagenum;
2447 2182  
2448 2183                          CQ_OPEN(mainq);
2449 2184  
2450 2185                          /*
2451 2186                           * If there are no helpers the main task does
2452 2187                           * non-streams lzjb compress.
2453 2188                           */
2454      -                        if (dumpserial) {
     2189 +                        if (dumpcfg.clevel == DUMP_CLEVEL_SERIAL) {
2455 2190                                  dumpsys_lzjb_page(dumpcfg.helper, cp);
2456      -                                break;
     2191 +                        } else {
     2192 +                                /* pass mapped pages to a helper */
     2193 +                                CQ_PUT(helperq, cp, CBUF_INREADY);
2457 2194                          }
2458 2195  
2459      -                        /* pass mapped pages to a helper */
2460      -                        CQ_PUT(helperq, cp, CBUF_INREADY);
2461      -
2462 2196                          /* the last page was done */
2463 2197                          if (bitnum >= dumpcfg.bitmapsize)
2464 2198                                  CQ_CLOSE(helperq);
2465 2199  
2466 2200                          break;
2467 2201  
2468 2202                  case CBUF_USEDMAP:
2469 2203  
2470 2204                          ds->npages += btop(cp->used);
2471 2205  
↓ open down ↓ 84 lines elided ↑ open up ↑
2556 2290                          P("\n");
2557 2291          }
2558 2292  
2559 2293          P("ncbuf_used,%d\n", cfg->ncbuf_used);
2560 2294          P("ncmap,%d\n", cfg->ncmap);
2561 2295  
2562 2296          P("Found %ldM ranges,%ld\n", (CBUF_MAPSIZE / DUMP_1MB), cfg->found4m);
2563 2297          P("Found small pages,%ld\n", cfg->foundsm);
2564 2298  
2565 2299          P("Compression level,%d\n", cfg->clevel);
2566      -        P("Compression type,%s %s\n", cfg->clevel == 0 ? "serial" : "parallel",
2567      -            cfg->clevel >= DUMP_CLEVEL_BZIP2 ? "bzip2" : "lzjb");
     2300 +        P("Compression type,%s lzjb\n",
     2301 +            cfg->clevel == DUMP_CLEVEL_SERIAL ? "serial" : "parallel");
2568 2302          P("Compression ratio,%d.%02d\n", compress_ratio / 100, compress_ratio %
2569 2303              100);
2570 2304          P("nhelper_used,%d\n", cfg->nhelper_used);
2571 2305  
2572 2306          P("Dump I/O rate MBS,%d.%02d\n", iorate / 100, iorate % 100);
2573 2307          P("..total bytes,%lld\n", (u_longlong_t)ds->nwrite);
2574 2308          P("..total nsec,%lld\n", (u_longlong_t)ds->iotime);
2575 2309          P("dumpbuf.iosize,%ld\n", dumpbuf.iosize);
2576 2310          P("dumpbuf.size,%ld\n", dumpbuf.size);
2577 2311  
↓ open down ↓ 87 lines elided ↑ open up ↑
2665 2399          dumphdr->dump_nvtop = 0;
2666 2400          bzero(dumpcfg.bitmap, BT_SIZEOFMAP(dumpcfg.bitmapsize));
2667 2401          dump_timeleft = dump_timeout;
2668 2402  
2669 2403          if (panicstr) {
2670 2404                  dumphdr->dump_flags &= ~DF_LIVE;
2671 2405                  (void) VOP_DUMPCTL(dumpvp, DUMP_FREE, NULL, NULL);
2672 2406                  (void) VOP_DUMPCTL(dumpvp, DUMP_ALLOC, NULL, NULL);
2673 2407                  (void) vsnprintf(dumphdr->dump_panicstring, DUMP_PANICSIZE,
2674 2408                      panicstr, panicargs);
2675      -
     2409 +                (void) strncpy(dumphdr->dump_uuid, dump_get_uuid(),
     2410 +                    sizeof (dumphdr->dump_uuid));
2676 2411          }
2677 2412  
2678 2413          if (dump_conflags & DUMP_ALL)
2679 2414                  content = "all";
2680 2415          else if (dump_conflags & DUMP_CURPROC)
2681 2416                  content = "kernel + curproc";
2682 2417          else
2683 2418                  content = "kernel";
2684 2419          uprintf("dumping to %s, offset %lld, content: %s\n", dumppath,
2685 2420              dumphdr->dump_start, content);
↓ open down ↓ 24 lines elided ↑ open up ↑
2710 2445                          }
2711 2446                  }
2712 2447          }
2713 2448  
2714 2449          /*
2715 2450           * Store a hires timestamp so we can look it up during debugging.
2716 2451           */
2717 2452          lbolt_debug_entry();
2718 2453  
2719 2454          /*
2720      -         * Leave room for the message and ereport save areas and terminal dump
2721      -         * header.
     2455 +         * Leave room for the summary, message and ereport save areas
     2456 +         * and terminal dump header.
2722 2457           */
2723 2458          dumpbuf.vp_limit = dumpvp_size - DUMP_LOGSIZE - DUMP_OFFSET -
2724      -            DUMP_ERPTSIZE;
     2459 +            DUMP_ERPTSIZE - DUMP_SUMMARYSIZE;
2725 2460  
2726 2461          /*
2727 2462           * Write out the symbol table.  It's no longer compressed,
2728 2463           * so its 'size' and 'csize' are equal.
2729 2464           */
2730 2465          dumpbuf.vp_off = dumphdr->dump_ksyms = dumphdr->dump_start + PAGESIZE;
2731 2466          dumphdr->dump_ksyms_size = dumphdr->dump_ksyms_csize =
2732 2467              ksyms_snapshot(dumpvp_ksyms_write, NULL, LONG_MAX);
2733 2468  
2734 2469          /*
↓ open down ↓ 83 lines elided ↑ open up ↑
2818 2553          dump_plat_pfn();
2819 2554  
2820 2555          /*
2821 2556           * Write out all the pages.
2822 2557           * Map pages, copy them handling UEs, compress, and write them out.
2823 2558           * Cooperate with any helpers running on CPUs in panic_idle().
2824 2559           */
2825 2560          dumphdr->dump_data = dumpvp_flush();
2826 2561  
2827 2562          bzero(dumpcfg.helpermap, BT_SIZEOFMAP(NCPU));
2828      -        ds->live = dumpcfg.clevel > 0 &&
     2563 +        ds->live = dumpcfg.clevel > DUMP_CLEVEL_SERIAL &&
2829 2564              (dumphdr->dump_flags & DF_LIVE) != 0;
2830 2565  
2831 2566          save_dump_clevel = dumpcfg.clevel;
2832 2567          if (panicstr)
2833 2568                  dumpsys_get_maxmem();
2834      -        else if (dumpcfg.clevel >= DUMP_CLEVEL_BZIP2)
2835      -                dumpcfg.clevel = DUMP_CLEVEL_LZJB;
2836 2569  
2837 2570          dumpcfg.nhelper_used = 0;
2838 2571          for (hp = dumpcfg.helper; hp != hpend; hp++) {
2839 2572                  if (hp->page == NULL) {
2840 2573                          hp->helper = DONEHELPER;
2841 2574                          continue;
2842 2575                  }
2843 2576                  ++dumpcfg.nhelper_used;
2844 2577                  hp->helper = FREEHELPER;
2845 2578                  hp->taskqid = NULL;
2846 2579                  hp->ds = ds;
2847 2580                  bzero(&hp->perpage, sizeof (hp->perpage));
2848      -                if (dumpcfg.clevel >= DUMP_CLEVEL_BZIP2)
2849      -                        (void) BZ2_bzCompressReset(&hp->bzstream);
2850 2581          }
2851 2582  
2852 2583          CQ_OPEN(freebufq);
2853 2584          CQ_OPEN(helperq);
2854 2585  
2855 2586          dumpcfg.ncbuf_used = 0;
2856 2587          for (cp = dumpcfg.cbuf; cp != &dumpcfg.cbuf[dumpcfg.ncbuf]; cp++) {
2857 2588                  if (cp->buf != NULL) {
2858 2589                          CQ_PUT(freebufq, cp, CBUF_FREEBUF);
2859 2590                          ++dumpcfg.ncbuf_used;
↓ open down ↓ 17 lines elided ↑ open up ↑
2877 2608                          if (hp->page == NULL)
2878 2609                                  continue;
2879 2610                          hp->helper = hp - dumpcfg.helper;
2880 2611                          hp->taskqid = taskq_dispatch(livetaskq,
2881 2612                              dumpsys_live_helper, (void *)hp, TQ_NOSLEEP);
2882 2613                  }
2883 2614  
2884 2615          } else {
2885 2616                  if (panicstr)
2886 2617                          kmem_dump_begin();
2887      -                dumpcfg.helpers_wanted = dumpcfg.clevel > 0;
     2618 +                dumpcfg.helpers_wanted = dumpcfg.clevel > DUMP_CLEVEL_SERIAL;
2888 2619                  dumpsys_spinunlock(&dumpcfg.helper_lock);
2889 2620          }
2890 2621  
2891 2622          /* run main task */
2892 2623          dumpsys_main_task(ds);
2893 2624  
2894 2625          ds->elapsed = gethrtime() - ds->start;
2895 2626          if (ds->elapsed < 1)
2896 2627                  ds->elapsed = 1;
2897 2628  
↓ open down ↓ 140 lines elided ↑ open up ↑
3038 2769          if (error == 0 && vattr.va_size < 2 * DUMP_LOGSIZE + DUMP_ERPTSIZE) {
3039 2770                  mutex_exit(&dump_lock);
3040 2771                  return (ENOSPC);
3041 2772          }
3042 2773  
3043 2774          dumpvp_size = vattr.va_size & -DUMP_OFFSET;
3044 2775          mutex_exit(&dump_lock);
3045 2776          return (0);
3046 2777  }
3047 2778  
3048      -int
3049      -dump_set_uuid(const char *uuidstr)
     2779 +static int
     2780 +dump_validate_uuid(const char *uuidstr)
3050 2781  {
3051 2782          const char *ptr;
3052 2783          int i;
3053 2784  
3054      -        if (uuidstr == NULL || strnlen(uuidstr, 36 + 1) != 36)
     2785 +        if (uuidstr == NULL || strlen(uuidstr) !=
     2786 +            UUID_PRINTABLE_STRING_LENGTH - 1)
3055 2787                  return (EINVAL);
3056 2788  
3057 2789          /* uuid_parse is not common code so check manually */
3058      -        for (i = 0, ptr = uuidstr; i < 36; i++, ptr++) {
     2790 +        for (i = 0, ptr = uuidstr; i < UUID_PRINTABLE_STRING_LENGTH - 1;
     2791 +            i++, ptr++) {
3059 2792                  switch (i) {
3060 2793                  case 8:
3061 2794                  case 13:
3062 2795                  case 18:
3063 2796                  case 23:
3064 2797                          if (*ptr != '-')
3065 2798                                  return (EINVAL);
3066 2799                          break;
3067 2800  
3068 2801                  default:
3069 2802                          if (!isxdigit(*ptr))
3070 2803                                  return (EINVAL);
3071 2804                          break;
3072 2805                  }
3073 2806          }
3074 2807  
     2808 +        return (0);
     2809 +}
     2810 +
     2811 +int
     2812 +dump_update_uuid(const char *uuidstr)
     2813 +{
     2814 +
     2815 +        if (dump_validate_uuid(uuidstr) != 0 || dumphdr == NULL)
     2816 +                return (EINVAL);
     2817 +
     2818 +        bzero(dumphdr->dump_uuid, sizeof (dumphdr->dump_uuid));
     2819 +        (void) strncpy(dumphdr->dump_uuid, uuidstr,
     2820 +            sizeof (dumphdr->dump_uuid));
     2821 +
     2822 +        return (0);
     2823 +}
     2824 +
     2825 +int
     2826 +dump_set_uuid(const char *uuidstr)
     2827 +{
     2828 +        if (dump_validate_uuid(uuidstr) != 0)
     2829 +                return (EINVAL);
     2830 +
3075 2831          if (dump_osimage_uuid[0] != '\0')
3076 2832                  return (EALREADY);
3077 2833  
3078      -        (void) strncpy(dump_osimage_uuid, uuidstr, 36 + 1);
     2834 +        (void) strncpy(dump_osimage_uuid, uuidstr,
     2835 +            UUID_PRINTABLE_STRING_LENGTH);
3079 2836  
3080 2837          cmn_err(CE_CONT, "?This Solaris instance has UUID %s\n",
3081 2838              dump_osimage_uuid);
3082 2839  
3083 2840          return (0);
3084 2841  }
3085 2842  
3086 2843  const char *
3087 2844  dump_get_uuid(void)
3088 2845  {
3089 2846          return (dump_osimage_uuid[0] != '\0' ? dump_osimage_uuid : "");
3090 2847  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX