Whamcloud - gitweb
LU-1346 libcfs: replace libcfs wrappers with kernel API
[fs/lustre-release.git] / libcfs / libcfs / tracefile.c
index 63a23ef..cdc218e 100644 (file)
@@ -1,6 +1,4 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
  * GPL HEADER START
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -26,7 +24,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  */
 /*
@@ -52,7 +50,7 @@ union cfs_trace_data_union (*cfs_trace_data[TCD_MAX_TYPES])[CFS_NR_CPUS] __cache
 char cfs_tracefile[TRACEFILE_NAME_SIZE];
 long long cfs_tracefile_size = CFS_TRACEFILE_SIZE;
 static struct tracefiled_ctl trace_tctl;
-cfs_semaphore_t cfs_trace_thread_sem;
+struct mutex cfs_trace_thread_mutex;
 static int thread_running = 0;
 
 cfs_atomic_t cfs_tage_allocated = CFS_ATOMIC_INIT(0);
@@ -71,6 +69,10 @@ static struct cfs_trace_page *cfs_tage_alloc(int gfp)
         cfs_page_t            *page;
         struct cfs_trace_page *tage;
 
+        /* My caller is trying to free memory */
+        if (!cfs_in_interrupt() && cfs_memory_pressure_get())
+                return NULL;
+
         /*
          * Don't spam console with allocation failures: they will be reported
          * by upper layer anyway.
@@ -196,7 +198,7 @@ static void cfs_tcd_shrink(struct cfs_trace_cpu_data *tcd)
                        pgcount + 1, tcd->tcd_cur_pages);
 
         CFS_INIT_LIST_HEAD(&pc.pc_pages);
-        cfs_spin_lock_init(&pc.pc_lock);
+       spin_lock_init(&pc.pc_lock);
 
         cfs_list_for_each_entry_safe_typed(tage, tmp, &tcd->tcd_pages,
                                            struct cfs_trace_page, linkage) {
@@ -239,8 +241,21 @@ static struct cfs_trace_page *cfs_trace_get_tage(struct cfs_trace_cpu_data *tcd,
         return tage;
 }
 
-int libcfs_debug_vmsg2(cfs_debug_limit_state_t *cdls, int subsys, int mask,
-                       const char *file, const char *fn, const int line,
+int libcfs_debug_msg(struct libcfs_debug_msg_data *msgdata,
+                     const char *format, ...)
+{
+        va_list args;
+        int     rc;
+
+        va_start(args, format);
+        rc = libcfs_debug_vmsg2(msgdata, format, args, NULL);
+        va_end(args);
+
+        return rc;
+}
+EXPORT_SYMBOL(libcfs_debug_msg);
+
+int libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata,
                        const char *format1, va_list args,
                        const char *format2, ...)
 {
@@ -257,14 +272,20 @@ int libcfs_debug_vmsg2(cfs_debug_limit_state_t *cdls, int subsys, int mask,
         int                        depth;
         int                        i;
         int                        remain;
+        int                        mask = msgdata->msg_mask;
+        char                      *file = (char *)msgdata->msg_file;
+        cfs_debug_limit_state_t   *cdls = msgdata->msg_cdls;
 
         if (strchr(file, '/'))
                 file = strrchr(file, '/') + 1;
 
+        tcd = cfs_trace_get_tcd();
 
-        cfs_set_ptldebug_header(&header, subsys, mask, line, CDEBUG_STACK());
+        /* cfs_trace_get_tcd() grabs a lock, which disables preemption and
+         * pins us to a particular CPU.  This avoids an smp_processor_id()
+         * warning on Linux when debugging is enabled. */
+        cfs_set_ptldebug_header(&header, msgdata, CDEBUG_STACK());
 
-        tcd = cfs_trace_get_tcd();
         if (tcd == NULL)                /* arch may not log in IRQ context */
                 goto console;
 
