4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 021110-1307, USA
24 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
25 * Copyright (c) 2011, 2012, Whamcloud, Inc.
28 * This file is part of Lustre, http://www.lustre.org/
29 * Lustre is a trademark of Sun Microsystems, Inc.
31 * Author: liang@whamcloud.com
35 # define EXPORT_SYMTAB
37 #define DEBUG_SUBSYSTEM S_LNET
39 #include <libcfs/libcfs.h>
41 struct cfs_var_array {
42 unsigned int va_count; /* # of buffers */
43 unsigned int va_size; /* size of each var */
44 struct cfs_cpt_table *va_cptab; /* cpu partition table */
45 void *va_ptrs[0]; /* buffer addresses */
49 * free per-cpu data, see more detail in cfs_percpt_free
52 cfs_percpt_free(void *vars)
54 struct cfs_var_array *arr;
57 arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
59 for (i = 0; i < arr->va_count; i++) {
60 if (arr->va_ptrs[i] != NULL)
61 LIBCFS_FREE(arr->va_ptrs[i], arr->va_size);
64 LIBCFS_FREE(arr, offsetof(struct cfs_var_array,
65 va_ptrs[arr->va_count]));
67 EXPORT_SYMBOL(cfs_percpt_free);
70 * allocate per cpu-partition variables, returned value is an array of pointers,
71 * variable can be indexed by CPU partition ID, i.e:
73 * arr = cfs_percpt_alloc(cfs_cpu_pt, size);
74 * then caller can access memory block for CPU 0 by arr[0],
75 * memory block for CPU 1 by arr[1]...
76 * memory block for CPU N by arr[N]...
81 cfs_percpt_alloc(struct cfs_cpt_table *cptab, unsigned int size)
83 struct cfs_var_array *arr;
87 count = cfs_cpt_number(cptab);
89 LIBCFS_ALLOC(arr, offsetof(struct cfs_var_array, va_ptrs[count]));
93 arr->va_size = size = CFS_L1_CACHE_ALIGN(size);
94 arr->va_count = count;
95 arr->va_cptab = cptab;
97 for (i = 0; i < count; i++) {
98 LIBCFS_CPT_ALLOC(arr->va_ptrs[i], cptab, i, size);
99 if (arr->va_ptrs[i] == NULL) {
100 cfs_percpt_free((void *)&arr->va_ptrs[0]);
105 return (void *)&arr->va_ptrs[0];
107 EXPORT_SYMBOL(cfs_percpt_alloc);
110 * return number of CPUs (or number of elements in per-cpu data)
111 * according to cptab of @vars
114 cfs_percpt_number(void *vars)
116 struct cfs_var_array *arr;
118 arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
120 return arr->va_count;
122 EXPORT_SYMBOL(cfs_percpt_number);
125 * return memory block shadowed from current CPU
128 cfs_percpt_current(void *vars)
130 struct cfs_var_array *arr;
133 arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
134 cpt = cfs_cpt_current(arr->va_cptab, 0);
138 return arr->va_ptrs[cpt];
140 EXPORT_SYMBOL(cfs_percpt_current);
143 cfs_percpt_index(void *vars, int idx)
145 struct cfs_var_array *arr;
147 arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
149 LASSERT(idx >= 0 && idx < arr->va_count);
150 return arr->va_ptrs[idx];
152 EXPORT_SYMBOL(cfs_percpt_index);
155 * free variable array, see more detail in cfs_array_alloc
158 cfs_array_free(void *vars)
160 struct cfs_var_array *arr;
163 arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
165 for (i = 0; i < arr->va_count; i++) {
166 if (arr->va_ptrs[i] == NULL)
169 LIBCFS_FREE(arr->va_ptrs[i], arr->va_size);
171 LIBCFS_FREE(arr, offsetof(struct cfs_var_array,
172 va_ptrs[arr->va_count]));
174 EXPORT_SYMBOL(cfs_array_free);
177 * allocate a variable array, returned value is an array of pointers.
178 * Caller can specify length of array by @count, @size is size of each
179 * memory block in array.
182 cfs_array_alloc(int count, unsigned int size)
184 struct cfs_var_array *arr;
187 LIBCFS_ALLOC(arr, offsetof(struct cfs_var_array, va_ptrs[count]));
191 arr->va_count = count;
194 for (i = 0; i < count; i++) {
195 LIBCFS_ALLOC(arr->va_ptrs[i], size);
197 if (arr->va_ptrs[i] == NULL) {
198 cfs_array_free((void *)&arr->va_ptrs[0]);
203 return (void *)&arr->va_ptrs[0];
205 EXPORT_SYMBOL(cfs_array_alloc);