2 * Copyright (c) 2017 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #include <vppinfra/clib.h>
17 #include <vppinfra/clib_error.h>
18 #include <vppinfra/format.h>
20 #include <sys/types.h>
25 #define DEFAULT_HUGETLB_SIZE 2048
28 clib_sysfs_write (char *file_name, char *fmt, ...)
32 clib_error_t *error = 0;
34 fd = open (file_name, O_WRONLY);
36 return clib_error_return_unix (0, "open `%s'", file_name);
40 s = va_format (0, fmt, &va);
43 if (write (fd, s, vec_len (s)) < 0)
44 error = clib_error_return_unix (0, "write `%s'", file_name);
52 clib_sysfs_read (char *file_name, char *fmt, ...)
54 unformat_input_t input;
60 fd = open (file_name, O_RDONLY);
62 return clib_error_return_unix (0, "open `%s'", file_name);
64 vec_validate (s, 4095);
66 sz = read (fd, s, vec_len (s));
71 return clib_error_return_unix (0, "read `%s'", file_name);
75 unformat_init_vector (&input, s);
79 result = va_unformat (&input, fmt, &va);
86 return clib_error_return (0, "unformat error");
92 clib_sysfs_link_to_name (char *link)
99 r = readlink (link, buffer, sizeof (buffer) - 1);
105 p = strrchr (buffer, '/');
110 unformat_init_string (&in, p + 1, strlen (p + 1));
111 if (unformat (&in, "%s", &s) != 1)
112 clib_unix_warning ("no string?");
119 clib_sysfs_set_nr_hugepages (int numa_node, int log2_page_size, int nr)
121 clib_error_t *error = 0;
124 int page_size = log2_page_size ? 1ULL << (log2_page_size - 10) :
125 DEFAULT_HUGETLB_SIZE;
127 p = format (p, "/sys/devices/system/node/node%u%c", numa_node, 0);
129 if (stat ((char *) p, &sb) == 0)
131 if (S_ISDIR (sb.st_mode) == 0)
133 error = clib_error_return (0, "'%s' is not directory", p);
137 else if (numa_node == 0)
139 vec_reset_length (p);
140 p = format (p, "/sys/kernel/mm%c", 0);
141 if (stat ((char *) p, &sb) < 0 || S_ISDIR (sb.st_mode) == 0)
143 error = clib_error_return (0, "'%s' does not exist or it is not "
150 error = clib_error_return (0, "'%s' does not exist", p);
155 p = format (p, "/hugepages/hugepages-%ukB/nr_hugepages%c", page_size, 0);
156 clib_sysfs_write ((char *) p, "%d", nr);
164 static clib_error_t *
165 clib_sysfs_get_xxx_hugepages (char *type, int numa_node,
166 int log2_page_size, int *val)
168 clib_error_t *error = 0;
171 int page_size = log2_page_size ? 1ULL << (log2_page_size - 10) :
172 DEFAULT_HUGETLB_SIZE;
174 p = format (p, "/sys/devices/system/node/node%u%c", numa_node, 0);
176 if (stat ((char *) p, &sb) == 0)
178 if (S_ISDIR (sb.st_mode) == 0)
180 error = clib_error_return (0, "'%s' is not directory", p);
184 else if (numa_node == 0)
186 vec_reset_length (p);
187 p = format (p, "/sys/kernel/mm%c", 0);
188 if (stat ((char *) p, &sb) < 0 || S_ISDIR (sb.st_mode) == 0)
190 error = clib_error_return (0, "'%s' does not exist or it is not "
197 error = clib_error_return (0, "'%s' does not exist", p);
202 p = format (p, "/hugepages/hugepages-%ukB/%s_hugepages%c", page_size,
204 error = clib_sysfs_read ((char *) p, "%d", val);
212 clib_sysfs_get_free_hugepages (int numa_node, int log2_page_size, int *v)
214 return clib_sysfs_get_xxx_hugepages ("free", numa_node, log2_page_size, v);
218 clib_sysfs_get_nr_hugepages (int numa_node, int log2_page_size, int *v)
220 return clib_sysfs_get_xxx_hugepages ("nr", numa_node, log2_page_size, v);
224 clib_sysfs_get_surplus_hugepages (int numa_node, int log2_page_size, int *v)
226 return clib_sysfs_get_xxx_hugepages ("surplus", numa_node, log2_page_size,
231 clib_sysfs_prealloc_hugepages (int numa_node, int log2_page_size, int nr)
233 clib_error_t *error = 0;
235 int page_size = log2_page_size ? 1ULL << (log2_page_size - 10) :
236 DEFAULT_HUGETLB_SIZE;
237 error = clib_sysfs_get_free_hugepages (numa_node, log2_page_size, &n);
244 error = clib_sysfs_get_nr_hugepages (numa_node, log2_page_size, &n);
247 clib_warning ("pre-allocating %u additional %uK hugepages on numa node %u",
248 needed, page_size, numa_node);
249 return clib_sysfs_set_nr_hugepages (numa_node, log2_page_size, n + needed);
254 * fd.io coding-style-patch-verification: ON
257 * eval: (c-set-style "gnu")