Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Linux Kernel Markers: fix marker mutex not taken upon module load

Upon module load, we must take the markers mutex. It implies that the marker
mutex must be nested inside the module mutex.

It implies changing the nesting order : now the marker mutex nests inside the
module mutex. Make the necessary changes to reverse the order in which the
mutexes are taken.

Includes some cleanup from Dave Hansen <haveblue@us.ibm.com>.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Mathieu Desnoyers and committed by
Linus Torvalds
314de8a9 f433dc56

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