@@ -279,8 +300,8 @@ int libcfs_debug_vmsg2(cfs_debug_limit_state_t *cdls, int subsys, int mask,
 
         depth = __current_nesting_level();
         known_size = strlen(file) + 1 + depth;
-        if (fn)
-                known_size += strlen(fn) + 1;
+        if (msgdata->msg_fn)
+                known_size += strlen(msgdata->msg_fn) + 1;
 
         if (libcfs_debug_binary)
                 known_size += sizeof(header);
@@ -306,7 +327,7 @@ int libcfs_debug_vmsg2(cfs_debug_limit_state_t *cdls, int subsys, int mask,
 
                 max_nob = CFS_PAGE_SIZE - tage->used - known_size;
                 if (max_nob <= 0) {
-                        printk(CFS_KERN_EMERG "negative max_nob: %i\n",
+                        printk(CFS_KERN_EMERG "negative max_nob: %d\n",
                                max_nob);
                         mask |= D_ERROR;
                         cfs_trace_put_tcd(tcd);
@@ -337,8 +358,8 @@ int libcfs_debug_vmsg2(cfs_debug_limit_state_t *cdls, int subsys, int mask,
         }
 
         if (*(string_buf+needed-1) != '\n')
-                printk(CFS_KERN_INFO "format at %s:%d:%s doesn't end in newline\n",
-                       file, line, fn);
+                printk(CFS_KERN_INFO "format at %s:%d:%s doesn't end in "
+                       "newline\n", file, msgdata->msg_line, msgdata->msg_fn);
 
         header.ph_len = known_size + needed;
         debug_buf = (char *)cfs_page_address(tage->page) + tage->used;
@@ -359,10 +380,10 @@ int libcfs_debug_vmsg2(cfs_debug_limit_state_t *cdls, int subsys, int mask,
         tage->used += strlen(file) + 1;
         debug_buf += strlen(file) + 1;
 
-        if (fn) {
-                strcpy(debug_buf, fn);
-                tage->used += strlen(fn) + 1;
-                debug_buf += strlen(fn) + 1;
+        if (msgdata->msg_fn) {
+                strcpy(debug_buf, msgdata->msg_fn);
+                tage->used += strlen(msgdata->msg_fn) + 1;
+                debug_buf += strlen(msgdata->msg_fn) + 1;
         }
 
         __LASSERT(debug_buf == string_buf);
@@ -409,7 +430,7 @@ console:
 
         if (tcd != NULL) {
                 cfs_print_to_console(&header, mask, string_buf, needed, file,
-                                     fn);
+                                     msgdata->msg_fn);
                 cfs_trace_put_tcd(tcd);
         } else {
                 string_buf = cfs_trace_get_console_buffer();
@@ -426,12 +447,13 @@ console:
                         remain = CFS_TRACE_CONSOLE_BUFFER_SIZE - needed;
                         if (remain > 0) {
                                 va_start(ap, format2);
-                                needed += vsnprintf(string_buf+needed, remain, format2, ap);
+                                needed += vsnprintf(string_buf+needed, remain,
+                                                    format2, ap);
                                 va_end(ap);
                         }
                 }
                 cfs_print_to_console(&header, mask,
-                                     string_buf, needed, file, fn);
+                                     string_buf, needed, file, msgdata->msg_fn);
 
                 cfs_trace_put_console_buffer(string_buf);
         }
@@ -440,11 +462,12 @@ console:
                 string_buf = cfs_trace_get_console_buffer();
 
                 needed = snprintf(string_buf, CFS_TRACE_CONSOLE_BUFFER_SIZE,
-                         "Skipped %d previous similar message%s\n",
-                         cdls->cdls_count, (cdls->cdls_count > 1) ? "s" : "");
+                                  "Skipped %d previous similar message%s\n",
+                                  cdls->cdls_count,
+                                  (cdls->cdls_count > 1) ? "s" : "");
 
                 cfs_print_to_console(&header, mask,
-                                 string_buf, needed, file, fn);
+                                     string_buf, needed, file, msgdata->msg_fn);
 
                 cfs_trace_put_console_buffer(string_buf);
                 cdls->cdls_count = 0;
@@ -455,19 +478,17 @@ console:
 EXPORT_SYMBOL(libcfs_debug_vmsg2);
 
 void
-libcfs_assertion_failed(const char *expr, const char *file,
-                        const char *func, const int line)
+libcfs_assertion_failed(const char *expr, struct libcfs_debug_msg_data *msgdata)
 {
-        libcfs_debug_msg(NULL, 0, D_EMERG, file, func, line,
-                         "ASSERTION(%s) failed\n", expr);
+        libcfs_debug_msg(msgdata, "ASSERTION(%s) failed\n", expr);
         /* cfs_enter_debugger(); */
-        lbug_with_loc(file, func, line);
+        lbug_with_loc(msgdata);
 }
 EXPORT_SYMBOL(libcfs_assertion_failed);
 
 void
 cfs_trace_assertion_failed(const char *str,
-                           const char *fn, const char *file, int line)
+                           struct libcfs_debug_msg_data *msgdata)
 {
         struct ptldebug_header hdr;
 
@@ -475,10 +496,10 @@ cfs_trace_assertion_failed(const char *str,
         libcfs_catastrophe = 1;
         cfs_mb();
 
-        cfs_set_ptldebug_header(&hdr, DEBUG_SUBSYSTEM, D_EMERG, line,
-                                CDEBUG_STACK());
+        cfs_set_ptldebug_header(&hdr, msgdata, CDEBUG_STACK());
 
-        cfs_print_to_console(&hdr, D_EMERG, str, strlen(str), file, fn);
+        cfs_print_to_console(&hdr, D_EMERG, str, strlen(str),
+                             msgdata->msg_file, msgdata->msg_fn);
 
         LIBCFS_PANIC("Lustre debug assertion failure\n");
 
@@ -511,10 +532,10 @@ panic_collect_pages(struct page_collection *pc)
 
 static void collect_pages_on_all_cpus(struct page_collection *pc)
 {
-        struct cfs_trace_cpu_data *tcd;
-        int i, cpu;
+       struct cfs_trace_cpu_data *tcd;
+       int i, cpu;
 
-        cfs_spin_lock(&pc->pc_lock);
+       spin_lock(&pc->pc_lock);
         cfs_for_each_possible_cpu(cpu) {
                 cfs_tcd_for_each_type_lock(tcd, i, cpu) {
                         cfs_list_splice_init(&tcd->tcd_pages, &pc->pc_pages);
@@ -526,7 +547,7 @@ static void collect_pages_on_all_cpus(struct page_collection *pc)
                         }
                 }
         }
-        cfs_spin_unlock(&pc->pc_lock);
+       spin_unlock(&pc->pc_lock);
 }
 
 static void collect_pages(struct page_collection *pc)
@@ -547,7 +568,7 @@ static void put_pages_back_on_all_cpus(struct page_collection *pc)
         struct cfs_trace_page *tmp;
         int i, cpu;
 
-        cfs_spin_lock(&pc->pc_lock);
+       spin_lock(&pc->pc_lock);
         cfs_for_each_possible_cpu(cpu) {
                 cfs_tcd_for_each_type_lock(tcd, i, cpu) {
                         cur_head = tcd->tcd_pages.next;
@@ -567,7 +588,7 @@ static void put_pages_back_on_all_cpus(struct page_collection *pc)
                         }
                 }
         }
