Skip to content

Commit

Permalink
Linux Kernel Markers: fix marker mutex not taken upon module load
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mathieu Desnoyers authored and Linus Torvalds committed Nov 15, 2007
1 parent f433dc5 commit 314de8a
Showing 1 changed file with 17 additions and 24 deletions.
41 changes: 17 additions & 24 deletions kernel/marker.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ extern struct marker __start___markers[];
extern struct marker __stop___markers[];

/*
* module_mutex nests inside markers_mutex. Markers mutex protects the builtin
* markers_mutex nests inside module_mutex. Markers mutex protects the builtin
* and module markers, the hash table and deferred_sync.
*/
static DEFINE_MUTEX(markers_mutex);
Expand Down Expand Up @@ -257,7 +257,6 @@ static void disable_marker(struct marker *elem)
* @refcount: number of references left to the given probe_module (out)
*
* Updates the probe callback corresponding to a range of markers.
* Must be called with markers_mutex held.
*/
void marker_update_probe_range(struct marker *begin,
struct marker *end, struct module *probe_module,
Expand All @@ -266,6 +265,7 @@ void marker_update_probe_range(struct marker *begin,
struct marker *iter;
struct marker_entry *mark_entry;

mutex_lock(&markers_mutex);
for (iter = begin; iter < end; iter++) {
mark_entry = get_marker(iter->name);
if (mark_entry && mark_entry->refcount) {
Expand All @@ -281,6 +281,7 @@ void marker_update_probe_range(struct marker *begin,
disable_marker(iter);
}
}
mutex_unlock(&markers_mutex);
}

/*
Expand All @@ -293,7 +294,6 @@ static void marker_update_probes(struct module *probe_module)
{
int refcount = 0;

mutex_lock(&markers_mutex);
/* Core kernel markers */
marker_update_probe_range(__start___markers,
__stop___markers, probe_module, &refcount);
Expand All @@ -303,7 +303,6 @@ static void marker_update_probes(struct module *probe_module)
synchronize_sched();
deferred_sync = 0;
}
mutex_unlock(&markers_mutex);
}

/**
Expand All @@ -320,7 +319,7 @@ int marker_probe_register(const char *name, const char *format,
marker_probe_func *probe, void *private)
{
struct marker_entry *entry;
int ret = 0, need_update = 0;
int ret = 0;

mutex_lock(&markers_mutex);
entry = get_marker(name);
Expand All @@ -335,11 +334,11 @@ int marker_probe_register(const char *name, const char *format,
ret = add_marker(name, format, probe, private);
if (ret)
goto end;
need_update = 1;
mutex_unlock(&markers_mutex);
marker_update_probes(NULL);
return ret;
end:
mutex_unlock(&markers_mutex);
if (need_update)
marker_update_probes(NULL);
return ret;
}
EXPORT_SYMBOL_GPL(marker_probe_register);
Expand All @@ -355,7 +354,6 @@ void *marker_probe_unregister(const char *name)
struct module *probe_module;
struct marker_entry *entry;
void *private;
int need_update = 0;

mutex_lock(&markers_mutex);
entry = get_marker(name);
Expand All @@ -368,11 +366,11 @@ void *marker_probe_unregister(const char *name)
probe_module = __module_text_address((unsigned long)entry->probe);
private = remove_marker(name);
deferred_sync = 1;
need_update = 1;
mutex_unlock(&markers_mutex);
marker_update_probes(probe_module);
return private;
end:
mutex_unlock(&markers_mutex);
if (need_update)
marker_update_probes(probe_module);
return private;
}
EXPORT_SYMBOL_GPL(marker_probe_unregister);
Expand All @@ -392,7 +390,6 @@ void *marker_probe_unregister_private_data(void *private)
struct marker_entry *entry;
int found = 0;
unsigned int i;
int need_update = 0;

mutex_lock(&markers_mutex);
for (i = 0; i < MARKER_TABLE_SIZE; i++) {
Expand All @@ -414,11 +411,11 @@ void *marker_probe_unregister_private_data(void *private)
probe_module = __module_text_address((unsigned long)entry->probe);
private = remove_marker(entry->name);
deferred_sync = 1;
need_update = 1;
mutex_unlock(&markers_mutex);
marker_update_probes(probe_module);
return private;
end:
mutex_unlock(&markers_mutex);
if (need_update)
marker_update_probes(probe_module);
return private;
}
EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data);
Expand All @@ -434,7 +431,7 @@ EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data);
int marker_arm(const char *name)
{
struct marker_entry *entry;
int ret = 0, need_update = 0;
int ret = 0;

mutex_lock(&markers_mutex);
entry = get_marker(name);
Expand All @@ -447,11 +444,9 @@ int marker_arm(const char *name)
*/
if (entry->refcount++)
goto end;
need_update = 1;
end:
mutex_unlock(&markers_mutex);
if (need_update)
marker_update_probes(NULL);
marker_update_probes(NULL);
return ret;
}
EXPORT_SYMBOL_GPL(marker_arm);
Expand All @@ -467,7 +462,7 @@ EXPORT_SYMBOL_GPL(marker_arm);
int marker_disarm(const char *name)
{
struct marker_entry *entry;
int ret = 0, need_update = 0;
int ret = 0;

mutex_lock(&markers_mutex);
entry = get_marker(name);
Expand All @@ -486,11 +481,9 @@ int marker_disarm(const char *name)
ret = -EPERM;
goto end;
}
need_update = 1;
end:
mutex_unlock(&markers_mutex);
if (need_update)
marker_update_probes(NULL);
marker_update_probes(NULL);
return ret;
}
EXPORT_SYMBOL_GPL(marker_disarm);
Expand Down

0 comments on commit 314de8a

Please sign in to comment.