Blame view

kernel/marker.c 25.2 KB
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  /*
   * Copyright (C) 2007 Mathieu Desnoyers
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * 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.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   */
  #include <linux/module.h>
  #include <linux/mutex.h>
  #include <linux/types.h>
  #include <linux/jhash.h>
  #include <linux/list.h>
  #include <linux/rcupdate.h>
  #include <linux/marker.h>
  #include <linux/err.h>
1aeb272cf   Robert P. J. Day   kernel: explicitl...
26
  #include <linux/slab.h>
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
27
28
29
  
  extern struct marker __start___markers[];
  extern struct marker __stop___markers[];
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
30
  /* Set to 1 to enable marker debug output */
ab883af53   Adrian Bunk   make marker_debug...
31
  static const int marker_debug;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
32

8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
33
  /*
314de8a9e   Mathieu Desnoyers   Linux Kernel Mark...
34
   * markers_mutex nests inside module_mutex. Markers mutex protects the builtin
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
35
   * and module markers and the hash table.
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
36
37
38
39
   */
  static DEFINE_MUTEX(markers_mutex);
  
  /*
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
40
41
42
43
44
   * Marker hash table, containing the active markers.
   * Protected by module_mutex.
   */
  #define MARKER_HASH_BITS 6
  #define MARKER_TABLE_SIZE (1 << MARKER_HASH_BITS)
4de62748e   Lai Jiangshan   markers: let mark...
45
  static struct hlist_head marker_table[MARKER_TABLE_SIZE];
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
46

fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
47
48
49
50
51
52
53
54
  /*
   * Note about RCU :
   * It is used to make sure every handler has finished using its private data
   * between two consecutive operation (add or remove) on a given marker.  It is
   * also used to delay the free of multiple probes array until a quiescent state
   * is reached.
   * marker entries modifications are protected by the markers_mutex.
   */
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
55
56
57
  struct marker_entry {
  	struct hlist_node hlist;
  	char *format;
dc102a8fa   Mathieu Desnoyers   Markers - remove ...
58
59
  			/* Probe wrapper */
  	void (*call)(const struct marker *mdata, void *call_private, ...);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
60
61
  	struct marker_probe_closure single;
  	struct marker_probe_closure *multi;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
62
  	int refcount;	/* Number of times armed. 0 if disarmed. */
ed86a5907   Mathieu Desnoyers   markers: re-enabl...
63
64
  	struct rcu_head rcu;
  	void *oldptr;
1b7ae37c0   Lai Jiangshan   markers: bit-fiel...
65
  	int rcu_pending;
de4fc64f0   Harvey Harrison   markers: fix spar...
66
  	unsigned char ptype:1;
0eec481e8   Lai Jiangshan   markers: simplify...
67
  	unsigned char format_allocated:1;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
68
69
  	char name[0];	/* Contains name'\0'format'\0' */
  };
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
70
71
  /**
   * __mark_empty_function - Empty probe callback
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
72
73
   * @probe_private: probe private data
   * @call_private: call site private data
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
74
75
76
77
78
79
80
81
   * @fmt: format string
   * @...: variable argument list
   *
   * Empty callback provided as a probe to the markers. By providing this to a
   * disabled marker, we make sure the  execution flow is always valid even
   * though the function pointer change and the marker enabling are two distinct
   * operations that modifies the execution flow of preemptible code.
   */
021aeb057   Mathieu Desnoyers   markers: use rcu_...
82
  notrace void __mark_empty_function(void *probe_private, void *call_private,
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
83
  	const char *fmt, va_list *args)
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
84
85
86
87
88
  {
  }
  EXPORT_SYMBOL_GPL(__mark_empty_function);
  
  /*
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
89
90
91
   * marker_probe_cb Callback that prepares the variable argument list for probes.
   * @mdata: pointer of type struct marker
   * @call_private: caller site private data
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
92
93
94
95
96
97
   * @...:  Variable argument list.
   *
   * Since we do not use "typical" pointer based RCU in the 1 argument case, we
   * need to put a full smp_rmb() in this branch. This is why we do not use
   * rcu_dereference() for the pointer read.
   */