-        cfs_spin_unlock(&pc->pc_lock);
+       spin_unlock(&pc->pc_lock);
 }
 
 static void put_pages_back(struct page_collection *pc)
@@ -581,12 +602,12 @@ static void put_pages_back(struct page_collection *pc)
  * if we have been steadily writing (and otherwise discarding) pages via the
  * debug daemon. */
 static void put_pages_on_tcd_daemon_list(struct page_collection *pc,
-                                         struct cfs_trace_cpu_data *tcd)
+                                        struct cfs_trace_cpu_data *tcd)
 {
-        struct cfs_trace_page *tage;
-        struct cfs_trace_page *tmp;
+       struct cfs_trace_page *tage;
+       struct cfs_trace_page *tmp;
 
-        cfs_spin_lock(&pc->pc_lock);
+       spin_lock(&pc->pc_lock);
         cfs_list_for_each_entry_safe_typed(tage, tmp, &pc->pc_pages,
                                            struct cfs_trace_page, linkage) {
 
@@ -611,7 +632,7 @@ static void put_pages_on_tcd_daemon_list(struct page_collection *pc,
                         tcd->tcd_cur_daemon_pages--;
                 }
         }
-        cfs_spin_unlock(&pc->pc_lock);
+       spin_unlock(&pc->pc_lock);
 }
 
 static void put_pages_on_daemon_list(struct page_collection *pc)
