12918c4a3SJohn Levon /*
22918c4a3SJohn Levon * This file and its contents are supplied under the terms of the
32918c4a3SJohn Levon * Common Development and Distribution License ("CDDL"), version 1.0.
42918c4a3SJohn Levon * You may only use this file in accordance with the terms of version
52918c4a3SJohn Levon * 1.0 of the CDDL.
62918c4a3SJohn Levon *
72918c4a3SJohn Levon * A full copy of the text of the CDDL should have accompanied this
82918c4a3SJohn Levon * source. A copy of the CDDL is also available via the Internet at
92918c4a3SJohn Levon * http://www.illumos.org/license/CDDL.
102918c4a3SJohn Levon */
112918c4a3SJohn Levon
122918c4a3SJohn Levon /*
13*f557613aSJohn Levon * Copyright 2019 Joyent, Inc.
142918c4a3SJohn Levon */
152918c4a3SJohn Levon
162918c4a3SJohn Levon #include <sys/cpu_uarray.h>
172918c4a3SJohn Levon #include <sys/sysmacros.h>
182918c4a3SJohn Levon #include <sys/cpuvar.h>
192918c4a3SJohn Levon #include <sys/debug.h>
202918c4a3SJohn Levon #include <sys/kmem.h>
212918c4a3SJohn Levon
222918c4a3SJohn Levon static size_t
cpu_uarray_size(size_t nr_items)232918c4a3SJohn Levon cpu_uarray_size(size_t nr_items)
242918c4a3SJohn Levon {
252918c4a3SJohn Levon size_t size = P2ROUNDUP(nr_items * sizeof (uint64_t), CUA_ALIGN);
262918c4a3SJohn Levon size *= NCPU;
272918c4a3SJohn Levon return (sizeof (cpu_uarray_t) + size);
282918c4a3SJohn Levon }
292918c4a3SJohn Levon
302918c4a3SJohn Levon cpu_uarray_t *
cpu_uarray_zalloc(size_t nr_items,int kmflags)312918c4a3SJohn Levon cpu_uarray_zalloc(size_t nr_items, int kmflags)
322918c4a3SJohn Levon {
332918c4a3SJohn Levon cpu_uarray_t *cua;
342918c4a3SJohn Levon
352918c4a3SJohn Levon cua = kmem_zalloc(cpu_uarray_size(nr_items), kmflags);
362918c4a3SJohn Levon
372918c4a3SJohn Levon if (cua != NULL) {
382918c4a3SJohn Levon VERIFY(IS_P2ALIGNED(cua->cu_vals, CUA_ALIGN));
392918c4a3SJohn Levon cua->cu_nr_items = nr_items;
402918c4a3SJohn Levon }
412918c4a3SJohn Levon
422918c4a3SJohn Levon return (cua);
432918c4a3SJohn Levon }
442918c4a3SJohn Levon
452918c4a3SJohn Levon void
cpu_uarray_free(cpu_uarray_t * cua)462918c4a3SJohn Levon cpu_uarray_free(cpu_uarray_t *cua)
472918c4a3SJohn Levon {
48*f557613aSJohn Levon if (cua != NULL)
492918c4a3SJohn Levon kmem_free(cua, cpu_uarray_size(cua->cu_nr_items));
502918c4a3SJohn Levon }
512918c4a3SJohn Levon
522918c4a3SJohn Levon uint64_t
cpu_uarray_sum(cpu_uarray_t * cua,size_t index)532918c4a3SJohn Levon cpu_uarray_sum(cpu_uarray_t *cua, size_t index)
542918c4a3SJohn Levon {
552918c4a3SJohn Levon uint64_t sum = 0;
562918c4a3SJohn Levon
572918c4a3SJohn Levon VERIFY3U(index, <, cua->cu_nr_items);
582918c4a3SJohn Levon
592918c4a3SJohn Levon for (size_t c = 0; c < ncpus; c++) {
602918c4a3SJohn Levon uint64_t addend = CPU_UARRAY_VAL(cua, c, index);
612918c4a3SJohn Levon sum = UINT64_OVERFLOW_ADD(sum, addend);
622918c4a3SJohn Levon }
632918c4a3SJohn Levon
642918c4a3SJohn Levon return (sum);
652918c4a3SJohn Levon }
662918c4a3SJohn Levon
672918c4a3SJohn Levon uint64_t
cpu_uarray_sum_all(cpu_uarray_t * cua)682918c4a3SJohn Levon cpu_uarray_sum_all(cpu_uarray_t *cua)
692918c4a3SJohn Levon {
702918c4a3SJohn Levon uint64_t sum = 0;
712918c4a3SJohn Levon
722918c4a3SJohn Levon for (size_t c = 0; c < ncpus; c++) {
732918c4a3SJohn Levon for (size_t i = 0; i < cua->cu_nr_items; i++) {
742918c4a3SJohn Levon uint64_t addend = CPU_UARRAY_VAL(cua, c, i);
752918c4a3SJohn Levon sum = UINT64_OVERFLOW_ADD(sum, addend);
762918c4a3SJohn Levon }
772918c4a3SJohn Levon }
782918c4a3SJohn Levon
792918c4a3SJohn Levon return (sum);
802918c4a3SJohn Levon }
81