xref: /illumos-gate/usr/src/uts/common/os/cpu_uarray.c (revision f557613a52efd99cf11a085bca7a35c5e93315f1)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2019 Joyent, Inc.
14  */
15 
16 #include <sys/cpu_uarray.h>
17 #include <sys/sysmacros.h>
18 #include <sys/cpuvar.h>
19 #include <sys/debug.h>
20 #include <sys/kmem.h>
21 
22 static size_t
cpu_uarray_size(size_t nr_items)23 cpu_uarray_size(size_t nr_items)
24 {
25 	size_t size = P2ROUNDUP(nr_items * sizeof (uint64_t), CUA_ALIGN);
26 	size *= NCPU;
27 	return (sizeof (cpu_uarray_t) + size);
28 }
29 
30 cpu_uarray_t *
cpu_uarray_zalloc(size_t nr_items,int kmflags)31 cpu_uarray_zalloc(size_t nr_items, int kmflags)
32 {
33 	cpu_uarray_t *cua;
34 
35 	cua = kmem_zalloc(cpu_uarray_size(nr_items), kmflags);
36 
37 	if (cua != NULL) {
38 		VERIFY(IS_P2ALIGNED(cua->cu_vals, CUA_ALIGN));
39 		cua->cu_nr_items = nr_items;
40 	}
41 
42 	return (cua);
43 }
44 
45 void
cpu_uarray_free(cpu_uarray_t * cua)46 cpu_uarray_free(cpu_uarray_t *cua)
47 {
48 	if (cua != NULL)
49 		kmem_free(cua, cpu_uarray_size(cua->cu_nr_items));
50 }
51 
52 uint64_t
cpu_uarray_sum(cpu_uarray_t * cua,size_t index)53 cpu_uarray_sum(cpu_uarray_t *cua, size_t index)
54 {
55 	uint64_t sum = 0;
56 
57 	VERIFY3U(index, <, cua->cu_nr_items);
58 
59 	for (size_t c = 0; c < ncpus; c++) {
60 		uint64_t addend = CPU_UARRAY_VAL(cua, c, index);
61 		sum = UINT64_OVERFLOW_ADD(sum, addend);
62 	}
63 
64 	return (sum);
65 }
66 
67 uint64_t
cpu_uarray_sum_all(cpu_uarray_t * cua)68 cpu_uarray_sum_all(cpu_uarray_t *cua)
69 {
70 	uint64_t sum = 0;
71 
72 	for (size_t c = 0; c < ncpus; c++) {
73 		for (size_t i = 0; i < cua->cu_nr_items; i++) {
74 			uint64_t addend = CPU_UARRAY_VAL(cua, c, i);
75 			sum = UINT64_OVERFLOW_ADD(sum, addend);
76 		}
77 	}
78 
79 	return (sum);
80 }
81