Thread (1 message) 1 message, 1 author, 2009-11-22

[2.6.32-rc8] set_all_monitor_traces() sleeping bug.

From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Date: 2009-11-22 13:49:11
Also in: lkml

Commit: 4ea7e38696c7e798c47ebbecadfd392f23f814f9

set_all_monitor_traces() calls tracepoint_synchronize_unregister()
with a spinlock held, but tracepoint_synchronize_unregister() may sleep.

static int set_all_monitor_traces(int state)
{
	int rc = 0;
	struct dm_hw_stat_delta *new_stat = NULL;
	struct dm_hw_stat_delta *temp;

	spin_lock(&trace_state_lock);

	switch (state) {
	case TRACE_ON:
		rc |= register_trace_kfree_skb(trace_kfree_skb_hit);
		rc |= register_trace_napi_poll(trace_napi_poll_hit);
		break;
	case TRACE_OFF:
		rc |= unregister_trace_kfree_skb(trace_kfree_skb_hit);
		rc |= unregister_trace_napi_poll(trace_napi_poll_hit);

		tracepoint_synchronize_unregister();

		/*
		 * Clean the device list
		 */
		list_for_each_entry_safe(new_stat, temp, &hw_stats_list, list) {
			if (new_stat->dev == NULL) {
				list_del_rcu(&new_stat->list);
				call_rcu(&new_stat->rcu, free_dm_hw_stat);
			}
		}
		break;
	default:
		rc = 1;
		break;
	}

	if (!rc)
		trace_state = state;

	spin_unlock(&trace_state_lock);

	if (rc)
		return -EINPROGRESS;
	return rc;
}
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help