021aeb057   Mathieu Desnoyers   markers: use rcu_...
98
99
  notrace void marker_probe_cb(const struct marker *mdata,
  		void *call_private, ...)
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
100
101
102
103
104
  {
  	va_list args;
  	char ptype;
  
  	/*
e2d3b75db   Mathieu Desnoyers   markers: fix unre...
105
106
107
  	 * rcu_read_lock_sched does two things : disabling preemption to make
  	 * sure the teardown of the callbacks can be done correctly when they
  	 * are in modules and they insure RCU read coherency.
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
108
  	 */
021aeb057   Mathieu Desnoyers   markers: use rcu_...
109
  	rcu_read_lock_sched_notrace();
58336114a   Mathieu Desnoyers   markers: remove A...
110
  	ptype = mdata->ptype;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
111
112
113
114
115
  	if (likely(!ptype)) {
  		marker_probe_func *func;
  		/* Must read the ptype before ptr. They are not data dependant,
  		 * so we put an explicit smp_rmb() here. */
  		smp_rmb();
58336114a   Mathieu Desnoyers   markers: remove A...
116
  		func = mdata->single.func;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
117
118
119
  		/* Must read the ptr before private data. They are not data
  		 * dependant, so we put an explicit smp_rmb() here. */
  		smp_rmb();
dc102a8fa   Mathieu Desnoyers   Markers - remove ...
120
121
122
  		va_start(args, call_private);
  		func(mdata->single.probe_private, call_private, mdata->format,
  			&args);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
123
124
125
126
127
  		va_end(args);
  	} else {
  		struct marker_probe_closure *multi;
  		int i;
  		/*
5def9a3a2   Mathieu Desnoyers   markers: fix mark...
128
129
130
131
132
  		 * Read mdata->ptype before mdata->multi.
  		 */
  		smp_rmb();
  		multi = mdata->multi;
  		/*
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
133
134
135
136
137
138
139
  		 * multi points to an array, therefore accessing the array
  		 * depends on reading multi. However, even in this case,
  		 * we must insure that the pointer is read _before_ the array
  		 * data. Same as rcu_dereference, but we need a full smp_rmb()
  		 * in the fast path, so put the explicit barrier here.
  		 */
  		smp_read_barrier_depends();
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
140
  		for (i = 0; multi[i].func; i++) {
dc102a8fa   Mathieu Desnoyers   Markers - remove ...
141
142
143
  			va_start(args, call_private);
  			multi[i].func(multi[i].probe_private, call_private,
  				mdata->format, &args);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
144
145
146
  			va_end(args);
  		}
  	}
021aeb057   Mathieu Desnoyers   markers: use rcu_...
147
  	rcu_read_unlock_sched_notrace();
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
148
149
150
151
152
153
154
  }
  EXPORT_SYMBOL_GPL(marker_probe_cb);
  
  /*
   * marker_probe_cb Callback that does not prepare the variable argument list.
   * @mdata: pointer of type struct marker
   * @call_private: caller site private data
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
155
156
157
158
   * @...:  Variable argument list.
   *
   * Should be connected to markers "MARK_NOARGS".
   */
021aeb057   Mathieu Desnoyers   markers: use rcu_...
159
160
  static notrace void marker_probe_cb_noarg(const struct marker *mdata,
  		void *call_private, ...)
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
161
162
163
  {
  	va_list args;	/* not initialized */
  	char ptype;
021aeb057   Mathieu Desnoyers   markers: use rcu_...
164
  	rcu_read_lock_sched_notrace();
58336114a   Mathieu Desnoyers   markers: remove A...
165
  	ptype = mdata->ptype;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
166
167
168
169
170
  	if (likely(!ptype)) {
  		marker_probe_func *func;
  		/* Must read the ptype before ptr. They are not data dependant,
  		 * so we put an explicit smp_rmb() here. */
  		smp_rmb();
58336114a   Mathieu Desnoyers   markers: remove A...
171
  		func = mdata->single.func;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
172
173
174
  		/* Must read the ptr before private data. They are not data
  		 * dependant, so we put an explicit smp_rmb() here. */
  		smp_rmb();
dc102a8fa   Mathieu Desnoyers   Markers - remove ...
175
176
  		func(mdata->single.probe_private, call_private, mdata->format,
  			&args);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
177
178
179
180
  	} else {
  		struct marker_probe_closure *multi;
  		int i;
  		/*
5def9a3a2   Mathieu Desnoyers   markers: fix mark...
181
182
183
184
185
  		 * Read mdata->ptype before mdata->multi.
  		 */
  		smp_rmb();
  		multi = mdata->multi;
  		/*
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
186
187
188
189
190
191
192
  		 * multi points to an array, therefore accessing the array
  		 * depends on reading multi. However, even in this case,
  		 * we must insure that the pointer is read _before_ the array
  		 * data. Same as rcu_dereference, but we need a full smp_rmb()
  		 * in the fast path, so put the explicit barrier here.
  		 */
  		smp_read_barrier_depends();
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
193
  		for (i = 0; multi[i].func; i++)
dc102a8fa   Mathieu Desnoyers   Markers - remove ...
194
195
  			multi[i].func(multi[i].probe_private, call_private,
  				mdata->format, &args);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
196
  	}
021aeb057   Mathieu Desnoyers   markers: use rcu_...
197
  	rcu_read_unlock_sched_notrace();
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
198
  }
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
199

