Whamcloud - gitweb
bz-13516
[fs/lustre-release.git] / lnet / libcfs / lwt.c
index a40a7ed..6455ece 100644 (file)
  *   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... */
@@ -57,6 +61,8 @@ 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
@@ -65,12 +71,24 @@ lwt_lookup_string (int *size, char *knl_ptr,
         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);
 }
 
@@ -84,34 +102,45 @@ lwt_control (int enable, int clear)
         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;
@@ -122,12 +151,16 @@ lwt_snapshot (int *ncpu, int *total_size,
 
         *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,
@@ -149,15 +182,16 @@ lwt_init ()
 {
        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++) {
@@ -170,7 +204,7 @@ lwt_init ()
                                return (-ENOMEM);
                        }
 
-                        PORTAL_ALLOC(lwtp, sizeof (*lwtp));
+                        LIBCFS_ALLOC(lwtp, sizeof (*lwtp));
                        if (lwtp == NULL) {
                                CERROR ("Can't allocate lwtp\n");
                                 __free_page(page);
@@ -180,7 +214,7 @@ lwt_init ()
 
                         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);
@@ -194,6 +228,8 @@ lwt_init ()
         lwt_enabled = 1;
         mb();
 
+        LWT_EVENT(0,0,0,0);
+
         return (0);
 }
 
@@ -201,10 +237,9 @@ void
 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;
@@ -220,7 +255,7 @@ lwt_fini ()
                         }
                         
                         __free_page (lwtp->lwtp_page);
-                        PORTAL_FREE (lwtp, sizeof (*lwtp));
+                        LIBCFS_FREE (lwtp, sizeof (*lwtp));
                 }
 }