diff options
Diffstat (limited to 'kernel/marker.c')
-rw-r--r-- | kernel/marker.c | 41 |
1 files changed, 17 insertions, 24 deletions
diff --git a/kernel/marker.c b/kernel/marker.c index ccb48d9a3657..5323cfaedbce 100644 --- a/kernel/marker.c +++ b/kernel/marker.c | |||
@@ -28,7 +28,7 @@ extern struct marker __start___markers[]; | |||
28 | extern struct marker __stop___markers[]; | 28 | extern struct marker __stop___markers[]; |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * module_mutex nests inside markers_mutex. Markers mutex protects the builtin | 31 | * markers_mutex nests inside module_mutex. Markers mutex protects the builtin |
32 | * and module markers, the hash table and deferred_sync. | 32 | * and module markers, the hash table and deferred_sync. |
33 | */ | 33 | */ |
34 | static DEFINE_MUTEX(markers_mutex); | 34 | static DEFINE_MUTEX(markers_mutex); |
@@ -257,7 +257,6 @@ static void disable_marker(struct marker *elem) | |||
257 | * @refcount: number of references left to the given probe_module (out) | 257 | * @refcount: number of references left to the given probe_module (out) |
258 | * | 258 | * |
259 | * Updates the probe callback corresponding to a range of markers. | 259 | * Updates the probe callback corresponding to a range of markers. |
260 | * Must be called with markers_mutex held. | ||
261 | */ | 260 | */ |
262 | void marker_update_probe_range(struct marker *begin, | 261 | void marker_update_probe_range(struct marker *begin, |
263 | struct marker *end, struct module *probe_module, | 262 | struct marker *end, struct module *probe_module, |
@@ -266,6 +265,7 @@ void marker_update_probe_range(struct marker *begin, | |||
266 | struct marker *iter; | 265 | struct marker *iter; |
267 | struct marker_entry *mark_entry; | 266 | struct marker_entry *mark_entry; |
268 | 267 | ||
268 | mutex_lock(&markers_mutex); | ||
269 | for (iter = begin; iter < end; iter++) { | 269 | for (iter = begin; iter < end; iter++) { |
270 | mark_entry = get_marker(iter->name); | 270 | mark_entry = get_marker(iter->name); |
271 | if (mark_entry && mark_entry->refcount) { | 271 | if (mark_entry && mark_entry->refcount) { |
@@ -281,6 +281,7 @@ void marker_update_probe_range(struct marker *begin, | |||
281 | disable_marker(iter); | 281 | disable_marker(iter); |
282 | } | 282 | } |
283 | } | 283 | } |
284 | mutex_unlock(&markers_mutex); | ||
284 | } | 285 | } |
285 | 286 | ||
286 | /* | 287 | /* |
@@ -293,7 +294,6 @@ static void marker_update_probes(struct module *probe_module) | |||
293 | { | 294 | { |
294 | int refcount = 0; | 295 | int refcount = 0; |
295 | 296 | ||
296 | mutex_lock(&markers_mutex); | ||
297 | /* Core kernel markers */ | 297 | /* Core kernel markers */ |
298 | marker_update_probe_range(__start___markers, | 298 | marker_update_probe_range(__start___markers, |
299 | __stop___markers, probe_module, &refcount); | 299 | __stop___markers, probe_module, &refcount); |
@@ -303,7 +303,6 @@ static void marker_update_probes(struct module *probe_module) | |||
303 | synchronize_sched(); | 303 | synchronize_sched(); |
304 | deferred_sync = 0; | 304 | deferred_sync = 0; |
305 | } | 305 | } |
306 | mutex_unlock(&markers_mutex); | ||
307 | } | 306 | } |
308 | 307 | ||
309 | /** | 308 | /** |
@@ -320,7 +319,7 @@ int marker_probe_register(const char *name, const char *format, | |||
320 | marker_probe_func *probe, void *private) | 319 | marker_probe_func *probe, void *private) |
321 | { | 320 | { |
322 | struct marker_entry *entry; | 321 | struct marker_entry *entry; |
323 | int ret = 0, need_update = 0; | 322 | int ret = 0; |
324 | 323 | ||
325 | mutex_lock(&markers_mutex); | 324 | mutex_lock(&markers_mutex); |
326 | entry = get_marker(name); | 325 | entry = get_marker(name); |
@@ -335,11 +334,11 @@ int marker_probe_register(const char *name, const char *format, | |||
335 | ret = add_marker(name, format, probe, private); | 334 | ret = add_marker(name, format, probe, private); |
336 | if (ret) | 335 | if (ret) |
337 | goto end; | 336 | goto end; |
338 | need_update = 1; | 337 | mutex_unlock(&markers_mutex); |
338 | marker_update_probes(NULL); | ||
339 | return ret; | ||
339 | end: | 340 | end: |
340 | mutex_unlock(&markers_mutex); | 341 | mutex_unlock(&markers_mutex); |
341 | if (need_update) | ||
342 | marker_update_probes(NULL); | ||
343 | return ret; | 342 | return ret; |
344 | } | 343 | } |
345 | EXPORT_SYMBOL_GPL(marker_probe_register); | 344 | EXPORT_SYMBOL_GPL(marker_probe_register); |
@@ -355,7 +354,6 @@ void *marker_probe_unregister(const char *name) | |||
355 | struct module *probe_module; | 354 | struct module *probe_module; |
356 | struct marker_entry *entry; | 355 | struct marker_entry *entry; |
357 | void *private; | 356 | void *private; |
358 | int need_update = 0; | ||
359 | 357 | ||
360 | mutex_lock(&markers_mutex); | 358 | mutex_lock(&markers_mutex); |
361 | entry = get_marker(name); | 359 | entry = get_marker(name); |
@@ -368,11 +366,11 @@ void *marker_probe_unregister(const char *name) | |||
368 | probe_module = __module_text_address((unsigned long)entry->probe); | 366 | probe_module = __module_text_address((unsigned long)entry->probe); |
369 | private = remove_marker(name); | 367 | private = remove_marker(name); |
370 | deferred_sync = 1; | 368 | deferred_sync = 1; |
371 | need_update = 1; | 369 | mutex_unlock(&markers_mutex); |
370 | marker_update_probes(probe_module); | ||
371 | return private; | ||
372 | end: | 372 | end: |
373 | mutex_unlock(&markers_mutex); | 373 | mutex_unlock(&markers_mutex); |
374 | if (need_update) | ||
375 | marker_update_probes(probe_module); | ||
376 | return private; | 374 | return private; |
377 | } | 375 | } |
378 | EXPORT_SYMBOL_GPL(marker_probe_unregister); | 376 | EXPORT_SYMBOL_GPL(marker_probe_unregister); |
@@ -392,7 +390,6 @@ void *marker_probe_unregister_private_data(void *private) | |||
392 | struct marker_entry *entry; | 390 | struct marker_entry *entry; |
393 | int found = 0; | 391 | int found = 0; |
394 | unsigned int i; | 392 | unsigned int i; |
395 | int need_update = 0; | ||
396 | 393 | ||
397 | mutex_lock(&markers_mutex); | 394 | mutex_lock(&markers_mutex); |
398 | for (i = 0; i < MARKER_TABLE_SIZE; i++) { | 395 | for (i = 0; i < MARKER_TABLE_SIZE; i++) { |
@@ -414,11 +411,11 @@ iter_end: | |||
414 | probe_module = __module_text_address((unsigned long)entry->probe); | 411 | probe_module = __module_text_address((unsigned long)entry->probe); |
415 | private = remove_marker(entry->name); | 412 | private = remove_marker(entry->name); |
416 | deferred_sync = 1; | 413 | deferred_sync = 1; |
417 | need_update = 1; | 414 | mutex_unlock(&markers_mutex); |
415 | marker_update_probes(probe_module); | ||
416 | return private; | ||
418 | end: | 417 | end: |
419 | mutex_unlock(&markers_mutex); | 418 | mutex_unlock(&markers_mutex); |
420 | if (need_update) | ||
421 | marker_update_probes(probe_module); | ||
422 | return private; | 419 | return private; |
423 | } | 420 | } |
424 | EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data); | 421 | EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data); |
@@ -434,7 +431,7 @@ EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data); | |||
434 | int marker_arm(const char *name) | 431 | int marker_arm(const char *name) |
435 | { | 432 | { |
436 | struct marker_entry *entry; | 433 | struct marker_entry *entry; |
437 | int ret = 0, need_update = 0; | 434 | int ret = 0; |
438 | 435 | ||
439 | mutex_lock(&markers_mutex); | 436 | mutex_lock(&markers_mutex); |
440 | entry = get_marker(name); | 437 | entry = get_marker(name); |
@@ -447,11 +444,9 @@ int marker_arm(const char *name) | |||
447 | */ | 444 | */ |
448 | if (entry->refcount++) | 445 | if (entry->refcount++) |
449 | goto end; | 446 | goto end; |
450 | need_update = 1; | ||
451 | end: | 447 | end: |
452 | mutex_unlock(&markers_mutex); | 448 | mutex_unlock(&markers_mutex); |
453 | if (need_update) | 449 | marker_update_probes(NULL); |
454 | marker_update_probes(NULL); | ||
455 | return ret; | 450 | return ret; |
456 | } | 451 | } |
457 | EXPORT_SYMBOL_GPL(marker_arm); | 452 | EXPORT_SYMBOL_GPL(marker_arm); |
@@ -467,7 +462,7 @@ EXPORT_SYMBOL_GPL(marker_arm); | |||
467 | int marker_disarm(const char *name) | 462 | int marker_disarm(const char *name) |
468 | { | 463 | { |
469 | struct marker_entry *entry; | 464 | struct marker_entry *entry; |
470 | int ret = 0, need_update = 0; | 465 | int ret = 0; |
471 | 466 | ||
472 | mutex_lock(&markers_mutex); | 467 | mutex_lock(&markers_mutex); |
473 | entry = get_marker(name); | 468 | entry = get_marker(name); |
@@ -486,11 +481,9 @@ int marker_disarm(const char *name) | |||
486 | ret = -EPERM; | 481 | ret = -EPERM; |
487 | goto end; | 482 | goto end; |
488 | } | 483 | } |
489 | need_update = 1; | ||
490 | end: | 484 | end: |
491 | mutex_unlock(&markers_mutex); | 485 | mutex_unlock(&markers_mutex); |
492 | if (need_update) | 486 | marker_update_probes(NULL); |
493 | marker_update_probes(NULL); | ||
494 | return ret; | 487 | return ret; |
495 | } | 488 | } |
496 | EXPORT_SYMBOL_GPL(marker_disarm); | 489 | EXPORT_SYMBOL_GPL(marker_disarm); |