Deleted Added
full compact
memstat_uma.c (148354) memstat_uma.c (148357)
1/*-
2 * Copyright (c) 2005 Robert N. M. Watson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 2005 Robert N. M. Watson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/lib/libmemstat/memstat_uma.c 148354 2005-07-23 21:17:15Z rwatson $
26 * $FreeBSD: head/lib/libmemstat/memstat_uma.c 148357 2005-07-24 01:28:54Z rwatson $
27 */
28
29#include <sys/param.h>
30#include <sys/sysctl.h>
31
32#include <vm/uma.h>
33
34#include <err.h>

--- 19 unchanged lines hidden (view full) ---

54 */
55int
56memstat_sysctl_uma(struct memory_type_list *list, int flags)
57{
58 struct uma_stream_header *ushp;
59 struct uma_type_header *uthp;
60 struct uma_percpu_stat *upsp;
61 struct memory_type *mtp;
27 */
28
29#include <sys/param.h>
30#include <sys/sysctl.h>
31
32#include <vm/uma.h>
33
34#include <err.h>

--- 19 unchanged lines hidden (view full) ---

54 */
55int
56memstat_sysctl_uma(struct memory_type_list *list, int flags)
57{
58 struct uma_stream_header *ushp;
59 struct uma_type_header *uthp;
60 struct uma_percpu_stat *upsp;
61 struct memory_type *mtp;
62 int count, error, hint_dontsearch, i, j, maxcpus;
62 int count, hint_dontsearch, i, j, maxcpus;
63 char *buffer, *p;
64 size_t size;
65
63 char *buffer, *p;
64 size_t size;
65
66 hint_dontsearch = LIST_EMPTY(list);
66 hint_dontsearch = LIST_EMPTY(&list->mtl_list);
67
68 /*
69 * Query the number of CPUs, number of malloc types so that we can
70 * guess an initial buffer size. We loop until we succeed or really
71 * fail. Note that the value of maxcpus we query using sysctl is not
72 * the version we use when processing the real data -- that is read
73 * from the header.
74 */
75retry:
76 size = sizeof(maxcpus);
77 if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) {
67
68 /*
69 * Query the number of CPUs, number of malloc types so that we can
70 * guess an initial buffer size. We loop until we succeed or really
71 * fail. Note that the value of maxcpus we query using sysctl is not
72 * the version we use when processing the real data -- that is read
73 * from the header.
74 */
75retry:
76 size = sizeof(maxcpus);
77 if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) {
78 error = errno;
79 perror("kern.smp.maxcpus");
80 errno = error;
78 if (errno == EACCES || errno == EPERM)
79 list->mtl_error = MEMSTAT_ERROR_PERMISSION;
80 else
81 list->mtl_error = MEMSTAT_ERROR_DATAERROR;
81 return (-1);
82 }
83 if (size != sizeof(maxcpus)) {
82 return (-1);
83 }
84 if (size != sizeof(maxcpus)) {
84 fprintf(stderr, "kern.smp.maxcpus: wrong size");
85 errno = EINVAL;
85 list->mtl_error = MEMSTAT_ERROR_DATAERROR;
86 return (-1);
87 }
88
89 if (maxcpus > MEMSTAT_MAXCPU) {
86 return (-1);
87 }
88
89 if (maxcpus > MEMSTAT_MAXCPU) {
90 fprintf(stderr, "kern.smp.maxcpus: too many CPUs\n");
91 errno = EINVAL;
90 list->mtl_error = MEMSTAT_ERROR_TOOMANYCPUS;
92 return (-1);
93 }
94
95 size = sizeof(count);
96 if (sysctlbyname("vm.zone_count", &count, &size, NULL, 0) < 0) {
91 return (-1);
92 }
93
94 size = sizeof(count);
95 if (sysctlbyname("vm.zone_count", &count, &size, NULL, 0) < 0) {
97 error = errno;
98 perror("vm.zone_count");
99 errno = error;
96 if (errno == EACCES || errno == EPERM)
97 list->mtl_error = MEMSTAT_ERROR_PERMISSION;
98 else
99 list->mtl_error = MEMSTAT_ERROR_VERSION;
100 return (-1);
101 }
102 if (size != sizeof(count)) {
100 return (-1);
101 }
102 if (size != sizeof(count)) {
103 fprintf(stderr, "vm.zone_count: wrong size");
104 errno = EINVAL;
103 list->mtl_error = MEMSTAT_ERROR_DATAERROR;
105 return (-1);
106 }
107
108 size = sizeof(*uthp) + count * (sizeof(*uthp) + sizeof(*upsp) *
109 maxcpus);
110
111 buffer = malloc(size);
112 if (buffer == NULL) {
104 return (-1);
105 }
106
107 size = sizeof(*uthp) + count * (sizeof(*uthp) + sizeof(*upsp) *
108 maxcpus);
109
110 buffer = malloc(size);
111 if (buffer == NULL) {
113 error = errno;
114 perror("malloc");
115 errno = error;
112 list->mtl_error = MEMSTAT_ERROR_NOMEMORY;
116 return (-1);
117 }
118
119 if (sysctlbyname("vm.zone_stats", buffer, &size, NULL, 0) < 0) {
120 /*
121 * XXXRW: ENOMEM is an ambiguous return, we should bound the
122 * number of loops, perhaps.
123 */
124 if (errno == ENOMEM) {
125 free(buffer);
126 goto retry;
127 }
113 return (-1);
114 }
115
116 if (sysctlbyname("vm.zone_stats", buffer, &size, NULL, 0) < 0) {
117 /*
118 * XXXRW: ENOMEM is an ambiguous return, we should bound the
119 * number of loops, perhaps.
120 */
121 if (errno == ENOMEM) {
122 free(buffer);
123 goto retry;
124 }
128 error = errno;
125 if (errno == EACCES || errno == EPERM)
126 list->mtl_error = MEMSTAT_ERROR_PERMISSION;
127 else
128 list->mtl_error = MEMSTAT_ERROR_VERSION;
129 free(buffer);
129 free(buffer);
130 perror("vm.zone_stats");
131 errno = error;
132 return (-1);
133 }
134
135 if (size == 0) {
136 free(buffer);
137 return (0);
138 }
139
140 if (size < sizeof(*ushp)) {
130 return (-1);
131 }
132
133 if (size == 0) {
134 free(buffer);
135 return (0);
136 }
137
138 if (size < sizeof(*ushp)) {
141 fprintf(stderr, "sysctl_uma: invalid malloc header");
139 list->mtl_error = MEMSTAT_ERROR_VERSION;
142 free(buffer);
140 free(buffer);
143 errno = EINVAL;
144 return (-1);
145 }
146 p = buffer;
147 ushp = (struct uma_stream_header *)p;
148 p += sizeof(*ushp);
149
150 if (ushp->ush_version != UMA_STREAM_VERSION) {
141 return (-1);
142 }
143 p = buffer;
144 ushp = (struct uma_stream_header *)p;
145 p += sizeof(*ushp);
146
147 if (ushp->ush_version != UMA_STREAM_VERSION) {
151 fprintf(stderr, "sysctl_uma: unknown malloc version");
148 list->mtl_error = MEMSTAT_ERROR_VERSION;
152 free(buffer);
149 free(buffer);
153 errno = EINVAL;
154 return (-1);
155 }
156
157 if (ushp->ush_maxcpus > MEMSTAT_MAXCPU) {
150 return (-1);
151 }
152
153 if (ushp->ush_maxcpus > MEMSTAT_MAXCPU) {
158 fprintf(stderr, "sysctl_uma: too many CPUs");
154 list->mtl_error = MEMSTAT_ERROR_TOOMANYCPUS;
159 free(buffer);
155 free(buffer);
160 errno = EINVAL;
161 return (-1);
162 }
163
164 /*
165 * For the remainder of this function, we are quite trusting about
166 * the layout of structures and sizes, since we've determined we have
167 * a matching version and acceptable CPU count.
168 */

--- 9 unchanged lines hidden (view full) ---

178 } else
179 mtp = NULL;
180 if (mtp == NULL)
181 mtp = _memstat_mt_allocate(list, ALLOCATOR_UMA,
182 uthp->uth_name);
183 if (mtp == NULL) {
184 memstat_mtl_free(list);
185 free(buffer);
156 return (-1);
157 }
158
159 /*
160 * For the remainder of this function, we are quite trusting about
161 * the layout of structures and sizes, since we've determined we have
162 * a matching version and acceptable CPU count.
163 */

--- 9 unchanged lines hidden (view full) ---

173 } else
174 mtp = NULL;
175 if (mtp == NULL)
176 mtp = _memstat_mt_allocate(list, ALLOCATOR_UMA,
177 uthp->uth_name);
178 if (mtp == NULL) {
179 memstat_mtl_free(list);
180 free(buffer);
186 errno = ENOMEM;
187 perror("malloc");
188 errno = ENOMEM;
181 list->mtl_error = MEMSTAT_ERROR_NOMEMORY;
189 return (-1);
190 }
191
192 /*
193 * Reset the statistics on a current node.
194 */
195 _memstat_mt_reset_stats(mtp);
196

--- 32 unchanged lines hidden ---
182 return (-1);
183 }
184
185 /*
186 * Reset the statistics on a current node.
187 */
188 _memstat_mt_reset_stats(mtp);
189

--- 32 unchanged lines hidden ---