]>
Commit | Line | Data |
---|---|---|
55abb092 BB |
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. | |
3d6af2dd | 9 | * For details, see <http://zfsonlinux.org/>. |
55abb092 BB |
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 */ |