]> git.proxmox.com Git - mirror_spl-debian.git/blob - include/spl-trace.h
Imported Upstream version 0.6.1
[mirror_spl-debian.git] / include / spl-trace.h
1 /*****************************************************************************\
2 * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
3 * Copyright (C) 2007 The Regents of the University of California.
4 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
5 * Written by Brian Behlendorf <behlendorf1@llnl.gov>.
6 * UCRL-CODE-235197
7 *
8 * This file is part of the SPL, Solaris Porting Layer.
9 * For details, see <http://zfsonlinux.org/>.
10 *
11 * The SPL is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 * The SPL is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 * for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with the SPL. If not, see <http://www.gnu.org/licenses/>.
23 \*****************************************************************************/
24
25 #ifndef _SPL_TRACE_H
26 #define _SPL_TRACE_H
27
28 #define TCD_MAX_PAGES (5 << (20 - PAGE_SHIFT))
29 #define TCD_STOCK_PAGES (TCD_MAX_PAGES)
30 #define TRACE_CONSOLE_BUFFER_SIZE 1024
31
32 #define SPL_DEFAULT_MAX_DELAY (600 * HZ)
33 #define SPL_DEFAULT_MIN_DELAY ((HZ + 1) / 2)
34 #define SPL_DEFAULT_BACKOFF 2
35
36 #define DL_NOTHREAD 0x0001 /* Do not create a new thread */
37 #define DL_SINGLE_CPU 0x0002 /* Collect pages from this CPU*/
38
39 typedef struct dumplog_priv {
40 wait_queue_head_t dp_waitq;
41 pid_t dp_pid;
42 int dp_flags;
43 atomic_t dp_done;
44 } dumplog_priv_t;
45
46 /* Three trace data types */
47 typedef enum {
48 TCD_TYPE_PROC,
49 TCD_TYPE_SOFTIRQ,
50 TCD_TYPE_IRQ,
51 TCD_TYPE_MAX
52 } tcd_type_t;
53
54 union trace_data_union {
55 struct trace_cpu_data {
56 /* pages with trace records not yet processed by tracefiled */
57 struct list_head tcd_pages;
58 /* number of pages on ->tcd_pages */
59 unsigned long tcd_cur_pages;
60 /* Max number of pages allowed on ->tcd_pages */
61 unsigned long tcd_max_pages;
62
63 /*
64 * preallocated pages to write trace records into. Pages from
65 * ->tcd_stock_pages are moved to ->tcd_pages by spl_debug_msg().
66 *
67 * This list is necessary, because on some platforms it's
68 * impossible to perform efficient atomic page allocation in a
69 * non-blockable context.
70 *
71 * Such platforms fill ->tcd_stock_pages "on occasion", when
72 * tracing code is entered in blockable context.
73 *
74 * trace_get_tage_try() tries to get a page from
75 * ->tcd_stock_pages first and resorts to atomic page
76 * allocation only if this queue is empty. ->tcd_stock_pages
77 * is replenished when tracing code is entered in blocking
78 * context (darwin-tracefile.c:trace_get_tcd()). We try to
79 * maintain TCD_STOCK_PAGES (40 by default) pages in this
80 * queue. Atomic allocation is only required if more than
81 * TCD_STOCK_PAGES pagesful are consumed by trace records all
82 * emitted in non-blocking contexts. Which is quite unlikely.
83 */
84 struct list_head tcd_stock_pages;
85 /* number of pages on ->tcd_stock_pages */
86 unsigned long tcd_cur_stock_pages;
87
88 unsigned short tcd_shutting_down;
89 unsigned short tcd_cpu;
90 unsigned short tcd_type;
91 /* The factors to share debug memory. */
92 unsigned short tcd_pages_factor;
93
94 /*
95 * This spinlock is needed to workaround the problem of
96 * set_cpus_allowed() being GPL-only. Since we cannot
97 * schedule a thread on a specific CPU when dumping the
98 * pages, we must use the spinlock for mutual exclusion.
99 */
100 spinlock_t tcd_lock;
101 unsigned long tcd_lock_flags;
102 } tcd;
103 char __pad[L1_CACHE_ALIGN(sizeof(struct trace_cpu_data))];
104 };
105
106 extern union trace_data_union (*trace_data[TCD_TYPE_MAX])[NR_CPUS];
107
108 #define tcd_for_each(tcd, i, j) \
109 for (i = 0; i < TCD_TYPE_MAX && trace_data[i]; i++) \
110 for (j = 0, ((tcd) = &(*trace_data[i])[j].tcd); \
111 j < num_possible_cpus(); j++, (tcd) = &(*trace_data[i])[j].tcd)
112
113 #define tcd_for_each_type_lock(tcd, i, cpu) \
114 for (i = 0; i < TCD_TYPE_MAX && trace_data[i] && \
115 (tcd = &(*trace_data[i])[cpu].tcd) && \
116 trace_lock_tcd(tcd); trace_unlock_tcd(tcd), i++)
117
118 struct trace_page {
119 struct page *page; /* page itself */
120 struct list_head linkage; /* Used by trace_data_union */
121 unsigned int used; /* number of bytes used within this page */
122 unsigned short cpu; /* cpu that owns this page */
123 unsigned short type; /* type(context) of this page */
124 };
125
126 struct page_collection {
127 struct list_head pc_pages;
128 spinlock_t pc_lock;
129 int pc_want_daemon_pages;
130 };
131
132 #endif /* SPL_TRACE_H */