Whamcloud - gitweb
LU-19098 hsm: don't print progname twice with lhsmtool
[fs/lustre-release.git] / libcfs / libcfs / tracefile.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2
3 /*
4  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
5  * Use is subject to license terms.
6  *
7  * Copyright (c) 2012, 2017, Intel Corporation.
8  */
9
10 /*
11  * This file is part of Lustre, http://www.lustre.org/
12  */
13
14 #ifndef __LIBCFS_TRACEFILE_H__
15 #define __LIBCFS_TRACEFILE_H__
16
17 #include <libcfs/libcfs.h>
18
19 #define TRACEFILE_NAME_SIZE 1024
20 extern char      cfs_tracefile[TRACEFILE_NAME_SIZE];
21 extern long long cfs_tracefile_size;
22
23 /**
24  * The path of debug log dump upcall script.
25  */
26 extern char lnet_debug_log_upcall[1024];
27
28 int cfs_tracefile_dump_all_pages(char *filename);
29 void cfs_trace_debug_print(void);
30 void cfs_trace_flush_pages(void);
31 int cfs_trace_start_thread(void);
32 void cfs_trace_stop_thread(void);
33 int cfs_tracefile_init(int max_pages);
34 void cfs_tracefile_exit(void);
35
36
37
38 int cfs_trace_copyout_string(char __user *usr_buffer, int usr_buffer_nob,
39                              const char *knl_str, char *append);
40 int cfs_trace_dump_debug_buffer_usrstr(void __user *usr_str, int usr_str_nob);
41 int cfs_trace_daemon_command(char *str);
42 int cfs_trace_daemon_command_usrstr(void __user *usr_str, int usr_str_nob);
43 int cfs_trace_set_debug_mb(int mb);
44 int cfs_trace_get_debug_mb(void);
45
46 extern int  libcfs_panic_in_progress;
47
48 #define TCD_MAX_PAGES (5 << (20 - PAGE_SHIFT))
49 #define TCD_STOCK_PAGES (TCD_MAX_PAGES)
50 #define CFS_TRACEFILE_SIZE (500 << 20)
51
52 union cfs_trace_data_union {
53         struct cfs_trace_cpu_data {
54                 /*
55                  * Even though this structure is meant to be per-CPU, locking
56                  * is needed because in some places the data may be accessed
57                  * from other CPUs. This lock is directly used in trace_get_tcd
58                  * and trace_put_tcd, which are called in libcfs_debug_msg and
59                  * tcd_for_each_type_lock
60                  */
61                 spinlock_t              tcd_lock;
62                 unsigned long           tcd_lock_flags;
63
64                 /*
65                  * pages with trace records not yet processed by tracefiled.
66                  */
67                 struct list_head        tcd_pages;
68                 /* number of pages on ->tcd_pages */
69                 unsigned long           tcd_cur_pages;
70
71                 /*
72                  * Maximal number of pages allowed on ->tcd_pages
73                  * Always TCD_MAX_PAGES * tcd_pages_factor / 100 in current
74                  * implementation.
75                  */
76                 unsigned long           tcd_max_pages;
77
78                 /*
79                  * preallocated pages to write trace records into. Pages from
80                  * ->tcd_stock_pages are moved to ->tcd_pages by
81                  * portals_debug_msg().
82                  *
83                  * This list is necessary, because on some platforms it's
84                  * impossible to perform efficient atomic page allocation in a
85                  * non-blockable context.
86                  *
87                  * Such platforms fill ->tcd_stock_pages "on occasion", when
88                  * tracing code is entered in blockable context.
89                  *
90                  * trace_get_tage_try() tries to get a page from
91                  * ->tcd_stock_pages first and resorts to atomic page
92                  * allocation only if this queue is empty. ->tcd_stock_pages
93                  * is replenished when tracing code is entered in blocking
94                  * context (darwin-tracefile.c:trace_get_tcd()). We try to
95                  * maintain TCD_STOCK_PAGES (40 by default) pages in this
96                  * queue. Atomic allocation is only required if more than
97                  * TCD_STOCK_PAGES pagesful are consumed by trace records all
98                  * emitted in non-blocking contexts. Which is quite unlikely.
99                  */
100                 struct list_head        tcd_stock_pages;
101                 /* number of pages on ->tcd_stock_pages */
102                 unsigned long           tcd_cur_stock_pages;
103
104                 unsigned short          tcd_shutting_down;
105                 unsigned short          tcd_cpu;
106                 unsigned short          tcd_type;
107                 /* The factors to share debug memory. */
108                 unsigned short          tcd_pages_factor;
109         } tcd;
110         char __pad[L1_CACHE_ALIGN(sizeof(struct cfs_trace_cpu_data))];
111 };
112
113 /* XXX nikita: this declaration is internal to tracefile.c and should probably
114  * be moved there */
115 struct page_collection {
116         struct list_head        pc_pages;
117 };
118
119 /*
120  * small data-structure for each page owned by tracefiled.
121  */
122 /* XXX nikita: this declaration is internal to tracefile.c and should probably
123  * be moved there */
124 struct cfs_trace_page {
125         /*
126          * page itself
127          */
128         struct page             *page;
129         /*
130          * linkage into one of the lists in trace_data_union or
131          * page_collection
132          */
133         struct list_head        linkage;
134         /*
135          * number of bytes used within this page
136          */
137         unsigned int            used;
138         /*
139          * cpu that owns this page
140          */
141         unsigned short          cpu;
142         /*
143          * type(context) of this page
144          */
145         unsigned short          type;
146 };
147
148 int cfs_tcd_owns_tage(struct cfs_trace_cpu_data *tcd,
149                       struct cfs_trace_page *tage);
150
151 extern void cfs_trace_assertion_failed(const char *str,
152                                        struct libcfs_debug_msg_data *m);
153
154 /* ASSERTION that is safe to use within the debug system */
155 #define __LASSERT(cond)                                                 \
156 do {                                                                    \
157         if (unlikely(!(cond))) {                                        \
158                 LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_EMERG, NULL);     \
159                 cfs_trace_assertion_failed("ASSERTION("#cond") failed", \
160                                            &msgdata);                   \
161         }                                                               \
162 } while (0)
163
164 #define __LASSERT_TAGE_INVARIANT(tage)                                  \
165 do {                                                                    \
166         __LASSERT(tage != NULL);                                        \
167         __LASSERT(tage->page != NULL);                                  \
168         __LASSERT(tage->used <= PAGE_SIZE);                             \
169         __LASSERT(page_count(tage->page) > 0);                          \
170 } while (0)
171
172 #endif /* __LIBCFS_TRACEFILE_H__ */