ed86a5907   Mathieu Desnoyers   markers: re-enabl...
200
201
202
203
204
205
206
207
208
  static void free_old_closure(struct rcu_head *head)
  {
  	struct marker_entry *entry = container_of(head,
  		struct marker_entry, rcu);
  	kfree(entry->oldptr);
  	/* Make sure we free the data before setting the pending flag to 0 */
  	smp_wmb();
  	entry->rcu_pending = 0;
  }
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
  static void debug_print_probes(struct marker_entry *entry)
  {
  	int i;
  
  	if (!marker_debug)
  		return;
  
  	if (!entry->ptype) {
  		printk(KERN_DEBUG "Single probe : %p %p
  ",
  			entry->single.func,
  			entry->single.probe_private);
  	} else {
  		for (i = 0; entry->multi[i].func; i++)
  			printk(KERN_DEBUG "Multi probe %d : %p %p
  ", i,
  				entry->multi[i].func,
  				entry->multi[i].probe_private);
  	}
  }
  
  static struct marker_probe_closure *
  marker_entry_add_probe(struct marker_entry *entry,
  		marker_probe_func *probe, void *probe_private)
  {
  	int nr_probes = 0;
  	struct marker_probe_closure *old, *new;
  
  	WARN_ON(!probe);
  
  	debug_print_probes(entry);
  	old = entry->multi;
  	if (!entry->ptype) {
  		if (entry->single.func == probe &&
  				entry->single.probe_private == probe_private)
  			return ERR_PTR(-EBUSY);
  		if (entry->single.func == __mark_empty_function) {
  			/* 0 -> 1 probes */
  			entry->single.func = probe;
  			entry->single.probe_private = probe_private;
  			entry->refcount = 1;
  			entry->ptype = 0;
  			debug_print_probes(entry);
  			return NULL;
  		} else {
  			/* 1 -> 2 probes */
  			nr_probes = 1;
  			old = NULL;
  		}
  	} else {
  		/* (N -> N+1), (N != 0, 1) probes */
  		for (nr_probes = 0; old[nr_probes].func; nr_probes++)
  			if (old[nr_probes].func == probe
  					&& old[nr_probes].probe_private
  						== probe_private)
  				return ERR_PTR(-EBUSY);
  	}
  	/* + 2 : one for new probe, one for NULL func */
  	new = kzalloc((nr_probes + 2) * sizeof(struct marker_probe_closure),
  			GFP_KERNEL);
  	if (new == NULL)
  		return ERR_PTR(-ENOMEM);
  	if (!old)
  		new[0] = entry->single;
  	else
  		memcpy(new, old,
  			nr_probes * sizeof(struct marker_probe_closure));
  	new[nr_probes].func = probe;
  	new[nr_probes].probe_private = probe_private;
  	entry->refcount = nr_probes + 1;
  	entry->multi = new;
  	entry->ptype = 1;
  	debug_print_probes(entry);
  	return old;
  }
  
  static struct marker_probe_closure *
  marker_entry_remove_probe(struct marker_entry *entry,
  		marker_probe_func *probe, void *probe_private)
  {
  	int nr_probes = 0, nr_del = 0, i;
  	struct marker_probe_closure *old, *new;
  
  	old = entry->multi;
  
  	debug_print_probes(entry);
  	if (!entry->ptype) {
  		/* 0 -> N is an error */
  		WARN_ON(entry->single.func == __mark_empty_function);
  		/* 1 -> 0 probes */
  		WARN_ON(probe && entry->single.func != probe);
  		WARN_ON(entry->single.probe_private != probe_private);
  		entry->single.func = __mark_empty_function;
  		entry->refcount = 0;
  		entry->ptype = 0;
  		debug_print_probes(entry);
  		return NULL;
  	} else {
  		/* (N -> M), (N > 1, M >= 0) probes */
  		for (nr_probes = 0; old[nr_probes].func; nr_probes++) {
  			if ((!probe || old[nr_probes].func == probe)
  					&& old[nr_probes].probe_private
  						== probe_private)
  				nr_del++;
  		}
  	}
  
  	if (nr_probes - nr_del == 0) {
  		/* N -> 0, (N > 1) */
  		entry->single.func = __mark_empty_function;
  		entry->refcount = 0;
  		entry->ptype = 0;
  	} else if (nr_probes - nr_del == 1) {
  		/* N -> 1, (N > 1) */
  		for (i = 0; old[i].func; i++)
  			if ((probe && old[i].func != probe) ||
  					old[i].probe_private != probe_private)
  				entry->single = old[i];
  		entry->refcount = 1;
  		entry->ptype = 0;
  	} else {
  		int j = 0;
  		/* N -> M, (N > 1, M > 1) */
  		/* + 1 for NULL */
  		new = kzalloc((nr_probes - nr_del + 1)
  			* sizeof(struct marker_probe_closure), GFP_KERNEL);
  		if (new == NULL)
  			return ERR_PTR(-ENOMEM);
  		for (i = 0; old[i].func; i++)
  			if ((probe && old[i].func != probe) ||
  					old[i].probe_private != probe_private)
  				new[j++] = old[i];
  		entry->refcount = nr_probes - nr_del;
  		entry->ptype = 1;
  		entry->multi = new;
  	}
  	debug_print_probes(entry);
  	return old;
  }
  
  /*
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
   * Get marker if the marker is present in the marker hash table.
   * Must be called with markers_mutex held.
   * Returns NULL if not present.
   */
  static struct marker_entry *get_marker(const char *name)
  {
  	struct hlist_head *head;
  	struct hlist_node *node;
  	struct marker_entry *e;
  	u32 hash = jhash(name, strlen(name), 0);
  
  	head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
  	hlist_for_each_entry(e, node, head, hlist) {
  		if (!strcmp(name, e->name))
  			return e;
  	}
  	return NULL;
  }
  
  /*
   * Add the marker to the marker hash table. Must be called with markers_mutex
   * held.
   */
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
373
  static struct marker_entry *add_marker(const char *name, const char *format)
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
374
375
376
377
378
379
380
381
382
383
384
385
386
387
  {
  	struct hlist_head *head;
  	struct hlist_node *node;
  	struct marker_entry *e;
  	size_t name_len = strlen(name) + 1;
  	size_t format_len = 0;
  	u32 hash = jhash(name, name_len-1, 0);
  
  	if (format)
  		format_len = strlen(format) + 1;
  	head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
  	hlist_for_each_entry(e, node, head, hlist) {
  		if (!strcmp(name, e->name)) {
  			printk(KERN_NOTICE
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
388
389
390
  				"Marker %s busy
  ", name);
  			return ERR_PTR(-EBUSY);	/* Already there */
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
391
392
393
394
395
396
397
398
399
  		}
  	}
  	/*
  	 * Using kmalloc here to allocate a variable length element. Could
  	 * cause some memory fragmentation if overused.
  	 */
  	e = kmalloc(sizeof(struct marker_entry) + name_len + format_len,
  			GFP_KERNEL);
  	if (!e)
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
400
  		return ERR_PTR(-ENOMEM);
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
401
402
403
404
  	memcpy(&e->name[0], name, name_len);
  	if (format) {
  		e->format = &e->name[name_len];
  		memcpy(e->format, format, format_len);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
405
406
407
408
  		if (strcmp(e->format, MARK_NOARGS) == 0)
  			e->call = marker_probe_cb_noarg;
  		else
  			e->call = marker_probe_cb;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
409
410
  		trace_mark(core_marker_format, "name %s format %s",
  				e->name, e->format);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
411
  	} else {
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
412
  		e->format = NULL;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
413
414
415
416
417
418
  		e->call = marker_probe_cb;
  	}
  	e->single.func = __mark_empty_function;
  	e->single.probe_private = NULL;
  	e->multi = NULL;
  	e->ptype = 0;
0eec481e8   Lai Jiangshan   markers: simplify...
419
  	e->format_allocated = 0;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
420
  	e->refcount = 0;
ed86a5907   Mathieu Desnoyers   markers: re-enabl...
421
  	e->rcu_pending = 0;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
422
  	hlist_add_head(&e->hlist, head);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
423
  	return e;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
424
425
426
427
428
429
  }
  
  /*
   * Remove the marker from the marker hash table. Must be called with mutex_lock
   * held.
   */
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
430
  static int remove_marker(const char *name)
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
431
432
433
434
435
436
  {
  	struct hlist_head *head;
  	struct hlist_node *node;
  	struct marker_entry *e;
  	int found = 0;
  	size_t len = strlen(name) + 1;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
437
438
439
440
441
442
443
444
445
  	u32 hash = jhash(name, len-1, 0);
  
  	head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
  	hlist_for_each_entry(e, node, head, hlist) {
  		if (!strcmp(name, e->name)) {
  			found = 1;
  			break;
  		}
  	}
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
446
447
448
449
450
  	if (!found)
  		return -ENOENT;
  	if (e->single.func != __mark_empty_function)
  		return -EBUSY;
  	hlist_del(&e->hlist);
0eec481e8   Lai Jiangshan   markers: simplify...
451
452
  	if (e->format_allocated)
  		kfree(e->format);
ed86a5907   Mathieu Desnoyers   markers: re-enabl...
453
454
455
  	/* Make sure the call_rcu has been executed */
  	if (e->rcu_pending)
  		rcu_barrier_sched();
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
456
457
  	kfree(e);
  	return 0;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
458
459
460
461
462
  }
  
  /*
   * Set the mark_entry format to the format found in the element.
   */
0eec481e8   Lai Jiangshan   markers: simplify...
463
  static int marker_set_format(struct marker_entry *entry, const char *format)
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
464
  {
0eec481e8   Lai Jiangshan   markers: simplify...
465
466
  	entry->format = kstrdup(format, GFP_KERNEL);
  	if (!entry->format)
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
467
  		return -ENOMEM;
0eec481e8   Lai Jiangshan   markers: simplify...
468
  	entry->format_allocated = 1;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
469
  	trace_mark(core_marker_format, "name %s format %s",
0eec481e8   Lai Jiangshan   markers: simplify...
470
  			entry->name, entry->format);
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
471
472
473
474
475
476
  	return 0;
  }
  
  /*
   * Sets the probe callback corresponding to one marker.
   */
0eec481e8   Lai Jiangshan   markers: simplify...
477
  static int set_marker(struct marker_entry *entry, struct marker *elem,
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
478
  		int active)
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
479
  {
c1df1bd2c   Mathieu Desnoyers   markers: auto ena...
480
  	int ret = 0;
0eec481e8   Lai Jiangshan   markers: simplify...
481
  	WARN_ON(strcmp(entry->name, elem->name) != 0);
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
482

0eec481e8   Lai Jiangshan   markers: simplify...
483
484
  	if (entry->format) {
  		if (strcmp(entry->format, elem->format) != 0) {
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
485
486
487
488
  			printk(KERN_NOTICE
  				"Format mismatch for probe %s "
  				"(%s), marker (%s)
  ",
0eec481e8   Lai Jiangshan   markers: simplify...
489
490
  				entry->name,
  				entry->format,
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
491
492
493
494
495
496
497
498
  				elem->format);
  			return -EPERM;
  		}
  	} else {
  		ret = marker_set_format(entry, elem->format);
  		if (ret)
  			return ret;
  	}
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
499
500
501
502
503
504
505
  
  	/*
  	 * probe_cb setup (statically known) is done here. It is
  	 * asynchronous with the rest of execution, therefore we only
  	 * pass from a "safe" callback (with argument) to an "unsafe"
  	 * callback (does not set arguments).
  	 */
0eec481e8   Lai Jiangshan   markers: simplify...
506
  	elem->call = entry->call;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
507
508
509
510
511
512
  	/*
  	 * Sanity check :
  	 * We only update the single probe private data when the ptr is
  	 * set to a _non_ single probe! (0 -> 1 and N -> 1, N != 1)
  	 */
  	WARN_ON(elem->single.func != __mark_empty_function
0eec481e8   Lai Jiangshan   markers: simplify...
513
514
515
  		&& elem->single.probe_private != entry->single.probe_private
  		&& !elem->ptype);
  	elem->single.probe_private = entry->single.probe_private;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
516
517
518
519
520
  	/*
  	 * Make sure the private data is valid when we update the
  	 * single probe ptr.
  	 */
  	smp_wmb();
0eec481e8   Lai Jiangshan   markers: simplify...
521
  	elem->single.func = entry->single.func;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
522
523
524
525
  	/*
  	 * We also make sure that the new probe callbacks array is consistent
  	 * before setting a pointer to it.
  	 */
0eec481e8   Lai Jiangshan   markers: simplify...
526
  	rcu_assign_pointer(elem->multi, entry->multi);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
527
528
529
530
531
  	/*
  	 * Update the function or multi probe array pointer before setting the
  	 * ptype.
  	 */
  	smp_wmb();
0eec481e8   Lai Jiangshan   markers: simplify...
532
  	elem->ptype = entry->ptype;
c1df1bd2c   Mathieu Desnoyers   markers: auto ena...
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
  
  	if (elem->tp_name && (active ^ elem->state)) {
  		WARN_ON(!elem->tp_cb);
  		/*
  		 * It is ok to directly call the probe registration because type
  		 * checking has been done in the __trace_mark_tp() macro.
  		 */
  
  		if (active) {
  			/*
  			 * try_module_get should always succeed because we hold
  			 * lock_module() to get the tp_cb address.
  			 */
  			ret = try_module_get(__module_text_address(
  				(unsigned long)elem->tp_cb));
  			BUG_ON(!ret);
  			ret = tracepoint_probe_register_noupdate(
  				elem->tp_name,
  				elem->tp_cb);
  		} else {
  			ret = tracepoint_probe_unregister_noupdate(
  				elem->tp_name,
  				elem->tp_cb);
  			/*
  			 * tracepoint_probe_update_all() must be called
  			 * before the module containing tp_cb is unloaded.
  			 */
  			module_put(__module_text_address(
  				(unsigned long)elem->tp_cb));
  		}
  	}
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
564
  	elem->state = active;
c1df1bd2c   Mathieu Desnoyers   markers: auto ena...
565
  	return ret;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
566
567
568
569
  }
  
  /*
   * Disable a marker and its probe callback.
fd3c36f8b   Mathieu Desnoyers   markers: update p...
570
571
   * Note: only waiting an RCU period after setting elem->call to the empty
   * function insures that the original callback is not used anymore. This insured
e2d3b75db   Mathieu Desnoyers   markers: fix unre...
572
   * by rcu_read_lock_sched around the call site.
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
573
574
575
   */
  static void disable_marker(struct marker *elem)
  {
c1df1bd2c   Mathieu Desnoyers   markers: auto ena...
576
  	int ret;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
577
  	/* leave "call" as is. It is known statically. */
c1df1bd2c   Mathieu Desnoyers   markers: auto ena...
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
  	if (elem->tp_name && elem->state) {
  		WARN_ON(!elem->tp_cb);
  		/*
  		 * It is ok to directly call the probe registration because type
  		 * checking has been done in the __trace_mark_tp() macro.
  		 */
  		ret = tracepoint_probe_unregister_noupdate(elem->tp_name,
  			elem->tp_cb);
  		WARN_ON(ret);
  		/*
  		 * tracepoint_probe_update_all() must be called
  		 * before the module containing tp_cb is unloaded.
  		 */
  		module_put(__module_text_address((unsigned long)elem->tp_cb));
  	}
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
593
  	elem->state = 0;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
594
595
596
597
  	elem->single.func = __mark_empty_function;
  	/* Update the function before setting the ptype */
  	smp_wmb();
  	elem->ptype = 0;	/* single probe */
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
598
599
  	/*
  	 * Leave the private data and id there, because removal is racy and
fd3c36f8b   Mathieu Desnoyers   markers: update p...
600
601
  	 * should be done only after an RCU period. These are never used until
  	 * the next initialization anyway.
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
602
603
604
605
606
607
608
  	 */
  }
  
  /**
   * marker_update_probe_range - Update a probe range
   * @begin: beginning of the range
   * @end: end of the range
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
609
610
   *
   * Updates the probe callback corresponding to a range of markers.
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
611
612
   */
  void marker_update_probe_range(struct marker *begin,
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
613
  	struct marker *end)
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
614
615
616
  {
  	struct marker *iter;
  	struct marker_entry *mark_entry;
314de8a9e   Mathieu Desnoyers   Linux Kernel Mark...
617
  	mutex_lock(&markers_mutex);
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
618
619
  	for (iter = begin; iter < end; iter++) {
  		mark_entry = get_marker(iter->name);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
620
  		if (mark_entry) {
0eec481e8   Lai Jiangshan   markers: simplify...
621
  			set_marker(mark_entry, iter, !!mark_entry->refcount);
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
622
623
624
  			/*
  			 * ignore error, continue
  			 */
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
625
626
627
628
  		} else {
  			disable_marker(iter);
  		}
  	}
314de8a9e   Mathieu Desnoyers   Linux Kernel Mark...
629
  	mutex_unlock(&markers_mutex);
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
630
631
632
633
  }
  
  /*
   * Update probes, removing the faulty probes.
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
634
635
636
637
638
639
640
641
642
643
644
645
646
647
   *
   * Internal callback only changed before the first probe is connected to it.
   * Single probe private data can only be changed on 0 -> 1 and 2 -> 1
   * transitions.  All other transitions will leave the old private data valid.
   * This makes the non-atomicity of the callback/private data updates valid.
   *
   * "special case" updates :
   * 0 -> 1 callback
   * 1 -> 0 callback
   * 1 -> 2 callbacks
   * 2 -> 1 callbacks
   * Other updates all behave the same, just like the 2 -> 3 or 3 -> 2 updates.
   * Site effect : marker_set_format may delete the marker entry (creating a
   * replacement).
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
648
   */
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
649
  static void marker_update_probes(void)
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
650
  {
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
651
  	/* Core kernel markers */
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
652
  	marker_update_probe_range(__start___markers, __stop___markers);
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
653
  	/* Markers in modules. */
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
654
  	module_update_markers();
c1df1bd2c   Mathieu Desnoyers   markers: auto ena...
655
  	tracepoint_probe_update_all();
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
656
657
658
659
660
661
662
  }
  
  /**
   * marker_probe_register -  Connect a probe to a marker
   * @name: marker name
   * @format: format string
   * @probe: probe handler
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
663
   * @probe_private: probe private data
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
664
665
666
   *
   * private data must be a valid allocated memory address, or NULL.
   * Returns 0 if ok, error value on error.
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
667
   * The probe address must at least be aligned on the architecture pointer size.
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
668
669
   */
  int marker_probe_register(const char *name, const char *format,
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
670
  			marker_probe_func *probe, void *probe_private)
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
671
672
  {
  	struct marker_entry *entry;
314de8a9e   Mathieu Desnoyers   Linux Kernel Mark...
673
  	int ret = 0;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
674
  	struct marker_probe_closure *old;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
675
676
677
  
  	mutex_lock(&markers_mutex);
  	entry = get_marker(name);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
678
679
  	if (!entry) {
  		entry = add_marker(name, format);
48043bcdf   Lai Jiangshan   markers: fix unch...
680
  		if (IS_ERR(entry))
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
681
  			ret = PTR_ERR(entry);
48043bcdf   Lai Jiangshan   markers: fix unch...
682
683
  	} else if (format) {
  		if (!entry->format)
0eec481e8   Lai Jiangshan   markers: simplify...
684
  			ret = marker_set_format(entry, format);
48043bcdf   Lai Jiangshan   markers: fix unch...
685
686
  		else if (strcmp(entry->format, format))
  			ret = -EPERM;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
687
  	}
48043bcdf   Lai Jiangshan   markers: fix unch...
688
689
  	if (ret)
  		goto end;
ed86a5907   Mathieu Desnoyers   markers: re-enabl...
690
691
692
693
694
695
  	/*
  	 * If we detect that a call_rcu is pending for this marker,
  	 * make sure it's executed now.
  	 */
  	if (entry->rcu_pending)
  		rcu_barrier_sched();
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
696
697
698
  	old = marker_entry_add_probe(entry, probe, probe_private);
  	if (IS_ERR(old)) {
  		ret = PTR_ERR(old);
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
699
  		goto end;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
700
  	}
314de8a9e   Mathieu Desnoyers   Linux Kernel Mark...
701
  	mutex_unlock(&markers_mutex);
2bdba316c   Mathieu Desnoyers   markers: fix unre...
702
  	marker_update_probes();
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
703
704
  	mutex_lock(&markers_mutex);
  	entry = get_marker(name);
2bdba316c   Mathieu Desnoyers   markers: fix unre...
705
706
  	if (!entry)
  		goto end;
ed86a5907   Mathieu Desnoyers   markers: re-enabl...
707
708
709
710
711
712
713
  	if (entry->rcu_pending)
  		rcu_barrier_sched();
  	entry->oldptr = old;
  	entry->rcu_pending = 1;
  	/* write rcu_pending before calling the RCU callback */
  	smp_wmb();
  	call_rcu_sched(&entry->rcu, free_old_closure);
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
714
715
  end:
  	mutex_unlock(&markers_mutex);
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
716
717
718
719
720
721
722
  	return ret;
  }
  EXPORT_SYMBOL_GPL(marker_probe_register);
  
  /**
   * marker_probe_unregister -  Disconnect a probe from a marker
   * @name: marker name
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
723
724
   * @probe: probe function pointer
   * @probe_private: probe private data
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
725
726
   *
   * Returns the private data given to marker_probe_register, or an ERR_PTR().
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
727
728
729
730
   * We do not need to call a synchronize_sched to make sure the probes have
   * finished running before doing a module unload, because the module unload
   * itself uses stop_machine(), which insures that every preempt disabled section
   * have finished.
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
731
   */
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
732
733
  int marker_probe_unregister(const char *name,
  	marker_probe_func *probe, void *probe_private)
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
734
  {
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
735
  	struct marker_entry *entry;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
736
  	struct marker_probe_closure *old;
544adb410   Jesper Juhl   markers: don't ri...
737
  	int ret = -ENOENT;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
738
739
740
  
  	mutex_lock(&markers_mutex);
  	entry = get_marker(name);
544adb410   Jesper Juhl   markers: don't ri...
741
  	if (!entry)
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
742
  		goto end;
ed86a5907   Mathieu Desnoyers   markers: re-enabl...
743
744
  	if (entry->rcu_pending)
  		rcu_barrier_sched();
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
745
  	old = marker_entry_remove_probe(entry, probe, probe_private);
314de8a9e   Mathieu Desnoyers   Linux Kernel Mark...
746
  	mutex_unlock(&markers_mutex);
2bdba316c   Mathieu Desnoyers   markers: fix unre...
747
  	marker_update_probes();
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
748
749
  	mutex_lock(&markers_mutex);
  	entry = get_marker(name);
544adb410   Jesper Juhl   markers: don't ri...
750
751
  	if (!entry)
  		goto end;
ed86a5907   Mathieu Desnoyers   markers: re-enabl...
752
753
754
755
756
757
758
  	if (entry->rcu_pending)
  		rcu_barrier_sched();
  	entry->oldptr = old;
  	entry->rcu_pending = 1;
  	/* write rcu_pending before calling the RCU callback */
  	smp_wmb();
  	call_rcu_sched(&entry->rcu, free_old_closure);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
759
  	remove_marker(name);	/* Ignore busy error message */
544adb410   Jesper Juhl   markers: don't ri...
760
  	ret = 0;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
761
762
  end:
  	mutex_unlock(&markers_mutex);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
763
  	return ret;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
764
765
  }
  EXPORT_SYMBOL_GPL(marker_probe_unregister);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
766
767
  static struct marker_entry *
  get_marker_from_private_data(marker_probe_func *probe, void *probe_private)
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
768
  {
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
769
  	struct marker_entry *entry;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
770
  	unsigned int i;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
771
772
  	struct hlist_head *head;
  	struct hlist_node *node;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
773

8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
774
775
776
  	for (i = 0; i < MARKER_TABLE_SIZE; i++) {
  		head = &marker_table[i];
  		hlist_for_each_entry(entry, node, head, hlist) {
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
777
778
779
780
781
782
783
784
785
786
787
788
789
790
  			if (!entry->ptype) {
  				if (entry->single.func == probe
  						&& entry->single.probe_private
  						== probe_private)
  					return entry;
  			} else {
  				struct marker_probe_closure *closure;
  				closure = entry->multi;
  				for (i = 0; closure[i].func; i++) {
  					if (closure[i].func == probe &&
  							closure[i].probe_private
  							== probe_private)
  						return entry;
  				}
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
791
792
793
  			}
  		}
  	}
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
794
  	return NULL;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
795
  }
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
796
797
  
  /**
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
798
799
800
   * marker_probe_unregister_private_data -  Disconnect a probe from a marker
   * @probe: probe function
   * @probe_private: probe private data
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
801
   *
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
802
803
804
805
806
807
808
   * Unregister a probe by providing the registered private data.
   * Only removes the first marker found in hash table.
   * Return 0 on success or error value.
   * We do not need to call a synchronize_sched to make sure the probes have
   * finished running before doing a module unload, because the module unload
   * itself uses stop_machine(), which insures that every preempt disabled section
   * have finished.
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
809
   */
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
810
811
  int marker_probe_unregister_private_data(marker_probe_func *probe,
  		void *probe_private)
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
812
813
  {
  	struct marker_entry *entry;
314de8a9e   Mathieu Desnoyers   Linux Kernel Mark...
814
  	int ret = 0;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
815
  	struct marker_probe_closure *old;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
816
817
  
  	mutex_lock(&markers_mutex);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
818
  	entry = get_marker_from_private_data(probe, probe_private);
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
819
820
821
822
  	if (!entry) {
  		ret = -ENOENT;
  		goto end;
  	}
ed86a5907   Mathieu Desnoyers   markers: re-enabl...
823
824
  	if (entry->rcu_pending)
  		rcu_barrier_sched();
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
825
  	old = marker_entry_remove_probe(entry, NULL, probe_private);
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
826
  	mutex_unlock(&markers_mutex);
2bdba316c   Mathieu Desnoyers   markers: fix unre...
827
  	marker_update_probes();
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
828
  	mutex_lock(&markers_mutex);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
829
  	entry = get_marker_from_private_data(probe, probe_private);
2bdba316c   Mathieu Desnoyers   markers: fix unre...
830
831
  	if (!entry)
  		goto end;
ed86a5907   Mathieu Desnoyers   markers: re-enabl...
832
833
834
835
836
837
838
  	if (entry->rcu_pending)
  		rcu_barrier_sched();
  	entry->oldptr = old;
  	entry->rcu_pending = 1;
  	/* write rcu_pending before calling the RCU callback */
  	smp_wmb();
  	call_rcu_sched(&entry->rcu, free_old_closure);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
839
  	remove_marker(entry->name);	/* Ignore busy error message */
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
840
841
  end:
  	mutex_unlock(&markers_mutex);
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
842
843
  	return ret;
  }
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
844
  EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data);
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
845
846
847
848
  
  /**
   * marker_get_private_data - Get a marker's probe private data
   * @name: marker name
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
849
850
   * @probe: probe to match
   * @num: get the nth matching probe's private data
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
851
   *
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
852
853
   * Returns the nth private data pointer (starting from 0) matching, or an
   * ERR_PTR.
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
854
855
856
857
858
   * Returns the private data pointer, or an ERR_PTR.
   * The private data pointer should _only_ be dereferenced if the caller is the
   * owner of the data, or its content could vanish. This is mostly used to
   * confirm that a caller is the owner of a registered probe.
   */
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
859
860
  void *marker_get_private_data(const char *name, marker_probe_func *probe,
  		int num)
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
861
862
863
864
865
866
  {
  	struct hlist_head *head;
  	struct hlist_node *node;
  	struct marker_entry *e;
  	size_t name_len = strlen(name) + 1;
  	u32 hash = jhash(name, name_len-1, 0);
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
867
  	int i;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
868
869
870
871
  
  	head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
  	hlist_for_each_entry(e, node, head, hlist) {
  		if (!strcmp(name, e->name)) {
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
872
873
874
  			if (!e->ptype) {
  				if (num == 0 && e->single.func == probe)
  					return e->single.probe_private;
fb40bd78b   Mathieu Desnoyers   Linux Kernel Mark...
875
876
877
878
879
880
881
882
883
884
885
  			} else {
  				struct marker_probe_closure *closure;
  				int match = 0;
  				closure = e->multi;
  				for (i = 0; closure[i].func; i++) {
  					if (closure[i].func != probe)
  						continue;
  					if (match++ == num)
  						return closure[i].probe_private;
  				}
  			}
5d9881ea1   Zhaolei   markers: break th...
886
  			break;
8256e47cd   Mathieu Desnoyers   Linux Kernel Markers
887
888
889
890
891
  		}
  	}
  	return ERR_PTR(-ENOENT);
  }
  EXPORT_SYMBOL_GPL(marker_get_private_data);
a419246ac   Mathieu Desnoyers   markers: use modu...
892

227a83756   Ingo Molnar   markers/tracpoint...
893
  #ifdef CONFIG_MODULES
a419246ac   Mathieu Desnoyers   markers: use modu...
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
  int marker_module_notify(struct notifier_block *self,
  			 unsigned long val, void *data)
  {
  	struct module *mod = data;
  
  	switch (val) {
  	case MODULE_STATE_COMING:
  		marker_update_probe_range(mod->markers,
  			mod->markers + mod->num_markers);
  		break;
  	case MODULE_STATE_GOING:
  		marker_update_probe_range(mod->markers,
  			mod->markers + mod->num_markers);
  		break;
  	}
  	return 0;
  }
  
  struct notifier_block marker_module_nb = {
  	.notifier_call = marker_module_notify,
  	.priority = 0,
  };
  
  static int init_markers(void)
  {
  	return register_module_notifier(&marker_module_nb);
  }
  __initcall(init_markers);
227a83756   Ingo Molnar   markers/tracpoint...
922
923
  
  #endif /* CONFIG_MODULES */