@@ -627,11 +648,11 @@ static void put_pages_on_daemon_list(struct page_collection *pc)
 
 void cfs_trace_debug_print(void)
 {
-        struct page_collection pc;
-        struct cfs_trace_page *tage;
-        struct cfs_trace_page *tmp;
+       struct page_collection pc;
+       struct cfs_trace_page *tage;
+       struct cfs_trace_page *tmp;
 
-        cfs_spin_lock_init(&pc.pc_lock);
+       spin_lock_init(&pc.pc_lock);
 
         pc.pc_want_daemon_pages = 1;
         collect_pages(&pc);
@@ -687,7 +708,7 @@ int cfs_tracefile_dump_all_pages(char *filename)
                 goto out;
         }
 
-        cfs_spin_lock_init(&pc.pc_lock);
+       spin_lock_init(&pc.pc_lock);
         pc.pc_want_daemon_pages = 1;
         collect_pages(&pc);
         if (cfs_list_empty(&pc.pc_pages)) {
@@ -728,11 +749,11 @@ int cfs_tracefile_dump_all_pages(char *filename)
 
 void cfs_trace_flush_pages(void)
 {
-        struct page_collection pc;
-        struct cfs_trace_page *tage;
-        struct cfs_trace_page *tmp;
+       struct page_collection pc;
+       struct cfs_trace_page *tage;
+       struct cfs_trace_page *tmp;
 
-        cfs_spin_lock_init(&pc.pc_lock);
+       spin_lock_init(&pc.pc_lock);
 
         pc.pc_want_daemon_pages = 1;
         collect_pages(&pc);
@@ -772,6 +793,7 @@ int cfs_trace_copyin_string(char *knl_buffer, int knl_buffer_nob,
         knl_buffer[nob + 1] = 0;                /* terminate */
         return 0;
 }
+EXPORT_SYMBOL(cfs_trace_copyin_string);
 
 int cfs_trace_copyout_string(char *usr_buffer, int usr_buffer_nob,
                              const char *knl_buffer, char *append)
@@ -907,13 +929,18 @@ int cfs_trace_set_debug_mb(int mb)
         int limit = cfs_trace_max_debug_mb();
         struct cfs_trace_cpu_data *tcd;
 
-        if (mb < cfs_num_possible_cpus())
-                return -EINVAL;
+        if (mb < cfs_num_possible_cpus()) {
+                printk(CFS_KERN_WARNING
+                       "Lustre: %d MB is too small for debug buffer size, "
+                       "setting it to %d MB.\n", mb, cfs_num_possible_cpus());
+                mb = cfs_num_possible_cpus();
+        }
 
         if (mb > limit) {
-                printk(CFS_KERN_ERR "Lustre: Refusing to set debug buffer size "
-                       "to %dMB - limit is %d\n", mb, limit);
-                return -EINVAL;
+                printk(CFS_KERN_WARNING
+                       "Lustre: %d MB is too large for debug buffer size, "
+                       "setting it to %d MB.\n", mb, limit);
+                mb = limit;
         }
 
         mb /= cfs_num_possible_cpus();
@@ -974,8 +1001,8 @@ static int tracefiled(void *arg)
         /* this is so broken in uml?  what on earth is going on? */
         cfs_daemonize("ktracefiled");
 
-        cfs_spin_lock_init(&pc.pc_lock);
-        cfs_complete(&tctl->tctl_start);
+       spin_lock_init(&pc.pc_lock);
+       complete(&tctl->tctl_start);
 
         while (1) {
                 cfs_waitlink_t __wait;
@@ -1037,7 +1064,7 @@ static int tracefiled(void *arg)
                         printk(CFS_KERN_ERR "total cpus(%d): ",
                                cfs_num_possible_cpus());
                         for (i = 0; i < cfs_num_possible_cpus(); i++)
-                                if (cfs_cpu_online(i))
+                                if (cpu_online(i))
                                         printk(CFS_KERN_ERR "%d(on) ", i);
                                 else
                                         printk(CFS_KERN_ERR "%d(off) ", i);
@@ -1068,7 +1095,7 @@ end_loop:
                                     cfs_time_seconds(1));
                 cfs_waitq_del(&tctl->tctl_waitq, &__wait);
         }
-        cfs_complete(&tctl->tctl_stop);
+       complete(&tctl->tctl_stop);
         return 0;
 }
 
