Whamcloud - gitweb
LU-9859 libcfs: remove cfs_trace_refill_stack()
[fs/lustre-release.git] / libcfs / libcfs / tracefile.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2012, 2017, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Sun Microsystems, Inc.
31  *
32  * libcfs/libcfs/tracefile.c
33  *
34  * Author: Zach Brown <zab@clusterfs.com>
35  * Author: Phil Schwan <phil@clusterfs.com>
36  */
37
38
39 #define DEBUG_SUBSYSTEM S_LNET
40 #define LUSTRE_TRACEFILE_PRIVATE
41 #include "tracefile.h"
42
43 #include <linux/ctype.h>
44 #include <linux/fs.h>
45 #include <linux/kthread.h>
46 #include <linux/pagemap.h>
47 #include <linux/poll.h>
48 #include <linux/tty.h>
49 #include <linux/uaccess.h>
50 #include <libcfs/linux/linux-fs.h>
51 #include <libcfs/libcfs.h>
52
53 /* XXX move things up to the top, comment */
54 union cfs_trace_data_union (*cfs_trace_data[TCD_MAX_TYPES])[NR_CPUS] __cacheline_aligned;
55
56 char *cfs_trace_console_buffers[NR_CPUS][CFS_TCD_TYPE_MAX];
57 char cfs_tracefile[TRACEFILE_NAME_SIZE];
58 long long cfs_tracefile_size = CFS_TRACEFILE_SIZE;
59 static struct tracefiled_ctl trace_tctl;
60 static DEFINE_MUTEX(cfs_trace_thread_mutex);
61 static int thread_running = 0;
62
63 static atomic_t cfs_tage_allocated = ATOMIC_INIT(0);
64 static DECLARE_RWSEM(cfs_tracefile_sem);
65
66 static void put_pages_on_tcd_daemon_list(struct page_collection *pc,
67                                         struct cfs_trace_cpu_data *tcd);
68
69 /* trace file lock routines */
70 /* The walking argument indicates the locking comes from all tcd types
71  * iterator and we must lock it and dissable local irqs to avoid deadlocks
72  * with other interrupt locks that might be happening. See LU-1311
73  * for details.
74  */
75 int cfs_trace_lock_tcd(struct cfs_trace_cpu_data *tcd, int walking)
76         __acquires(&tcd->tcd_lock)
77 {
78         __LASSERT(tcd->tcd_type < CFS_TCD_TYPE_MAX);
79         if (tcd->tcd_type == CFS_TCD_TYPE_IRQ)
80                 spin_lock_irqsave(&tcd->tcd_lock, tcd->tcd_lock_flags);
81         else if (tcd->tcd_type == CFS_TCD_TYPE_SOFTIRQ)
82                 spin_lock_bh(&tcd->tcd_lock);
83         else if (unlikely(walking))
84                 spin_lock_irq(&tcd->tcd_lock);
85         else
86                 spin_lock(&tcd->tcd_lock);
87         return 1;
88 }
89
90 void cfs_trace_unlock_tcd(struct cfs_trace_cpu_data *tcd, int walking)
91         __releases(&tcd->tcd_lock)
92 {
93         __LASSERT(tcd->tcd_type < CFS_TCD_TYPE_MAX);
94         if (tcd->tcd_type == CFS_TCD_TYPE_IRQ)
95                 spin_unlock_irqrestore(&tcd->tcd_lock, tcd->tcd_lock_flags);
96         else if (tcd->tcd_type == CFS_TCD_TYPE_SOFTIRQ)
97                 spin_unlock_bh(&tcd->tcd_lock);
98         else if (unlikely(walking))
99                 spin_unlock_irq(&tcd->tcd_lock);
100         else
101                 spin_unlock(&tcd->tcd_lock);
102 }
103
104 #define cfs_tcd_for_each_type_lock(tcd, i, cpu)                         \
105         for (i = 0; cfs_trace_data[i] &&                                \
106              (tcd = &(*cfs_trace_data[i])[cpu].tcd) &&                  \
107              cfs_trace_lock_tcd(tcd, 1); cfs_trace_unlock_tcd(tcd, 1), i++)
108
109 enum cfs_trace_buf_type cfs_trace_buf_idx_get(void)
110 {
111         if (in_irq())
112                 return CFS_TCD_TYPE_IRQ;
113         if (in_softirq())
114                 return CFS_TCD_TYPE_SOFTIRQ;
115         return CFS_TCD_TYPE_PROC;
116 }
117
118 static inline struct cfs_trace_cpu_data *
119 cfs_trace_get_tcd(void)
120 {
121         struct cfs_trace_cpu_data *tcd =
122                 &(*cfs_trace_data[cfs_trace_buf_idx_get()])[get_cpu()].tcd;
123
124         cfs_trace_lock_tcd(tcd, 0);
125
126         return tcd;
127 }
128
129 static inline void cfs_trace_put_tcd(struct cfs_trace_cpu_data *tcd)
130 {
131         cfs_trace_unlock_tcd(tcd, 0);
132
133         put_cpu();
134 }
135
136 /* percents to share the total debug memory for each type */
137 static unsigned int pages_factor[CFS_TCD_TYPE_MAX] = {
138         80,     /* 80% pages for CFS_TCD_TYPE_PROC */
139         10,     /* 10% pages for CFS_TCD_TYPE_SOFTIRQ */
140         10      /* 10% pages for CFS_TCD_TYPE_IRQ */
141 };
142
143 int cfs_tracefile_init_arch(void)
144 {
145         struct cfs_trace_cpu_data *tcd;
146         int i;
147         int j;
148
149         /* initialize trace_data */
150         memset(cfs_trace_data, 0, sizeof(cfs_trace_data));
151         for (i = 0; i < CFS_TCD_TYPE_MAX; i++) {
152                 cfs_trace_data[i] =
153                         kmalloc_array(num_possible_cpus(),
154                                       sizeof(union cfs_trace_data_union),
155                                       GFP_KERNEL);
156                 if (!cfs_trace_data[i])
157                         goto out_trace_data;
158         }
159
160         /* arch related info initialized */
161         cfs_tcd_for_each(tcd, i, j) {
162                 spin_lock_init(&tcd->tcd_lock);
163                 tcd->tcd_pages_factor = pages_factor[i];
164                 tcd->tcd_type = i;
165                 tcd->tcd_cpu = j;
166         }
167
168         for (i = 0; i < num_possible_cpus(); i++)
169                 for (j = 0; j < 3; j++) {
170                         cfs_trace_console_buffers[i][j] =
171                                 kmalloc(CFS_TRACE_CONSOLE_BUFFER_SIZE,
172                                         GFP_KERNEL);
173
174                         if (!cfs_trace_console_buffers[i][j])
175                                 goto out_buffers;
176                 }
177
178         return 0;
179
180 out_buffers:
181         for (i = 0; i < num_possible_cpus(); i++)
182                 for (j = 0; j < 3; j++) {
183                         kfree(cfs_trace_console_buffers[i][j]);
184                         cfs_trace_console_buffers[i][j] = NULL;
185                 }
186 out_trace_data:
187         for (i = 0; cfs_trace_data[i]; i++) {
188                 kfree(cfs_trace_data[i]);
189                 cfs_trace_data[i] = NULL;
190         }
191         pr_err("lnet: Not enough memory\n");
192         return -ENOMEM;
193 }
194
195 void cfs_tracefile_fini_arch(void)
196 {
197         int i;
198         int j;
199
200         for (i = 0; i < num_possible_cpus(); i++)
201                 for (j = 0; j < 3; j++) {
202                         kfree(cfs_trace_console_buffers[i][j]);
203                         cfs_trace_console_buffers[i][j] = NULL;
204                 }
205
206         for (i = 0; cfs_trace_data[i]; i++) {
207                 kfree(cfs_trace_data[i]);
208                 cfs_trace_data[i] = NULL;
209         }
210 }
211
212 static inline struct cfs_trace_page *
213 cfs_tage_from_list(struct list_head *list)
214 {
215         return list_entry(list, struct cfs_trace_page, linkage);
216 }
217
218 static struct cfs_trace_page *cfs_tage_alloc(gfp_t gfp)
219 {
220         struct page            *page;
221         struct cfs_trace_page *tage;
222
223         /* My caller is trying to free memory */
224         if (!in_interrupt() && (current->flags & PF_MEMALLOC))
225                 return NULL;
226
227         /*
228          * Don't spam console with allocation failures: they will be reported
229          * by upper layer anyway.
230          */
231         gfp |= __GFP_NOWARN;
232         page = alloc_page(gfp);
233         if (page == NULL)
234                 return NULL;
235
236         tage = kmalloc(sizeof(*tage), gfp);
237         if (tage == NULL) {
238                 __free_page(page);
239                 return NULL;
240         }
241
242         tage->page = page;
243         atomic_inc(&cfs_tage_allocated);
244         return tage;
245 }
246
247 static void cfs_tage_free(struct cfs_trace_page *tage)
248 {
249         __LASSERT(tage != NULL);
250         __LASSERT(tage->page != NULL);
251
252         __free_page(tage->page);
253         kfree(tage);
254         atomic_dec(&cfs_tage_allocated);
255 }
256
257 static void cfs_tage_to_tail(struct cfs_trace_page *tage,
258                              struct list_head *queue)
259 {
260         __LASSERT(tage != NULL);
261         __LASSERT(queue != NULL);
262
263         list_move_tail(&tage->linkage, queue);
264 }
265
266 /* return a page that has 'len' bytes left at the end */
267 static struct cfs_trace_page *
268 cfs_trace_get_tage_try(struct cfs_trace_cpu_data *tcd, unsigned long len)
269 {
270         struct cfs_trace_page *tage;
271
272         if (tcd->tcd_cur_pages > 0) {
273                 __LASSERT(!list_empty(&tcd->tcd_pages));
274                 tage = cfs_tage_from_list(tcd->tcd_pages.prev);
275                 if (tage->used + len <= PAGE_SIZE)
276                         return tage;
277         }
278
279         if (tcd->tcd_cur_pages < tcd->tcd_max_pages) {
280                 if (tcd->tcd_cur_stock_pages > 0) {
281                         tage = cfs_tage_from_list(tcd->tcd_stock_pages.prev);
282                         --tcd->tcd_cur_stock_pages;
283                         list_del_init(&tage->linkage);
284                 } else {
285                         tage = cfs_tage_alloc(GFP_ATOMIC);
286                         if (unlikely(tage == NULL)) {
287                                 if ((!(current->flags & PF_MEMALLOC) ||
288                                      in_interrupt()) && printk_ratelimit())
289                                         pr_warn("Lustre: cannot allocate a tage (%ld)\n",
290                                                 tcd->tcd_cur_pages);
291                                 return NULL;
292                         }
293                 }
294
295                 tage->used = 0;
296                 tage->cpu = smp_processor_id();
297                 tage->type = tcd->tcd_type;
298                 list_add_tail(&tage->linkage, &tcd->tcd_pages);
299                 tcd->tcd_cur_pages++;
300
301                 if (tcd->tcd_cur_pages > 8 && thread_running) {
302                         struct tracefiled_ctl *tctl = &trace_tctl;
303                         /*
304                          * wake up tracefiled to process some pages.
305                          */
306                         wake_up(&tctl->tctl_waitq);
307                 }
308                 return tage;
309         }
310         return NULL;
311 }
312
313 static void cfs_tcd_shrink(struct cfs_trace_cpu_data *tcd)
314 {
315         int pgcount = tcd->tcd_cur_pages / 10;
316         struct page_collection pc;
317         struct cfs_trace_page *tage;
318         struct cfs_trace_page *tmp;
319
320         /*
321          * XXX nikita: do NOT call portals_debug_msg() (CDEBUG/ENTRY/EXIT)
322          * from here: this will lead to infinite recursion.
323          */
324
325         if (printk_ratelimit())
326                 pr_warn("Lustre: debug daemon buffer overflowed; discarding 10%% of pages (%d of %ld)\n",
327                         pgcount + 1, tcd->tcd_cur_pages);
328
329         INIT_LIST_HEAD(&pc.pc_pages);
330
331         list_for_each_entry_safe(tage, tmp, &tcd->tcd_pages, linkage) {
332                 if (pgcount-- == 0)
333                         break;
334
335                 list_move_tail(&tage->linkage, &pc.pc_pages);
336                 tcd->tcd_cur_pages--;
337         }
338         put_pages_on_tcd_daemon_list(&pc, tcd);
339 }
340
341 /* return a page that has 'len' bytes left at the end */
342 static struct cfs_trace_page *cfs_trace_get_tage(struct cfs_trace_cpu_data *tcd,
343                                                  unsigned long len)
344 {
345         struct cfs_trace_page *tage;
346
347         /*
348          * XXX nikita: do NOT call portals_debug_msg() (CDEBUG/ENTRY/EXIT)
349          * from here: this will lead to infinite recursion.
350          */
351
352         if (len > PAGE_SIZE) {
353                 pr_err("LustreError: cowardly refusing to write %lu bytes in a page\n",
354                        len);
355                 return NULL;
356         }
357
358         tage = cfs_trace_get_tage_try(tcd, len);
359         if (tage != NULL)
360                 return tage;
361         if (thread_running)
362                 cfs_tcd_shrink(tcd);
363         if (tcd->tcd_cur_pages > 0) {
364                 tage = cfs_tage_from_list(tcd->tcd_pages.next);
365                 tage->used = 0;
366                 cfs_tage_to_tail(tage, &tcd->tcd_pages);
367         }
368         return tage;
369 }
370
371 static void cfs_set_ptldebug_header(struct ptldebug_header *header,
372                                     struct libcfs_debug_msg_data *msgdata,
373                                     unsigned long stack)
374 {
375         struct timespec64 ts;
376
377         ktime_get_real_ts64(&ts);
378
379         header->ph_subsys = msgdata->msg_subsys;
380         header->ph_mask = msgdata->msg_mask;
381         header->ph_cpu_id = smp_processor_id();
382         header->ph_type = cfs_trace_buf_idx_get();
383         /* y2038 safe since all user space treats this as unsigned, but
384          * will overflow in 2106
385          */
386         header->ph_sec = (u32)ts.tv_sec;
387         header->ph_usec = ts.tv_nsec / NSEC_PER_USEC;
388         header->ph_stack = stack;
389         header->ph_pid = current->pid;
390         header->ph_line_num = msgdata->msg_line;
391         header->ph_extern_pid = 0;
392 }
393
394 /**
395  * tty_write_msg - write a message to a certain tty, not just the console.
396  * @tty: the destination tty_struct
397  * @msg: the message to write
398  *
399  * tty_write_message is not exported, so write a same function for it
400  *
401  */
402 static void tty_write_msg(struct tty_struct *tty, const char *msg)
403 {
404         mutex_lock(&tty->atomic_write_lock);
405         tty_lock(tty);
406         if (tty->ops->write && tty->count > 0)
407                 tty->ops->write(tty, msg, strlen(msg));
408         tty_unlock(tty);
409         mutex_unlock(&tty->atomic_write_lock);
410         wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
411 }
412
413 static void cfs_tty_write_message(const char *prefix, int mask, const char *msg)
414 {
415         struct tty_struct *tty;
416
417         tty = get_current_tty();
418         if (!tty)
419                 return;
420
421         tty_write_msg(tty, prefix);
422         if ((mask & D_EMERG) || (mask & D_ERROR))
423                 tty_write_msg(tty, "Error");
424         tty_write_msg(tty, ": ");
425         tty_write_msg(tty, msg);
426         tty_kref_put(tty);
427 }
428
429 static void cfs_print_to_console(struct ptldebug_header *hdr, int mask,
430                                  const char *buf, int len, const char *file,
431                                  const char *fn)
432 {
433         char *prefix = "Lustre";
434
435         if (hdr->ph_subsys == S_LND || hdr->ph_subsys == S_LNET)
436                 prefix = "LNet";
437
438         if (mask & D_CONSOLE) {
439                 if (mask & D_EMERG)
440                         pr_emerg("%sError: %.*s", prefix, len, buf);
441                 else if (mask & D_ERROR)
442                         pr_err("%sError: %.*s", prefix, len, buf);
443                 else if (mask & D_WARNING)
444                         pr_warn("%s: %.*s", prefix, len, buf);
445                 else if (mask & libcfs_printk)
446                         pr_info("%s: %.*s", prefix, len, buf);
447         } else {
448                 if (mask & D_EMERG)
449                         pr_emerg("%sError: %d:%d:(%s:%d:%s()) %.*s", prefix,
450                                  hdr->ph_pid, hdr->ph_extern_pid, file,
451                                  hdr->ph_line_num, fn, len, buf);
452                 else if (mask & D_ERROR)
453                         pr_err("%sError: %d:%d:(%s:%d:%s()) %.*s", prefix,
454                                hdr->ph_pid, hdr->ph_extern_pid, file,
455                                hdr->ph_line_num, fn, len, buf);
456                 else if (mask & D_WARNING)
457                         pr_warn("%s: %d:%d:(%s:%d:%s()) %.*s", prefix,
458                                 hdr->ph_pid, hdr->ph_extern_pid, file,
459                                 hdr->ph_line_num, fn, len, buf);
460                 else if (mask & (D_CONSOLE | libcfs_printk))
461                         pr_info("%s: %.*s", prefix, len, buf);
462         }
463
464         if (mask & D_TTY)
465                 cfs_tty_write_message(prefix, mask, buf);
466 }
467
468 int libcfs_debug_msg(struct libcfs_debug_msg_data *msgdata,
469                      const char *format, ...)
470 {
471         struct cfs_trace_cpu_data *tcd = NULL;
472         struct ptldebug_header header = {0};
473         struct cfs_trace_page *tage;
474         /* string_buf is used only if tcd != NULL, and is always set then */
475         char *string_buf = NULL;
476         char *debug_buf;
477         int known_size;
478         int needed = 85; /* seeded with average message length */
479         int max_nob;
480         va_list ap;
481         int retry;
482         int mask = msgdata->msg_mask;
483         char *file = (char *)msgdata->msg_file;
484         struct cfs_debug_limit_state *cdls = msgdata->msg_cdls;
485
486         if (strchr(file, '/'))
487                 file = strrchr(file, '/') + 1;
488
489         tcd = cfs_trace_get_tcd();
490
491         /* cfs_trace_get_tcd() grabs a lock, which disables preemption and
492          * pins us to a particular CPU.  This avoids an smp_processor_id()
493          * warning on Linux when debugging is enabled.
494          */
495         cfs_set_ptldebug_header(&header, msgdata, CDEBUG_STACK());
496
497         if (!tcd)                /* arch may not log in IRQ context */
498                 goto console;
499
500         if (tcd->tcd_cur_pages == 0)
501                 header.ph_flags |= PH_FLAG_FIRST_RECORD;
502
503         if (tcd->tcd_shutting_down) {
504                 cfs_trace_put_tcd(tcd);
505                 tcd = NULL;
506                 goto console;
507         }
508
509         known_size = strlen(file) + 1;
510         if (msgdata->msg_fn)
511                 known_size += strlen(msgdata->msg_fn) + 1;
512
513         if (libcfs_debug_binary)
514                 known_size += sizeof(header);
515
516         /*
517          * May perform an additional pass to update 'needed' and increase
518          * tage buffer size to match vsnprintf reported size required
519          * On the second pass (retry=1) use vscnprintf [which returns
520          * number of bytes written not including the terminating nul]
521          * to clarify `needed` is used as number of bytes written
522          * for the remainder of this function
523          */
524         for (retry = 0; retry < 2; retry++) {
525                 tage = cfs_trace_get_tage(tcd, needed + known_size + 1);
526                 if (!tage) {
527                         if (needed + known_size > PAGE_SIZE)
528                                 mask |= D_ERROR;
529
530                         cfs_trace_put_tcd(tcd);
531                         tcd = NULL;
532                         goto console;
533                 }
534
535                 string_buf = (char *)page_address(tage->page) +
536                              tage->used + known_size;
537
538                 max_nob = PAGE_SIZE - tage->used - known_size;
539                 if (max_nob <= 0) {
540                         pr_emerg("LustreError: negative max_nob: %d\n",
541                                  max_nob);
542                         mask |= D_ERROR;
543                         cfs_trace_put_tcd(tcd);
544                         tcd = NULL;
545                         goto console;
546                 }
547
548                 va_start(ap, format);
549                 if (retry)
550                         needed = vscnprintf(string_buf, max_nob, format, ap);
551                 else
552                         needed = vsnprintf(string_buf, max_nob, format, ap);
553                 va_end(ap);
554
555                 if (needed < max_nob) /* well. printing ok.. */
556                         break;
557         }
558
559         /* `needed` is actual bytes written to string_buf */
560         if (*(string_buf + needed - 1) != '\n') {
561                 pr_info("Lustre: format at %s:%d:%s doesn't end in newline\n",
562                         file, msgdata->msg_line, msgdata->msg_fn);
563         } else if (mask & D_TTY) {
564                 /* TTY needs '\r\n' to move carriage to leftmost position */
565                 if (needed < 2 || *(string_buf + needed - 2) != '\r')
566                         pr_info("Lustre: format at %s:%d:%s doesn't end in '\\r\\n'\n",
567                                 file, msgdata->msg_line, msgdata->msg_fn);
568         }
569
570         header.ph_len = known_size + needed;
571         debug_buf = (char *)page_address(tage->page) + tage->used;
572
573         if (libcfs_debug_binary) {
574                 memcpy(debug_buf, &header, sizeof(header));
575                 tage->used += sizeof(header);
576                 debug_buf += sizeof(header);
577         }
578
579         strlcpy(debug_buf, file, PAGE_SIZE - tage->used);
580         tage->used += strlen(file) + 1;
581         debug_buf += strlen(file) + 1;
582
583         if (msgdata->msg_fn) {
584                 strlcpy(debug_buf, msgdata->msg_fn, PAGE_SIZE - tage->used);
585                 tage->used += strlen(msgdata->msg_fn) + 1;
586                 debug_buf += strlen(msgdata->msg_fn) + 1;
587         }
588
589         __LASSERT(debug_buf == string_buf);
590
591         tage->used += needed;
592         __LASSERT(tage->used <= PAGE_SIZE);
593
594 console:
595         if ((mask & libcfs_printk) == 0) {
596                 /* no console output requested */
597                 if (tcd != NULL)
598                         cfs_trace_put_tcd(tcd);
599                 return 1;
600         }
601
602         if (cdls != NULL) {
603                 if (libcfs_console_ratelimit &&
604                     cdls->cdls_next != 0 &&     /* not first time ever */
605                     time_before(jiffies, cdls->cdls_next)) {
606                         /* skipping a console message */
607                         cdls->cdls_count++;
608                         if (tcd != NULL)
609                                 cfs_trace_put_tcd(tcd);
610                         return 1;
611                 }
612
613                 if (time_after(jiffies, cdls->cdls_next +
614                                         libcfs_console_max_delay +
615                                         cfs_time_seconds(10))) {
616                         /* last timeout was a long time ago */
617                         cdls->cdls_delay /= libcfs_console_backoff * 4;
618                 } else {
619                         cdls->cdls_delay *= libcfs_console_backoff;
620                 }
621
622                 if (cdls->cdls_delay < libcfs_console_min_delay)
623                         cdls->cdls_delay = libcfs_console_min_delay;
624                 else if (cdls->cdls_delay > libcfs_console_max_delay)
625                         cdls->cdls_delay = libcfs_console_max_delay;
626
627                 /* ensure cdls_next is never zero after it's been seen */
628                 cdls->cdls_next = (jiffies + cdls->cdls_delay) | 1;
629         }
630
631         if (tcd) {
632                 cfs_print_to_console(&header, mask, string_buf, needed, file,
633                                      msgdata->msg_fn);
634                 cfs_trace_put_tcd(tcd);
635         } else {
636                 string_buf = cfs_trace_get_console_buffer();
637
638                 va_start(ap, format);
639                 needed = vscnprintf(string_buf, CFS_TRACE_CONSOLE_BUFFER_SIZE,
640                                     format, ap);
641                 va_end(ap);
642
643                 cfs_print_to_console(&header, mask,
644                                      string_buf, needed, file, msgdata->msg_fn);
645
646                 put_cpu();
647         }
648
649         if (cdls != NULL && cdls->cdls_count != 0) {
650                 string_buf = cfs_trace_get_console_buffer();
651
652                 needed = scnprintf(string_buf, CFS_TRACE_CONSOLE_BUFFER_SIZE,
653                                    "Skipped %d previous similar message%s\n",
654                                    cdls->cdls_count,
655                                    (cdls->cdls_count > 1) ? "s" : "");
656
657                 /* Do not allow print this to TTY */
658                 cfs_print_to_console(&header, mask & ~D_TTY, string_buf,
659                                      needed, file, msgdata->msg_fn);
660
661                 put_cpu();
662                 cdls->cdls_count = 0;
663         }
664
665         return 0;
666 }
667 EXPORT_SYMBOL(libcfs_debug_msg);
668
669 void
670 cfs_trace_assertion_failed(const char *str,
671                            struct libcfs_debug_msg_data *msgdata)
672 {
673         struct ptldebug_header hdr;
674
675         libcfs_panic_in_progress = 1;
676         libcfs_catastrophe = 1;
677         smp_mb();
678
679         cfs_set_ptldebug_header(&hdr, msgdata, CDEBUG_STACK());
680
681         cfs_print_to_console(&hdr, D_EMERG, str, strlen(str),
682                              msgdata->msg_file, msgdata->msg_fn);
683
684         panic("Lustre debug assertion failure\n");
685
686         /* not reached */
687 }
688
689 static void
690 panic_collect_pages(struct page_collection *pc)
691 {
692         /* Do the collect_pages job on a single CPU: assumes that all other
693          * CPUs have been stopped during a panic.  If this isn't true for some
694          * arch, this will have to be implemented separately in each arch.  */
695         int                        i;
696         int                        j;
697         struct cfs_trace_cpu_data *tcd;
698
699         INIT_LIST_HEAD(&pc->pc_pages);
700
701         cfs_tcd_for_each(tcd, i, j) {
702                 list_splice_init(&tcd->tcd_pages, &pc->pc_pages);
703                 tcd->tcd_cur_pages = 0;
704
705                 if (pc->pc_want_daemon_pages) {
706                         list_splice_init(&tcd->tcd_daemon_pages,
707                                                 &pc->pc_pages);
708                         tcd->tcd_cur_daemon_pages = 0;
709                 }
710         }
711 }
712
713 static void collect_pages_on_all_cpus(struct page_collection *pc)
714 {
715         struct cfs_trace_cpu_data *tcd;
716         int i, cpu;
717
718         for_each_possible_cpu(cpu) {
719                 cfs_tcd_for_each_type_lock(tcd, i, cpu) {
720                         list_splice_init(&tcd->tcd_pages, &pc->pc_pages);
721                         tcd->tcd_cur_pages = 0;
722                         if (pc->pc_want_daemon_pages) {
723                                 list_splice_init(&tcd->tcd_daemon_pages,
724                                                         &pc->pc_pages);
725                                 tcd->tcd_cur_daemon_pages = 0;
726                         }
727                 }
728         }
729 }
730
731 static void collect_pages(struct page_collection *pc)
732 {
733         INIT_LIST_HEAD(&pc->pc_pages);
734
735         if (libcfs_panic_in_progress)
736                 panic_collect_pages(pc);
737         else
738                 collect_pages_on_all_cpus(pc);
739 }
740
741 static void put_pages_back_on_all_cpus(struct page_collection *pc)
742 {
743         struct cfs_trace_cpu_data *tcd;
744         struct list_head *cur_head;
745         struct cfs_trace_page *tage;
746         struct cfs_trace_page *tmp;
747         int i, cpu;
748
749         for_each_possible_cpu(cpu) {
750                 cfs_tcd_for_each_type_lock(tcd, i, cpu) {
751                         cur_head = tcd->tcd_pages.next;
752
753                         list_for_each_entry_safe(tage, tmp, &pc->pc_pages,
754                                                  linkage) {
755
756                                 __LASSERT_TAGE_INVARIANT(tage);
757
758                                 if (tage->cpu != cpu || tage->type != i)
759                                         continue;
760
761                                 cfs_tage_to_tail(tage, cur_head);
762                                 tcd->tcd_cur_pages++;
763                         }
764                 }
765         }
766 }
767
768 static void put_pages_back(struct page_collection *pc)
769 {
770         if (!libcfs_panic_in_progress)
771                 put_pages_back_on_all_cpus(pc);
772 }
773
774 /* Add pages to a per-cpu debug daemon ringbuffer.  This buffer makes sure that
775  * we have a good amount of data at all times for dumping during an LBUG, even
776  * if we have been steadily writing (and otherwise discarding) pages via the
777  * debug daemon. */
778 static void put_pages_on_tcd_daemon_list(struct page_collection *pc,
779                                          struct cfs_trace_cpu_data *tcd)
780 {
781         struct cfs_trace_page *tage;
782         struct cfs_trace_page *tmp;
783
784         list_for_each_entry_safe(tage, tmp, &pc->pc_pages, linkage) {
785                 __LASSERT_TAGE_INVARIANT(tage);
786
787                 if (tage->cpu != tcd->tcd_cpu || tage->type != tcd->tcd_type)
788                         continue;
789
790                 cfs_tage_to_tail(tage, &tcd->tcd_daemon_pages);
791                 tcd->tcd_cur_daemon_pages++;
792
793                 if (tcd->tcd_cur_daemon_pages > tcd->tcd_max_pages) {
794                         struct cfs_trace_page *victim;
795
796                         __LASSERT(!list_empty(&tcd->tcd_daemon_pages));
797                         victim = cfs_tage_from_list(tcd->tcd_daemon_pages.next);
798
799                         __LASSERT_TAGE_INVARIANT(victim);
800
801                         list_del(&victim->linkage);
802                         cfs_tage_free(victim);
803                         tcd->tcd_cur_daemon_pages--;
804                 }
805         }
806 }
807
808 static void put_pages_on_daemon_list(struct page_collection *pc)
809 {
810         struct cfs_trace_cpu_data *tcd;
811         int i, cpu;
812
813         for_each_possible_cpu(cpu) {
814                 cfs_tcd_for_each_type_lock(tcd, i, cpu)
815                         put_pages_on_tcd_daemon_list(pc, tcd);
816         }
817 }
818
819 void cfs_trace_debug_print(void)
820 {
821         struct page_collection pc;
822         struct cfs_trace_page *tage;
823         struct cfs_trace_page *tmp;
824
825         pc.pc_want_daemon_pages = 1;
826         collect_pages(&pc);
827         list_for_each_entry_safe(tage, tmp, &pc.pc_pages, linkage) {
828                 char *p, *file, *fn;
829                 struct page *page;
830
831                 __LASSERT_TAGE_INVARIANT(tage);
832
833                 page = tage->page;
834                 p = page_address(page);
835                 while (p < ((char *)page_address(page) + tage->used)) {
836                         struct ptldebug_header *hdr;
837                         int len;
838                         hdr = (void *)p;
839                         p += sizeof(*hdr);
840                         file = p;
841                         p += strlen(file) + 1;
842                         fn = p;
843                         p += strlen(fn) + 1;
844                         len = hdr->ph_len - (int)(p - (char *)hdr);
845
846                         cfs_print_to_console(hdr, D_EMERG, p, len, file, fn);
847
848                         p += len;
849                 }
850
851                 list_del(&tage->linkage);
852                 cfs_tage_free(tage);
853         }
854 }
855
856 int cfs_tracefile_dump_all_pages(char *filename)
857 {
858         struct page_collection  pc;
859         struct file             *filp;
860         struct cfs_trace_page   *tage;
861         struct cfs_trace_page   *tmp;
862         char                    *buf;
863         int rc;
864
865         down_write(&cfs_tracefile_sem);
866
867         filp = filp_open(filename, O_CREAT|O_EXCL|O_WRONLY|O_LARGEFILE, 0600);
868         if (IS_ERR(filp)) {
869                 rc = PTR_ERR(filp);
870                 filp = NULL;
871                 pr_err("LustreError: can't open %s for dump: rc = %d\n",
872                       filename, rc);
873                 goto out;
874         }
875
876         pc.pc_want_daemon_pages = 1;
877         collect_pages(&pc);
878         if (list_empty(&pc.pc_pages)) {
879                 rc = 0;
880                 goto close;
881         }
882
883         /* ok, for now, just write the pages.  in the future we'll be building
884          * iobufs with the pages and calling generic_direct_IO */
885         list_for_each_entry_safe(tage, tmp, &pc.pc_pages, linkage) {
886
887                 __LASSERT_TAGE_INVARIANT(tage);
888
889                 buf = kmap(tage->page);
890                 rc = cfs_kernel_write(filp, buf, tage->used, &filp->f_pos);
891                 kunmap(tage->page);
892                 if (rc != (int)tage->used) {
893                         pr_warn("Lustre: wanted to write %u but wrote %d\n",
894                                 tage->used, rc);
895                         put_pages_back(&pc);
896                         __LASSERT(list_empty(&pc.pc_pages));
897                         break;
898                 }
899                 list_del(&tage->linkage);
900                 cfs_tage_free(tage);
901         }
902
903         rc = vfs_fsync_range(filp, 0, LLONG_MAX, 1);
904         if (rc)
905                 pr_err("LustreError: sync returns: rc = %d\n", rc);
906 close:
907         filp_close(filp, NULL);
908 out:
909         up_write(&cfs_tracefile_sem);
910         return rc;
911 }
912
913 void cfs_trace_flush_pages(void)
914 {
915         struct page_collection pc;
916         struct cfs_trace_page *tage;
917         struct cfs_trace_page *tmp;
918
919         pc.pc_want_daemon_pages = 1;
920         collect_pages(&pc);
921         list_for_each_entry_safe(tage, tmp, &pc.pc_pages, linkage) {
922
923                 __LASSERT_TAGE_INVARIANT(tage);
924
925                 list_del(&tage->linkage);
926                 cfs_tage_free(tage);
927         }
928 }
929
930 int cfs_trace_copyin_string(char *knl_buffer, int knl_buffer_nob,
931                             const char __user *usr_buffer, int usr_buffer_nob)
932 {
933         int    nob;
934
935         if (usr_buffer_nob > knl_buffer_nob)
936                 return -EOVERFLOW;
937
938         if (copy_from_user(knl_buffer, usr_buffer, usr_buffer_nob))
939                 return -EFAULT;
940
941         nob = strnlen(knl_buffer, usr_buffer_nob);
942         while (--nob >= 0)                      /* strip trailing whitespace */
943                 if (!isspace(knl_buffer[nob]))
944                         break;
945
946         if (nob < 0)                            /* empty string */
947                 return -EINVAL;
948
949         if (nob == knl_buffer_nob)              /* no space to terminate */
950                 return -EOVERFLOW;
951
952         knl_buffer[nob + 1] = 0;                /* terminate */
953         return 0;
954 }
955 EXPORT_SYMBOL(cfs_trace_copyin_string);
956
957 int cfs_trace_copyout_string(char __user *usr_buffer, int usr_buffer_nob,
958                              const char *knl_buffer, char *append)
959 {
960         /* NB if 'append' != NULL, it's a single character to append to the
961          * copied out string - usually "\n", for /proc entries and "" (i.e. a
962          * terminating zero byte) for sysctl entries */
963         int   nob = strlen(knl_buffer);
964
965         if (nob > usr_buffer_nob)
966                 nob = usr_buffer_nob;
967
968         if (copy_to_user(usr_buffer, knl_buffer, nob))
969                 return -EFAULT;
970
971         if (append != NULL && nob < usr_buffer_nob) {
972                 if (copy_to_user(usr_buffer + nob, append, 1))
973                         return -EFAULT;
974
975                 nob++;
976         }
977
978         return nob;
979 }
980 EXPORT_SYMBOL(cfs_trace_copyout_string);
981
982 int cfs_trace_allocate_string_buffer(char **str, int nob)
983 {
984         if (nob > 2 * PAGE_SIZE)        /* string must be "sensible" */
985                 return -EINVAL;
986
987         *str = kmalloc(nob, GFP_KERNEL | __GFP_ZERO);
988         if (*str == NULL)
989                 return -ENOMEM;
990
991         return 0;
992 }
993
994 int cfs_trace_dump_debug_buffer_usrstr(void __user *usr_str, int usr_str_nob)
995 {
996         char         *str;
997         int           rc;
998
999         rc = cfs_trace_allocate_string_buffer(&str, usr_str_nob + 1);
1000         if (rc != 0)
1001                 return rc;
1002
1003         rc = cfs_trace_copyin_string(str, usr_str_nob + 1,
1004                                      usr_str, usr_str_nob);
1005         if (rc != 0)
1006                 goto out;
1007
1008         if (str[0] != '/') {
1009                 rc = -EINVAL;
1010                 goto out;
1011         }
1012         rc = cfs_tracefile_dump_all_pages(str);
1013 out:
1014         kfree(str);
1015         return rc;
1016 }
1017
1018 int cfs_trace_daemon_command(char *str)
1019 {
1020         int       rc = 0;
1021
1022         down_write(&cfs_tracefile_sem);
1023
1024         if (strcmp(str, "stop") == 0) {
1025                 up_write(&cfs_tracefile_sem);
1026                 cfs_trace_stop_thread();
1027                 down_write(&cfs_tracefile_sem);
1028                 memset(cfs_tracefile, 0, sizeof(cfs_tracefile));
1029
1030         } else if (strncmp(str, "size=", 5) == 0) {
1031                 unsigned long tmp;
1032
1033                 rc = kstrtoul(str + 5, 10, &tmp);
1034                 if (!rc) {
1035                         if (tmp < 10 || tmp > 20480)
1036                                 cfs_tracefile_size = CFS_TRACEFILE_SIZE;
1037                         else
1038                                 cfs_tracefile_size = tmp << 20;
1039                 }
1040         } else if (strlen(str) >= sizeof(cfs_tracefile)) {
1041                 rc = -ENAMETOOLONG;
1042         } else if (str[0] != '/') {
1043                 rc = -EINVAL;
1044         } else {
1045                 strcpy(cfs_tracefile, str);
1046
1047                 pr_info("Lustre: debug daemon will attempt to start writing to %s (%lukB max)\n",
1048                         cfs_tracefile, (long)(cfs_tracefile_size >> 10));
1049
1050                 cfs_trace_start_thread();
1051         }
1052
1053         up_write(&cfs_tracefile_sem);
1054         return rc;
1055 }
1056
1057 int cfs_trace_daemon_command_usrstr(void __user *usr_str, int usr_str_nob)
1058 {
1059         char *str;
1060         int   rc;
1061
1062         rc = cfs_trace_allocate_string_buffer(&str, usr_str_nob + 1);
1063         if (rc != 0)
1064                 return rc;
1065
1066         rc = cfs_trace_copyin_string(str, usr_str_nob + 1,
1067                                  usr_str, usr_str_nob);
1068         if (rc == 0)
1069                 rc = cfs_trace_daemon_command(str);
1070
1071         kfree(str);
1072         return rc;
1073 }
1074
1075 int cfs_trace_set_debug_mb(int mb)
1076 {
1077         int i;
1078         int j;
1079         unsigned long pages;
1080         unsigned long total_mb = (cfs_totalram_pages() >> (20 - PAGE_SHIFT));
1081         unsigned long limit = max_t(unsigned long, 512, (total_mb * 4) / 5);
1082         struct cfs_trace_cpu_data *tcd;
1083
1084         if (mb < num_possible_cpus()) {
1085                 pr_warn("Lustre: %d MB is too small for debug buffer size, setting it to %d MB.\n",
1086                         mb, num_possible_cpus());
1087                 mb = num_possible_cpus();
1088         }
1089
1090         if (mb > limit) {
1091                 pr_warn("Lustre: %d MB is too large for debug buffer size, setting it to %lu MB.\n",
1092                         mb, limit);
1093                 mb = limit;
1094         }
1095
1096         mb /= num_possible_cpus();
1097         pages = mb << (20 - PAGE_SHIFT);
1098
1099         down_write(&cfs_tracefile_sem);
1100
1101         cfs_tcd_for_each(tcd, i, j)
1102                 tcd->tcd_max_pages = (pages * tcd->tcd_pages_factor) / 100;
1103
1104         up_write(&cfs_tracefile_sem);
1105
1106         return mb;
1107 }
1108
1109 int cfs_trace_get_debug_mb(void)
1110 {
1111         int i;
1112         int j;
1113         struct cfs_trace_cpu_data *tcd;
1114         int total_pages = 0;
1115
1116         down_read(&cfs_tracefile_sem);
1117
1118         cfs_tcd_for_each(tcd, i, j)
1119                 total_pages += tcd->tcd_max_pages;
1120
1121         up_read(&cfs_tracefile_sem);
1122
1123         return (total_pages >> (20 - PAGE_SHIFT)) + 1;
1124 }
1125
1126 static int tracefiled(void *arg)
1127 {
1128         struct page_collection pc;
1129         struct tracefiled_ctl *tctl = arg;
1130         struct cfs_trace_page *tage;
1131         struct cfs_trace_page *tmp;
1132         struct file *filp;
1133         char *buf;
1134         int last_loop = 0;
1135         int rc;
1136
1137         /* we're started late enough that we pick up init's fs context */
1138         /* this is so broken in uml?  what on earth is going on? */
1139
1140         complete(&tctl->tctl_start);
1141
1142         while (1) {
1143                 wait_queue_entry_t __wait;
1144
1145                 pc.pc_want_daemon_pages = 0;
1146                 collect_pages(&pc);
1147                 if (list_empty(&pc.pc_pages))
1148                         goto end_loop;
1149
1150                 filp = NULL;
1151                 down_read(&cfs_tracefile_sem);
1152                 if (cfs_tracefile[0] != 0) {
1153                         filp = filp_open(cfs_tracefile,
1154                                          O_CREAT | O_RDWR | O_LARGEFILE,
1155                                          0600);
1156                         if (IS_ERR(filp)) {
1157                                 rc = PTR_ERR(filp);
1158                                 filp = NULL;
1159                                 pr_warn("Lustre: couldn't open %s: rc = %d\n",
1160                                         cfs_tracefile, rc);
1161                         }
1162                 }
1163                 up_read(&cfs_tracefile_sem);
1164                 if (filp == NULL) {
1165                         put_pages_on_daemon_list(&pc);
1166                         __LASSERT(list_empty(&pc.pc_pages));
1167                         goto end_loop;
1168                 }
1169
1170                 list_for_each_entry_safe(tage, tmp, &pc.pc_pages, linkage) {
1171                         struct dentry *de = file_dentry(filp);
1172                         static loff_t f_pos;
1173
1174                         __LASSERT_TAGE_INVARIANT(tage);
1175
1176                         if (f_pos >= (off_t)cfs_tracefile_size)
1177                                 f_pos = 0;
1178                         else if (f_pos > i_size_read(de->d_inode))
1179                                 f_pos = i_size_read(de->d_inode);
1180
1181                         buf = kmap(tage->page);
1182                         rc = cfs_kernel_write(filp, buf, tage->used, &f_pos);
1183                         kunmap(tage->page);
1184                         if (rc != (int)tage->used) {
1185                                 pr_warn("Lustre: wanted to write %u but wrote %d\n",
1186                                         tage->used, rc);
1187                                 put_pages_back(&pc);
1188                                 __LASSERT(list_empty(&pc.pc_pages));
1189                                 break;
1190                         }
1191                 }
1192
1193                 filp_close(filp, NULL);
1194                 put_pages_on_daemon_list(&pc);
1195                 if (!list_empty(&pc.pc_pages)) {
1196                         int i;
1197
1198                         pr_alert("Lustre: trace pages aren't empty\n");
1199                         pr_err("Lustre: total cpus(%d): ", num_possible_cpus());
1200                         for (i = 0; i < num_possible_cpus(); i++)
1201                                 if (cpu_online(i))
1202                                         pr_cont("%d(on) ", i);
1203                                 else
1204                                         pr_cont("%d(off) ", i);
1205                         pr_cont("\n");
1206
1207                         i = 0;
1208                         list_for_each_entry_safe(tage, tmp, &pc.pc_pages,
1209                                                  linkage)
1210                                 pr_err("Lustre: page %d belongs to cpu %d\n",
1211                                        ++i, tage->cpu);
1212                         pr_err("Lustre: There are %d pages unwritten\n", i);
1213                 }
1214                 __LASSERT(list_empty(&pc.pc_pages));
1215 end_loop:
1216                 if (atomic_read(&tctl->tctl_shutdown)) {
1217                         if (last_loop == 0) {
1218                                 last_loop = 1;
1219                                 continue;
1220                         } else {
1221                                 break;
1222                         }
1223                 }
1224                 init_waitqueue_entry(&__wait, current);
1225                 add_wait_queue(&tctl->tctl_waitq, &__wait);
1226                 schedule_timeout_interruptible(cfs_time_seconds(1));
1227                 remove_wait_queue(&tctl->tctl_waitq, &__wait);
1228         }
1229         complete(&tctl->tctl_stop);
1230         return 0;
1231 }
1232
1233 int cfs_trace_start_thread(void)
1234 {
1235         struct tracefiled_ctl *tctl = &trace_tctl;
1236         int rc = 0;
1237
1238         mutex_lock(&cfs_trace_thread_mutex);
1239         if (thread_running)
1240                 goto out;
1241
1242         init_completion(&tctl->tctl_start);
1243         init_completion(&tctl->tctl_stop);
1244         init_waitqueue_head(&tctl->tctl_waitq);
1245         atomic_set(&tctl->tctl_shutdown, 0);
1246
1247         if (IS_ERR(kthread_run(tracefiled, tctl, "ktracefiled"))) {
1248                 rc = -ECHILD;
1249                 goto out;
1250         }
1251
1252         wait_for_completion(&tctl->tctl_start);
1253         thread_running = 1;
1254 out:
1255         mutex_unlock(&cfs_trace_thread_mutex);
1256         return rc;
1257 }
1258
1259 void cfs_trace_stop_thread(void)
1260 {
1261         struct tracefiled_ctl *tctl = &trace_tctl;
1262
1263         mutex_lock(&cfs_trace_thread_mutex);
1264         if (thread_running) {
1265                 pr_info("Lustre: shutting down debug daemon thread...\n");
1266                 atomic_set(&tctl->tctl_shutdown, 1);
1267                 wait_for_completion(&tctl->tctl_stop);
1268                 thread_running = 0;
1269         }
1270         mutex_unlock(&cfs_trace_thread_mutex);
1271 }
1272
1273 int cfs_tracefile_init(int max_pages)
1274 {
1275         struct cfs_trace_cpu_data *tcd;
1276         int     i;
1277         int     j;
1278         int     rc;
1279         int     factor;
1280
1281         rc = cfs_tracefile_init_arch();
1282         if (rc != 0)
1283                 return rc;
1284
1285         cfs_tcd_for_each(tcd, i, j) {
1286                 /* tcd_pages_factor is initialized int tracefile_init_arch. */
1287                 factor = tcd->tcd_pages_factor;
1288                 INIT_LIST_HEAD(&tcd->tcd_pages);
1289                 INIT_LIST_HEAD(&tcd->tcd_stock_pages);
1290                 INIT_LIST_HEAD(&tcd->tcd_daemon_pages);
1291                 tcd->tcd_cur_pages = 0;
1292                 tcd->tcd_cur_stock_pages = 0;
1293                 tcd->tcd_cur_daemon_pages = 0;
1294                 tcd->tcd_max_pages = (max_pages * factor) / 100;
1295                 LASSERT(tcd->tcd_max_pages > 0);
1296                 tcd->tcd_shutting_down = 0;
1297         }
1298         return 0;
1299 }
1300
1301 static void trace_cleanup_on_all_cpus(void)
1302 {
1303         struct cfs_trace_cpu_data *tcd;
1304         struct cfs_trace_page *tage;
1305         struct cfs_trace_page *tmp;
1306         int i, cpu;
1307
1308         for_each_possible_cpu(cpu) {
1309                 cfs_tcd_for_each_type_lock(tcd, i, cpu) {
1310                         tcd->tcd_shutting_down = 1;
1311
1312                         list_for_each_entry_safe(tage, tmp, &tcd->tcd_pages, linkage) {
1313                                 __LASSERT_TAGE_INVARIANT(tage);
1314
1315                                 list_del(&tage->linkage);
1316                                 cfs_tage_free(tage);
1317                         }
1318                         tcd->tcd_cur_pages = 0;
1319                 }
1320         }
1321 }
1322
1323 static void cfs_trace_cleanup(void)
1324 {
1325         struct page_collection pc;
1326
1327         INIT_LIST_HEAD(&pc.pc_pages);
1328
1329         trace_cleanup_on_all_cpus();
1330
1331         cfs_tracefile_fini_arch();
1332 }
1333
1334 void cfs_tracefile_exit(void)
1335 {
1336         cfs_trace_stop_thread();
1337         cfs_trace_cleanup();
1338 }