| 1287 | } |
| 1288 | |
| 1289 | static int |
| 1290 | sysctl_kern_malloc_stats(SYSCTL_HANDLER_ARGS) |
| 1291 | { |
| 1292 | struct malloc_type_stream_header mtsh; |
| 1293 | struct malloc_type_internal *mtip; |
| 1294 | struct malloc_type_stats *mtsp, zeromts; |
| 1295 | struct malloc_type_header mth; |
| 1296 | struct malloc_type *mtp; |
| 1297 | int error, i; |
| 1298 | struct sbuf sbuf; |
| 1299 | |
| 1300 | error = sysctl_wire_old_buffer(req, 0); |
| 1301 | if (error != 0) |
| 1302 | return (error); |
| 1303 | sbuf_new_for_sysctl(&sbuf, NULL, 128, req); |
| 1304 | sbuf_clear_flags(&sbuf, SBUF_INCLUDENUL); |
| 1305 | mtx_lock(&malloc_mtx); |
| 1306 | |
| 1307 | bzero(&zeromts, sizeof(zeromts)); |
| 1308 | |
| 1309 | /* |
| 1310 | * Insert stream header. |
| 1311 | */ |
| 1312 | bzero(&mtsh, sizeof(mtsh)); |
| 1313 | mtsh.mtsh_version = MALLOC_TYPE_STREAM_VERSION; |
| 1314 | mtsh.mtsh_maxcpus = MAXCPU; |
| 1315 | mtsh.mtsh_count = kmemcount; |
| 1316 | (void)sbuf_bcat(&sbuf, &mtsh, sizeof(mtsh)); |
| 1317 | |
| 1318 | /* |
| 1319 | * Insert alternating sequence of type headers and type statistics. |
| 1320 | */ |
| 1321 | for (mtp = kmemstatistics; mtp != NULL; mtp = mtp->ks_next) { |
| 1322 | mtip = &mtp->ks_mti; |
| 1323 | |
| 1324 | /* |
| 1325 | * Insert type header. |
| 1326 | */ |
| 1327 | bzero(&mth, sizeof(mth)); |
| 1328 | strlcpy(mth.mth_name, mtp->ks_shortdesc, MALLOC_MAX_NAME); |
| 1329 | (void)sbuf_bcat(&sbuf, &mth, sizeof(mth)); |
| 1330 | |
| 1331 | /* |
| 1332 | * Insert type statistics for each CPU. |
| 1333 | */ |
| 1334 | for (i = 0; i <= mp_maxid; i++) { |
| 1335 | mtsp = zpcpu_get_cpu(mtip->mti_stats, i); |
| 1336 | (void)sbuf_bcat(&sbuf, mtsp, sizeof(*mtsp)); |
| 1337 | } |
| 1338 | /* |
| 1339 | * Fill in the missing CPUs. |
| 1340 | */ |
| 1341 | for (; i < MAXCPU; i++) { |
| 1342 | (void)sbuf_bcat(&sbuf, &zeromts, sizeof(zeromts)); |
| 1343 | } |
| 1344 | } |
| 1345 | mtx_unlock(&malloc_mtx); |
| 1346 | error = sbuf_finish(&sbuf); |
nothing calls this directly
no test coverage detected