@@ -1077,24 +1104,24 @@ int cfs_trace_start_thread(void)
         struct tracefiled_ctl *tctl = &trace_tctl;
         int rc = 0;
 
-        cfs_mutex_down(&cfs_trace_thread_sem);
+       mutex_lock(&cfs_trace_thread_mutex);
         if (thread_running)
                 goto out;
 
-        cfs_init_completion(&tctl->tctl_start);
-        cfs_init_completion(&tctl->tctl_stop);
+       init_completion(&tctl->tctl_start);
+       init_completion(&tctl->tctl_stop);
         cfs_waitq_init(&tctl->tctl_waitq);
         cfs_atomic_set(&tctl->tctl_shutdown, 0);
 
-        if (cfs_kernel_thread(tracefiled, tctl, 0) < 0) {
+        if (cfs_create_thread(tracefiled, tctl, 0) < 0) {
                 rc = -ECHILD;
                 goto out;
         }
 
-        cfs_wait_for_completion(&tctl->tctl_start);
+       wait_for_completion(&tctl->tctl_start);
         thread_running = 1;
 out:
-        cfs_mutex_up(&cfs_trace_thread_sem);
+       mutex_unlock(&cfs_trace_thread_mutex);
         return rc;
 }
 
@@ -1102,15 +1129,15 @@ void cfs_trace_stop_thread(void)
 {
         struct tracefiled_ctl *tctl = &trace_tctl;
 
-        cfs_mutex_down(&cfs_trace_thread_sem);
+       mutex_lock(&cfs_trace_thread_mutex);
         if (thread_running) {
                 printk(CFS_KERN_INFO
                        "Lustre: shutting down debug daemon thread...\n");
                 cfs_atomic_set(&tctl->tctl_shutdown, 1);
-                cfs_wait_for_completion(&tctl->tctl_stop);
+               wait_for_completion(&tctl->tctl_stop);
                 thread_running = 0;
         }
-        cfs_mutex_up(&cfs_trace_thread_sem);
+       mutex_unlock(&cfs_trace_thread_mutex);
 }
 
 int cfs_tracefile_init(int max_pages)
@@ -1170,14 +1197,14 @@ static void trace_cleanup_on_all_cpus(void)
 
 static void cfs_trace_cleanup(void)
 {
-        struct page_collection pc;
+       struct page_collection pc;
 
-        CFS_INIT_LIST_HEAD(&pc.pc_pages);
-        cfs_spin_lock_init(&pc.pc_lock);
+       CFS_INIT_LIST_HEAD(&pc.pc_pages);
+       spin_lock_init(&pc.pc_lock);
 
-        trace_cleanup_on_all_cpus();
+       trace_cleanup_on_all_cpus();
 
-        cfs_tracefile_fini_arch();
+       cfs_tracefile_fini_arch();
 }
 
 void cfs_tracefile_exit(void)