The LWT code has been disabled on all platforms since being merged.
Now that its functionality can be replaces by Systemtap etc, it is
on longer needed.
Signed-off-by: Peng Tao <bergwolf@gmail.com>
Change-Id: I21dc913bfdbbf1bfba5e0d7de3d43b183f0e5b23
Reviewed-on: http://review.whamcloud.com/8340
Reviewed-by: Dmitry Eremin <dmitry.eremin@intel.com>
Reviewed-by: James Simmons <uja.ornl@gmail.com>
Reviewed-by: John L. Hammond <john.hammond@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
#endif
#define BITS_PER_LONG LONG_BIT
-/******************************************************************************/
-/* Light-weight trace
- * Support for temporary event tracing with minimal Heisenberg effect. */
-#define LWT_SUPPORT 0
-
-typedef struct {
- long long lwte_when;
- char *lwte_where;
- void *lwte_task;
- long lwte_p1;
- long lwte_p2;
- long lwte_p3;
- long lwte_p4;
-} lwt_event_t;
-
-# define LWT_EVENT(p1,p2,p3,p4) /* no lwt implementation yet */
-
-/* -------------------------------------------------------------------------- */
#define IOCTL_LIBCFS_TYPE struct libcfs_ioctl_data
#define IOC_LIBCFS_PANIC _IOWR('e', 30, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_CLEAR_DEBUG _IOWR('e', 31, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_MARK_DEBUG _IOWR('e', 32, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_LWT_CONTROL _IOWR('e', 33, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_LWT_SNAPSHOT _IOWR('e', 34, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_LWT_LOOKUP_STRING _IOWR('e', 35, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_MEMHOG _IOWR('e', 36, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_PING_TEST _IOWR('e', 37, IOCTL_LIBCFS_TYPE)
/* lnet ioctls */
# define CFS_CURRENT_TIME time(0)
#endif
-/* --------------------------------------------------------------------
- * Light-weight trace
- * Support for temporary event tracing with minimal Heisenberg effect.
- * All stuff about lwt are put in arch/kp30.h
- * -------------------------------------------------------------------- */
-
struct libcfs_device_userstate
{
int ldu_memhog_pages;
# define printf(format, b...) CDEBUG(D_OTHER, format , ## b)
# define time(a) CURRENT_TIME
-/******************************************************************************/
-/* Light-weight trace
- * Support for temporary event tracing with minimal Heisenberg effect. */
-#define LWT_SUPPORT 0
-
-#define LWT_MEMORY (16<<20)
-
-#ifndef KLWT_SUPPORT
-# if defined(__KERNEL__)
-# if !defined(BITS_PER_LONG)
-# error "BITS_PER_LONG not defined"
-# endif
-# elif !defined(__WORDSIZE)
-# error "__WORDSIZE not defined"
-# else
-# define BITS_PER_LONG __WORDSIZE
-# endif
-
-/* kernel hasn't defined this? */
-typedef struct {
- long long lwte_when;
- char *lwte_where;
- void *lwte_task;
- long lwte_p1;
- long lwte_p2;
- long lwte_p3;
- long lwte_p4;
-# if BITS_PER_LONG > 32
- long lwte_pad;
-# endif
-} lwt_event_t;
-#endif /* !KLWT_SUPPORT */
-
-#if LWT_SUPPORT
-# ifdef __KERNEL__
-# if !KLWT_SUPPORT
-
-typedef struct _lwt_page {
- struct list_head lwtp_list;
- struct page *lwtp_page;
- lwt_event_t *lwtp_events;
-} lwt_page_t;
-
-typedef struct {
- int lwtc_current_index;
- lwt_page_t *lwtc_current_page;
-} lwt_cpu_t;
-
-extern int lwt_enabled;
-extern lwt_cpu_t lwt_cpus[];
-
-/* Note that we _don't_ define LWT_EVENT at all if LWT_SUPPORT isn't set.
- * This stuff is meant for finding specific problems; it never stays in
- * production code... */
-
-#define LWTSTR(n) #n
-#define LWTWHERE(f,l) f ":" LWTSTR(l)
-#define LWT_EVENTS_PER_PAGE (PAGE_CACHE_SIZE / sizeof(lwt_event_t))
-
-#define LWT_EVENT(p1, p2, p3, p4) \
-do { \
- unsigned long flags; \
- lwt_cpu_t *cpu; \
- lwt_page_t *p; \
- lwt_event_t *e; \
- \
- if (lwt_enabled) { \
- local_irq_save (flags); \
- \
- cpu = &lwt_cpus[smp_processor_id()]; \
- p = cpu->lwtc_current_page; \
- e = &p->lwtp_events[cpu->lwtc_current_index++]; \
- \
- if (cpu->lwtc_current_index >= LWT_EVENTS_PER_PAGE) { \
- cpu->lwtc_current_page = \
- list_entry (p->lwtp_list.next, \
- lwt_page_t, lwtp_list); \
- cpu->lwtc_current_index = 0; \
- } \
- \
- e->lwte_when = get_cycles(); \
- e->lwte_where = LWTWHERE(__FILE__,__LINE__); \
- e->lwte_task = current; \
- e->lwte_p1 = (long)(p1); \
- e->lwte_p2 = (long)(p2); \
- e->lwte_p3 = (long)(p3); \
- e->lwte_p4 = (long)(p4); \
- \
- local_irq_restore (flags); \
- } \
-} while (0)
-
-#endif /* !KLWT_SUPPORT */
-
-extern int lwt_init (void);
-extern void lwt_fini (void);
-extern int lwt_lookup_string (int *size, char *knlptr,
- char *usrptr, int usrsize);
-extern int lwt_control (int enable, int clear);
-extern int lwt_snapshot (cfs_cycles_t *now, int *ncpu, int *total_size,
- void *user_ptr, int user_size);
-# else /* __KERNEL__ */
-# define LWT_EVENT(p1,p2,p3,p4) /* no userland implementation yet */
-# endif /* __KERNEL__ */
-#endif /* LWT_SUPPORT */
-
-/* ------------------------------------------------------------------ */
-
#define IOCTL_LIBCFS_TYPE long
#ifdef __CYGWIN__
#ifndef __LIBCFS_LINUX_KP30_H__
#define __LIBCFS_LINUX_KP30_H__
-
-
#if defined(__CYGWIN__)
# include <cygwin-ioctl.h>
#endif
#define symbol_get(x) inter_module_get(#x)
#define symbol_put(x) inter_module_put(#x)
-
#ifdef __CYGWIN__
# ifndef BITS_PER_LONG
# if (~0UL) == 0xffffffffUL
# define BITS_PER_LONG __WORDSIZE
#endif
-
-/******************************************************************************/
-/* Light-weight trace
- * Support for temporary event tracing with minimal Heisenberg effect. */
-#define LWT_SUPPORT 0
-
-#define LWT_MEMORY (16<<20)
-
-typedef struct {
- long long lwte_when;
- char *lwte_where;
- void *lwte_task;
- long lwte_p1;
- long lwte_p2;
- long lwte_p3;
- long lwte_p4;
-# if BITS_PER_LONG > 32
- long lwte_pad;
-# endif
-} lwt_event_t;
-
-#if LWT_SUPPORT
-#define LWT_EVENT(p1,p2,p3,p4) /* no userland implementation yet */
-#endif /* LWT_SUPPORT */
-
-/* ------------------------------------------------------------------ */
-
#define IOCTL_LIBCFS_TYPE long
-
#if BITS_PER_LONG > 32
# define LI_POISON ((int)0x5a5a5a5a5a5a5a5a)
# define LL_POISON ((long)0x5a5a5a5a5a5a5a5a)
#endif /* End of !__KERNEL__ */
-/******************************************************************************/
-/* Light-weight trace
- * Support for temporary event tracing with minimal Heisenberg effect. */
-#define LWT_SUPPORT 0
-
-/* kernel hasn't defined this? */
-typedef struct {
- __s64 lwte_when;
- char *lwte_where;
- void *lwte_task;
- long_ptr_t lwte_p1;
- long_ptr_t lwte_p2;
- long_ptr_t lwte_p3;
- long_ptr_t lwte_p4;
-# if BITS_PER_LONG > 32
- long_ptr_t lwte_pad;
-# endif
-} lwt_event_t;
-
-
-# define LWT_EVENT(p1,p2,p3,p4)
-
-
-/* ------------------------------------------------------------------ */
-
#define IOCTL_LIBCFS_TYPE long_ptr_t
#ifdef __CYGWIN__
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * libcfs/libcfs/lwt.c
- *
- * Author: Eric Barton <eeb@clusterfs.com>
- */
-
-#define DEBUG_SUBSYSTEM S_LNET
-
-#include <libcfs/libcfs.h>
-
-#if LWT_SUPPORT
-
-#if !KLWT_SUPPORT
-int lwt_enabled;
-lwt_cpu_t lwt_cpus[NR_CPUS];
-#endif
-
-int lwt_pages_per_cpu;
-
-/* NB only root is allowed to retrieve LWT info; it's an open door into the
- * kernel... */
-
-int
-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
- * caller... */
-
- if (!cfs_capable(CFS_CAP_SYS_ADMIN))
- return (-EPERM);
-
- 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;
-}
-
-int
-lwt_control (int enable, int clear)
-{
- lwt_page_t *p;
- int i;
- int j;
-
- if (!cfs_capable(CFS_CAP_SYS_ADMIN))
- return (-EPERM);
-
- if (!enable) {
- LWT_EVENT(0,0,0,0);
- lwt_enabled = 0;
- smp_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, PAGE_CACHE_SIZE);
-
- p = list_entry(p->lwtp_list.next,
- lwt_page_t, lwtp_list);
- }
- }
-
- if (enable) {
- lwt_enabled = 1;
- smp_mb();
- LWT_EVENT(0,0,0,0);
- }
-
- return (0);
-}
-
-int
-lwt_snapshot(cfs_cycles_t *now, int *ncpu, int *total_size,
- void *user_ptr, int user_size)
-{
- const int events_per_page = PAGE_CACHE_SIZE / sizeof(lwt_event_t);
- const int bytes_per_page = events_per_page * sizeof(lwt_event_t);
- lwt_page_t *p;
- int i;
- int j;
-
- if (!cfs_capable(CFS_CAP_SYS_ADMIN))
- return (-EPERM);
-
- *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,
- bytes_per_page))
- return -EFAULT;
-
- user_ptr = ((char *)user_ptr) + bytes_per_page;
- p = list_entry(p->lwtp_list.next,
- lwt_page_t, lwtp_list);
- }
- }
- return (0);
-}
-
-int lwt_init ()
-{
- int i;
- int j;
-
- for (i = 0; i < num_online_cpus(); i++)
- if (lwt_cpus[i].lwtc_current_page != NULL)
- return (-EALREADY);
-
- LASSERT (!lwt_enabled);
-
- /* NULL pointers, zero scalars */
- memset (lwt_cpus, 0, sizeof (lwt_cpus));
- lwt_pages_per_cpu = LWT_MEMORY / (num_online_cpus() * PAGE_CACHE_SIZE);
-
- for (i = 0; i < num_online_cpus(); i++)
- for (j = 0; j < lwt_pages_per_cpu; j++) {
- struct page *page = alloc_page(GFP_KERNEL);
- lwt_page_t *lwtp;
-
- if (page == NULL) {
- CERROR ("Can't allocate page\n");
- lwt_fini ();
- return (-ENOMEM);
- }
-
- LIBCFS_ALLOC(lwtp, sizeof (*lwtp));
- if (lwtp == NULL) {
- CERROR ("Can't allocate lwtp\n");
- __free_page(page);
- lwt_fini ();
- return (-ENOMEM);
- }
-
- lwtp->lwtp_page = page;
- lwtp->lwtp_events = page_address(page);
- memset(lwtp->lwtp_events, 0, PAGE_CACHE_SIZE);
-
- if (j == 0) {
- INIT_LIST_HEAD (&lwtp->lwtp_list);
- lwt_cpus[i].lwtc_current_page = lwtp;
- } else {
- list_add(&lwtp->lwtp_list,
- &lwt_cpus[i].lwtc_current_page->lwtp_list);
- }
- }
-
- lwt_enabled = 1;
- smp_mb();
-
- LWT_EVENT(0,0,0,0);
-
- return (0);
-}
-
-void lwt_fini ()
-{
- int i;
-
- 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;
-
- if (list_empty (&lwtp->lwtp_list)) {
- lwt_cpus[i].lwtc_current_page = NULL;
- } else {
- lwt_cpus[i].lwtc_current_page =
- list_entry(lwtp->lwtp_list.next,
- lwt_page_t, lwtp_list);
- list_del (&lwtp->lwtp_list);
- }
- __free_page (lwtp->lwtp_page);
- LIBCFS_FREE (lwtp, sizeof (*lwtp));
- }
-}
-
-EXPORT_SYMBOL(lwt_enabled);
-EXPORT_SYMBOL(lwt_cpus);
-
-EXPORT_SYMBOL(lwt_init);
-EXPORT_SYMBOL(lwt_fini);
-EXPORT_SYMBOL(lwt_lookup_string);
-EXPORT_SYMBOL(lwt_control);
-EXPORT_SYMBOL(lwt_snapshot);
-#endif
RETURN(-EINVAL);
libcfs_debug_mark_buffer(data->ioc_inlbuf1);
RETURN(0);
-#if LWT_SUPPORT
- case IOC_LIBCFS_LWT_CONTROL:
- err = lwt_control ((data->ioc_flags & 1) != 0,
- (data->ioc_flags & 2) != 0);
- break;
-
- case IOC_LIBCFS_LWT_SNAPSHOT: {
- cfs_cycles_t now;
- int ncpu;
- int total_size;
-
- err = lwt_snapshot (&now, &ncpu, &total_size,
- data->ioc_pbuf1, data->ioc_plen1);
- data->ioc_u64[0] = now;
- data->ioc_u32[0] = ncpu;
- data->ioc_u32[1] = total_size;
-
- /* Hedge against broken user/kernel typedefs (e.g. cycles_t) */
- data->ioc_u32[2] = sizeof(lwt_event_t);
- data->ioc_u32[3] = offsetof(lwt_event_t, lwte_where);
-
- if (err == 0 &&
- libcfs_ioctl_popdata(arg, data, sizeof (*data)))
- err = -EFAULT;
- break;
- }
-
- case IOC_LIBCFS_LWT_LOOKUP_STRING:
- err = lwt_lookup_string (&data->ioc_count, data->ioc_pbuf1,
- data->ioc_pbuf2, data->ioc_plen2);
- if (err == 0 &&
- libcfs_ioctl_popdata(arg, data, sizeof (*data)))
- err = -EFAULT;
- break;
-#endif
case IOC_LIBCFS_MEMHOG:
if (pfile->private_data == NULL) {
err = -EINVAL;
if (rc != 0)
goto cleanup_debug;
-#if LWT_SUPPORT
- rc = lwt_init();
- if (rc != 0) {
- CERROR("lwt_init: error %d\n", rc);
- goto cleanup_debug;
- }
-#endif
rc = misc_register(&libcfs_dev);
if (rc) {
CERROR("misc_register: error %d\n", rc);
- goto cleanup_lwt;
+ goto cleanup_cpu;
}
rc = cfs_wi_startup();
CDEBUG (D_OTHER, "portals setup OK\n");
return 0;
- cleanup_crypto:
+cleanup_crypto:
cfs_crypto_unregister();
- cleanup_wi:
+cleanup_wi:
cfs_wi_shutdown();
- cleanup_deregister:
+cleanup_deregister:
misc_deregister(&libcfs_dev);
- cleanup_lwt:
-#if LWT_SUPPORT
- lwt_fini();
-#endif
- cleanup_debug:
+cleanup_cpu:
+ cfs_cpu_fini();
+cleanup_debug:
libcfs_debug_cleanup();
return rc;
}
if (rc)
CERROR("misc_deregister error %d\n", rc);
-#if LWT_SUPPORT
- lwt_fini();
-#endif
cfs_cpu_fini();
if (atomic_read(&libcfs_kmemory) != 0)
int jt_ptl_notify_router (int argc, char **argv);
int jt_ptl_print_routes (int argc, char **argv);
int jt_ptl_fail_nid (int argc, char **argv);
-int jt_ptl_lwt(int argc, char **argv);
int jt_ptl_testprotocompat(int argc, char **argv);
int jt_ptl_memhog(int argc, char **argv);
return (0);
}
-static int
-lwt_control(int enable, int clear)
-{
- struct libcfs_ioctl_data data;
- int rc;
-
- LIBCFS_IOC_INIT(data);
- data.ioc_flags = (enable ? 1 : 0) | (clear ? 2 : 0);
-
- rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LWT_CONTROL, &data);
- if (rc == 0)
- return (0);
-
- fprintf(stderr, "IOC_LIBCFS_LWT_CONTROL failed: %s\n",
- strerror(errno));
- return (-1);
-}
-
-static int
-lwt_snapshot(cfs_cycles_t *now, int *ncpu, int *totalsize,
- lwt_event_t *events, int size)
-{
- struct libcfs_ioctl_data data;
- int rc;
-
- LIBCFS_IOC_INIT(data);
- data.ioc_pbuf1 = (char *)events;
- data.ioc_plen1 = size;
-
- rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LWT_SNAPSHOT, &data);
- if (rc != 0) {
- fprintf(stderr, "IOC_LIBCFS_LWT_SNAPSHOT failed: %s\n",
- strerror(errno));
- return (-1);
- }
-
- /* crappy overloads */
- if (data.ioc_u32[2] != sizeof(lwt_event_t) ||
- data.ioc_u32[3] != offsetof(lwt_event_t, lwte_where)) {
- fprintf(stderr,"kernel/user LWT event mismatch %d(%d),%d(%d)\n",
- (int)data.ioc_u32[2], (int)sizeof(lwt_event_t),
- (int)data.ioc_u32[3],
- (int)offsetof(lwt_event_t, lwte_where));
- return (-1);
- }
-
- if (now != NULL)
- *now = data.ioc_u64[0];
-
- LASSERT (data.ioc_u32[0] != 0);
- if (ncpu != NULL)
- *ncpu = data.ioc_u32[0];
-
- LASSERT (data.ioc_u32[1] != 0);
- if (totalsize != NULL)
- *totalsize = data.ioc_u32[1];
-
- return (0);
-}
-
-static char *
-lwt_get_string(char *kstr)
-{
- char *ustr;
- struct libcfs_ioctl_data data;
- int size;
- int rc;
-
- /* FIXME: this could maintain a symbol table since we expect to be
- * looking up the same strings all the time... */
-
- LIBCFS_IOC_INIT(data);
- data.ioc_pbuf1 = kstr;
- data.ioc_plen1 = 1; /* non-zero just to fool portal_ioctl_is_invalid() */
- data.ioc_pbuf2 = NULL;
- data.ioc_plen2 = 0;
-
- rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LWT_LOOKUP_STRING, &data);
- if (rc != 0) {
- fprintf(stderr, "IOC_LIBCFS_LWT_LOOKUP_STRING failed: %s\n",
- strerror(errno));
- return (NULL);
- }
-
- size = data.ioc_count;
- ustr = (char *)malloc(size);
- if (ustr == NULL) {
- fprintf(stderr, "Can't allocate string storage of size %d\n",
- size);
- return (NULL);
- }
-
- LIBCFS_IOC_INIT(data);
- data.ioc_pbuf1 = kstr;
- data.ioc_plen1 = 1; /* non-zero just to fool portal_ioctl_is_invalid() */
- data.ioc_pbuf2 = ustr;
- data.ioc_plen2 = size;
-
- rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LWT_LOOKUP_STRING, &data);
- if (rc != 0) {
- fprintf(stderr, "IOC_LIBCFS_LWT_LOOKUP_STRING failed: %s\n",
- strerror(errno));
- return (NULL);
- }
-
- LASSERT(strlen(ustr) == size - 1);
- return (ustr);
-}
-
-static void
-lwt_put_string(char *ustr)
-{
- free(ustr);
-}
-
-static int
-lwt_print(FILE *f, cfs_cycles_t t0, cfs_cycles_t tlast, double mhz, int cpu,
- lwt_event_t *e)
-{
-#ifndef __WORDSIZE
-# error "__WORDSIZE not defined"
-#elif __WORDSIZE == 32
-# define XFMT "%#010lx"
-#elif __WORDSIZE== 64
-# define XFMT "%#018lx"
-#else
-# error "Unexpected __WORDSIZE"
-#endif
- char *where = lwt_get_string(e->lwte_where);
-
- if (where == NULL)
- return (-1);
-
- fprintf(f, XFMT" "XFMT" "XFMT" "XFMT": "XFMT" %2d %10.6f %10.2f %s\n",
- e->lwte_p1, e->lwte_p2, e->lwte_p3, e->lwte_p4,
- (long)e->lwte_task, cpu, (e->lwte_when - t0) / (mhz * 1000000.0),
- (t0 == e->lwte_when) ? 0.0 : (e->lwte_when - tlast) / mhz,
- where);
-
- lwt_put_string(where);
-
- return (0);
-#undef XFMT
-}
-
double
get_cycles_per_usec ()
{
return (1000.0);
}
-#define LWT_MAX_CPUS (32)
-
-int
-jt_ptl_lwt(int argc, char **argv)
-{
- int ncpus;
- int totalspace;
- int nevents_per_cpu;
- lwt_event_t *events;
- lwt_event_t *cpu_event[LWT_MAX_CPUS + 1];
- lwt_event_t *next_event[LWT_MAX_CPUS];
- lwt_event_t *first_event[LWT_MAX_CPUS];
- int cpu;
- lwt_event_t *e;
- int rc;
- int i;
- double mhz;
- cfs_cycles_t t0;
- cfs_cycles_t tlast;
- cfs_cycles_t tnow;
- struct timeval tvnow;
- int printed_date = 0;
- int nlines = 0;
- FILE *f = stdout;
-
- if (argc < 2 ||
- (strcmp(argv[1], "start") &&
- strcmp(argv[1], "stop"))) {
- fprintf(stderr,
- "usage: %s start\n"
- " %s stop [fname]\n", argv[0], argv[0]);
- return (-1);
- }
-
- if (!strcmp(argv[1], "start")) {
- /* disable */
- if (lwt_control(0, 0) != 0)
- return (-1);
-
- /* clear */
- if (lwt_control(0, 1) != 0)
- return (-1);
-
- /* enable */
- if (lwt_control(1, 0) != 0)
- return (-1);
-
- return (0);
- }
-
- if (lwt_snapshot(NULL, &ncpus, &totalspace, NULL, 0) != 0)
- return (-1);
-
- if (ncpus > LWT_MAX_CPUS) {
- fprintf(stderr, "Too many cpus: %d (%d)\n",
- ncpus, LWT_MAX_CPUS);
- return (-1);
- }
-
- events = (lwt_event_t *)malloc(totalspace);
- if (events == NULL) {
- fprintf(stderr, "Can't allocate %d\n", totalspace);
- return (-1);
- }
-
- if (lwt_control(0, 0) != 0) { /* disable */
- free(events);
- return (-1);
- }
-
- if (lwt_snapshot(&tnow, NULL, NULL, events, totalspace)) {
- free(events);
- return (-1);
- }
-
- /* we want this time to be sampled at snapshot time */
- gettimeofday(&tvnow, NULL);
-
- if (argc > 2) {
- f = fopen (argv[2], "w");
- if (f == NULL) {
- fprintf(stderr, "Can't open %s for writing: %s\n", argv[2], strerror (errno));
- free(events);
- return (-1);
- }
- }
-
- mhz = get_cycles_per_usec();
-
- /* carve events into per-cpu slices */
- nevents_per_cpu = totalspace / (ncpus * sizeof(lwt_event_t));
- for (cpu = 0; cpu <= ncpus; cpu++)
- cpu_event[cpu] = &events[cpu * nevents_per_cpu];
-
- /* find the earliest event on each cpu */
- for (cpu = 0; cpu < ncpus; cpu++) {
- first_event[cpu] = NULL;
-
- for (e = cpu_event[cpu]; e < cpu_event[cpu + 1]; e++) {
-
- if (e->lwte_where == NULL) /* not an event */
- continue;
-
- if (first_event[cpu] == NULL ||
- first_event[cpu]->lwte_when > e->lwte_when)
- first_event[cpu] = e;
- }
-
- next_event[cpu] = first_event[cpu];
- }
-
- t0 = tlast = 0;
- for (cpu = 0; cpu < ncpus; cpu++) {
- e = first_event[cpu];
- if (e == NULL) /* no events this cpu */
- continue;
-
- if (e == cpu_event[cpu])
- e = cpu_event[cpu + 1] - 1;
- else
- e = e - 1;
-
- /* If there's an event immediately before the first one, this
- * cpu wrapped its event buffer */
- if (e->lwte_where == NULL)
- continue;
-
- /* We should only start outputting events from the most recent
- * first event in any wrapped cpu. Events before this time on
- * other cpus won't have any events from this CPU to interleave
- * with. */
- if (t0 < first_event[cpu]->lwte_when)
- t0 = first_event[cpu]->lwte_when;
- }
-
- for (;;) {
- /* find which cpu has the next event */
- cpu = -1;
- for (i = 0; i < ncpus; i++) {
-
- if (next_event[i] == NULL) /* this cpu exhausted */
- continue;
-
- if (cpu < 0 ||
- next_event[i]->lwte_when < next_event[cpu]->lwte_when)
- cpu = i;
- }
-
- if (cpu < 0) /* all cpus exhausted */
- break;
-
- if (t0 == 0) {
- /* no wrapped cpus and this is he first ever event */
- t0 = next_event[cpu]->lwte_when;
- }
-
- if (t0 <= next_event[cpu]->lwte_when) {
- /* on or after the first event */
- if (!printed_date) {
- cfs_cycles_t du = (tnow - t0) / mhz;
- time_t then = tvnow.tv_sec - du/1000000;
-
- if (du % 1000000 > tvnow.tv_usec)
- then--;
-
- fprintf(f, "%s", ctime(&then));
- printed_date = 1;
- }
-
- rc = lwt_print(f, t0, tlast, mhz, cpu, next_event[cpu]);
- if (rc != 0)
- break;
-
- if (++nlines % 10000 == 0 && f != stdout) {
- /* show some activity... */
- printf(".");
- fflush (stdout);
- }
- }
-
- tlast = next_event[cpu]->lwte_when;
-
- next_event[cpu]++;
- if (next_event[cpu] == cpu_event[cpu + 1])
- next_event[cpu] = cpu_event[cpu];
-
- if (next_event[cpu]->lwte_where == NULL ||
- next_event[cpu] == first_event[cpu])
- next_event[cpu] = NULL;
- }
-
- if (f != stdout) {
- printf("\n");
- fclose(f);
- }
-
- free(events);
- return (0);
-}
-
int jt_ptl_memhog(int argc, char **argv)
{
static int gfp = 0; /* sticky! */
{"test_brw", jt_obd_test_brw, 0,
"do <num> bulk read/writes (<npages> per I/O, on OST object <objid>)\n"
"usage: test_brw [t]<num> [write [verbose [npages [[t]objid]]]]"},
- {"lwt", jt_ptl_lwt, 0,
- "light-weight tracing\n"
- "usage: lwt start\n"
- " lwt stop [file]"},
{"memhog", jt_ptl_memhog, 0,
"memory pressure testing\n"
"usage: memhog <page count> [<gfp flags>]"},