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); |
