Print this page
10082 intel_nhm is checking for NULL arrays
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/io/intel_nhm/dimm_topo.c
+++ new/usr/src/uts/intel/io/intel_nhm/dimm_topo.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
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 2010 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 +/*
28 + * Copyright (c) 2018, Joyent, Inc.
29 + */
30 +
27 31 #include <sys/types.h>
28 32 #include <sys/time.h>
29 33 #include <sys/nvpair.h>
30 34 #include <sys/cmn_err.h>
31 35 #include <sys/cred.h>
32 36 #include <sys/open.h>
33 37 #include <sys/ddi.h>
34 38 #include <sys/sunddi.h>
35 39 #include <sys/conf.h>
36 40 #include <sys/modctl.h>
37 41 #include <sys/cyclic.h>
38 42 #include <sys/errorq.h>
39 43 #include <sys/stat.h>
40 44 #include <sys/cpuvar.h>
41 45 #include <sys/mc_intel.h>
42 46 #include <sys/mc.h>
43 47 #include <sys/fm/protocol.h>
44 48 #include "nhm_log.h"
45 49 #include "intel_nhm.h"
46 50
47 51 extern nvlist_t *inhm_mc_nvl[MAX_CPU_NODES];
48 52 extern char closed_page;
49 53 extern char ecc_enabled;
50 54 extern char lockstep[MAX_CPU_NODES];
51 55 extern char mirror_mode[MAX_CPU_NODES];
52 56 extern char spare_channel[MAX_CPU_NODES];
53 57
54 58 static void
55 59 inhm_vrank(nvlist_t *vrank, int num, uint64_t dimm_base, uint64_t limit,
56 60 uint32_t sinterleave, uint32_t cinterleave, uint32_t rinterleave,
57 61 uint32_t sway, uint32_t cway, uint32_t rway)
58 62 {
59 63 char buf[128];
60 64
61 65 (void) snprintf(buf, sizeof (buf), "dimm-rank-base-%d", num);
62 66 (void) nvlist_add_uint64(vrank, buf, dimm_base);
63 67 (void) snprintf(buf, sizeof (buf), "dimm-rank-limit-%d", num);
64 68 (void) nvlist_add_uint64(vrank, buf, dimm_base + limit);
65 69 if (sinterleave > 1) {
66 70 (void) snprintf(buf, sizeof (buf), "dimm-socket-interleave-%d",
67 71 num);
68 72 (void) nvlist_add_uint32(vrank, buf, sinterleave);
69 73 (void) snprintf(buf, sizeof (buf),
70 74 "dimm-socket-interleave-way-%d", num);
71 75 (void) nvlist_add_uint32(vrank, buf, sway);
72 76 }
73 77 if (cinterleave > 1) {
74 78 (void) snprintf(buf, sizeof (buf), "dimm-channel-interleave-%d",
75 79 num);
76 80 (void) nvlist_add_uint32(vrank, buf, cinterleave);
77 81 (void) snprintf(buf, sizeof (buf),
78 82 "dimm-channel-interleave-way-%d", num);
79 83 (void) nvlist_add_uint32(vrank, buf, cway);
80 84 }
81 85 if (rinterleave > 1) {
82 86 (void) snprintf(buf, sizeof (buf), "dimm-rank-interleave-%d",
83 87 num);
84 88 (void) nvlist_add_uint32(vrank, buf, rinterleave);
85 89 (void) snprintf(buf, sizeof (buf),
86 90 "dimm-rank-interleave-way-%d", num);
87 91 (void) nvlist_add_uint32(vrank, buf, rway);
88 92 }
89 93 }
90 94
91 95 static void
92 96 inhm_rank(nvlist_t *newdimm, nhm_dimm_t *nhm_dimm, uint32_t node,
93 97 uint8_t channel, uint32_t dimm, uint64_t rank_size)
94 98 {
95 99 nvlist_t **newrank;
96 100 int num;
97 101 int i;
98 102 uint64_t dimm_base;
99 103 uint64_t vrank_sz;
100 104 uint64_t rank_addr;
101 105 uint64_t pa;
102 106 uint32_t sinterleave, cinterleave, rinterleave;
103 107 uint32_t sway, cway, rway;
104 108
105 109 newrank = kmem_zalloc(sizeof (nvlist_t *) * nhm_dimm->nranks, KM_SLEEP);
106 110 for (i = 0; i < nhm_dimm->nranks; i++) {
107 111 (void) nvlist_alloc(&newrank[i], NV_UNIQUE_NAME, KM_SLEEP);
108 112 rank_addr = 0;
109 113 num = 0;
110 114 while (rank_addr < rank_size) {
111 115 pa = dimm_to_addr(node, channel, dimm * 4 + i,
112 116 rank_addr, &dimm_base, &vrank_sz, &sinterleave,
113 117 &cinterleave, &rinterleave, &sway, &cway, &rway);
114 118 if (pa == -1 || vrank_sz == 0)
115 119 break;
116 120 inhm_vrank(newrank[i], num, dimm_base,
117 121 vrank_sz * sinterleave * cinterleave * rinterleave,
118 122 sinterleave, cinterleave, rinterleave, sway, cway,
119 123 rway);
120 124 rank_addr += vrank_sz;
121 125 num++;
122 126 }
123 127
124 128 }
125 129 (void) nvlist_add_nvlist_array(newdimm, MCINTEL_NVLIST_RANKS, newrank,
126 130 nhm_dimm->nranks);
127 131 for (i = 0; i < nhm_dimm->nranks; i++)
128 132 nvlist_free(newrank[i]);
129 133 kmem_free(newrank, sizeof (nvlist_t *) * nhm_dimm->nranks);
130 134 }
131 135
132 136 static nvlist_t *
133 137 inhm_dimm(nhm_dimm_t *nhm_dimm, uint32_t node, uint8_t channel, uint32_t dimm)
134 138 {
135 139 nvlist_t *newdimm;
136 140 uint8_t t;
137 141 char sbuf[65];
138 142
139 143 (void) nvlist_alloc(&newdimm, NV_UNIQUE_NAME, KM_SLEEP);
140 144 (void) nvlist_add_uint32(newdimm, "dimm-number", dimm);
141 145
142 146 if (nhm_dimm->dimm_size >= 1024*1024*1024) {
143 147 (void) snprintf(sbuf, sizeof (sbuf), "%dG",
144 148 (int)(nhm_dimm->dimm_size / (1024*1024*1024)));
145 149 } else {
146 150 (void) snprintf(sbuf, sizeof (sbuf), "%dM",
147 151 (int)(nhm_dimm->dimm_size / (1024*1024)));
148 152 }
↓ open down ↓ |
112 lines elided |
↑ open up ↑ |
149 153 (void) nvlist_add_string(newdimm, "dimm-size", sbuf);
150 154 (void) nvlist_add_uint64(newdimm, "size", nhm_dimm->dimm_size);
151 155 (void) nvlist_add_uint32(newdimm, "nbanks", (uint32_t)nhm_dimm->nbanks);
152 156 (void) nvlist_add_uint32(newdimm, "ncolumn",
153 157 (uint32_t)nhm_dimm->ncolumn);
154 158 (void) nvlist_add_uint32(newdimm, "nrow", (uint32_t)nhm_dimm->nrow);
155 159 (void) nvlist_add_uint32(newdimm, "width", (uint32_t)nhm_dimm->width);
156 160 (void) nvlist_add_uint32(newdimm, "ranks", (uint32_t)nhm_dimm->nranks);
157 161 inhm_rank(newdimm, nhm_dimm, node, channel, dimm,
158 162 nhm_dimm->dimm_size / nhm_dimm->nranks);
159 - if (nhm_dimm->manufacturer && nhm_dimm->manufacturer[0]) {
163 + if (nhm_dimm->manufacturer[0]) {
160 164 t = sizeof (nhm_dimm->manufacturer);
161 165 (void) strncpy(sbuf, nhm_dimm->manufacturer, t);
162 166 sbuf[t] = 0;
163 167 (void) nvlist_add_string(newdimm, "manufacturer", sbuf);
164 168 }
165 - if (nhm_dimm->serial_number && nhm_dimm->serial_number[0]) {
169 + if (nhm_dimm->serial_number[0]) {
166 170 t = sizeof (nhm_dimm->serial_number);
167 171 (void) strncpy(sbuf, nhm_dimm->serial_number, t);
168 172 sbuf[t] = 0;
169 173 (void) nvlist_add_string(newdimm, FM_FMRI_HC_SERIAL_ID, sbuf);
170 174 }
171 - if (nhm_dimm->part_number && nhm_dimm->part_number[0]) {
175 + if (nhm_dimm->part_number[0]) {
172 176 t = sizeof (nhm_dimm->part_number);
173 177 (void) strncpy(sbuf, nhm_dimm->part_number, t);
174 178 sbuf[t] = 0;
175 179 (void) nvlist_add_string(newdimm, FM_FMRI_HC_PART, sbuf);
176 180 }
177 - if (nhm_dimm->revision && nhm_dimm->revision[0]) {
181 + if (nhm_dimm->revision[0]) {
178 182 t = sizeof (nhm_dimm->revision);
179 183 (void) strncpy(sbuf, nhm_dimm->revision, t);
180 184 sbuf[t] = 0;
181 185 (void) nvlist_add_string(newdimm, FM_FMRI_HC_REVISION, sbuf);
182 186 }
183 187 t = sizeof (nhm_dimm->label);
184 188 (void) strncpy(sbuf, nhm_dimm->label, t);
185 189 sbuf[t] = 0;
186 190 (void) nvlist_add_string(newdimm, FM_FAULT_FRU_LABEL, sbuf);
187 191 return (newdimm);
188 192 }
189 193
190 194 static void
191 195 inhm_dimmlist(uint32_t node, nvlist_t *nvl)
192 196 {
193 197 nvlist_t **dimmlist;
194 198 nvlist_t **newchannel;
195 199 int nchannels = CHANNELS_PER_MEMORY_CONTROLLER;
196 200 int nd;
197 201 uint8_t i, j;
198 202 nhm_dimm_t **dimmpp;
199 203 nhm_dimm_t *dimmp;
200 204
201 205 dimmlist = kmem_zalloc(sizeof (nvlist_t *) * MAX_DIMMS_PER_CHANNEL,
202 206 KM_SLEEP);
203 207 newchannel = kmem_zalloc(sizeof (nvlist_t *) * nchannels, KM_SLEEP);
204 208 dimmpp = &nhm_dimms[node * CHANNELS_PER_MEMORY_CONTROLLER *
205 209 MAX_DIMMS_PER_CHANNEL];
206 210 (void) nvlist_add_string(nvl, "memory-policy",
207 211 closed_page ? "closed-page" : "open-page");
208 212 (void) nvlist_add_string(nvl, "memory-ecc",
209 213 ecc_enabled ? lockstep[node] ? "x8" : "x4" : "no");
210 214 for (i = 0; i < nchannels; i++) {
211 215 (void) nvlist_alloc(&newchannel[i], NV_UNIQUE_NAME, KM_SLEEP);
212 216 (void) nvlist_add_string(newchannel[i], "channel-mode",
213 217 CHANNEL_DISABLED(MC_STATUS_RD(node), i) ? "disabled" :
214 218 i != 2 && lockstep[node] ? "lockstep" :
215 219 i != 2 && mirror_mode[node] ?
216 220 REDUNDANCY_LOSS(MC_RAS_STATUS_RD(node)) ?
217 221 "redundancy-loss" : "mirror" :
218 222 i == 2 && spare_channel[node] &&
219 223 !REDUNDANCY_LOSS(MC_RAS_STATUS_RD(node)) ? "spare" :
220 224 "independent");
221 225 nd = 0;
222 226 for (j = 0; j < MAX_DIMMS_PER_CHANNEL; j++) {
223 227 dimmp = *dimmpp;
224 228 if (dimmp != NULL) {
225 229 dimmlist[nd] = inhm_dimm(dimmp, node, i,
226 230 (uint32_t)j);
227 231 nd++;
228 232 }
229 233 dimmpp++;
230 234 }
231 235 if (nd) {
232 236 (void) nvlist_add_nvlist_array(newchannel[i],
233 237 "memory-dimms", dimmlist, nd);
234 238 for (j = 0; j < nd; j++)
235 239 nvlist_free(dimmlist[j]);
236 240 }
237 241 }
238 242 (void) nvlist_add_nvlist_array(nvl, MCINTEL_NVLIST_MC, newchannel,
239 243 nchannels);
240 244 for (i = 0; i < nchannels; i++)
241 245 nvlist_free(newchannel[i]);
242 246 kmem_free(dimmlist, sizeof (nvlist_t *) * MAX_DIMMS_PER_CHANNEL);
243 247 kmem_free(newchannel, sizeof (nvlist_t *) * nchannels);
244 248 }
245 249
246 250 char *
247 251 inhm_mc_name()
248 252 {
249 253 return (NHM_INTERCONNECT);
250 254 }
251 255
252 256 void
253 257 inhm_create_nvl(int chip)
254 258 {
255 259 nvlist_t *nvl;
256 260
257 261 (void) nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP);
258 262 (void) nvlist_add_uint8(nvl, MCINTEL_NVLIST_VERSTR,
259 263 MCINTEL_NVLIST_VERS);
260 264 (void) nvlist_add_string(nvl, MCINTEL_NVLIST_MEM, inhm_mc_name());
261 265 (void) nvlist_add_uint8(nvl, MCINTEL_NVLIST_NMEM, 1);
262 266 (void) nvlist_add_uint8(nvl, MCINTEL_NVLIST_NRANKS, 4);
263 267 inhm_dimmlist(chip, nvl);
264 268
265 269 nvlist_free(inhm_mc_nvl[chip]);
266 270 inhm_mc_nvl[chip] = nvl;
267 271 }
↓ open down ↓ |
80 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX