Blame view

drivers/dma-buf/sync_debug.c 5.8 KB
0f0d8406f   Maarten Lankhorst   android: convert ...
1
  /*
e912c881f   Gustavo Padovan   staging/android: ...
2
   * Sync File validation framework and debug information
0f0d8406f   Maarten Lankhorst   android: convert ...
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
   *
   * Copyright (C) 2012 Google, Inc.
   *
   * This software is licensed under the terms of the GNU General Public
   * License version 2, as published by the Free Software Foundation, and
   * may be copied, distributed, and modified under those terms.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   */
  
  #include <linux/debugfs.h>
1fe82e2e1   Gustavo Padovan   staging/android: ...
18
  #include "sync_debug.h"
0f0d8406f   Maarten Lankhorst   android: convert ...
19

8a0044846   Gustavo Padovan   staging/android: ...
20
  static struct dentry *dbgfs;
0f0d8406f   Maarten Lankhorst   android: convert ...
21
22
  static LIST_HEAD(sync_timeline_list_head);
  static DEFINE_SPINLOCK(sync_timeline_list_lock);
d7fdb0ae9   Gustavo Padovan   staging/android: ...
23
24
  static LIST_HEAD(sync_file_list_head);
  static DEFINE_SPINLOCK(sync_file_list_lock);
0f0d8406f   Maarten Lankhorst   android: convert ...
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
  
  void sync_timeline_debug_add(struct sync_timeline *obj)
  {
  	unsigned long flags;
  
  	spin_lock_irqsave(&sync_timeline_list_lock, flags);
  	list_add_tail(&obj->sync_timeline_list, &sync_timeline_list_head);
  	spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
  }
  
  void sync_timeline_debug_remove(struct sync_timeline *obj)
  {
  	unsigned long flags;
  
  	spin_lock_irqsave(&sync_timeline_list_lock, flags);
  	list_del(&obj->sync_timeline_list);
  	spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
  }
d7fdb0ae9   Gustavo Padovan   staging/android: ...
43
  void sync_file_debug_add(struct sync_file *sync_file)
0f0d8406f   Maarten Lankhorst   android: convert ...
44
45
  {
  	unsigned long flags;
d7fdb0ae9   Gustavo Padovan   staging/android: ...
46
47
48
  	spin_lock_irqsave(&sync_file_list_lock, flags);
  	list_add_tail(&sync_file->sync_file_list, &sync_file_list_head);
  	spin_unlock_irqrestore(&sync_file_list_lock, flags);
0f0d8406f   Maarten Lankhorst   android: convert ...
49
  }
d7fdb0ae9   Gustavo Padovan   staging/android: ...
50
  void sync_file_debug_remove(struct sync_file *sync_file)
0f0d8406f   Maarten Lankhorst   android: convert ...
51
52
  {
  	unsigned long flags;
d7fdb0ae9   Gustavo Padovan   staging/android: ...
53
54
55
  	spin_lock_irqsave(&sync_file_list_lock, flags);
  	list_del(&sync_file->sync_file_list);
  	spin_unlock_irqrestore(&sync_file_list_lock, flags);
0f0d8406f   Maarten Lankhorst   android: convert ...
56
57
58
59
60
61
  }
  
  static const char *sync_status_str(int status)
  {
  	if (status == 0)
  		return "signaled";
954513551   Peter Senna Tschudin   staging: android:...
62
63
  
  	if (status > 0)
0f0d8406f   Maarten Lankhorst   android: convert ...
64
  		return "active";
954513551   Peter Senna Tschudin   staging: android:...
65
66
  
  	return "error";
0f0d8406f   Maarten Lankhorst   android: convert ...
67
  }
b55b54b5d   Gustavo Padovan   staging/android: ...
68
  static void sync_print_fence(struct seq_file *s, struct fence *fence, bool show)
