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).
18 /* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
19 * Copyright (c) 2012, Intel Corporation.
21 /* This file is part of Lustre, http://www.lustre.org/
23 * Author: liang@whamcloud.com
26 #define DEBUG_SUBSYSTEM S_LNET
28 #include <linux/kernel.h>
29 #include <linux/module.h>
30 #include <libcfs/libcfs.h>
31 #include <libcfs/libcfs_cpu.h>
32 #include <linux/slab.h>
35 struct cfs_var_array {
36 unsigned int va_count; /* # of buffers */
37 unsigned int va_size; /* size of each var */
38 struct cfs_cpt_table *va_cptab; /* cpu partition table */
39 void *va_ptrs[0]; /* buffer addresses */
42 /* free per-cpu data, see more detail in cfs_percpt_free
45 cfs_percpt_free(void *vars)
47 struct cfs_var_array *arr;
50 arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
52 for (i = 0; i < arr->va_count; i++) {
53 if (arr->va_ptrs[i] != NULL)
54 LIBCFS_FREE(arr->va_ptrs[i], arr->va_size);
57 LIBCFS_FREE(arr, offsetof(struct cfs_var_array,
58 va_ptrs[arr->va_count]));
60 EXPORT_SYMBOL(cfs_percpt_free);
62 /* allocate per cpu-partition variables, returned value is an array of pointers,
63 * variable can be indexed by CPU partition ID, i.e:
65 * arr = cfs_percpt_alloc(cfs_cpu_pt, size);
66 * then caller can access memory block for CPU 0 by arr[0],
67 * memory block for CPU 1 by arr[1]...
68 * memory block for CPU N by arr[N]...
73 cfs_percpt_alloc(struct cfs_cpt_table *cptab, unsigned int size)
75 struct cfs_var_array *arr;
79 count = cfs_cpt_number(cptab);
81 LIBCFS_ALLOC(arr, offsetof(struct cfs_var_array, va_ptrs[count]));
85 size = L1_CACHE_ALIGN(size);
87 arr->va_count = count;
88 arr->va_cptab = cptab;
90 for (i = 0; i < count; i++) {
91 LIBCFS_CPT_ALLOC(arr->va_ptrs[i], cptab, i, size);
92 if (!arr->va_ptrs[i]) {
93 cfs_percpt_free((void *)&arr->va_ptrs[0]);
98 return (void *)&arr->va_ptrs[0];
100 EXPORT_SYMBOL(cfs_percpt_alloc);
102 /* return number of CPUs (or number of elements in per-cpu data)
103 * according to cptab of @vars
106 cfs_percpt_number(void *vars)
108 struct cfs_var_array *arr;
110 arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
112 return arr->va_count;
114 EXPORT_SYMBOL(cfs_percpt_number);