Motr  M0
ktrace.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2012-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #include <linux/vmalloc.h> /* vmalloc, vfree */
24 #include <linux/kernel.h> /* vprintk, kstrtoul */
25 #include <linux/jiffies.h> /* time_in_range_open */
26 #include <linux/version.h>
27 
28 #include "lib/errno.h"
29 #include "lib/atomic.h"
30 #include "lib/arith.h" /* m0_align */
31 #include "lib/memory.h" /* m0_free */
32 #include "lib/string.h" /* m0_strdup */
33 #include "lib/trace.h"
34 #include "lib/trace_internal.h"
35 #include "lib/linux_kernel/trace.h"
37 
46 static char *trace_immediate_mask;
47 module_param(trace_immediate_mask, charp, S_IRUGO);
49  " a bitmask or comma separated list of subsystem names"
50  " of what should be printed immediately to console");
51 
52 static char *trace_level;
53 module_param(trace_level, charp, S_IRUGO);
55  " trace level: level[+][,level[+]] where level is one of"
56  " call|debug|info|notice|warn|error|fatal");
57 
58 static char *trace_print_context;
59 module_param(trace_print_context, charp, S_IRUGO);
61  " controls whether to display additional trace point"
62  " info, like subsystem, file, func, etc.; values:"
63  " none, func, short, full");
64 
65 static unsigned long trace_buf_size = M0_TRACE_KBUF_SIZE;
66 module_param(trace_buf_size, ulong, S_IRUGO);
67 MODULE_PARM_DESC(trace_buf_size, "size of trace buffer in bytes");
68 
69 static struct m0_trace_stats stats;
70 
71 
72 M0_INTERNAL const char *m0_trace_file_path_get(void)
73 {
74  return "";
75 }
76 
77 M0_INTERNAL int m0_trace_set_immediate_mask(const char *mask_str)
78 {
79  int rc;
80  unsigned long mask;
81  char *mask_str_copy;
82 
83  /* check if argument was specified for 'mask_str' param */
84  if (mask_str == NULL)
85  return 0;
86 
87  /* first, check if 'mask_str' contains a numeric bitmask */
88  rc = kstrtoul(mask_str, 0, &mask);
89  if (rc == 0)
90  goto set_mask;
91 
92  /*
93  * if above strtoul() conversion has failed it means that mask_str
94  * contains a comma-separated list of subsystem names
95  */
96  mask_str_copy = m0_strdup(mask_str);
97  if (mask_str_copy == NULL)
98  return -ENOMEM;
99 
100  rc = m0_trace_subsys_list_to_mask(mask_str_copy, &mask);
101  m0_free(mask_str_copy);
102  if (rc != 0)
103  return rc;
104 
105 set_mask:
107  pr_info("Motr trace immediate mask: 0x%lx\n", m0_trace_immediate_mask);
108 
109  return 0;
110 }
111 M0_EXPORTED(m0_trace_set_immediate_mask);
112 
113 M0_INTERNAL const struct m0_trace_stats *m0_trace_get_stats(void)
114 {
115  return &stats;
116 }
117 M0_EXPORTED(m0_trace_get_stats);
118 
119 M0_INTERNAL void m0_trace_stats_update(uint32_t rec_size)
120 {
121  static unsigned long prev_jiffies = INITIAL_JIFFIES;
122  static uint64_t prev_logbuf_pos;
123  static uint64_t prev_rec_total;
124 
125  if (prev_jiffies == INITIAL_JIFFIES) {
126  prev_jiffies = jiffies;
127  prev_logbuf_pos = 0;
128  prev_rec_total = 0;
129  }
130 
131  if (rec_size > 0) {
132  m0_atomic64_inc(&stats.trs_rec_total);
133  stats.trs_avg_rec_size = (rec_size + stats.trs_avg_rec_size) / 2;
134  stats.trs_max_rec_size = max(rec_size, stats.trs_max_rec_size);
135  }
136 
137  if (time_after_eq(jiffies, prev_jiffies + HZ)) {
138  stats.trs_rec_per_sec =
139  m0_atomic64_get(&stats.trs_rec_total) - prev_rec_total;
140  stats.trs_bytes_per_sec =
141  m0_trace_logbuf_pos_get() - prev_logbuf_pos;
142 
143  stats.trs_avg_rec_per_sec
144  = (stats.trs_rec_per_sec + stats.trs_avg_rec_per_sec) / 2;
145  stats.trs_avg_bytes_per_sec
146  = (stats.trs_bytes_per_sec + stats.trs_avg_bytes_per_sec) / 2;
147 
148  stats.trs_max_rec_per_sec
149  = max(stats.trs_rec_per_sec, stats.trs_max_rec_per_sec);
150  stats.trs_max_bytes_per_sec
151  = max(stats.trs_bytes_per_sec, stats.trs_max_bytes_per_sec);
152 
153  prev_jiffies = jiffies;
154  prev_logbuf_pos = m0_trace_logbuf_pos_get();
155  prev_rec_total = m0_atomic64_get(&stats.trs_rec_total);
156  }
157 }
158 M0_EXPORTED(m0_trace_stats_update);
159 
160 void m0_console_vprintf(const char *fmt, va_list args)
161 {
162  vprintk(fmt, args);
163 }
164 
166 {
167 }
168 
169 void m0_error_printf(const char *fmt, ...)
170 {
171  va_list ap;
172 
173  va_start(ap, fmt);
174  vprintk(fmt, ap);
175  va_end(ap);
176 }
177 
178 M0_INTERNAL int m0_arch_trace_init()
179 {
180  int rc;
181  struct m0_trace_area *trace_area;
182 
183  m0_atomic64_set(&stats.trs_rec_total, 0);
184 
186  if (rc != 0)
187  return rc;
188 
190  if (rc != 0)
191  return rc;
192 
194  if (rc != 0)
195  return rc;
196 
197  if (trace_buf_size == 0 || !m0_is_po2(trace_buf_size) ||
198  trace_buf_size % PAGE_SIZE != 0)
199  {
200  pr_err("motr: incorrect value for trace_buffer_size parameter,"
201  " it can't be zero, should be a power of 2 and a"
202  " multiple of PAGE_SIZE value\n");
203  return -EINVAL;
204  }
205 
206  trace_area = vzalloc(sizeof (trace_area->ta_header) + trace_buf_size);
207  if (trace_area == NULL) {
208  pr_err("motr: failed to allocate %lu bytes for trace buffer\n",
210  return -ENOMEM;
211  }
212 
214 
215  m0_logbuf_header = &trace_area->ta_header;
216  m0_logbuf = trace_area->ta_buf;
218 
219  pr_info("motr: trace header address: 0x%p\n", m0_logbuf_header);
220  pr_info("motr: trace buffer address: 0x%p\n", m0_logbuf);
221 
222  return 0;
223 }
224 
225 M0_INTERNAL void m0_arch_trace_fini(void)
226 {
227  void *old_buffer = m0_logbuf_header;
228 
230  vfree(old_buffer);
231 }
232 
234 {
235  const struct module *m = m0_motr_ko_get_module();
236 
240  tbh->tbh_module_struct = m;
241 }
242 
245 /*
246  * Local variables:
247  * c-indentation-style: "K&R"
248  * c-basic-offset: 8
249  * tab-width: 8
250  * fill-column: 80
251  * scroll-step: 1
252  * End:
253  */
static void m0_atomic64_inc(struct m0_atomic64 *a)
M0_INTERNAL void m0_trace_buf_header_init(struct m0_trace_buf_header *tbh, size_t buf_size)
Definition: trace.c:956
#define m0_strdup(s)
Definition: string.h:43
#define NULL
Definition: misc.h:38
static struct m0_addb2_mach * m
Definition: consumer.c:38
void m0_error_printf(const char *fmt,...)
Definition: ktrace.c:169
M0_INTERNAL void m0_trace_logbuf_size_set(size_t size)
Definition: trace.c:630
M0_INTERNAL const char * m0_trace_file_path_get(void)
Definition: ktrace.c:72
static bool m0_is_po2(uint64_t val)
Definition: arith.h:153
void * m0_logbuf
Definition: trace.c:86
module_param(trace_immediate_mask, charp, S_IRUGO)
void m0_console_vprintf(const char *fmt, va_list args)
Definition: ktrace.c:160
#define PAGE_SIZE
Definition: lnet_ut.c:277
#define M0_MOTR_KO_SIZE(module)
Definition: module.h:34
Definition: ub.c:49
#define M0_TRACE_KBUF_SIZE
Definition: config.h:293
struct m0_trace_buf_header ta_header
static struct m0_trace_stats stats
Definition: ktrace.c:69
M0_INTERNAL const struct module * m0_motr_ko_get_module(void)
Definition: module.c:28
M0_INTERNAL void m0_arch_trace_fini(void)
Definition: ktrace.c:225
unsigned int tbh_module_core_size
Definition: trace.h:409
const void * tbh_module_struct
Definition: trace.h:402
M0_INTERNAL int m0_trace_subsys_list_to_mask(char *subsys_names, unsigned long *ret_mask)
Definition: trace.c:414
M0_INTERNAL void m0_trace_switch_to_static_logbuf(void)
Definition: trace.c:986
static char * trace_immediate_mask
Definition: ktrace.c:46
M0_INTERNAL int m0_trace_set_print_context(const char *ctx_name)
Definition: trace.c:562
M0_INTERNAL void m0_trace_stats_update(uint32_t rec_size)
Definition: ktrace.c:119
static long long max(long long a, long long b)
Definition: crate.c:196
char * fmt(const char *format,...) __attribute__((format(printf
static int64_t m0_atomic64_get(const struct m0_atomic64 *a)
#define M0_MOTR_KO_BASE(module)
Definition: module.h:33
const void * tbh_module_core_addr
Definition: trace.h:407
void m0_console_flush(void)
Definition: ktrace.c:165
Definition: beck.c:130
static unsigned long trace_buf_size
Definition: ktrace.c:65
M0_INTERNAL int m0_trace_set_immediate_mask(const char *mask_str)
Definition: ktrace.c:77
static char * trace_print_context
Definition: ktrace.c:58
M0_INTERNAL const struct m0_trace_stats * m0_trace_get_stats(void)
Definition: ktrace.c:113
MODULE_PARM_DESC(trace_immediate_mask, " a bitmask or comma separated list of subsystem names" " of what should be printed immediately to console")
unsigned long m0_trace_immediate_mask
Definition: trace.c:91
M0_INTERNAL int m0_arch_trace_init()
Definition: ktrace.c:178
M0_INTERNAL void m0_arch_trace_buf_header_init(struct m0_trace_buf_header *tbh)
Definition: ktrace.c:233
struct m0_trace_buf_header * m0_logbuf_header
Definition: trace.c:85
void m0_free(void *data)
Definition: memory.c:146
M0_INTERNAL uint64_t m0_trace_logbuf_pos_get(void)
Definition: trace.c:638
int32_t rc
Definition: trigger_fop.h:47
uint16_t tbh_buf_type
Definition: trace.h:378
static char * trace_level
Definition: ktrace.c:52
static void m0_atomic64_set(struct m0_atomic64 *a, int64_t num)
M0_INTERNAL int m0_trace_set_level(const char *level_str)
Definition: trace.c:581