0f0d8406f   Maarten Lankhorst   android: convert ...
69
70
  {
  	int status = 1;
b55b54b5d   Gustavo Padovan   staging/android: ...
71
  	struct sync_timeline *parent = fence_parent(fence);
0f0d8406f   Maarten Lankhorst   android: convert ...
72

b55b54b5d   Gustavo Padovan   staging/android: ...
73
74
  	if (fence_is_signaled_locked(fence))
  		status = fence->status;
0f0d8406f   Maarten Lankhorst   android: convert ...
75

b55b54b5d   Gustavo Padovan   staging/android: ...
76
77
78
  	seq_printf(s, "  %s%sfence %s",
  		   show ? parent->name : "",
  		   show ? "_" : "",
0f0d8406f   Maarten Lankhorst   android: convert ...
79
80
81
  		   sync_status_str(status));
  
  	if (status <= 0) {
0541cdf58   Steve Pennington   Staging: android:...
82
  		struct timespec64 ts64 =
b55b54b5d   Gustavo Padovan   staging/android: ...
83
  			ktime_to_timespec64(fence->timestamp);
954513551   Peter Senna Tschudin   staging: android:...
84

353fdf170   Tapasweni Pathak   staging: android:...
85
  		seq_printf(s, "@%lld.%09ld", (s64)ts64.tv_sec, ts64.tv_nsec);
0f0d8406f   Maarten Lankhorst   android: convert ...
86
  	}
724812d6a   Gustavo Padovan   staging/android: ...
87
  	if (fence->ops->timeline_value_str &&
b55b54b5d   Gustavo Padovan   staging/android: ...
88
  		fence->ops->fence_value_str) {
0f0d8406f   Maarten Lankhorst   android: convert ...
89
  		char value[64];
73465f1c0   Maarten Lankhorst   staging/android/s...
90
  		bool success;
954513551   Peter Senna Tschudin   staging: android:...
91

b55b54b5d   Gustavo Padovan   staging/android: ...
92
  		fence->ops->fence_value_str(fence, value, sizeof(value));
73465f1c0   Maarten Lankhorst   staging/android/s...
93
  		success = strlen(value);
724812d6a   Gustavo Padovan   staging/android: ...
94
  		if (success) {
73465f1c0   Maarten Lankhorst   staging/android/s...
95
  			seq_printf(s, ": %s", value);
b55b54b5d   Gustavo Padovan   staging/android: ...
96
97
  			fence->ops->timeline_value_str(fence, value,
  						       sizeof(value));
73465f1c0   Maarten Lankhorst   staging/android/s...
98
99
100
  
  			if (strlen(value))
  				seq_printf(s, " / %s", value);
0f0d8406f   Maarten Lankhorst   android: convert ...
101
102
103
104
105
106
107
108
109
110
111
  		}
  	}
  
  	seq_puts(s, "
  ");
  }
  
  static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj)
  {
  	struct list_head *pos;
  	unsigned long flags;
b9bc2b7b6   Gustavo Padovan   staging/android: ...
112
113
  	seq_printf(s, "%s: %d
  ", obj->name, obj->value);
0f0d8406f   Maarten Lankhorst   android: convert ...
114
115
116
  
  	spin_lock_irqsave(&obj->child_list_lock, flags);
  	list_for_each(pos, &obj->child_list_head) {
0431b9065   Gustavo Padovan   staging/android: ...
117
118
119
  		struct sync_pt *pt =
  			container_of(pos, struct sync_pt, child_list);
  		sync_print_fence(s, &pt->base, false);
0f0d8406f   Maarten Lankhorst   android: convert ...
120
121
122
  	}
  	spin_unlock_irqrestore(&obj->child_list_lock, flags);
  }
d7fdb0ae9   Gustavo Padovan   staging/android: ...
123
124
  static void sync_print_sync_file(struct seq_file *s,
  				  struct sync_file *sync_file)
b55b54b5d   Gustavo Padovan   staging/android: ...
125
  {
0f0d8406f   Maarten Lankhorst   android: convert ...
126
  	int i;
d7fdb0ae9   Gustavo Padovan   staging/android: ...
127
128
  	seq_printf(s, "[%p] %s: %s
  ", sync_file, sync_file->name,
a02b9dc90   Gustavo Padovan   dma-buf/sync_file...
129
  		   sync_status_str(!fence_is_signaled(sync_file->fence)));
0f0d8406f   Maarten Lankhorst   android: convert ...
130

a02b9dc90   Gustavo Padovan   dma-buf/sync_file...
131
132
133
134
135
136
137
138
  	if (fence_is_array(sync_file->fence)) {
  		struct fence_array *array = to_fence_array(sync_file->fence);
  
  		for (i = 0; i < array->num_fences; ++i)
  			sync_print_fence(s, array->fences[i], true);
  	} else {
  		sync_print_fence(s, sync_file->fence, true);
  	}
b55b54b5d   Gustavo Padovan   staging/android: ...
139
  }
0f0d8406f   Maarten Lankhorst   android: convert ...
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
  static int sync_debugfs_show(struct seq_file *s, void *unused)
  {
  	unsigned long flags;
  	struct list_head *pos;
  
  	seq_puts(s, "objs:
  --------------
  ");
  
  	spin_lock_irqsave(&sync_timeline_list_lock, flags);
  	list_for_each(pos, &sync_timeline_list_head) {
  		struct sync_timeline *obj =
  			container_of(pos, struct sync_timeline,
  				     sync_timeline_list);
  
  		sync_print_obj(s, obj);
  		seq_puts(s, "
  ");
  	}
  	spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
  
  	seq_puts(s, "fences:
  --------------
  ");
d7fdb0ae9   Gustavo Padovan   staging/android: ...
164
165
166
167
  	spin_lock_irqsave(&sync_file_list_lock, flags);
  	list_for_each(pos, &sync_file_list_head) {
  		struct sync_file *sync_file =
  			container_of(pos, struct sync_file, sync_file_list);
0f0d8406f   Maarten Lankhorst   android: convert ...
168

d7fdb0ae9   Gustavo Padovan   staging/android: ...
169
  		sync_print_sync_file(s, sync_file);
0f0d8406f   Maarten Lankhorst   android: convert ...
170
171
172
  		seq_puts(s, "
  ");
  	}
d7fdb0ae9   Gustavo Padovan   staging/android: ...
173
  	spin_unlock_irqrestore(&sync_file_list_lock, flags);
0f0d8406f   Maarten Lankhorst   android: convert ...
174
175
  	return 0;
  }
8a0044846   Gustavo Padovan   staging/android: ...
176
  static int sync_info_debugfs_open(struct inode *inode, struct file *file)
0f0d8406f   Maarten Lankhorst   android: convert ...
177
178
179
  {
  	return single_open(file, sync_debugfs_show, inode->i_private);
  }
8a0044846   Gustavo Padovan   staging/android: ...
180
181
  static const struct file_operations sync_info_debugfs_fops = {
  	.open           = sync_info_debugfs_open,
0f0d8406f   Maarten Lankhorst   android: convert ...
182
183
184
185
186
187
188
  	.read           = seq_read,
  	.llseek         = seq_lseek,
  	.release        = single_release,
  };
  
  static __init int sync_debugfs_init(void)
  {
8a0044846   Gustavo Padovan   staging/android: ...
189
  	dbgfs = debugfs_create_dir("sync", NULL);
0fd9da9a9   Nicolai Stange   staging/android: ...
190
191
192
193
194
195
196
197
198
  	/*
  	 * The debugfs files won't ever get removed and thus, there is
  	 * no need to protect it against removal races. The use of
  	 * debugfs_create_file_unsafe() is actually safe here.
  	 */
  	debugfs_create_file_unsafe("info", 0444, dbgfs, NULL,
  				   &sync_info_debugfs_fops);
  	debugfs_create_file_unsafe("sw_sync", 0644, dbgfs, NULL,
  				   &sw_sync_debugfs_fops);
8a0044846   Gustavo Padovan   staging/android: ...
199

0f0d8406f   Maarten Lankhorst   android: convert ...
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
  	return 0;
  }
  late_initcall(sync_debugfs_init);
  
  #define DUMP_CHUNK 256
  static char sync_dump_buf[64 * 1024];
  void sync_dump(void)
  {
  	struct seq_file s = {
  		.buf = sync_dump_buf,
  		.size = sizeof(sync_dump_buf) - 1,
  	};
  	int i;
  
  	sync_debugfs_show(&s, NULL);
  
  	for (i = 0; i < s.count; i += DUMP_CHUNK) {
  		if ((s.count - i) > DUMP_CHUNK) {
  			char c = s.buf[i + DUMP_CHUNK];
954513551   Peter Senna Tschudin   staging: android:...
219

0f0d8406f   Maarten Lankhorst   android: convert ...
220
221
222
223
224
225
226
227
228
  			s.buf[i + DUMP_CHUNK] = 0;
  			pr_cont("%s", s.buf + i);
  			s.buf[i + DUMP_CHUNK] = c;
  		} else {
  			s.buf[s.count] = 0;
  			pr_cont("%s", s.buf + i);
  		}
  	}
  }