Print this page
11927 Log, or optionally panic, on zero-length kmem allocations
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Jason King <jason.brian.king@gmail.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/os/kmem.c
          +++ new/usr/src/uts/common/os/kmem.c
↓ open down ↓ 1003 lines elided ↑ open up ↑
1004 1004  clock_t kmem_reap_interval;     /* cache reaping rate [15 * HZ ticks] */
1005 1005  int kmem_depot_contention = 3;  /* max failed tryenters per real interval */
1006 1006  pgcnt_t kmem_reapahead = 0;     /* start reaping N pages before pageout */
1007 1007  int kmem_panic = 1;             /* whether to panic on error */
1008 1008  int kmem_logging = 1;           /* kmem_log_enter() override */
1009 1009  uint32_t kmem_mtbf = 0;         /* mean time between failures [default: off] */
1010 1010  size_t kmem_transaction_log_size; /* transaction log size [2% of memory] */
1011 1011  size_t kmem_content_log_size;   /* content log size [2% of memory] */
1012 1012  size_t kmem_failure_log_size;   /* failure log [4 pages per CPU] */
1013 1013  size_t kmem_slab_log_size;      /* slab create log [4 pages per CPU] */
     1014 +size_t kmem_zerosized_log_size; /* zero-sized log [4 pages per CPU] */
1014 1015  size_t kmem_content_maxsave = 256; /* KMF_CONTENTS max bytes to log */
1015 1016  size_t kmem_lite_minsize = 0;   /* minimum buffer size for KMF_LITE */
1016 1017  size_t kmem_lite_maxalign = 1024; /* maximum buffer alignment for KMF_LITE */
1017 1018  int kmem_lite_pcs = 4;          /* number of PCs to store in KMF_LITE mode */
1018 1019  size_t kmem_maxverify;          /* maximum bytes to inspect in debug routines */
1019 1020  size_t kmem_minfirewall;        /* hardware-enforced redzone threshold */
1020 1021  
     1022 +#ifdef DEBUG
     1023 +int kmem_warn_zerosized = 1;    /* whether to warn on zero-sized KM_SLEEP */
     1024 +#else
     1025 +int kmem_warn_zerosized = 0;    /* whether to warn on zero-sized KM_SLEEP */
     1026 +#endif
     1027 +
     1028 +int kmem_panic_zerosized = 0;   /* whether to panic on zero-sized KM_SLEEP */
     1029 +
1021 1030  #ifdef _LP64
1022 1031  size_t  kmem_max_cached = KMEM_BIG_MAXBUF;      /* maximum kmem_alloc cache */
1023 1032  #else
1024 1033  size_t  kmem_max_cached = KMEM_BIG_MAXBUF_32BIT; /* maximum kmem_alloc cache */
1025 1034  #endif
1026 1035  
1027 1036  #ifdef DEBUG
1028 1037  int kmem_flags = KMF_AUDIT | KMF_DEADBEEF | KMF_REDZONE | KMF_CONTENTS;
1029 1038  #else
1030 1039  int kmem_flags = 0;
↓ open down ↓ 13 lines elided ↑ open up ↑
1044 1053  static vmem_t           *kmem_msb_arena;        /* arena for metadata caches */
1045 1054  static vmem_t           *kmem_cache_arena;
1046 1055  static vmem_t           *kmem_hash_arena;
1047 1056  static vmem_t           *kmem_log_arena;
1048 1057  static vmem_t           *kmem_oversize_arena;
1049 1058  static vmem_t           *kmem_va_arena;
1050 1059  static vmem_t           *kmem_default_arena;
1051 1060  static vmem_t           *kmem_firewall_va_arena;
1052 1061  static vmem_t           *kmem_firewall_arena;
1053 1062  
     1063 +static int              kmem_zerosized;         /* # of zero-sized allocs */
     1064 +
1054 1065  /*
1055 1066   * kmem slab consolidator thresholds (tunables)
1056 1067   */
1057 1068  size_t kmem_frag_minslabs = 101;        /* minimum total slabs */
1058 1069  size_t kmem_frag_numer = 1;             /* free buffers (numerator) */
1059 1070  size_t kmem_frag_denom = KMEM_VOID_FRACTION; /* buffers (denominator) */
1060 1071  /*
1061 1072   * Maximum number of slabs from which to move buffers during a single
1062 1073   * maintenance interval while the system is not low on memory.
1063 1074   */
↓ open down ↓ 27 lines elided ↑ open up ↑
1091 1102  
1092 1103  static void kmem_cache_scan(kmem_cache_t *);
1093 1104  static void kmem_cache_defrag(kmem_cache_t *);
1094 1105  static void kmem_slab_prefill(kmem_cache_t *, kmem_slab_t *);
1095 1106  
1096 1107  
1097 1108  kmem_log_header_t       *kmem_transaction_log;
1098 1109  kmem_log_header_t       *kmem_content_log;
1099 1110  kmem_log_header_t       *kmem_failure_log;
1100 1111  kmem_log_header_t       *kmem_slab_log;
     1112 +kmem_log_header_t       *kmem_zerosized_log;
