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, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
31 * This file is part of Lustre, http://www.lustre.org/
32 * Lustre is a trademark of Sun Microsystems, Inc.
36 * Author: Eric Barton <eeb@clusterfs.com>
39 #define DEBUG_SUBSYSTEM S_LNET
41 #include <libcfs/libcfs.h>
47 lwt_cpu_t lwt_cpus[CFS_NR_CPUS];
50 int lwt_pages_per_cpu;
52 /* NB only root is allowed to retrieve LWT info; it's an open door into the
56 lwt_lookup_string (int *size, char *knl_ptr,
57 char *user_ptr, int user_size)
61 /* knl_ptr was retrieved from an LWT snapshot and the caller wants to
62 * turn it into a string. NB we can crash with an access violation
63 * trying to determine the string length, so we're trusting our
66 if (!cfs_capable(CFS_CAP_SYS_ADMIN))
73 *size = strnlen (knl_ptr, maxsize - 1) + 1;
75 if (user_ptr != NULL) {
79 if (copy_to_user(user_ptr, knl_ptr, *size))
82 /* Did I truncate the string? */
83 if (knl_ptr[*size - 1] != 0)
84 copy_to_user(user_ptr + *size - 4, "...", 4);
91 lwt_control (int enable, int clear)
97 if (!cfs_capable(CFS_CAP_SYS_ADMIN))
104 /* give people some time to stop adding traces */
105 cfs_schedule_timeout(10);
108 for (i = 0; i < num_online_cpus(); i++) {
109 p = lwt_cpus[i].lwtc_current_page;
117 for (j = 0; j < lwt_pages_per_cpu; j++) {
118 memset(p->lwtp_events, 0, PAGE_CACHE_SIZE);
120 p = cfs_list_entry (p->lwtp_list.next,
121 lwt_page_t, lwtp_list);
135 lwt_snapshot(cfs_cycles_t *now, int *ncpu, int *total_size,
136 void *user_ptr, int user_size)
138 const int events_per_page = PAGE_CACHE_SIZE / sizeof(lwt_event_t);
139 const int bytes_per_page = events_per_page * sizeof(lwt_event_t);
144 if (!cfs_capable(CFS_CAP_SYS_ADMIN))
147 *ncpu = num_online_cpus();
148 *total_size = num_online_cpus() * lwt_pages_per_cpu * bytes_per_page;
151 if (user_ptr == NULL)
154 for (i = 0; i < num_online_cpus(); i++) {
155 p = lwt_cpus[i].lwtc_current_page;
160 for (j = 0; j < lwt_pages_per_cpu; j++) {
161 if (copy_to_user(user_ptr, p->lwtp_events,
165 user_ptr = ((char *)user_ptr) + bytes_per_page;
166 p = cfs_list_entry(p->lwtp_list.next,
167 lwt_page_t, lwtp_list);
179 for (i = 0; i < num_online_cpus(); i++)
180 if (lwt_cpus[i].lwtc_current_page != NULL)
183 LASSERT (!lwt_enabled);
185 /* NULL pointers, zero scalars */
186 memset (lwt_cpus, 0, sizeof (lwt_cpus));
187 lwt_pages_per_cpu = LWT_MEMORY / (num_online_cpus() * PAGE_CACHE_SIZE);
189 for (i = 0; i < num_online_cpus(); i++)
190 for (j = 0; j < lwt_pages_per_cpu; j++) {
191 struct page *page = alloc_page(GFP_KERNEL);
195 CERROR ("Can't allocate page\n");
200 LIBCFS_ALLOC(lwtp, sizeof (*lwtp));
202 CERROR ("Can't allocate lwtp\n");
208 lwtp->lwtp_page = page;
209 lwtp->lwtp_events = page_address(page);
210 memset(lwtp->lwtp_events, 0, PAGE_CACHE_SIZE);
213 CFS_INIT_LIST_HEAD (&lwtp->lwtp_list);
214 lwt_cpus[i].lwtc_current_page = lwtp;
216 cfs_list_add (&lwtp->lwtp_list,
217 &lwt_cpus[i].lwtc_current_page->lwtp_list);
235 for (i = 0; i < num_online_cpus(); i++)
236 while (lwt_cpus[i].lwtc_current_page != NULL) {
237 lwt_page_t *lwtp = lwt_cpus[i].lwtc_current_page;
239 if (cfs_list_empty (&lwtp->lwtp_list)) {
240 lwt_cpus[i].lwtc_current_page = NULL;
242 lwt_cpus[i].lwtc_current_page =
243 cfs_list_entry (lwtp->lwtp_list.next,
244 lwt_page_t, lwtp_list);
246 cfs_list_del (&lwtp->lwtp_list);
249 __free_page (lwtp->lwtp_page);
250 LIBCFS_FREE (lwtp, sizeof (*lwtp));
254 EXPORT_SYMBOL(lwt_enabled);
255 EXPORT_SYMBOL(lwt_cpus);
257 EXPORT_SYMBOL(lwt_init);
258 EXPORT_SYMBOL(lwt_fini);
259 EXPORT_SYMBOL(lwt_lookup_string);
260 EXPORT_SYMBOL(lwt_control);
261 EXPORT_SYMBOL(lwt_snapshot);