aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>2007-11-14 19:59:48 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-11-14 21:45:40 -0500
commit314de8a9e17f70243eacc80d2dd22a5d74b09fce (patch)
treebb802f67c89f3f188f93066842284e863ddd8a33
parentf433dc56344cb72cc3de5ba0819021cec3aef807 (diff)
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>
-rw-r--r--kernel/marker.c41
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[];
28extern struct marker __stop___markers[]; 28extern 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 */
34static DEFINE_MUTEX(markers_mutex); 34static 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 */
262void marker_update_probe_range(struct marker *begin, 261void 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;
339end: 340end:
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}
345EXPORT_SYMBOL_GPL(marker_probe_register); 344EXPORT_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;
372end: 372end:
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}
378EXPORT_SYMBOL_GPL(marker_probe_unregister); 376EXPORT_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;
418end: 417end:
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}
424EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data); 421EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data);
@@ -434,7 +431,7 @@ EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data);
434int marker_arm(const char *name) 431int 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;
451end: 447end:
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}
457EXPORT_SYMBOL_GPL(marker_arm); 452EXPORT_SYMBOL_GPL(marker_arm);
@@ -467,7 +462,7 @@ EXPORT_SYMBOL_GPL(marker_arm);
467int marker_disarm(const char *name) 462int 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;
490end: 484end:
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}
496EXPORT_SYMBOL_GPL(marker_disarm); 489EXPORT_SYMBOL_GPL(marker_disarm);