1101 1113  
1102 1114  static int              kmem_lite_count; /* # of PCs in kmem_buftag_lite_t */
1103 1115  
1104 1116  #define KMEM_BUFTAG_LITE_ENTER(bt, count, caller)                       \
1105 1117          if ((count) > 0) {                                              \
1106 1118                  pc_t *_s = ((kmem_buftag_lite_t *)(bt))->bt_history;    \
1107 1119                  pc_t *_e;                                               \
1108 1120                  /* memmove() the old entries down one notch */          \
1109 1121                  for (_e = &_s[(count) - 1]; _e > _s; _e--)              \
1110 1122                          *_e = *(_e - 1);                                \
↓ open down ↓ 1735 lines elided ↑ open up ↑
2846 2858          if ((index = ((size - 1) >> KMEM_ALIGN_SHIFT)) < KMEM_ALLOC_TABLE_MAX) {
2847 2859                  cp = kmem_alloc_table[index];
2848 2860                  /* fall through to kmem_cache_alloc() */
2849 2861  
2850 2862          } else if ((index = ((size - 1) >> KMEM_BIG_SHIFT)) <
2851 2863              kmem_big_alloc_table_max) {
2852 2864                  cp = kmem_big_alloc_table[index];
2853 2865                  /* fall through to kmem_cache_alloc() */
2854 2866  
2855 2867          } else {
2856      -                if (size == 0)
     2868 +                if (size == 0) {
     2869 +                        if (kmflag != KM_SLEEP && !(kmflag & KM_PANIC))
     2870 +                                return (NULL);
     2871 +
     2872 +                        /*
     2873 +                         * If this is a sleeping allocation or one that has
     2874 +                         * been specified to panic on allocation failure, we
     2875 +                         * consider it to be deprecated behavior to allocate
     2876 +                         * 0 bytes.  If we have been configured to panic under
     2877 +                         * this condition, we panic; if to warn, we warn -- and
     2878 +                         * regardless, we log to the kmem_zerosized_log that
     2879 +                         * that this condition has occurred (which gives us
     2880 +                         * enough information to be able to debug it).
     2881 +                         */
     2882 +                        if (kmem_panic && kmem_panic_zerosized)
     2883 +                                panic("attempted to kmem_alloc() size of 0");
     2884 +
     2885 +                        if (kmem_warn_zerosized) {
     2886 +                                cmn_err(CE_WARN, "kmem_alloc(): sleeping "
     2887 +                                    "allocation with size of 0; "
     2888 +                                    "see kmem_zerosized_log for details");
     2889 +                        }
     2890 +
     2891 +                        kmem_log_event(kmem_zerosized_log, NULL, NULL, NULL);
     2892 +
2857 2893                          return (NULL);
     2894 +                }
2858 2895  
2859 2896                  buf = vmem_alloc(kmem_oversize_arena, size,
2860 2897                      kmflag & KM_VMFLAGS);
2861 2898                  if (buf == NULL)
2862 2899                          kmem_log_event(kmem_failure_log, NULL, NULL,
2863 2900                              (void *)size);
2864 2901                  else if (KMEM_DUMP(kmem_slab_cache)) {
2865 2902                          /* stats for dump intercept */
2866 2903                          kmem_dump_oversize_allocs++;
2867 2904                          if (size > kmem_dump_oversize_max)
↓ open down ↓ 1522 lines elided ↑ open up ↑
4390 4427                  kmem_transaction_log = kmem_log_init(kmem_transaction_log_size);
4391 4428          }
4392 4429  
4393 4430          if (kmem_flags & (KMF_CONTENTS | KMF_RANDOMIZE)) {
4394 4431                  if (kmem_content_log_size == 0)
4395 4432                          kmem_content_log_size = kmem_maxavail() / 50;
4396 4433                  kmem_content_log = kmem_log_init(kmem_content_log_size);
4397 4434          }
4398 4435  
4399 4436          kmem_failure_log = kmem_log_init(kmem_failure_log_size);
4400      -
4401 4437          kmem_slab_log = kmem_log_init(kmem_slab_log_size);
     4438 +        kmem_zerosized_log = kmem_log_init(kmem_zerosized_log_size);
4402 4439  
4403 4440          /*
4404 4441           * Initialize STREAMS message caches so allocb() is available.
4405 4442           * This allows us to initialize the logging framework (cmn_err(9F),
4406 4443           * strlog(9F), etc) so we can start recording messages.
4407 4444           */
4408 4445          streams_msg_init();
4409 4446  
4410 4447          /*
4411 4448           * Initialize the ZSD framework in Zones so modules loaded henceforth
↓ open down ↓ 971 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX