* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+#ifndef AUTOCONF_INCLUDED
#include <linux/config.h>
+#endif
#include <linux/module.h>
#include <linux/kmod.h>
#include <linux/kernel.h>
#include <asm/system.h>
#include <asm/uaccess.h>
-#define DEBUG_SUBSYSTEM S_PORTALS
+#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/kp30.h>
+#include <libcfs/kp30.h>
#if LWT_SUPPORT
-#define LWT_MEMORY (1<<20) /* 1Mb of trace memory */
-#define LWT_MAX_CPUS 4
-
+#if !KLWT_SUPPORT
int lwt_enabled;
+lwt_cpu_t lwt_cpus[NR_CPUS];
+#endif
+
int lwt_pages_per_cpu;
-lwt_cpu_t lwt_cpus[LWT_MAX_CPUS];
/* NB only root is allowed to retrieve LWT info; it's an open door into the
* kernel... */
lwt_lookup_string (int *size, char *knl_ptr,
char *user_ptr, int user_size)
{
+ int maxsize = 128;
+
/* knl_ptr was retrieved from an LWT snapshot and the caller wants to
* turn it into a string. NB we can crash with an access violation
* trying to determine the string length, so we're trusting our
if (!capable(CAP_SYS_ADMIN))
return (-EPERM);
- *size = strlen (knl_ptr) + 1;
-
- if (user_ptr != NULL &&
- copy_to_user (user_ptr, knl_ptr, *size))
- return (-EFAULT);
+ if (user_size > 0 &&
+ maxsize > user_size)
+ maxsize = user_size;
+
+ *size = strnlen (knl_ptr, maxsize - 1) + 1;
+ if (user_ptr != NULL) {
+ if (user_size < 4)
+ return (-EINVAL);
+
+ if (copy_to_user (user_ptr, knl_ptr, *size))
+ return (-EFAULT);
+
+ /* Did I truncate the string? */
+ if (knl_ptr[*size - 1] != 0)
+ copy_to_user (user_ptr + *size - 4, "...", 4);
+ }
+
return (0);
}
if (!capable(CAP_SYS_ADMIN))
return (-EPERM);
- if (clear)
- for (i = 0; i < num_online_cpus(); i++) {
- p = lwt_cpus[i].lwtc_current_page;
-
- for (j = 0; j < lwt_pages_per_cpu; j++) {
-
- memset (p->lwtp_events, 0, PAGE_SIZE);
-
- p = list_entry (p->lwtp_list.next,
- lwt_page_t, lwtp_list);
- }
- }
-
- lwt_enabled = enable;
- mb();
if (!enable) {
+ LWT_EVENT(0,0,0,0);
+ lwt_enabled = 0;
+ mb();
/* give people some time to stop adding traces */
schedule_timeout(10);
}
+ for (i = 0; i < num_online_cpus(); i++) {
+ p = lwt_cpus[i].lwtc_current_page;
+
+ if (p == NULL)
+ return (-ENODATA);
+
+ if (!clear)
+ continue;
+
+ for (j = 0; j < lwt_pages_per_cpu; j++) {
+ memset (p->lwtp_events, 0, CFS_PAGE_SIZE);
+
+ p = list_entry (p->lwtp_list.next,
+ lwt_page_t, lwtp_list);
+ }
+ }
+
+ if (enable) {
+ lwt_enabled = 1;
+ mb();
+ LWT_EVENT(0,0,0,0);
+ }
+
return (0);
}
int
-lwt_snapshot (int *ncpu, int *total_size,
- void *user_ptr, int user_size)
+lwt_snapshot (cycles_t *now, int *ncpu, int *total_size,
+ void *user_ptr, int user_size)
{
- const int events_per_page = PAGE_SIZE / sizeof(lwt_event_t);
+ const int events_per_page = CFS_PAGE_SIZE / sizeof(lwt_event_t);
const int bytes_per_page = events_per_page * sizeof(lwt_event_t);
lwt_page_t *p;
int i;
*ncpu = num_online_cpus();
*total_size = num_online_cpus() * lwt_pages_per_cpu * bytes_per_page;
-
+ *now = get_cycles();
+
if (user_ptr == NULL)
return (0);
for (i = 0; i < num_online_cpus(); i++) {
p = lwt_cpus[i].lwtc_current_page;
+
+ if (p == NULL)
+ return (-ENODATA);
for (j = 0; j < lwt_pages_per_cpu; j++) {
if (copy_to_user(user_ptr, p->lwtp_events,
{
int i;
int j;
+
+ for (i = 0; i < num_online_cpus(); i++)
+ if (lwt_cpus[i].lwtc_current_page != NULL)
+ return (-EALREADY);
- if (num_online_cpus() > LWT_MAX_CPUS) {
- CERROR ("Too many CPUs\n");
- return (-EINVAL);
- }
+ LASSERT (!lwt_enabled);
/* NULL pointers, zero scalars */
memset (lwt_cpus, 0, sizeof (lwt_cpus));
- lwt_pages_per_cpu = LWT_MEMORY / (num_online_cpus() * PAGE_SIZE);
+ lwt_pages_per_cpu = LWT_MEMORY / (num_online_cpus() * CFS_PAGE_SIZE);
for (i = 0; i < num_online_cpus(); i++)
for (j = 0; j < lwt_pages_per_cpu; j++) {
return (-ENOMEM);
}
- PORTAL_ALLOC(lwtp, sizeof (*lwtp));
+ LIBCFS_ALLOC(lwtp, sizeof (*lwtp));
if (lwtp == NULL) {
CERROR ("Can't allocate lwtp\n");
__free_page(page);
lwtp->lwtp_page = page;
lwtp->lwtp_events = page_address(page);
- memset (lwtp->lwtp_events, 0, PAGE_SIZE);
+ memset (lwtp->lwtp_events, 0, CFS_PAGE_SIZE);
if (j == 0) {
INIT_LIST_HEAD (&lwtp->lwtp_list);
lwt_enabled = 1;
mb();
+ LWT_EVENT(0,0,0,0);
+
return (0);
}
lwt_fini ()
{
int i;
-
- if (num_online_cpus() > LWT_MAX_CPUS)
- return;
+ lwt_control(0, 0);
+
for (i = 0; i < num_online_cpus(); i++)
while (lwt_cpus[i].lwtc_current_page != NULL) {
lwt_page_t *lwtp = lwt_cpus[i].lwtc_current_page;
}
__free_page (lwtp->lwtp_page);
- PORTAL_FREE (lwtp, sizeof (*lwtp));
+ LIBCFS_FREE (lwtp, sizeof (*lwtp));
}
}